mirror of
https://github.com/OMGeeky/andors-trail.git
synced 2026-01-20 10:31:28 +01:00
Refactor content editor - Removed old files.
This commit is contained in:
@@ -1,336 +0,0 @@
|
||||
var model;
|
||||
var imageSelector;
|
||||
var tabs;
|
||||
var questlogDialog;
|
||||
var onHitConditionsDialog;
|
||||
var equipConditionsDialog;
|
||||
var droplistItemDialog;
|
||||
var phraseRewardDialog;
|
||||
|
||||
require([
|
||||
"FieldList",
|
||||
"DataStore",
|
||||
"ImageSelector",
|
||||
"EditorTabs",
|
||||
"EditorFunctions",
|
||||
"ImportExport",
|
||||
"Editor_ActorCondition",
|
||||
"Editor_Quest",
|
||||
"Editor_Item",
|
||||
"Editor_Droplist",
|
||||
"Editor_Conversation",
|
||||
"Editor_Monster",
|
||||
"inc/jquery.dynatree.min",
|
||||
"inc/mustache",
|
||||
], function() {
|
||||
|
||||
function loadResourceFile(filename, onSuccess) {
|
||||
var url = document.location.href;
|
||||
url = url.substring(0, url.lastIndexOf('/'));
|
||||
url = url.substring(0, url.lastIndexOf('/'));
|
||||
url += "/AndorsTrail/res/" + filename;
|
||||
//var url = "http://andors-trail.googlecode.com/git/AndorsTrail/res/" + filename;
|
||||
$.get(url, function(data) {
|
||||
onSuccess(data);
|
||||
}, 'text')
|
||||
.error(function() { alert("Error loading " + url); });
|
||||
}
|
||||
|
||||
function openTabForObject(obj, dataStore) {
|
||||
tabs.openTabForObject(obj, dataStore.objectTypename, obj[dataStore.nameField]);
|
||||
}
|
||||
|
||||
function bindObjectsToItemList(itemListDiv, dataStore) {
|
||||
itemListDiv.children().remove();
|
||||
var createListItem = function(obj) {
|
||||
var item = $( Mustache.to_html( $('#listitem').html(), { name: obj[dataStore.nameField] } ) );
|
||||
if (dataStore.iconField) {
|
||||
var elem = $( 'img', item );
|
||||
imageSelector.setImage( elem , obj[dataStore.iconField] , 0.7);
|
||||
}
|
||||
return item;
|
||||
};
|
||||
var addToList = function(obj) {
|
||||
var item = createListItem(obj);
|
||||
item.click(function() { openTabForObject(obj, dataStore); });
|
||||
itemListDiv.append(item);
|
||||
item.hide().fadeIn('slow');
|
||||
};
|
||||
dataStore.items.forEach(addToList);
|
||||
dataStore.onAdded = addToList;
|
||||
dataStore.onDeserialized = function() {
|
||||
bindObjectsToItemList(itemListDiv, dataStore);
|
||||
// TODO: Should also close all tabs.
|
||||
};
|
||||
dataStore.onPropertyChanged = function(obj, propertyName, value) {
|
||||
var listItem = $("li:eq(" + dataStore.items.indexOf(obj) + ")", itemListDiv);
|
||||
listItem.html( createListItem(obj).html() );
|
||||
if (propertyName == dataStore.nameField) {
|
||||
//TODO: Should this really be in the same function?
|
||||
// (splitting the left part from the tab controls would reduce coupling, which would be a good thing.)
|
||||
tabs.renameTabForObject(obj, value);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
function bindEditorType(dataStore, div, createObjectEditor, newObjectCreator) {
|
||||
tabs.registerEditorType(dataStore.objectTypename, createObjectEditor);
|
||||
|
||||
bindObjectsToItemList( $( "ul", div ), dataStore );
|
||||
|
||||
$( "#add", div )
|
||||
.button()
|
||||
.click(function() {
|
||||
var obj = newObjectCreator();
|
||||
dataStore.add(obj);
|
||||
openTabForObject( obj, dataStore );
|
||||
});
|
||||
|
||||
$( "#clear", div )
|
||||
.button()
|
||||
.click(function() {
|
||||
if (confirm("Are you sure?")) {
|
||||
dataStore.clear();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function addExampleModelItems(model) {
|
||||
model.actorConditions.add({id: "bless", name: "Bless", isPositive: true, iconID: "actorconditions_1:38", category: 0, hasAbilityEffect: 1, attackChance: 15, blockChance: 5});
|
||||
model.actorConditions.add({id: "poison_weak", name: "Weak Poison", iconID: "actorconditions_1:60", category: 3, hasRoundEffect: 1, round_visualEffectID: 2, round_boostHP_Min: -1, round_boostHP_Max: -1});
|
||||
|
||||
model.quests.add({id: "testQuest", name: "Test quest", stages: [ { progress: 10, logText: "Stage 10"} , { progress: 20, logText: "Stage 20", finishesQuest: 1 } ] });
|
||||
|
||||
model.items.add({id: "item0", iconID: "items_weapons:0", name: "Longsword", category: 'lsword', baseMarketCost: 51, hasEquipEffect: 1, equip_attackChance: 10, equip_attackDamage_Min: 2, equip_attackDamage_Max: 4, equip_attackCost: 4});
|
||||
model.items.add({id: "dmg_ring1", iconID: "items_jewelry:0", name: "Ring of damage +1", category: 'ring', baseMarketCost: 62, hasEquipEffect: 1, equip_attackDamage_Min: 1, equip_attackDamage_Max: 1});
|
||||
|
||||
model.droplists.add({id: "merchant1", items: [ { itemID: 'dmg_ring1', quantity_Min: 4, quantity_Max: 5, chance: 100 } , { itemID: 'item0', quantity_Min: 1, quantity_Max: 1, chance: 100 } ] } );
|
||||
|
||||
model.dialogue.add({id: "mikhail_default", message: 'Anything else I can help you with?', replies: [ { text: 'Do you have any tasks for me?', nextPhraseID: 'mikhail_tasks' }, { text: 'Is there anything else you can tell me about Andor?', nextPhraseID: 'mikhail_andor1' } ]});
|
||||
model.dialogue.add({id: 'mikhail_andor1', message: 'As I said, Andor went out yesterday and hasn\'t been back since. I\'m starting to worry about him. Please go look for your brother, he said he would only be out a short while.'});
|
||||
model.dialogue.add({id: 'mikhail_tasks', message: 'Oh yes, there were some things I need help with, bread and rats. Which one would you like to talk about?'});
|
||||
|
||||
model.monsters.add({id: "small_ant", name: "Small ant", iconID: "monsters_insects:2", maxHP: 30, size: '1x1'});
|
||||
model.monsters.add({id: "red_ant", name: "Red ant", iconID: "monsters_insects:3", maxHP: 20, size: '1x1'});
|
||||
model.monsters.add({id: "wasp", name: "Wasp", iconID: "monsters_insects:1", maxHP: 10, size: '1x1'});
|
||||
}
|
||||
|
||||
$(document).ready(function() {
|
||||
|
||||
model = {
|
||||
actorConditions: new DataStore({
|
||||
objectTypename: 'actorcondition'
|
||||
,fieldList: new FieldList("[id|name|iconID|category|isStacking|isPositive|"
|
||||
+ "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|"
|
||||
+ "];"
|
||||
)
|
||||
,idField: 'id'
|
||||
,nameField: 'name'
|
||||
,iconField: 'iconID'
|
||||
})
|
||||
,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("[id|iconID|name|category|displaytype|hasManualPrice|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|]|"
|
||||
+ "];"
|
||||
)
|
||||
,idField: 'id'
|
||||
,nameField: 'name'
|
||||
,iconField: 'iconID'
|
||||
})
|
||||
,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|rewards[rewardType|rewardID|value|]|replies[text|nextPhraseID|requires_Progress|requires_itemID|requires_Quantity|requires_Type|]|];")
|
||||
,idField: 'id'
|
||||
,nameField: 'id'
|
||||
})
|
||||
,monsters: new DataStore({
|
||||
objectTypename: 'monster'
|
||||
,fieldList: new FieldList("[id|iconID|name|tags|size|monsterClass|unique|faction|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: 'id'
|
||||
,nameField: 'name'
|
||||
,iconField: 'iconID'
|
||||
})
|
||||
,itemCategories: new DataStore({
|
||||
objectTypename: 'itemcategory'
|
||||
,fieldList: new FieldList("[id|name|actionType|inventorySlot|size|];")
|
||||
,idField: 'id'
|
||||
,nameField: 'name'
|
||||
})
|
||||
};
|
||||
|
||||
addExampleModelItems(model);
|
||||
|
||||
|
||||
|
||||
|
||||
imageSelector = new ImageSelector("../AndorsTrail/res/drawable/", $( "#dialog-images" ) );
|
||||
imageSelector.add(new TilesetImage("actorconditions_1", {x:14, y:8}, undefined, [ 'conditions' ] ));
|
||||
imageSelector.add(new TilesetImage("actorconditions_2", {x:3, y:1}, undefined, [ 'conditions' ] ));
|
||||
imageSelector.add(new TilesetImage("items_armours", {x:14, y:3}, undefined, [ 'items' ] ));
|
||||
imageSelector.add(new TilesetImage("items_armours_3", {x:10, y:4}, undefined, [ 'items' ] ));
|
||||
imageSelector.add(new TilesetImage("items_armours_2", {x:7, y:1}, undefined, [ 'items' ] ));
|
||||
imageSelector.add(new TilesetImage("items_weapons", {x:14, y:6}, undefined, [ 'items' ] ));
|
||||
imageSelector.add(new TilesetImage("items_weapons_3", {x:13, y:5}, undefined, [ 'items' ] ));
|
||||
imageSelector.add(new TilesetImage("items_weapons_2", {x:7, y:1}, undefined, [ 'items' ] ));
|
||||
imageSelector.add(new TilesetImage("items_jewelry", {x:14, y:1}, undefined, [ 'items' ] ));
|
||||
imageSelector.add(new TilesetImage("items_rings_1", {x:10, y:3}, undefined, [ 'items' ] ));
|
||||
imageSelector.add(new TilesetImage("items_necklaces_1", {x:10, y:3}, undefined, [ 'items' ] ));
|
||||
imageSelector.add(new TilesetImage("items_consumables", {x:14, y:5}, undefined, [ 'items' ] ));
|
||||
imageSelector.add(new TilesetImage("items_books", {x:11, y:1}, undefined, [ 'items' ] ));
|
||||
imageSelector.add(new TilesetImage("items_misc", {x:14, y:4}, undefined, [ 'items' ] ));
|
||||
imageSelector.add(new TilesetImage("items_misc_2", {x:20, y:12}, undefined, [ 'items' ] ));
|
||||
imageSelector.add(new TilesetImage("items_misc_3", {x:20, y:12}, undefined, [ 'items' ] ));
|
||||
imageSelector.add(new TilesetImage("items_misc_4", {x:20, y:4}, undefined, [ 'items' ] ));
|
||||
imageSelector.add(new TilesetImage("monsters_armor1", {x: 1, y:1}, undefined, [ 'monsters' ] ));
|
||||
imageSelector.add(new TilesetImage("monsters_demon1", {x: 1, y:1}, {x:64, y:64}, [ 'monsters' ] ));
|
||||
imageSelector.add(new TilesetImage("monsters_dogs", {x: 7, y:1}, undefined, [ 'monsters' ] ));
|
||||
imageSelector.add(new TilesetImage("monsters_eye1", {x: 1, y:1}, undefined, [ 'monsters' ] ));
|
||||
imageSelector.add(new TilesetImage("monsters_eye2", {x: 1, y:1}, undefined, [ 'monsters' ] ));
|
||||
imageSelector.add(new TilesetImage("monsters_eye3", {x: 1, y:1}, undefined, [ 'monsters' ] ));
|
||||
imageSelector.add(new TilesetImage("monsters_eye4", {x: 1, y:1}, undefined, [ 'monsters' ] ));
|
||||
imageSelector.add(new TilesetImage("monsters_ghost1", {x: 1, y:1}, undefined, [ 'monsters' ] ));
|
||||
imageSelector.add(new TilesetImage("monsters_hydra1", {x: 1, y:1}, undefined, [ 'monsters' ] ));
|
||||
imageSelector.add(new TilesetImage("monsters_insects", {x: 6, y:1}, undefined, [ 'monsters' ] ));
|
||||
imageSelector.add(new TilesetImage("monsters_liches", {x: 4, y:1}, undefined, [ 'monsters' ] ));
|
||||
imageSelector.add(new TilesetImage("monsters_mage", {x: 1, y:1}, undefined, [ 'monsters' ] ));
|
||||
imageSelector.add(new TilesetImage("monsters_mage2", {x: 1, y:1}, undefined, [ 'monsters' ] ));
|
||||
imageSelector.add(new TilesetImage("monsters_man1", {x: 1, y:1}, undefined, [ 'monsters' ] ));
|
||||
imageSelector.add(new TilesetImage("monsters_men", {x: 9, y:1}, undefined, [ 'monsters' ] ));
|
||||
imageSelector.add(new TilesetImage("monsters_men2", {x: 10, y:1}, undefined, [ 'monsters' ] ));
|
||||
imageSelector.add(new TilesetImage("monsters_misc", {x: 12, y:1}, undefined, [ 'monsters' ] ));
|
||||
imageSelector.add(new TilesetImage("monsters_rats", {x: 5, y:1}, undefined, [ 'monsters' ] ));
|
||||
imageSelector.add(new TilesetImage("monsters_rogue1", {x: 1, y:1}, undefined, [ 'monsters' ] ));
|
||||
imageSelector.add(new TilesetImage("monsters_skeleton1", {x: 1, y:1}, undefined, [ 'monsters' ] ));
|
||||
imageSelector.add(new TilesetImage("monsters_skeleton2", {x: 1, y:1}, undefined, [ 'monsters' ] ));
|
||||
imageSelector.add(new TilesetImage("monsters_snakes", {x: 6, y:1}, undefined, [ 'monsters' ] ));
|
||||
imageSelector.add(new TilesetImage("monsters_cyclops", {x: 1, y:1}, {x:64, y:96}, [ 'monsters' ] ));
|
||||
imageSelector.add(new TilesetImage("monsters_warrior1", {x: 1, y:1}, undefined, [ 'monsters' ] ));
|
||||
imageSelector.add(new TilesetImage("monsters_wraiths", {x: 3, y:1}, undefined, [ 'monsters' ] ));
|
||||
imageSelector.add(new TilesetImage("monsters_zombie1", {x: 1, y:1}, undefined, [ 'monsters' ] ));
|
||||
imageSelector.add(new TilesetImage("monsters_zombie2", {x: 1, y:1}, undefined, [ 'monsters' ] ));
|
||||
imageSelector.add(new TilesetImage("monsters_karvis1", {x: 2, y:1}, undefined, [ 'monsters' ] ));
|
||||
imageSelector.add(new TilesetImage("monsters_karvis2", {x: 9, y:1}, undefined, [ 'monsters' ] ));
|
||||
imageSelector.add(new TilesetImage("monsters_rltiles1", {x:20, y:8}, undefined, [ 'monsters' ] ));
|
||||
imageSelector.add(new TilesetImage("monsters_rltiles2", {x:20, y:9}, undefined, [ 'monsters' ] ));
|
||||
imageSelector.add(new TilesetImage("monsters_rltiles3", {x:10, y:3}, undefined, [ 'monsters' ] ));
|
||||
imageSelector.add(new TilesetImage("monsters_redshrike1", {x:6, y:1}, undefined, [ 'monsters' ] ));
|
||||
imageSelector.add(new TilesetImage("monsters_ld1", {x:20, y:12}, undefined, [ 'monsters' ] ));
|
||||
imageSelector.add(new TilesetImage("monsters_ld2", {x:20, y:12}, undefined, [ 'monsters' ] ));
|
||||
|
||||
|
||||
|
||||
$( "#left #tools" ).accordion({ fillSpace: true });
|
||||
|
||||
tabs = new EditorTabs( $( "#center #tabs" ) );
|
||||
|
||||
|
||||
bindEditorType(model.actorConditions, $( "#tools #actorconditionlist" ), createActorConditionEditor, function() {
|
||||
return {name: "New Condition", id: 'new_condition' };
|
||||
});
|
||||
bindEditorType(model.quests, $( "#tools #questlist" ), createQuestEditor, function() {
|
||||
return {name: "New Quest", id: 'new_quest' };
|
||||
});
|
||||
bindEditorType(model.items, $( "#tools #itemlist" ), createItemEditor, function() {
|
||||
return {name: "New Item", id: "new_item", category: 'other' };
|
||||
});
|
||||
bindEditorType(model.droplists, $( "#tools #droplist" ), createDroplistEditor, function() {
|
||||
return {id: "new_droplist" };
|
||||
});
|
||||
bindEditorType(model.dialogue, $( "#tools #conversationlist" ), createConversationEditor, function() {
|
||||
return {id: "new_conversation" };
|
||||
});
|
||||
bindEditorType(model.monsters, $( "#tools #monsterlist" ), createMonsterEditor, function() {
|
||||
return {id: "new_monster", name: "New Monster", maxAP: 10, attackCost: 5, moveCost: 5 };
|
||||
});
|
||||
|
||||
|
||||
|
||||
$( "#buttons #import" ).button().click( showImportDialog );
|
||||
$( "#buttons #export" ).button().click( showExportDialog );
|
||||
|
||||
|
||||
var defaultButtons = {
|
||||
Close: function() { $( this ).dialog( "close" ); }
|
||||
};
|
||||
|
||||
prepareImportExportDialogs(defaultButtons);
|
||||
|
||||
questlogDialog = $( "#templates #dialog-questlog" )
|
||||
.dialog({
|
||||
title: "Quest log item",
|
||||
modal: true,
|
||||
autoOpen: false,
|
||||
width: 450,
|
||||
buttons: defaultButtons
|
||||
});
|
||||
|
||||
onHitConditionsDialog = $( "#templates #dialog-onHitConditions" )
|
||||
.dialog({
|
||||
title: "Actor status conditon",
|
||||
modal: true,
|
||||
autoOpen: false,
|
||||
width: 350,
|
||||
buttons: defaultButtons
|
||||
});
|
||||
|
||||
equipConditionsDialog = $( "#templates #dialog-equipConditions" )
|
||||
.dialog({
|
||||
title: "Actor status conditon",
|
||||
modal: true,
|
||||
autoOpen: false,
|
||||
width: 350,
|
||||
buttons: defaultButtons
|
||||
});
|
||||
|
||||
droplistItemDialog = $( "#templates #dialog-droplistItem" )
|
||||
.dialog({
|
||||
title: "Droplist item",
|
||||
modal: true,
|
||||
autoOpen: false,
|
||||
width: 350,
|
||||
buttons: defaultButtons
|
||||
});
|
||||
|
||||
phraseRewardDialog = $( "#templates #dialog-phrasereward" )
|
||||
.dialog({
|
||||
title: "Phrase reward",
|
||||
modal: true,
|
||||
autoOpen: false,
|
||||
width: 350,
|
||||
buttons: defaultButtons
|
||||
});
|
||||
|
||||
loadResourceFile( 'values/content_itemcategories.xml', function(data) {
|
||||
var allContent = '';
|
||||
$( data ).find("string").each(function() {
|
||||
allContent = allContent + $(this).text();
|
||||
});
|
||||
model.itemCategories.deserialize(allContent);
|
||||
model.itemCategories.items.forEach(function(c) {
|
||||
$("#editItem select#category").append( $("<option>").val(c.id).text(c.name) );
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
});
|
||||
@@ -1,143 +0,0 @@
|
||||
|
||||
function changeHidesElement(changedElement, elementToHide, visibilityEvaluator) {
|
||||
changedElement.change(function () {
|
||||
if (visibilityEvaluator()) {
|
||||
elementToHide.fadeIn("slow");
|
||||
} else {
|
||||
elementToHide.fadeOut("slow");
|
||||
}
|
||||
});
|
||||
elementToHide.toggle(visibilityEvaluator());
|
||||
}
|
||||
|
||||
function checkboxHidesElement(checkbox, element, visibleCondition) {
|
||||
var visible = bool(visibleCondition);
|
||||
checkbox.attr("checked", visible);
|
||||
var evaluator = function() { return checkbox.attr("checked"); };
|
||||
changeHidesElement(checkbox, element, evaluator);
|
||||
}
|
||||
|
||||
function checkboxShowsElement(checkbox, element, visibleCondition) {
|
||||
var visible = !bool(visibleCondition);
|
||||
checkbox.attr("checked", visible);
|
||||
var evaluator = function() { return !checkbox.attr("checked"); };
|
||||
changeHidesElement(checkbox, element, evaluator);
|
||||
}
|
||||
|
||||
function bool(v) {
|
||||
if (typeof(v) == 'undefined') return false;
|
||||
if (v == '') return false;
|
||||
if (v == '0') return false;
|
||||
if (v == 'false') return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
function setInputFieldsToObjectValues(div, obj) {
|
||||
div.find("input,select,textarea").each(function() {
|
||||
$(this).val(obj[$(this).attr("id")]);
|
||||
});
|
||||
div.find("input:checkbox").each(function() {
|
||||
$(this).attr("checked", bool(obj[$(this).attr("id")]));
|
||||
});
|
||||
}
|
||||
|
||||
function bindInputFieldChangesToObject(div, obj) {
|
||||
div.find("input,select,textarea").unbind("change").change(function() {
|
||||
obj[$(this).attr("id")] = $(this).val();
|
||||
});
|
||||
div.find("input:checkbox").unbind("change").change(function() {
|
||||
obj[$(this).attr("id")] = $(this).attr("checked") ? 1 : 0;
|
||||
});
|
||||
}
|
||||
|
||||
function applyEditorBindingsForObject(div, obj) {
|
||||
div.find("input").addClass("ui-widget-content ui-corner-all");
|
||||
setInputFieldsToObjectValues(div, obj);
|
||||
bindInputFieldChangesToObject(div, obj);
|
||||
}
|
||||
|
||||
function applyCommonEditorBindings(div, obj, dataStore) {
|
||||
applyEditorBindingsForObject(div, obj);
|
||||
if (dataStore) {
|
||||
div.find("input").change(function() {
|
||||
dataStore.onPropertyChanged(obj, $(this).attr('id'), $(this).val());
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
function bindFieldToDataStore(field, dataStore) {
|
||||
var dataCallback = function(request, response) {
|
||||
var result = [];
|
||||
var pattern = new RegExp(request.term, "i");
|
||||
dataStore.items.forEach(function(obj) {
|
||||
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);
|
||||
};
|
||||
field.autocomplete( "destroy" ).autocomplete({
|
||||
source: dataCallback,
|
||||
minLength: 0,
|
||||
select: function(event, ui) {
|
||||
field.val(ui.item.value);
|
||||
field.change();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
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) {
|
||||
$( "td", row ).each(function() {
|
||||
var id = $( this ).attr("id");
|
||||
var val = obj[id];
|
||||
val = val ? val : "";
|
||||
$( this ).text(shortenString(val, 30));
|
||||
});
|
||||
};
|
||||
|
||||
var onItemSelected = input.onItemSelected ? input.onItemSelected : function(obj, row) {
|
||||
var dialog = input.dialog;
|
||||
applyEditorBindingsForObject( dialog, obj );
|
||||
if (input.editorSetup) { input.editorSetup(dialog); }
|
||||
dialog.unbind( "dialogclose" ).bind( "dialogclose", function() {
|
||||
updateRowText(row, obj);
|
||||
});
|
||||
dialog.dialog( "open" );
|
||||
};
|
||||
|
||||
var table = input.table;
|
||||
var addToList = function(obj) {
|
||||
var row = $( "<tr>" );
|
||||
table.find("th").each(function() {
|
||||
var id = $( this ).attr("id");
|
||||
row.append( $( "<td>" ).attr("id", id) );
|
||||
});
|
||||
updateRowText(row, obj);
|
||||
table.append(row);
|
||||
row.click(function() { onItemSelected(obj, row); });
|
||||
return row;
|
||||
};
|
||||
table.parent().find("#add").button().unbind("click").click(function() {
|
||||
var obj = input.templateFunction();
|
||||
input.array.push( obj );
|
||||
if (input.onItemAdded) { input.onItemAdded(obj); }
|
||||
addToList( obj ).click();
|
||||
});
|
||||
table.addClass("ui-corner-all");
|
||||
$( "thead", table ).addClass("ui-widget-header");
|
||||
$( "tbody", table ).empty();
|
||||
input.array.forEach(addToList);
|
||||
}
|
||||
|
||||
@@ -1,98 +0,0 @@
|
||||
|
||||
function EditorTabs(div) {
|
||||
var mainTabs;
|
||||
var nextTabID;
|
||||
var tabInfos = [];
|
||||
var editorTypes = [];
|
||||
|
||||
// =====================================
|
||||
// Private methods
|
||||
|
||||
var closeTab = function(tabID, index) {
|
||||
tabInfos[tabID] = null;
|
||||
mainTabs.tabs( "remove", index );
|
||||
};
|
||||
|
||||
var closeCurrentTab = function() {
|
||||
var index = mainTabs.tabs('option', 'selected');
|
||||
var tab = findTabFromIndex(index);
|
||||
var tabID = $(tab).data("tabID");
|
||||
if (!tabID) { return; }
|
||||
closeTab(tabID, index);
|
||||
};
|
||||
|
||||
var findTab = function(tabID) { return mainTabs.find('ul li a[href="#tabs-' + tabID + '"]').parent(); }
|
||||
var findTabFromIndex = function(tabIndex) { return mainTabs.find('li')[tabIndex]; }
|
||||
var findTabIndex = function(tab) { return $( "li", mainTabs ).index(tab); }
|
||||
|
||||
var addTab = function(title, tabInfo) {
|
||||
var tabID = nextTabID;
|
||||
tabInfos[tabID] = tabInfo;
|
||||
mainTabs.tabs( "add", "#tabs-" + tabID, title );
|
||||
mainTabs.tabs( "select", -1 );
|
||||
var tab = findTab(tabID);
|
||||
tab.find( ".ui-icon-close" ).click(function() {
|
||||
var index = findTabIndex(tab);
|
||||
closeTab(tabID, index);
|
||||
});
|
||||
tab.data("tabID", tabID);
|
||||
nextTabID++;
|
||||
};
|
||||
|
||||
var findTabIDOfObject = function(obj) {
|
||||
for (var i = 1; i < tabInfos.length; ++i) {
|
||||
if (tabInfos[i] && tabInfos[i].obj == obj) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
};
|
||||
|
||||
var createObjectEditor = function(tabInfo) {
|
||||
var creator = editorTypes[tabInfo.objectType];
|
||||
if (!creator) {
|
||||
alert("unknown objectType: " + tabInfo.objectType);
|
||||
return;
|
||||
}
|
||||
return creator(tabInfo.obj);
|
||||
};
|
||||
|
||||
|
||||
// =====================================
|
||||
// Public methods
|
||||
|
||||
this.registerEditorType = function(objectType, editorCreator) {
|
||||
editorTypes[objectType] = editorCreator;
|
||||
};
|
||||
|
||||
this.renameTabForObject = function(obj, name) {
|
||||
var tabID = findTabIDOfObject(obj);
|
||||
if (!tabID) return;
|
||||
findTab(tabID).find("a").text(name);
|
||||
};
|
||||
|
||||
this.openTabForObject = function(obj, objectType, title) {
|
||||
var tabID = findTabIDOfObject(obj);
|
||||
if (tabID > 0) {
|
||||
var index = findTabIndex(findTab(tabID));
|
||||
mainTabs.tabs( "select", index );
|
||||
return;
|
||||
}
|
||||
addTab(title, {obj: obj, objectType: objectType});
|
||||
};
|
||||
|
||||
mainTabs = div.tabs({
|
||||
tabTemplate: "<li><a href='#{href}'>#{label}</a> <span class='ui-icon ui-icon-close'>Remove Tab</span></li>",
|
||||
add: function( event, ui ) {
|
||||
var editor = createObjectEditor( tabInfos[nextTabID] );
|
||||
$( ui.panel ).append( editor );
|
||||
mainTabs.tabs('select', ui.index);
|
||||
}
|
||||
});
|
||||
mainTabs.find( ".ui-tabs-nav" ).sortable({ axis: "x" });
|
||||
nextTabID = mainTabs.size() + 1;
|
||||
|
||||
div.keydown(function(e) {
|
||||
if (e.keyCode == 27 /* ESC */ ) { closeCurrentTab(); }
|
||||
});
|
||||
}
|
||||
@@ -1,12 +0,0 @@
|
||||
|
||||
function createActorConditionEditor(obj) {
|
||||
var div = $( "#templates #editActorCondition" ).clone();
|
||||
applyCommonEditorBindings(div, obj, model.actorConditions);
|
||||
checkboxHidesElement(div.find('#hasRoundEffect'), div.find('#hasRoundEffectDisplay'), obj.hasRoundEffect);
|
||||
checkboxHidesElement(div.find('#hasFullRoundEffect'), div.find('#hasFullRoundEffectDisplay'), obj.hasFullRoundEffect);
|
||||
checkboxHidesElement(div.find('#hasAbilityEffect'), div.find('#hasAbilityEffectDisplay'), obj.hasAbilityEffect);
|
||||
checkboxHidesElement(div.find('#hasCritical'), div.find('#hasCriticalDisplay'), obj.criticalChance || obj.criticalMultiplier);
|
||||
imageSelector.imageify(div.find('#actorconditionimage'), div.find('#iconID'), 'conditions');
|
||||
return div;
|
||||
}
|
||||
|
||||
@@ -1,319 +0,0 @@
|
||||
|
||||
|
||||
function createConversationEditor(obj) {
|
||||
var div = $( "#templates #editDialogue" ).clone(true);
|
||||
|
||||
var treeDiv = $ ( "#dialogueTree", div );
|
||||
treeDiv.dynatree({
|
||||
title: "Conversation flow"
|
||||
,imagePath: 'img'
|
||||
});
|
||||
var tree = treeDiv.dynatree("getTree");
|
||||
|
||||
var rootNode = treeDiv.dynatree("getRoot");
|
||||
updatePhraseTreeNodesBelow(tree, rootNode, obj);
|
||||
|
||||
treeDiv.dynatree({
|
||||
onActivate: function(node) {
|
||||
onConversationPhraseSelected(div, node.data.model, tree);
|
||||
}
|
||||
});
|
||||
|
||||
tree.activateKey(obj.id);
|
||||
|
||||
return div;
|
||||
}
|
||||
|
||||
function getPhraseByPhraseID(phraseID) {
|
||||
if (!phraseID) return;
|
||||
return model.dialogue.findById(phraseID);
|
||||
}
|
||||
|
||||
function onConversationPhraseSelected(div, obj, tree) {
|
||||
var dialoguePhrase = $( "#dialoguePhrase", div );
|
||||
var dialogueReply = $( "#dialogueReply", div );
|
||||
var dialoguePhraseReplies = $( "#dialoguePhraseReplies", div );
|
||||
dialogueReply.hide();
|
||||
dialoguePhrase.hide();
|
||||
dialoguePhraseReplies.hide();
|
||||
if (!obj) return;
|
||||
|
||||
var treeNodeKey = getTreeNodeKey(obj);
|
||||
var treeNode = tree.getNodeByKey(treeNodeKey);
|
||||
if (!treeNode) {
|
||||
treeNode = updatePhraseTreeNodesBelow(tree, tree.getRoot(), obj, true);
|
||||
}
|
||||
|
||||
treeNode.activateSilently();
|
||||
|
||||
applyCommonEditorBindings(div, obj, model.dialogue);
|
||||
|
||||
if (obj.isPhrase) {
|
||||
buildEditorForPhrase(div, obj, tree, treeNode);
|
||||
} else {
|
||||
buildEditorForReply(div, obj, tree, treeNode);
|
||||
}
|
||||
}
|
||||
|
||||
// ========================================================
|
||||
// Set up editor for NPC phrases
|
||||
|
||||
function buildEditorForPhrase(div, phrase, tree, treeNode) {
|
||||
var dialoguePhrase = $( "#dialoguePhrase", div );
|
||||
var dialoguePhraseReplies = $( "#dialoguePhraseReplies", div );
|
||||
|
||||
checkboxHidesElement( $( '#hasRewards', dialoguePhrase ), $( '#hasRewardsDisplay', dialoguePhrase ), phrase.rewards);
|
||||
|
||||
var rebuildChildNodes = function() {
|
||||
updatePhraseReplyTreeNodesBelow(tree, treeNode, phrase);
|
||||
}
|
||||
var reloadReplyTable = function() {
|
||||
applyTableEditor({
|
||||
table: $( "#replies", dialoguePhraseReplies ),
|
||||
array: phrase.replies,
|
||||
templateFunction: function() { return createReplyForPhrase(phrase); },
|
||||
onItemSelected: function(obj) {
|
||||
onConversationPhraseSelected(div, obj, tree);
|
||||
},
|
||||
onItemAdded: function(addedObject) {
|
||||
rebuildChildNodes();
|
||||
}
|
||||
});
|
||||
}
|
||||
reloadReplyTable();
|
||||
|
||||
var hasOnlyNextReply = $( '#hasOnlyNextReply', dialoguePhraseReplies );
|
||||
checkboxHidesElement( hasOnlyNextReply, $( '#hasOnlyNextReplyDisplay', dialoguePhraseReplies ), phrase.hasOnlyNextReply);
|
||||
checkboxShowsElement( hasOnlyNextReply, $( '#hasRepliesDisplay', dialoguePhraseReplies ), !phrase.hasOnlyNextReply);
|
||||
|
||||
hasOnlyNextReply.change(function() {
|
||||
if ( $(this).attr("checked") ) {
|
||||
var nextReply = createReplyForPhrase(phrase);
|
||||
nextReply.text = 'N';
|
||||
phrase.replies = [ nextReply ];
|
||||
} else {
|
||||
phrase.replies = [ ];
|
||||
reloadReplyTable();
|
||||
}
|
||||
rebuildChildNodes();
|
||||
});
|
||||
|
||||
var nextPhraseID = $( "#nextPhraseID", dialoguePhraseReplies );
|
||||
nextPhraseID.unbind("change").change(function() {
|
||||
phrase.replies[0].nextPhraseID = $( this ).val();
|
||||
rebuildChildNodes();
|
||||
});
|
||||
if (phrase.hasOnlyNextReply) {
|
||||
nextPhraseID.val(phrase.replies[0].nextPhraseID);
|
||||
}
|
||||
|
||||
var phraseID = $( "#id", dialoguePhrase );
|
||||
phraseID.change(function() {
|
||||
treeNode.data.key = phrase.id;
|
||||
rebuildChildNodes();
|
||||
});
|
||||
|
||||
$( "#followNextReply", dialoguePhraseReplies ).button().unbind('click').click(function() {
|
||||
openNextPhrase(nextPhraseID.val(), div, phrase.replies[0], tree);
|
||||
});
|
||||
|
||||
$( '#message', dialoguePhrase ).change(function() { treeNode.setTitle( getPhraseNodeText(phrase) ); });
|
||||
|
||||
var createNewReward = function() { return { rewardType: 0 }; }
|
||||
var setupEditor = function(div) { }
|
||||
if (!phrase.rewards) phrase.rewards = [];
|
||||
applyTableEditor({
|
||||
table: $( '#rewards', dialoguePhrase ),
|
||||
dialog: phraseRewardDialog,
|
||||
array: phrase.rewards,
|
||||
templateFunction: createNewReward,
|
||||
editorSetup: setupEditor
|
||||
});
|
||||
|
||||
dialoguePhrase.show();
|
||||
dialoguePhraseReplies.show();
|
||||
}
|
||||
|
||||
function createReplyForPhrase(phrase) {
|
||||
return {
|
||||
id: phrase.id,
|
||||
isPhrase: false,
|
||||
phrase: phrase
|
||||
};
|
||||
}
|
||||
|
||||
function openNextPhrase(nextPhraseID, div, reply, tree) {
|
||||
var createNewPhrase = true;
|
||||
var phrase;
|
||||
if (nextPhraseID) {
|
||||
phrase = getPhraseByPhraseID(nextPhraseID);
|
||||
if (phrase) {
|
||||
createNewPhrase = false;
|
||||
}
|
||||
} else {
|
||||
nextPhraseID = generatePhraseID(reply.phrase.id);
|
||||
}
|
||||
|
||||
if (createNewPhrase) {
|
||||
phrase = { id: nextPhraseID, isPhrase: true };
|
||||
model.dialogue.add(phrase);
|
||||
}
|
||||
reply.nextPhraseID = nextPhraseID;
|
||||
|
||||
var treeNodeKey = getTreeNodeKey(reply.phrase);
|
||||
var treeNode = tree.getNodeByKey(treeNodeKey);
|
||||
updatePhraseReplyTreeNodesBelow(tree, treeNode, reply.phrase);
|
||||
//alert("followNextReply: " + nextPhraseID);
|
||||
onConversationPhraseSelected(div, phrase, tree);
|
||||
}
|
||||
|
||||
function generatePhraseID(previousPhraseID) {
|
||||
var suffix;
|
||||
var n = 1;
|
||||
|
||||
var match = (/^(.*\D)(\d+)$/g).exec(previousPhraseID);
|
||||
if (match) {
|
||||
suffix = match[1];
|
||||
n = parseInt(match[2]) + 1;
|
||||
} else {
|
||||
suffix = previousPhraseID + "_";
|
||||
}
|
||||
|
||||
for (var i = n; i < 1000; ++i) {
|
||||
var phraseID = suffix + i;
|
||||
if (!getPhraseByPhraseID(phraseID)) return phraseID;
|
||||
}
|
||||
}
|
||||
|
||||
// ========================================================
|
||||
// Set up editor for replies
|
||||
|
||||
function buildEditorForReply(div, reply, tree, treeNode) {
|
||||
var dialogueReply = $( "#dialogueReply", div );
|
||||
|
||||
checkboxHidesElement( $( '#requiresItems', dialogueReply ), $( '#requiresItemsDisplay', dialogueReply ), reply.requires_itemID);
|
||||
checkboxHidesElement( $( '#requiresQuest', dialogueReply ), $( '#requiresQuestDisplay', dialogueReply ), reply.requires_Progress);
|
||||
bindFieldToDataStore( $( "#requires_itemID", dialogueReply ), model.items);
|
||||
bindFieldToDataStore( $( "#requires_Progress", dialogueReply ), model.quests);
|
||||
|
||||
var replyLeadsTo = $( "#replyLeadsTo", dialogueReply );
|
||||
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 );
|
||||
nextPhraseID.change(function() {
|
||||
updatePhraseTreeNodesBelow(tree, treeNode, getPhraseByPhraseID(reply.nextPhraseID) );
|
||||
});
|
||||
|
||||
$( "#followReply", dialogueReply ).button().unbind('click').click(function() {
|
||||
openNextPhrase(nextPhraseID.val(), div, reply, tree);
|
||||
});
|
||||
|
||||
$( '#text', dialogueReply ).change(function() { treeNode.setTitle( getReplyNodeText(reply) ); });
|
||||
|
||||
dialogueReply.show();
|
||||
}
|
||||
|
||||
|
||||
// ========================================================
|
||||
// Tree node key generators
|
||||
|
||||
function getTreeNodeKey(obj) {
|
||||
if (!obj) return "";
|
||||
if (obj.isPhrase) return obj.id;
|
||||
return getTreeNodeReplyKey(obj);
|
||||
}
|
||||
|
||||
function getTreeNodeReplyKey(obj) {
|
||||
var idx = 0;
|
||||
for (var i = 0; i < obj.phrase.replies.length; ++i) {
|
||||
if (obj.phrase.replies[i] == obj) {
|
||||
idx = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return getTreeNodeReplyKeyIndex(obj, idx);
|
||||
}
|
||||
|
||||
function getTreeNodeReplyKeyIndex(obj, idx) {
|
||||
return getTreeNodeKey(obj.phrase) + "__reply_" + idx;
|
||||
}
|
||||
|
||||
|
||||
// ========================================================
|
||||
// Tree node title generators
|
||||
|
||||
function getPhraseNodeText(phrase) {
|
||||
return phrase.message ? shortenString(phrase.message, 30) : "(no phrase text)";
|
||||
}
|
||||
|
||||
function getReplyNodeText(reply) {
|
||||
return reply.text ? shortenString(reply.text, 30) : "(no reply text)";
|
||||
}
|
||||
|
||||
// ========================================================
|
||||
// Tree-building functions
|
||||
|
||||
// (re)Build a NPC phrase node
|
||||
function updatePhraseTreeNodesBelow(tree, parent, phrase, keepExisting) {
|
||||
if (!keepExisting) { parent.removeChildren(); }
|
||||
|
||||
if (!phrase) return;
|
||||
|
||||
phrase.isPhrase = true;
|
||||
var key = getTreeNodeKey(phrase);
|
||||
|
||||
if (tree.getNodeByKey(key)) {
|
||||
parent.addChild({
|
||||
title: '(conversation loop)'
|
||||
,model: phrase
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
var phraseNode = parent.addChild({
|
||||
title: getPhraseNodeText(phrase)
|
||||
,key: key
|
||||
,model: phrase
|
||||
,icon: 'phrase.png'
|
||||
});
|
||||
|
||||
if (!phrase.replies) phrase.replies = [];
|
||||
updatePhraseReplyTreeNodesBelow(tree, phraseNode, phrase, phrase.replies);
|
||||
|
||||
phraseNode.expand(true);
|
||||
return phraseNode;
|
||||
}
|
||||
|
||||
// (re)Build all nodes below a NPC phrase (i.e. rebuild all reply nodes)
|
||||
function updatePhraseReplyTreeNodesBelow(tree, phraseNode, phrase) {
|
||||
phraseNode.removeChildren();
|
||||
|
||||
if (!phrase.replies) phrase.replies = [];
|
||||
|
||||
if (phrase.replies.length == 1) {
|
||||
var singleReply = phrase.replies[0];
|
||||
if (singleReply.text == 'N') {
|
||||
phrase.hasOnlyNextReply = true;
|
||||
updatePhraseTreeNodesBelow(tree, phraseNode, getPhraseByPhraseID(singleReply.nextPhraseID) );
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
phrase.replies.forEach(function(reply, idx) {
|
||||
jQuery.extend(reply, createReplyForPhrase(phrase));
|
||||
var key = getTreeNodeReplyKeyIndex(reply, idx);
|
||||
var replyNode = phraseNode.addChild({
|
||||
title: getReplyNodeText(reply)
|
||||
,key: key
|
||||
,model: reply
|
||||
,icon: 'reply.png'
|
||||
});
|
||||
if (reply.nextPhraseID) {
|
||||
updatePhraseTreeNodesBelow(tree, replyNode, getPhraseByPhraseID(reply.nextPhraseID) );
|
||||
}
|
||||
replyNode.expand(true);
|
||||
});
|
||||
}
|
||||
@@ -1,18 +0,0 @@
|
||||
|
||||
function createDroplistEditor(obj) {
|
||||
var div = $( "#templates #editDroplist" ).clone(true);
|
||||
applyCommonEditorBindings(div, obj, model.droplists);
|
||||
if (!obj.items) obj.items = [];
|
||||
|
||||
applyTableEditor({
|
||||
table: $( "#items", div ),
|
||||
dialog: droplistItemDialog,
|
||||
array: obj.items,
|
||||
templateFunction: function() { return { quantity: 1, chance: 100 } },
|
||||
editorSetup: function(div) {
|
||||
bindFieldToDataStore( $( "#itemID", div ), model.items);
|
||||
}
|
||||
});
|
||||
|
||||
return div;
|
||||
}
|
||||
@@ -1,160 +0,0 @@
|
||||
|
||||
function sgn(v) {
|
||||
if (v < 0) return -1;
|
||||
else if (v > 0) return 1;
|
||||
else return 0;
|
||||
}
|
||||
|
||||
function createItemEditor(obj) {
|
||||
var div = $( "#templates #editItem" ).clone();
|
||||
applyCommonEditorBindings(div, obj, model.items);
|
||||
checkboxHidesElement(div.find('#hasEquipEffect'), div.find('#hasEquipEffectDisplay'), obj.hasEquipEffect);
|
||||
checkboxHidesElement(div.find('#hasUseEffect'), div.find('#hasUseEffectDisplay'), obj.hasUseEffect);
|
||||
checkboxHidesElement(div.find('#equip_hasCritical'), div.find('#equip_hasCriticalDisplay'), obj.equip_criticalChance || obj.equip_criticalMultiplier);
|
||||
checkboxHidesElement(div.find('#hasHitEffect'), div.find('#hasHitEffectDisplay'), obj.hasHitEffect);
|
||||
checkboxHidesElement(div.find('#hasKillEffect'), div.find('#hasKillEffectDisplay'), obj.hasKillEffect);
|
||||
imageSelector.imageify(div.find('#itemimage'), div.find('#iconID'), 'items');
|
||||
|
||||
var createNewCondition = function() { return { chance: 100, magnitude: 1 }; }
|
||||
if (!obj.equip_conditions) obj.equip_conditions = [];
|
||||
if (!obj.use_conditionsSource) obj.use_conditionsSource = [];
|
||||
if (!obj.hit_conditionsSource) obj.hit_conditionsSource = [];
|
||||
if (!obj.hit_conditionsTarget) obj.hit_conditionsTarget = [];
|
||||
if (!obj.kill_conditionsSource) obj.kill_conditionsSource = [];
|
||||
var setupEditor = function(div) {
|
||||
bindFieldToDataStore( $( "#condition", div ), model.actorConditions);
|
||||
}
|
||||
|
||||
applyTableEditor({
|
||||
table: $( "#equip_conditions", div ),
|
||||
dialog: equipConditionsDialog,
|
||||
array: obj.equip_conditions,
|
||||
templateFunction: createNewCondition,
|
||||
editorSetup: setupEditor
|
||||
});
|
||||
applyTableEditor({
|
||||
table: $( "#use_conditionsSource", div ),
|
||||
dialog: onHitConditionsDialog,
|
||||
array: obj.use_conditionsSource,
|
||||
templateFunction: createNewCondition,
|
||||
editorSetup: setupEditor
|
||||
});
|
||||
applyTableEditor({
|
||||
table: $( "#hit_conditionsSource", div ),
|
||||
dialog: onHitConditionsDialog,
|
||||
array: obj.hit_conditionsSource,
|
||||
templateFunction: createNewCondition,
|
||||
editorSetup: setupEditor
|
||||
});
|
||||
applyTableEditor({
|
||||
table: $( "#hit_conditionsTarget", div ),
|
||||
dialog: onHitConditionsDialog,
|
||||
array: obj.hit_conditionsTarget,
|
||||
templateFunction: createNewCondition,
|
||||
editorSetup: setupEditor
|
||||
});
|
||||
applyTableEditor({
|
||||
table: $( "#kill_conditionsSource", div ),
|
||||
dialog: onHitConditionsDialog,
|
||||
array: obj.kill_conditionsSource,
|
||||
templateFunction: createNewCondition,
|
||||
editorSetup: setupEditor
|
||||
});
|
||||
|
||||
|
||||
var itemCostDependsOn = [];
|
||||
var sv = function(s) {
|
||||
var field = $( s, div );
|
||||
itemCostDependsOn.push(field);
|
||||
return field.val();
|
||||
}
|
||||
var v = function(s) {
|
||||
var val = sv(s);
|
||||
if (!val) return 0;
|
||||
return parseInt(val);
|
||||
}
|
||||
var cb = function(s) {
|
||||
var field = $( s, div );
|
||||
itemCostDependsOn.push(field);
|
||||
return field.attr("checked");
|
||||
}
|
||||
var calculateItemCost = function() {
|
||||
itemCostDependsOn = [];
|
||||
var averageHPBoost = (v("#use_boostHP_Min") + v("#use_boostHP_Max")) / 2;
|
||||
var costBoostHP = Math.round(0.1*sgn(averageHPBoost)*Math.pow(Math.abs(averageHPBoost), 2) + 3*averageHPBoost);
|
||||
var itemUsageCost = costBoostHP;
|
||||
|
||||
var isWeapon = model.itemCategories.findById(sv("#category")).inventorySlot == 0;
|
||||
|
||||
var equip_blockChance = v("#equip_blockChance");
|
||||
var equip_attackChance = v("#equip_attackChance");
|
||||
var equip_attackCost = v("#equip_attackCost");
|
||||
var equip_damageResistance = v("#equip_damageResistance");
|
||||
var equip_attackDamage_Min = v("#equip_attackDamage_Min");
|
||||
var equip_attackDamage_Max = v("#equip_attackDamage_Max");
|
||||
var equip_criticalChance = v("#equip_criticalChance");
|
||||
var equip_criticalMultiplier = v("#equip_criticalMultiplier");
|
||||
var costBC = Math.round(3*Math.pow(Math.max(0,equip_blockChance), 2.5) + 28*equip_blockChance);
|
||||
var costAC = Math.round(0.4*Math.pow(Math.max(0,equip_attackChance), 2.5) - 6*Math.pow(Math.abs(Math.min(0,equip_attackChance)),2.7));
|
||||
var costAP = isWeapon ?
|
||||
Math.round(0.2*Math.pow(10/equip_attackCost, 8) - 25*equip_attackCost)
|
||||
: -3125 * equip_attackCost;
|
||||
var costDR = 1325*equip_damageResistance;
|
||||
var costDMG_Min = isWeapon ?
|
||||
Math.round(10*Math.pow(equip_attackDamage_Min, 2.5))
|
||||
:Math.round(10*Math.pow(equip_attackDamage_Min, 3) + equip_attackDamage_Min*80);
|
||||
var costDMG_Max = isWeapon ?
|
||||
Math.round(2*Math.pow(equip_attackDamage_Max, 2.1))
|
||||
:Math.round(2*Math.pow(equip_attackDamage_Max, 3) + equip_attackDamage_Max*20);
|
||||
var costCC = Math.round(2.2*Math.pow(equip_criticalChance, 3));
|
||||
var costCM = Math.round(50*Math.pow(Math.max(0, equip_criticalMultiplier), 2));
|
||||
if (!cb("#equip_hasCritical")) {
|
||||
costCC = 0;
|
||||
costCM = 0;
|
||||
}
|
||||
var costCombat = costBC + costAC + costAP + costDR + costDMG_Min + costDMG_Max + costCC + costCM;
|
||||
|
||||
var equip_boostMaxHP = v("#equip_boostMaxHP");
|
||||
var equip_boostMaxAP = v("#equip_boostMaxAP");
|
||||
var equip_moveCostPenalty = v("#equip_moveCostPenalty");
|
||||
var costMaxHP = Math.round(30*Math.pow(Math.max(0,equip_boostMaxHP), 1.2) + 70*equip_boostMaxHP);
|
||||
var costMaxAP = Math.round(50*Math.pow(Math.max(0,equip_boostMaxAP), 3) + 750*equip_boostMaxAP);
|
||||
var costMovement = Math.round(510*Math.pow(Math.max(0,-equip_moveCostPenalty), 2.5) - 350*equip_moveCostPenalty);
|
||||
var itemEquipCost = costCombat + costMaxHP + costMaxAP + costMovement;
|
||||
|
||||
if (!cb("#hasEquipEffect")) { itemEquipCost = 0; }
|
||||
if (!cb("#hasUseEffect")) { itemUsageCost = 0; }
|
||||
|
||||
return itemEquipCost + itemUsageCost;
|
||||
}
|
||||
|
||||
var divBaseMarketCost = $( "#baseMarketCost", div );
|
||||
var recalculateStorePrice = function() {
|
||||
var val = parseInt(obj.baseMarketCost);
|
||||
if (!obj.hasManualPrice) {
|
||||
val = calculateItemCost(obj);
|
||||
obj.baseMarketCost = val;
|
||||
divBaseMarketCost.val(val);
|
||||
}
|
||||
$( "#marketCost_Sell", div ).val(Math.round(val * (100 + 15) / 100));
|
||||
$( "#marketCost_Buy", div ).val(Math.round(val * (100 - 15) / 100));
|
||||
};
|
||||
|
||||
divBaseMarketCost.change(recalculateStorePrice);
|
||||
$( "#hasManualPrice", div ).change(function() {
|
||||
if (obj.hasManualPrice) {
|
||||
divBaseMarketCost.removeAttr("readonly");
|
||||
} else {
|
||||
divBaseMarketCost.attr("readonly", "readonly");
|
||||
}
|
||||
recalculateStorePrice();
|
||||
}).change();
|
||||
|
||||
calculateItemCost();
|
||||
jQuery.each(itemCostDependsOn, function(idx, o) {
|
||||
o.change(recalculateStorePrice);
|
||||
});
|
||||
|
||||
return div;
|
||||
}
|
||||
|
||||
@@ -1,73 +0,0 @@
|
||||
|
||||
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);
|
||||
checkboxHidesElement(div.find('#hasCombat'), div.find('#hasCombatDisplay'), obj.attackChance);
|
||||
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 );
|
||||
|
||||
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 );
|
||||
}
|
||||
applyTableEditor({
|
||||
table: $( "#onHit_conditionsSource", div ),
|
||||
dialog: onHitConditionsDialog,
|
||||
array: obj.onHit_conditionsSource,
|
||||
templateFunction: createNewCondition,
|
||||
editorSetup: setupEditor
|
||||
});
|
||||
applyTableEditor({
|
||||
table: $( "#onHit_conditionsTarget", div ),
|
||||
dialog: onHitConditionsDialog,
|
||||
array: obj.onHit_conditionsTarget,
|
||||
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;
|
||||
}
|
||||
|
||||
@@ -1,21 +0,0 @@
|
||||
|
||||
function createQuestEditor(obj) {
|
||||
var div = $( "#templates #editQuest" ).clone(true);
|
||||
applyCommonEditorBindings(div, obj, model.quests);
|
||||
if (!obj.stages) obj.stages = [];
|
||||
var array = obj.stages;
|
||||
var createNewStage = function() {
|
||||
var nextProgress;
|
||||
if (array.length > 0) { nextProgress = parseInt(array[array.length - 1].progress) + 10; }
|
||||
if (!nextProgress) { nextProgress = 10; }
|
||||
return { progress: nextProgress };
|
||||
};
|
||||
applyTableEditor({
|
||||
table: $( "#stages", div ),
|
||||
dialog: questlogDialog,
|
||||
array: array,
|
||||
templateFunction: createNewStage
|
||||
});
|
||||
return div;
|
||||
}
|
||||
|
||||
@@ -1,122 +0,0 @@
|
||||
|
||||
function TilesetImage(name, numTiles, tileSize, tags) {
|
||||
this._name = name;
|
||||
this._numTiles = numTiles ? numTiles : { x: 1, y: 1 };
|
||||
this._tileSize = tileSize ? tileSize : { x: 32, y: 32 };
|
||||
this._tags = tags ? tags : [];
|
||||
|
||||
this.localIDToCoords = function(localID) {
|
||||
return {
|
||||
x: (localID % this._numTiles.x) * this._tileSize.x,
|
||||
y: Math.floor(localID / this._numTiles.x) * this._tileSize.y
|
||||
}
|
||||
}
|
||||
this.coordsToLocalID = function(x, y) {
|
||||
return Math.floor(x / this._tileSize.x)
|
||||
+ this._numTiles.x * Math.floor(y / this._tileSize.y)
|
||||
}
|
||||
}
|
||||
|
||||
var defaultimage = {
|
||||
name: 'defaultimage',
|
||||
localID: 0,
|
||||
path: ''
|
||||
};
|
||||
|
||||
function ImageSelector(imagePath, dialog) {
|
||||
var _tilesets = {};
|
||||
_tilesets[""] = new TilesetImage(defaultimage.name);
|
||||
_tilesets[defaultimage.name] = _tilesets[""];
|
||||
|
||||
var currentInput;
|
||||
|
||||
var get = function(name) { return _tilesets[name]; }
|
||||
|
||||
var parseImageID = function(str) {
|
||||
if (!str || str == "") return defaultimage;
|
||||
var v = str.split(":");
|
||||
if (v.length < 1) return defaultimage;
|
||||
return {
|
||||
name: v[0],
|
||||
localID: v[1],
|
||||
path: imagePath
|
||||
};
|
||||
}
|
||||
|
||||
var getImageID = function(name, localID) {
|
||||
if (!name) return "";
|
||||
return name + ":" + localID;
|
||||
}
|
||||
|
||||
this.setImage = function(imageElem, imageID, scale) {
|
||||
if (!scale) scale = 1;
|
||||
var img = parseImageID(imageID);
|
||||
var tilesetImage = get(img.name);
|
||||
if (!tilesetImage) { tilesetImage = get(""); }
|
||||
var c = tilesetImage.localIDToCoords(img.localID);
|
||||
imageElem.css({
|
||||
"background-image": "url(" +img.path + img.name + ".png)",
|
||||
"background-position": (-c.x)*scale+"px " + (-c.y)*scale+"px",
|
||||
"width": tilesetImage._tileSize.x * scale + "px",
|
||||
"height": tilesetImage._tileSize.y * scale + "px",
|
||||
"cursor": "pointer"
|
||||
});
|
||||
if (scale) {
|
||||
imageElem.css({
|
||||
"background-size":
|
||||
tilesetImage._tileSize.x * tilesetImage._numTiles.x * scale + "px "
|
||||
+ tilesetImage._tileSize.y * tilesetImage._numTiles.y * scale + "px "
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
this.add = function(tileset) {
|
||||
var name = tileset._name;
|
||||
_tilesets[name] = tileset;
|
||||
dialog.append("<img src=\"" + imagePath + name + ".png\" id=\"" + name + "\" style=\"cursor: pointer;\" />");
|
||||
|
||||
dialog.find("#" + name).click(function(e) {
|
||||
var x = e.pageX - $(this).offset().left;
|
||||
var y = e.pageY - $(this).offset().top;
|
||||
var localID = tileset.coordsToLocalID(x, y);
|
||||
currentInput.val(getImageID(name, localID));
|
||||
currentInput.change(); // Causes the change handler to be run, thus updating the image.
|
||||
dialog.dialog("close");
|
||||
});
|
||||
}
|
||||
|
||||
var showImages = function(showTilesetTag) {
|
||||
jQuery.each(_tilesets, function(idx, t) {
|
||||
if (!idx) return;
|
||||
var visible = t._tags.indexOf(showTilesetTag) >= 0;
|
||||
$( "#" + idx, dialog ).toggle(visible);
|
||||
});
|
||||
}
|
||||
|
||||
this.imageify = function(img, elem, showTilesetTag) {
|
||||
var setImage = this.setImage;
|
||||
elem.change(function() { setImage(img, elem.val()); });
|
||||
img.click(function() {
|
||||
currentInput = elem;
|
||||
showImages(showTilesetTag);
|
||||
dialog.dialog("open");
|
||||
});
|
||||
elem.change();
|
||||
}
|
||||
|
||||
|
||||
dialog.dialog({
|
||||
title: "Select icon",
|
||||
autoOpen: false,
|
||||
modal: true,
|
||||
width: 730,
|
||||
height: 800,
|
||||
position: [30,30],
|
||||
buttons: {
|
||||
Cancel: function() {
|
||||
$( this ).dialog( "close" );
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user