Updated resource editor: Improve autocomplete. Bugfix for table editor on chrome. Decrease indentation on conversation tree. Shorten strings in conversation tree. Dynamically calculate item store prices and monster exp. Tooltip for "follow next phrase" button in conversation editor.

git-svn-id: https://andors-trail.googlecode.com/svn/trunk@83 08aca716-68be-ccc6-4d58-36f5abd142ac
This commit is contained in:
oskar.wiksten
2011-05-07 14:42:14 +00:00
parent 8744c9f890
commit 0165021017
12 changed files with 140 additions and 350 deletions

View File

@@ -183,7 +183,7 @@ public final class ResourceLoader {
loader.prepareTileset(R.drawable.monsters_warrior1, "monsters_warrior1", src_sz1x1, defaultTileSize);
//loader.prepareTileset(R.drawable.monsters_wraiths, "monsters_wraiths", new Size(3, 1), defaultTileSize);
loader.prepareTileset(R.drawable.monsters_zombie1, "monsters_zombie1", src_sz1x1, defaultTileSize);
loader.prepareTileset(R.drawable.monsters_zombie2, "monsters_zombie2", src_sz1x1, defaultTileSize);
//loader.prepareTileset(R.drawable.monsters_zombie2, "monsters_zombie2", src_sz1x1, defaultTileSize);
//loader.prepareTileset(R.drawable.monsters_dragon1, "monsters_dragon1", src_sz1x1, dst_sz4x3);
if (AndorsTrailApplication.DEVELOPMENT_DEBUGRESOURCES) {

View File

@@ -16,7 +16,6 @@ IncludeJavascript("Editor_Droplist.js");
IncludeJavascript("Editor_Conversation.js");
IncludeJavascript("Editor_Monster.js");
IncludeJavascript("inc/jquery.shorten.min.js");
IncludeJavascript("inc/jquery.dynatree.min.js");
@@ -92,23 +91,56 @@ function addExampleModelItems(model) {
function startEditor() {
model = {
actorConditions: new DataStore('actorcondition', new FieldList("[id|name|iconID|isStacking|"
actorConditions: new DataStore({
objectTypename: 'actorcondition'
,fieldList: new FieldList("[id|name|iconID|isStacking|"
+ "hasRoundEffect|round_visualEffectID|round_boostHP_Min|round_boostHP_Max|round_boostAP_Min|round_boostAP_Max|"
+ "hasFullRoundEffect|fullround_visualEffectID|fullround_boostHP_Min|fullround_boostHP_Max|fullround_boostAP_Min|fullround_boostAP_Max|"
+ "hasAbilityEffect|boostMaxHP|boostMaxAP|moveCostPenalty|attackCost|attackChance|criticalChance|criticalMultiplier|attackDamage_Min|attackDamage_Max|blockChance|damageResistance|"
+ "];"))
,quests: new DataStore('quest', new FieldList("[id|name|showInLog|stages[progress|logText|rewardExperience|finishesQuest|]|];"))
,items: new DataStore('item', new FieldList("[searchTag|iconID|name|category|baseMarketCost|"
+ "];"
)
,idField: 'id'
,nameField: 'name'
})
,quests: new DataStore({
objectTypename: 'quest'
,fieldList: new FieldList("[id|name|showInLog|stages[progress|logText|rewardExperience|finishesQuest|]|];")
,idField: 'id'
,nameField: 'name'
})
,items: new DataStore({
objectTypename: 'item'
,fieldList: new FieldList("[searchTag|iconID|name|category|baseMarketCost|"
+ "hasEquipEffect|equip_boostMaxHP|equip_boostMaxAP|equip_moveCostPenalty|equip_attackCost|equip_attackChance|equip_criticalChance|equip_criticalMultiplier|equip_attackDamage_Min|equip_attackDamage_Max|equip_blockChance|equip_damageResistance|equip_conditions[condition|magnitude|]|"
+ "hasUseEffect|use_boostHP_Min|use_boostHP_Max|use_boostAP_Min|use_boostAP_Max|use_conditionsSource[condition|magnitude|duration|chance|]|"
+ "hasHitEffect|hit_boostHP_Min|hit_boostHP_Max|hit_boostAP_Min|hit_boostAP_Max|hit_conditionsSource[condition|magnitude|duration|chance|]|hit_conditionsTarget[condition|magnitude|duration|chance|]|"
+ "hasKillEffect|kill_boostHP_Min|kill_boostHP_Max|kill_boostAP_Min|kill_boostAP_Max|kill_conditionsSource[condition|magnitude|duration|chance|]|"
+ "];"))
,droplists: new DataStore('droplist', new FieldList("[id|items[itemID|quantity_Min|quantity_Max|chance|]|];"), 'id')
,dialogue: new DataStore('dialogue', new FieldList("[id|message|progressQuest|rewardDropListID|replies[text|nextPhraseID|requires_Progress|requires_itemID|requires_Quantity|]|];"), 'id')
,monsters: new DataStore('monster', new FieldList("[iconID|name|tags|size|maxHP|maxAP|moveCost|attackCost|attackChance|criticalChance|criticalMultiplier|attackDamage_Min|attackDamage_Max|blockChance|damageResistance|droplistID|phraseID|"
+ "];"
)
,idField: 'searchTag'
,nameField: 'name'
})
,droplists: new DataStore({
objectTypename: 'droplist'
,fieldList: new FieldList("[id|items[itemID|quantity_Min|quantity_Max|chance|]|];")
,idField: 'id'
,nameField: 'id'
})
,dialogue: new DataStore({
objectTypename: 'dialogue'
,fieldList: new FieldList("[id|message|progressQuest|rewardDropListID|replies[text|nextPhraseID|requires_Progress|requires_itemID|requires_Quantity|]|];")
,idField: 'id'
,nameField: 'id'
})
,monsters: new DataStore({
objectTypename: 'monster'
,fieldList: new FieldList("[iconID|name|tags|size|maxHP|maxAP|moveCost|attackCost|attackChance|criticalChance|criticalMultiplier|attackDamage_Min|attackDamage_Max|blockChance|damageResistance|droplistID|phraseID|"
+ "hasHitEffect|onHit_boostHP_Min|onHit_boostHP_Max|onHit_boostAP_Min|onHit_boostAP_Max|onHit_conditionsSource[condition|magnitude|duration|chance|]|onHit_conditionsTarget[condition|magnitude|duration|chance|]|"
+ "];"))
+ "];"
)
,idField: 'name'
,nameField: 'name'
})
};
addExampleModelItems(model);

View File

@@ -22,10 +22,11 @@ var specialEncodings = [
];
function DataStore(objectTypename, fieldList, nameField) {
this.objectTypename = objectTypename;
this.fieldList = fieldList;
this.nameField = nameField ? nameField : 'name';
function DataStore(input) {
this.objectTypename = input.objectTypename;
this.fieldList = input.fieldList;
this.nameField = input.nameField ? input.nameField : 'name';
this.idField = input.idField ? input.idField : 'id';
this.items = [];
this.add = function(obj) {
@@ -38,7 +39,8 @@ function DataStore(objectTypename, fieldList, nameField) {
this.clear = function() { this.items = {}; }
this.findById = function(id) {
for (var i = 0; i < this.items.length; ++i) {
if (this.items[i].id == id) return this.items[i];
var item = this.items[i];
if (item[this.idField] == id) return item;
}
}

View File

@@ -63,14 +63,16 @@ function applyCommonEditorBindings(div, obj, dataStore) {
}
}
function bindFieldToDataStore(field, dataStore, converter) {
function bindFieldToDataStore(field, dataStore) {
var dataCallback = function(request, response) {
var result = [];
var pattern = new RegExp(request.term, "i");
dataStore.items.forEach(function(obj) {
var name = converter(obj);
if (name.match(pattern)) {
result.push(name);
var id = obj[dataStore.idField];
var name = obj[dataStore.nameField];
var displayName = name + " (" + id + ")";
if (displayName.match(pattern)) {
result.push({label: displayName, value: id});
}
});
response(result);
@@ -85,6 +87,13 @@ function bindFieldToDataStore(field, dataStore, converter) {
});
}
function shortenString(str, maxChars) {
if (!str) return str;
str = str.toString();
if (str.length <= maxChars) return str;
return str.substring(0, maxChars) + "..";
}
function applyTableEditor(input) {
var updateRowText = function(row, obj) {
@@ -92,9 +101,7 @@ function applyTableEditor(input) {
var id = $( this ).attr("id");
var val = obj[id];
val = val ? val : "";
$( this ).text(val).shorten({
width: '200'
}).css('display','');
$( this ).text(shortenString(val, 30));
});
};

View File

@@ -64,8 +64,8 @@ function buildEditorForPhrase(div, phrase, tree, treeNode) {
checkboxHidesElement( $( '#hasProgressQuest', dialoguePhrase ), $( '#hasProgressQuestDisplay', dialoguePhrase ), phrase.progressQuest);
checkboxHidesElement( $( '#hasRewardDroplist', dialoguePhrase ), $( '#hasRewardDroplistDisplay', dialoguePhrase ), phrase.rewardDropListID);
bindFieldToDataStore( $( "#progressQuest", dialoguePhrase ), model.quests , function(obj) { return obj.id; } );
bindFieldToDataStore( $( "#rewardDropListID", dialoguePhrase ), model.droplists , function(obj) { return obj.id; } );
bindFieldToDataStore( $( "#progressQuest", dialoguePhrase ), model.quests);
bindFieldToDataStore( $( "#rewardDropListID", dialoguePhrase ), model.droplists);
var reloadReplyTable = function() {
applyTableEditor({
@@ -177,12 +177,13 @@ function buildEditorForReply(div, reply, tree, treeNode) {
checkboxHidesElement( $( '#requiresItems', dialogueReply ), $( '#requiresItemsDisplay', dialogueReply ), reply.requires_itemID);
checkboxHidesElement( $( '#requiresQuest', dialogueReply ), $( '#requiresQuestDisplay', dialogueReply ), reply.requires_Progress);
bindFieldToDataStore( $( "#requires_itemID", dialogueReply ), model.items , function(obj) { return obj.searchTag; } );
bindFieldToDataStore( $( "#requires_Progress", dialogueReply ), model.quests , function(obj) { return obj.id; } );
bindFieldToDataStore( $( "#requires_itemID", dialogueReply ), model.items);
bindFieldToDataStore( $( "#requires_Progress", dialogueReply ), model.quests);
var replyLeadsTo = $( "#replyLeadsTo", dialogueReply );
replyLeadsTo.change(function() { nextPhraseID.val( $(this).val() ).change(); });
replyLeadsTo.val(reply.nextPhraseID);
if (!replyLeadsTo.val()) { replyLeadsTo.val(""); }
replyLeadsTo.change(function() { nextPhraseID.val( $(this).val() ).change(); });
changeHidesElement(replyLeadsTo, $( "#nextPhraseIDDisplay", dialogueReply ) , function() { return replyLeadsTo.val() == ''; } );
var nextPhraseID = $( "#nextPhraseID", dialogueReply );
@@ -229,11 +230,11 @@ function buildEditorForReply(div, reply, tree, treeNode) {
// Tree node title generators
function getPhraseNodeText(phrase) {
return phrase.message ? phrase.message : "(no phrase text)";
return phrase.message ? shortenString(phrase.message, 30) : "(no phrase text)";
}
function getReplyNodeText(reply) {
return reply.text ? reply.text : "(no reply text)";
return reply.text ? shortenString(reply.text, 30) : "(no reply text)";
}
// ========================================================

View File

@@ -10,7 +10,7 @@ function createDroplistEditor(obj) {
array: obj.items,
templateFunction: function() { return { quantity: 1, chance: 100 } },
editorSetup: function(div) {
bindFieldToDataStore( $( "#itemID", div ), model.items , function(obj) { return obj.searchTag; } );
bindFieldToDataStore( $( "#itemID", div ), model.items);
}
});

View File

@@ -16,7 +16,7 @@ function createItemEditor(obj) {
if (!obj.hit_conditionsTarget) obj.hit_conditionsTarget = [];
if (!obj.kill_conditionsSource) obj.kill_conditionsSource = [];
var setupEditor = function(div) {
bindFieldToDataStore( $( "#condition", div ), model.actorConditions , function(obj) { return obj.id; } );
bindFieldToDataStore( $( "#condition", div ), model.actorConditions);
}
applyTableEditor({
@@ -55,6 +55,12 @@ function createItemEditor(obj) {
editorSetup: setupEditor
});
$( "#baseMarketCost", div ).change(function() {
var val = parseInt( $( this ).val() );
$( "#marketCost_Sell", div ).val(Math.round(val * (100 + 15) / 100));
$( "#marketCost_Buy", div ).val(Math.round(val * (100 - 15) / 100));
}).change();
return div;
}

View File

@@ -1,5 +1,8 @@
function createMonsterEditor(obj) {
if (!obj.maxAP) { obj.maxAP = 10; }
if (!obj.size) { obj.size = "1x1"; }
var div = $( "#templates #editMonster" ).clone();
applyCommonEditorBindings(div, obj, model.monsters);
checkboxHidesElement(div.find('#hasConversation'), div.find('#hasConversationDisplay'), obj.phraseID);
@@ -7,13 +10,13 @@ function createMonsterEditor(obj) {
checkboxHidesElement(div.find('#hasCritical'), div.find('#hasCriticalDisplay'), obj.criticalChance || obj.criticalMultiplier);
checkboxHidesElement(div.find('#hasHitEffect'), div.find('#hasHitEffectDisplay'), obj.hasHitEffect);
imageSelector.imageify(div.find('#monsterimage'), div.find('#iconID'), 'monsters');
bindFieldToDataStore( $( "#droplistID", div ), model.droplists , function(obj) { return obj.id; } );
bindFieldToDataStore( $( "#droplistID", div ), model.droplists );
var createNewCondition = function() { return { chance: 100, magnitude: 1 }; }
if (!obj.onHit_conditionsSource) obj.onHit_conditionsSource = [];
if (!obj.onHit_conditionsTarget) obj.onHit_conditionsTarget = [];
var setupEditor = function(div) {
bindFieldToDataStore( $( "#condition", div ), model.actorConditions , function(obj) { return obj.id; } );
bindFieldToDataStore( $( "#condition", div ), model.actorConditions );
}
applyTableEditor({
table: $( "#onHit_conditionsSource", div ),
@@ -29,6 +32,42 @@ function createMonsterEditor(obj) {
templateFunction: createNewCondition,
editorSetup: setupEditor
});
var expDependsOn = [];
var div100 = function(v) { return v / 100; }
var v = function(s) {
var field = $( s, div );
expDependsOn.push(field);
var val = field.val();
if (!val) return 0;
return parseInt(val);
}
var updateExperience = function() {
/*
final float avgAttackHP = t.getAttacksPerTurn(maxAP) * div100(t.attackChance) * t.damagePotential.averagef() * (1 + div100(t.criticalChance) * t.criticalMultiplier);
final float avgDefenseHP = maxHP * (1 + div100(t.blockChance)) + Constants.EXP_FACTOR_DAMAGERESISTANCE * t.damageResistance;
return (int) Math.ceil((avgAttackHP * 3 + avgDefenseHP) * Constants.EXP_FACTOR_SCALING);
*/
expDependsOn = [];
var EXP_FACTOR_DAMAGERESISTANCE = 9;
var EXP_FACTOR_SCALING = 0.7;
var attacksPerTurn = Math.floor(v("#maxAP") / v("#attackCost"));
var avgDamagePotential = (v("#attackDamage_Min") + v("#attackDamage_Max")) / 2;
var avgAttackHP = attacksPerTurn * div100(v("#attackChance")) * avgDamagePotential * (1 + div100(v("#criticalChance")) * v("#criticalMultiplier"));
var avgDefenseHP = v("#maxHP") * (1 + div100(v("#blockChance"))) + EXP_FACTOR_DAMAGERESISTANCE * v("#damageResistance");
var experience = (avgAttackHP * 3 + avgDefenseHP) * EXP_FACTOR_SCALING;
$( "#experience", div ).val(Math.ceil(experience));
};
updateExperience();
jQuery.each(expDependsOn, function(idx, o) {
o.change(updateExperience);
});
return div;
}

View File

@@ -19,7 +19,7 @@
<div class="andorsTrailLogo" id="title">
Andor's Trail Content Editor
<span id="version">
v0.6.9a0
v0.6.9a1
</span>
</div>
<div id="buttons">
@@ -143,6 +143,10 @@
</fieldset>
<fieldset class="fieldSet" id="hasCombatDisplay">
<legend>Combat</legend>
<div class="fieldWithLabel">
<label for="experience" class="label">Experience:</label>
<input class="field" type="text" size="7" id="experience" class="fieldInput integer" readonly="readonly" />
</div>
<div class="fieldWithLabel">
<label for="attackCost" class="label">Attack cost (AP):</label>
<input class="field" type="text" size="5" id="attackCost" class="fieldInput integer" />
@@ -346,6 +350,13 @@
<label for="baseMarketCost" class="label">Base market cost (gold):</label>
<input class="field" type="text" size="7" id="baseMarketCost" class="fieldInput integer" title="The actual price is adjusted 15% depending on if the item is being bought or sold. Set to 0 to prohibit selling this item type (for example, for a quest item)." />
</div>
<div class="fieldWithLabel">
<label for="marketCost_Sell" class="label">Actual price (gold):</label>
<div class="field">
<span>Sell: <input type="text" size="7" id="marketCost_Sell" class="fieldInput integer" readonly="readonly" /></span>
<span>Buy: <input type="text" size="7" id="marketCost_Buy" class="fieldInput integer" readonly="readonly" /></span>
</div>
</div>
<div class="fieldWithLabel">
<div class="label"><input type="checkbox" id="hasEquipEffect" />Has equip effect</div>
</div>
@@ -626,7 +637,7 @@
<label for="nextPhraseID" class="label">Phrase ID:</label>
<div class="field">
<input type="text" size="30" id="nextPhraseID" class="fieldInput" />
<img src="imgarrowright.png" alt="Follow" id="followNextReply" class="imageButton" />
<img src="imgarrowright.png" alt="Follow" id="followNextReply" class="imageButton" title="Open editor for the indicated phrase. Leave empty to automatically generate a new phrase id based on the prefix for this phrase, or supply a new phrase id that should be used." />
</div>
</div>
<div class="fieldWithLabel" id="hasRepliesDisplay">
@@ -666,7 +677,7 @@
<label for="nextPhraseID" class="label">Next phrase ID:</label>
<div class="field">
<input type="text" size="30" id="nextPhraseID" class="fieldInput"/>
<img src="imgarrowright.png" alt="Follow" id="followReply" class="imageButton" />
<img src="imgarrowright.png" alt="Follow" id="followReply" class="imageButton" title="Open editor for the indicated phrase. Leave empty to automatically generate a new phrase id based on the prefix for this phrase, or supply a new phrase id that should be used." />
</div>
</div>
<div class="fieldWithLabel">
@@ -718,17 +729,17 @@
<div class="label"><input type="checkbox" id="isStacking" />Allow stacked effects</div>
</div>
<div class="fieldWithLabel">
<div class="label"><input type="checkbox" id="hasRoundEffect" />Has effect every round</div>
<div class="label"><input type="checkbox" id="hasRoundEffect" />Has effect every round (every 6s)</div>
</div>
<div class="fieldWithLabel">
<div class="label"><input type="checkbox" id="hasFullRoundEffect" />Has effect every full round</div>
<div class="label"><input type="checkbox" id="hasFullRoundEffect" />Has effect every full round (every 25:th s)</div>
</div>
<div class="fieldWithLabel">
<div class="label"><input type="checkbox" id="hasAbilityEffect" />Has constant ability effect</div>
</div>
</fieldset>
<fieldset class="fieldSet" id="hasRoundEffectDisplay">
<legend>Every round</legend>
<legend>Every round (6s)</legend>
<div class="fieldWithLabel">
<label for="round_visualEffectID" class="label">Visual effect:</label>
<select class="field fieldInput" id="round_visualEffectID">
@@ -748,7 +759,7 @@
</div>
</fieldset>
<fieldset class="fieldSet" id="hasFullRoundEffectDisplay">
<legend>Every full round</legend>
<legend>Every full round (25s)</legend>
<div class="fieldWithLabel">
<label for="fullround_visualEffectID" class="label">Visual effect:</label>
<select class="field fieldInput" id="fullround_visualEffectID">

View File

@@ -1,301 +0,0 @@
var updatingOutput = false;
var parsingOutput = false;
function updateOutput() {
if (parsingOutput) return;
updatingOutput = true;
var rowcontainer = $("#datarows");
var op = "";
op += "[";
for (var i = 0; i < fields.length; i++) {
if (fields[i].type == "table") continue;
op += fields[i].name + "|";
}
op += "];\n";
$('tr', rowcontainer).each(function(i){
var row = $(this);
if (row.find("#" + fields[0].name).size() == 0) return;
op += "{";
for (var i = 0; i < fields.length; i++) {
row.find("#" + fields[i].name).each(function() { op += $(this).val() + "|"; });
}
op += "};\n";
});
$("#result").val(op);
updatingOutput = false;
}
var parse_currentRow;
var parse_fieldDef;
function parseLine(_, line) {
var match = line.match(/(.*?)\|/gm);
if (match.length != parse_fieldDef.length) {
alert("ERROR: Cannot parse row, expected " + parse_fieldDef.length + " fields, but found " + match.length + " fields.");
return;
}
for (var i = 0; i < match.length; i++) {
if (parse_fieldDef[i] >= 0) {
fields[parse_fieldDef[i]].value = match[i].replace(/\|/, '');
}
}
addRow();
}
function parseFieldDef(str) {
var fielddef = str.match(/\[(.+?)\];/gm);
parse_fieldDef = [];
if (fielddef && fielddef.length >= 1) {
fielddef = fielddef[0].match(/(.*?)\|/gm);
for (var i = 0; i < fielddef.length; i++) {
parse_fieldDef[i] = -1;
var fieldname = fielddef[i].replace(/[\[\]\|]/g, '');
for (var j = 0; j < fields.length; j++) {
if (fields[j].name == fieldname) {
parse_fieldDef[i] = j;
break;
}
}
}
} else {
for (var i = 0; i < fields.length; i++) {
parse_fieldDef[i] = i;
}
}
}
function parseOutput() {
if (updatingOutput) return;
parsingOutput = true;
$("#datarows").html("");
var str = $("#result").val();
parseFieldDef(str);
str.replace(/\{(.+?)\};/gm, parseLine);
parsingOutput = false;
}
function createField(field) {
if (field.value == undefined) field.value = "";
return "<td>" + eval("createField_" + field.type + "(field);") + "</td>";
}
function createTextField(field, size) {
return "<input type=\"text\" id=\"" + field.name + "\" value=\"" + field.value + "\" size=\"" + size + "\" />";
}
function createField_multiline(field) {
return "<textarea id=\"" + field.name + "\" cols=\"30\" rows=\"4\">" + field.value + "</textarea>";
}
function createField_longtext(field) { return createTextField(field, 20); }
function createField_text(field) { return createTextField(field, 10); }
function createField_size(field) { return createTextField(field, 5); }
function createField_range(field) { return createTextField(field, 5); }
function createField_int(field) { return createTextField(field, 3); }
function createField_table(field) {
var result = "<table cellspacing=\"0\"><thead><tr>";
for (var i = 0; i < field.fields.length; i++) {
result += "<th>" + field.fields[i].name + "</th>";
}
result += "</tr></thead><tbody>";
for (var j = 0; j < field.length; j++) {
result += "<tr>";
for (var i = 0; i < field.fields.length; i++) {
var f = fields[field.startindex + (j * field.fields.length) + i];
result += createField(f);
}
result += "</tr>";
}
result += "</tbody></table>";
return result;
}
function createField_image(field) {
return "<div id=\"image_" + field.name + "\" class=\"selectimage\"><input type=\"hidden\" id=\"" + field.name + "\" value=\"" + field.value + "\" /></div>";
}
function createField_select(field) {
var result = "<select id=\"" + field.name + "\">";
for (var i = 0; i < field.values.length; i++) {
var value = field.values[i];
var name = value;
var v = value.split(':');
if (v.length >= 2) {
name = v[0];
value = v[1];
}
result += "<option value=\"" + value + "\"";
if (field.value == value) {
result += " selected=\"selected\"";
}
result += ">" + name + "</option>";
}
result += "</select>";
return result;
}
function parseimageid(str) {
var defaultimage = {image: "defaultimage", lid: 0, path: '' };
if (str == null || str == "") return defaultimage;
var v = str.split(":");
if (v.length < 1) return defaultimage;
return {image: v[0], lid: v[1], path: imagepath };
}
function genimageid(v) {
if (v == null) return "";
return v.image + ":" + v.lid;
}
var currentIcon;
function selectimage(v) {
currentIcon = $(this);
$( "#selecticon_dialog" ).dialog("open");
}
function findTileImage(name) {
for (var i = 0; i < tileimages.length; i++) {
if (tileimages[i].name == name) {
return tileimages[i];
}
}
return 0;
}
function updateImageFromFormField(control) {
var imagestruct = parseimageid($(control).find("input").val());
var sourceimage = findTileImage(imagestruct.image);
var x = -(imagestruct.lid % sourceimage.numtilesx) * sourceimage.tilesizex;
var y = -Math.floor(imagestruct.lid / sourceimage.numtilesx) * sourceimage.tilesizey;
control.css({"background-image": "url(" +imagestruct.path + imagestruct.image + ".png)", "background-position": x+"px " + y+"px"});
}
function setSelectedImage(control, imagestruct) {
$(control).find("input").val(genimageid(imagestruct));
updateImageFromFormField(control);
$(control).change();
}
function addDefaultRow() {
for (var i = 0; i < fields.length; i++) {
fields[i].value = fields[i].default;
}
addRow();
}
function addNameRow(tagname) {
var result = "";
for (var i = 0; i < fields.length; i++) {
if (!fields[i].hide) {
result += "<" + tagname + ">" + fields[i].name + "</" + tagname + ">";
}
}
return result;
}
function addRow() {
var str = "";
for (var i = 0; i < fields.length; i++) {
if (!fields[i].hide) {
str += createField(fields[i]);
}
}
$("#datarows").append("<tr class='rowdiv'>" + str + "</tr>");
$("#datarows").find(".selectimage").click(selectimage);
$("#datarows").find(".selectimage").each(function() { updateImageFromFormField($(this)); });
if ($("#datarows > tr").size() % 10 == 0) {
$("#datarows").append("<tr>" + addNameRow("td") + "</tr>");
}
$("#datarows").change();
}
function explodeTableFields() {
var moreFields = [];
for (var n = 0; n < fields.length; n++) {
var field = fields[n];
if (field.type == "table") {
field.startindex = fields.length;
for (var j = 0; j < field.length; j++) {
for (var i = 0; i < field.fields.length; i++) {
var f = jQuery.extend(true, {}, field.fields[i]); // Deep copy
f.hide = 1;
f.name += j;
fields.push(f);
}
}
}
}
}
$(document).ready(function() {
explodeTableFields();
$("#result").resizable();
$("#inputarea").resizable();
var headerrow = $("#headerrow");
headerrow.append(addNameRow("th"));
var hasWarning = false;
for (var i = 0; i < tileimages.length; i++) {
tileimages[i].url = imagepath + tileimages[i].name + ".png";
var img = new Image();
img.src = tileimages[i].url;
tileimages[i].imgwidth = img.width;
tileimages[i].imgheight = img.height;
if (!hasWarning && (tileimages[i].imgwidth <= 0 || tileimages[i].imgheight <= 0)) {
alert("WARNING: could not load tile image " + tileimages[i].url + " . You may need to reload the page once.");
hasWarning = true;
}
tileimages[i].tilesizex = Math.floor(tileimages[i].imgwidth / tileimages[i].numtilesx);
tileimages[i].tilesizey = Math.floor(tileimages[i].imgheight / tileimages[i].numtilesy);
$("#selecticon_dialog_tileset").append("<img src=\"" + tileimages[i].url + "\" id=\"" + tileimages[i].name + "\" /><br />");
}
$("#selecticon_dialog_tileset img").each(function() {
var img = findTileImage($(this).attr("id"));
$(this).click(function(e) {
var x = e.pageX - $(this).offset().left;
var y = e.pageY - $(this).offset().top;
setSelectedImage(currentIcon, {
image: img.name,
lid: Math.floor(x / img.tilesizex) + img.numtilesx * Math.floor(y / img.tilesizey)
});
$( "#selecticon_dialog" ).dialog("close");
});
});
$( "#selecticon_dialog" ).dialog({
autoOpen: false,
modal: true,
width: 600,
height: 800,
position: [50,50],
buttons: {
Cancel: function() {
$( this ).dialog( "close" );
}
}
});
$("#buttons").append("<input type=\"button\" value=\"New\" id=\"newrow\" class=\"editorbutton\" />");
$("#newrow").click(addDefaultRow).click();
$("#buttons").append("<input type=\"checkbox\" id=\"autooutput\" checked=\"checked\" /><span class=\"editorbutton\" >Auto update output</span>");
$("#autooutput").change(function() {
if ($(this).attr('checked')) {
$("#datarows").change(updateOutput);
$("#result").change(parseOutput);
} else {
$("#datarows").unbind("change");
$("#result").unbind("change");
}
}).change();
$("#datarows").sortable();
//$("#updateoutput").click(updateOutput);
//$("#parseoutput").click(parseOutput);
});

View File

@@ -1,7 +0,0 @@
/*
* Shorten, a jQuery plugin to automatically shorten text to fit in a block or a pre-set width and configure how the text ends.
* Copyright (C) 2009-2011 Marc Diethelm
* License: (GPL 3, http://www.gnu.org/licenses/gpl-3.0.txt) see license.txt
*/
(function(a){function s(g,c){return c.measureText(g).width}function t(g,c){c.text(g);return c.width()}var q=false,o,j,k;a.fn.shorten=function(){var g={},c=arguments,r=c.callee;if(c.length)if(c[0].constructor==Object)g=c[0];else if(c[0]=="options")return a(this).eq(0).data("shorten-options");else g={width:parseInt(c[0]),tail:c[1]};this.css("visibility","hidden");var h=a.extend({},r.defaults,g);return this.each(function(){var e=a(this),d=e.text(),p=d.length,i,f=a("<span/>").html(h.tail).text(),l={shortened:false, textOverflow:false};i=e.css("float")!="none"?h.width||e.width():h.width||e.parent().width();if(i<0)return true;e.data("shorten-options",h);this.style.display="block";this.style.whiteSpace="nowrap";if(o){var b=a(this),n=document.createElement("canvas");ctx=n.getContext("2d");b.html(n);ctx.font=b.css("font-style")+" "+b.css("font-variant")+" "+b.css("font-weight")+" "+Math.ceil(parseFloat(b.css("font-size")))+"px "+b.css("font-family");j=ctx;k=s}else{b=a('<table style="padding:0; margin:0; border:none; font:inherit;width:auto;zoom:1;position:absolute;"><tr style="padding:0; margin:0; border:none; font:inherit;"><td style="padding:0; margin:0; border:none; font:inherit;white-space:nowrap;"></td></tr></table>'); $td=a("td",b);a(this).html(b);j=$td;k=t}b=k.call(this,d,j);if(b<i){e.text(d);this.style.visibility="visible";e.data("shorten-info",l);return true}h.tooltip&&this.setAttribute("title",d);if(r._native&&!g.width){n=a("<span>"+h.tail+"</span>").text();if(n.length==1&&n.charCodeAt(0)==8230){e.text(d);this.style.overflow="hidden";this.style[r._native]="ellipsis";this.style.visibility="visible";l.shortened=true;l.textOverflow="ellipsis";e.data("shorten-info",l);return true}}f=k.call(this,f,j);i-=f;f=i*1.15; if(b-f>0){f=d.substring(0,Math.ceil(p*(f/b)));if(k.call(this,f,j)>i){d=f;p=d.length}}do{p--;d=d.substring(0,p)}while(k.call(this,d,j)>=i);e.html(a.trim(a("<span/>").text(d).html())+h.tail);this.style.visibility="visible";l.shortened=true;e.data("shorten-info",l);return true})};var m=document.documentElement.style;if("textOverflow"in m)q="textOverflow";else if("OTextOverflow"in m)q="OTextOverflow";if(typeof Modernizr!="undefined"&&Modernizr.canvastext)o=Modernizr.canvastext;else{m=document.createElement("canvas"); o=!!(m.getContext&&m.getContext("2d")&&typeof m.getContext("2d").fillText==="function")}a.fn.shorten._is_canvasTextSupported=o;a.fn.shorten._native=q;a.fn.shorten.defaults={tail:"&hellip;",tooltip:true}})(jQuery);

View File

@@ -16,7 +16,7 @@ ul.dynatree-container
ul.dynatree-container ul
{
padding: 0 0 0 16px;
padding: 0 0 0 8px;
margin: 0;
}