diff --git a/AndorsTrailEdit/ImportExport.js b/AndorsTrailEdit/ImportExport.js deleted file mode 100644 index ef7ea7289..000000000 --- a/AndorsTrailEdit/ImportExport.js +++ /dev/null @@ -1,70 +0,0 @@ - -var importDialog; -var exportDialog; - -function exportIfExists(dataStore, div) { - var exportData = dataStore.serialize(); - $( "#value" , div ).val(exportData); -} - -function importDatastore(dataStore, content) { - dataStore.deserialize(content); -} - -function prepareImport(dataStore, div) { - var importButton = $( "#import", div ); - var textarea = $( "#value", div ); - importButton.button().click(function() { - if (!textarea.val()) return; - importDatastore(dataStore, textarea.val()); - }); - textarea.keyup(function() { - var disabled = $(this).val() ? false : true; - importButton.button( "option", "disabled", disabled ); - }); -} - -function showImportDialog() { - $( "#import", importDialog ).button( "option", "disabled", true ); - $( "#value", importDialog ).val(""); - importDialog.dialog( "open" ); -} - -function showExportDialog() { - exportIfExists(model.actorConditions, $( ".export-actorconditions", exportDialog )); - exportIfExists(model.quests, $( ".export-quests", exportDialog )); - exportIfExists(model.items, $( ".export-items", exportDialog )); - exportIfExists(model.droplists, $( ".export-droplists", exportDialog )); - exportIfExists(model.dialogue, $( ".export-dialogue", exportDialog )); - exportIfExists(model.monsters, $( ".export-monsters", exportDialog )); - exportDialog.dialog( "open" ); -} - -function prepareImportExportDialogs(buttons) { - importDialog = $( "#templates #dialog-import" ) - .dialog({ - title: "Import data", - modal: true, - autoOpen: false, - width: 840, - buttons: buttons - }); - prepareImport(model.actorConditions, $( ".import-actorconditions", importDialog )); - prepareImport(model.quests, $( ".import-quests", importDialog )); - prepareImport(model.items, $( ".import-items", importDialog )); - prepareImport(model.droplists, $( ".import-droplists", importDialog )); - prepareImport(model.dialogue, $( ".import-dialogue", importDialog )); - prepareImport(model.monsters, $( ".import-monsters", importDialog )); - $( "#importsections", importDialog ).accordion({ autoHeight: false }); - - exportDialog = $( "#templates #dialog-export" ) - .dialog({ - title: "Export data", - modal: true, - autoOpen: false, - width: 840, - buttons: buttons - }); - - $( "#exportsections", exportDialog ).accordion({ autoHeight: false }); -} diff --git a/AndorsTrailEdit/app.js b/AndorsTrailEdit/app.js index aef5d481c..bd5d18a51 100644 --- a/AndorsTrailEdit/app.js +++ b/AndorsTrailEdit/app.js @@ -1,5 +1,5 @@ -var app = (function(controllers) { - return angular +var ATEditor = (function(ATEditor, controllers) { + ATEditor.app = angular .module('ateditor', []) .config(['$routeProvider', function($routeProvider) { $routeProvider @@ -9,6 +9,9 @@ var app = (function(controllers) { .when('/droplist/edit/:id', {templateUrl: 'edit_droplist.html', controller: controllers.DropListController}) .when('/dialogue/edit/:id', {templateUrl: 'edit_dialogue.html', controller: controllers.DialogueController}) .when('/monster/edit/:id', {templateUrl: 'edit_monster.html', controller: controllers.MonsterController}) - .when('/itemcategory/edit/:id', {templateUrl: 'edit_itemcategory.html', controller: controllers.ItemCategoryController}); + .when('/itemcategory/edit/:id', {templateUrl: 'edit_itemcategory.html', controller: controllers.ItemCategoryController}) + .when('/import', {templateUrl: 'import.html', controller: controllers.ImportController}) + .when('/export', {templateUrl: 'export.html', controller: controllers.ExportController}); }]); -})(controllers); + return ATEditor; +})(ATEditor, ATEditor.controllers); diff --git a/AndorsTrailEdit/controllers.js b/AndorsTrailEdit/controllers.js index e38f2a990..ad7896d36 100644 --- a/AndorsTrailEdit/controllers.js +++ b/AndorsTrailEdit/controllers.js @@ -1,6 +1,8 @@ -var controllers = (function(model) { +var ATEditor = (function(ATEditor, model, importExport) { - function NavigationController($scope, $routeParams) { + var controllers = {}; + + controllers.NavigationController = function($scope, $routeParams) { $scope.sections = model.sections; $scope.previousItems = []; @@ -12,7 +14,7 @@ var controllers = (function(model) { if ($scope.previousItems.length > 5) { $scope.previousItems.pop(); } - window.location = "#/" + section.objectTypename + "/edit/" + obj.id; + window.location = "#/" + section.id + "/edit/" + obj.id; }; $scope.addObj = function(section) { var item = section.addNew(); @@ -36,44 +38,33 @@ var controllers = (function(model) { $scope.editObj(section, item); }; - } + }; - function ActorConditionController($scope, $routeParams) { + controllers.ActorConditionController = function($scope, $routeParams) { $scope.datasource = model.actorConditions; - $scope.obj = model.actorConditions.findById($routeParams.id); - } - function QuestController($scope, $routeParams) { + $scope.obj = $scope.datasource.findById($routeParams.id); + }; + controllers.QuestController = function($scope, $routeParams) { $scope.datasource = model.quests; - $scope.obj = model.quests.findById($routeParams.id); - } - function ItemController($scope, $routeParams) { + $scope.obj = $scope.datasource.findById($routeParams.id); + }; + controllers.ItemController = function($scope, $routeParams) { $scope.datasource = model.items; - $scope.obj = model.items.findById($routeParams.id); - } - function DropListController($scope, $routeParams) { + $scope.obj = $scope.datasource.findById($routeParams.id); + }; + controllers.DropListController = function($scope, $routeParams) { $scope.datasource = model.droplists; - $scope.obj = model.droplists.findById($routeParams.id); - } - function DialogueController($scope, $routeParams) { + $scope.obj = $scope.datasource.findById($routeParams.id); + }; + controllers.DialogueController = function($scope, $routeParams) { $scope.datasource = model.dialogue; - $scope.obj = model.dialogue.findById($routeParams.id); - } - function MonsterController($scope, $routeParams) { + $scope.obj = $scope.datasource.findById($routeParams.id); + }; + controllers.MonsterController = function($scope, $routeParams) { $scope.datasource = model.monsters; - var m = model.monsters.findById($routeParams.id) || {}; - m.attackDamage = m.attackDamage || {}; - m.hasConversation = m.phraseID; - m.hasCombatTraits = m.attackChance || m.attackDamage.min || m.criticalSkill || m.criticalMultiplier || m.blockChance || m.damageResistance || m.hitEffect; - m.hasHitEffect = m.hitEffect; - m.hitEffect = m.hitEffect || { conditionsSource: [], conditionsTarget: [] }; + var m = $scope.datasource.findById($routeParams.id) || {}; $scope.obj = m; $scope.getExperience = function(obj) { - /* - 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); - */ - var EXP_FACTOR_DAMAGERESISTANCE = 9; var EXP_FACTOR_SCALING = 0.7; @@ -81,10 +72,15 @@ var controllers = (function(model) { var v = function(i) { return i ? i : 0; } var attacksPerTurn = Math.floor(v(obj.maxAP) / v(obj.attackCost)); - var avgDamagePotential = (v(obj.attackDamage.min) + v(obj.attackDamage.max)) / 2; + var avgDamagePotential = 0; + if (obj.attackDamage) { avgDamagePotential = (v(obj.attackDamage.min) + v(obj.attackDamage.max)) / 2; } var avgAttackHP = attacksPerTurn * div100(v(obj.attackChance)) * avgDamagePotential * (1 + div100(v(obj.criticalSkill)) * v(obj.criticalMultiplier)); var avgDefenseHP = v(obj.maxHP) * (1 + div100(v(obj.blockChance))) + EXP_FACTOR_DAMAGERESISTANCE * v(obj.damageResistance); - var experience = (avgAttackHP * 3 + avgDefenseHP) * EXP_FACTOR_SCALING; + var attackConditionBonus = 0; + if (obj.hitEffect && obj.hitEffect.conditionsTarget && v(obj.hitEffect.conditionsTarget.length) > 0) { + attackConditionBonus = 50; + } + var experience = (avgAttackHP * 3 + avgDefenseHP) * EXP_FACTOR_SCALING + attackConditionBonus; return Math.ceil(experience); }; @@ -92,6 +88,17 @@ var controllers = (function(model) { $scope.experience = $scope.getExperience($scope.obj); }; $scope.recalculateExperience(); + $scope.$watch('obj.maxAP', $scope.recalculateExperience); + $scope.$watch('obj.attackCost', $scope.recalculateExperience); + $scope.$watch('obj.attackDamage.min', $scope.recalculateExperience); + $scope.$watch('obj.attackDamage.max', $scope.recalculateExperience); + $scope.$watch('obj.attackChance', $scope.recalculateExperience); + $scope.$watch('obj.criticalSkill', $scope.recalculateExperience); + $scope.$watch('obj.criticalMultiplier', $scope.recalculateExperience); + $scope.$watch('obj.maxHP', $scope.recalculateExperience); + $scope.$watch('obj.blockChance', $scope.recalculateExperience); + $scope.$watch('obj.damageResistance', $scope.recalculateExperience); + $scope.$watch('obj.hitEffect.conditionsTarget.length', $scope.recalculateExperience); $scope.addCondition = function(list) { list.push({magnitude:1, duration:1, chance:100}); }; @@ -99,20 +106,44 @@ var controllers = (function(model) { var idx = list.indexOf(cond); list.splice(idx, 1); }; - } - function ItemCategoryController($scope, $routeParams) { - $scope.datasource = model.itemCategories; - $scope.obj = model.itemCategories.findById($routeParams.id); - } - - return { - NavigationController: NavigationController - ,ActorConditionController: ActorConditionController - ,QuestController: QuestController - ,ItemController: ItemController - ,DropListController: DropListController - ,DialogueController: DialogueController - ,MonsterController: MonsterController - ,ItemCategoryController: ItemCategoryController }; -})(model); + controllers.ItemCategoryController = function($scope, $routeParams) { + $scope.datasource = model.itemCategories; + $scope.obj = $scope.datasource.findById($routeParams.id); + }; + + String.prototype.trim = String.prototype.trim || (function(){return this.replace(/^\s+|\s+$/g, '');}); + + controllers.ImportController = function($scope) { + $scope.sections = model.sections; + $scope.content = ""; + $scope.selectedSection = $scope.selectedSection || model.items; + + $scope.importData = function() { + $scope.errorMsg = ""; + $scope.importedMsg = ""; + + var section = $scope.selectedSection; + var countBefore = section.items.length; + function success() { + var countAfter = section.items.length; + $scope.importedMsg = "Imported " + (countAfter - countBefore) + " " + section.name; + } + function error(msg) { + $scope.errorMsg = "Error importing data: " + msg; + } + importExport.importData(section, $scope.content, success, error); + }; + }; + controllers.ExportController = function($scope) { + $scope.sections = model.sections; + $scope.content = ""; + $scope.selectedSection = $scope.selectedSection || model.items; + $scope.exportData = function() { + $scope.content = importExport.exportData($scope.selectedSection); + }; + }; + + ATEditor.controllers = controllers; + return ATEditor; +})(ATEditor, ATEditor.model, ATEditor.importExport); diff --git a/AndorsTrailEdit/DataStore.js b/AndorsTrailEdit/datastore.js similarity index 63% rename from AndorsTrailEdit/DataStore.js rename to AndorsTrailEdit/datastore.js index c5c0a89b3..55856da83 100644 --- a/AndorsTrailEdit/DataStore.js +++ b/AndorsTrailEdit/datastore.js @@ -1,19 +1,19 @@ - -var DataStore = (function(_) { - function DataStore(options) { +var ATEditor = (function(ATEditor, _) { + + ATEditor.DataStore = function(options) { var defaultOptions = { nameField: 'name' ,idField: 'id' ,iconIDField: 'iconID' ,newItemTemplate: function() { return {}; } }; - options = _.extend(defaultOptions, options); + _.defaults(options, defaultOptions); - this.items = []; + var items = []; + this.items = items; this.name = options.name; - this.objectTypename = options.objectTypename; - this.legacyFieldList = options.legacyFieldList; + this.id = options.id; this.findById = function(id) { return _.find(this.items, function(obj) { return obj[options.idField] === id; }); @@ -30,37 +30,49 @@ var DataStore = (function(_) { this.addNew = function() { var obj = options.newItemTemplate(); this.ensureUniqueId(obj); - this.items.push(obj); + items.push(obj); return obj; }; this.add = function(o) { - this.items.push(o); + items.push(o); }; this.clone = function(o) { - var obj = _.extend({}, o); + var obj = ATEditor.utils.deepClone(o); this.ensureUniqueId(obj); - this.items.push(obj); + items.push(obj); return obj; }; this.remove = function(o) { - this.items = _.without(this.items, o); + items = _.without(items, o); }; - this.findFirstFreeId = function(id) { - var i = 0; - var result = id; + if(!this.hasObjectWithId(id)) { + return id; + } + + var prefix; + var n = 1; + + var match = (/^(.*\D)(\d+)$/g).exec(id); + if (match) { + prefix = match[1]; + n = parseInt(match[2]) + 1; + } else { + prefix = id + "_"; + } + + var result = prefix + n; while(this.hasObjectWithId(result)) { - i = i + 1; - result = id + i; + n = n + 1; + result = prefix + n; } return result; }; this.ensureUniqueId = function(obj) { obj[options.idField] = this.findFirstFreeId(obj[options.idField]); }; - } + }; - - return DataStore; -})(_); + return ATEditor; +})(ATEditor || {}, _); diff --git a/AndorsTrailEdit/defaults.js b/AndorsTrailEdit/defaults.js new file mode 100644 index 000000000..ecdccbc51 --- /dev/null +++ b/AndorsTrailEdit/defaults.js @@ -0,0 +1,27 @@ +var ATEditor = (function(ATEditor, _) { + + var defaults = { + monster: { + size: "1x1" + ,maxHP: 1 + ,maxAP: 10 + ,moveCost: 10 + ,unique: 0 + ,monsterClass: 0 + ,attackDamage: {} + ,hitEffect: { increaseCurrentHP: {}, increaseCurrentAP: {}, conditionsSource: [], conditionsTarget: [] } + } + }; + + ATEditor.defaults = { + addDefaults: function(type, o) { + var copyOfDefaults = ATEditor.utils.deepClone(defaults[type]); + _.defaults(o, copyOfDefaults); + }, + removeDefaults: function(type, o) { + return ATEditor.utils.cleanCopy(o, defaults[type]); + } + }; + + return ATEditor; +})(ATEditor || {}, _); diff --git a/AndorsTrailEdit/directives.js b/AndorsTrailEdit/directives.js index 4c9b1f726..ae9fe47f7 100644 --- a/AndorsTrailEdit/directives.js +++ b/AndorsTrailEdit/directives.js @@ -1,4 +1,4 @@ -(function(app, $) { +var ATEditor = (function(ATEditor, app, $) { // Copied from http://jsfiddle.net/p69aT/ // -> originally from https://groups.google.com/forum/?fromgroups=#!topic/angular/7XVOebG6z6E @@ -52,4 +52,5 @@ }; }); -})(app, jQuery); + return ATEditor; +})(ATEditor, ATEditor.app, jQuery); diff --git a/AndorsTrailEdit/edit_monster.html b/AndorsTrailEdit/edit_monster.html index 0191cc21a..7b762ac16 100644 --- a/AndorsTrailEdit/edit_monster.html +++ b/AndorsTrailEdit/edit_monster.html @@ -19,7 +19,7 @@