Line data Source code
1 : /** 2 : * @file This provides a cache for Aura and Technology templates. 3 : * They may not be serialized, otherwise rejoined clients would refer 4 : * to different objects, triggering an Out-of-sync error. 5 : */ 6 : function ModificationTemplates(path) 7 : { 8 0 : let suffix = ".json"; 9 : 10 0 : this.names = deepfreeze(listFiles(path, suffix, true)); 11 : 12 0 : this.templates = {}; 13 : 14 0 : for (let name of this.names) 15 0 : this.templates[name] = Engine.ReadJSONFile(path + name + suffix); 16 : 17 0 : deepfreeze(this.templates); 18 : } 19 : 20 72 : ModificationTemplates.prototype.GetNames = function() 21 : { 22 0 : return this.names; 23 : }; 24 : 25 72 : ModificationTemplates.prototype.Has = function(name) 26 : { 27 0 : return this.names.indexOf(name) != -1; 28 : }; 29 : 30 72 : ModificationTemplates.prototype.Get = function(name) 31 : { 32 0 : return this.templates[name]; 33 : }; 34 : 35 72 : ModificationTemplates.prototype.GetAll = function() 36 : { 37 0 : return this.templates; 38 : }; 39 : 40 : 41 : function LoadModificationTemplates() 42 : { 43 0 : global.AuraTemplates = new ModificationTemplates("simulation/data/auras/"); 44 0 : global.TechnologyTemplates = new ModificationTemplates("simulation/data/technologies/"); 45 : } 46 : 47 : /** 48 : * Derives modifications (to be applied to entities) from a given aura/technology. 49 : * 50 : * @param {Object} techTemplate - The aura/technology template to derive the modifications from. 51 : * @return {Object} - An object containing the relevant modifications. 52 : */ 53 : function DeriveModificationsFromTech(techTemplate) 54 : { 55 14 : if (!techTemplate.modifications) 56 0 : return {}; 57 : 58 14 : let techMods = {}; 59 14 : let techAffects = []; 60 14 : if (techTemplate.affects && techTemplate.affects.length) 61 16 : techAffects = techTemplate.affects.map(affected => affected.split(/\s+/)); 62 : else 63 0 : techAffects.push([]); 64 : 65 14 : for (let mod of techTemplate.modifications) 66 : { 67 17 : let affects = techAffects.slice(); 68 17 : if (mod.affects) 69 : { 70 3 : let specAffects = mod.affects.split(/\s+/); 71 3 : for (let a in affects) 72 6 : affects[a] = affects[a].concat(specAffects); 73 : } 74 : 75 17 : let newModifier = { "affects": affects }; 76 17 : for (let idx in mod) 77 37 : if (idx !== "value" && idx !== "affects") 78 17 : newModifier[idx] = mod[idx]; 79 : 80 17 : if (!techMods[mod.value]) 81 16 : techMods[mod.value] = []; 82 17 : techMods[mod.value].push(newModifier); 83 : } 84 14 : return techMods; 85 : } 86 : 87 : /** 88 : * Derives modifications (to be applied to entities) from a provided array 89 : * of aura/technology template data. 90 : * 91 : * @param {Object[]} techsDataArray 92 : * @return {Object} - The combined relevant modifications of all the technologies. 93 : */ 94 : function DeriveModificationsFromTechnologies(techsDataArray) 95 : { 96 0 : if (!techsDataArray.length) 97 0 : return {}; 98 : 99 0 : let derivedModifiers = {}; 100 0 : for (let technology of techsDataArray) 101 : { 102 : // Auras don't have a "reqs" property 103 0 : if ('reqs' in technology && !technology.reqs) 104 0 : continue; 105 : 106 0 : let modifiers = DeriveModificationsFromTech(technology); 107 0 : for (let modPath in modifiers) 108 : { 109 0 : if (!derivedModifiers[modPath]) 110 0 : derivedModifiers[modPath] = []; 111 0 : derivedModifiers[modPath] = derivedModifiers[modPath].concat(modifiers[modPath]); 112 : } 113 : } 114 0 : return derivedModifiers; 115 : } 116 : 117 : /** 118 : * Common definition of the XML schema for in-template modifications. 119 : */ 120 : const ModificationSchema = 121 72 : "<interleave>" + 122 : "<element name='Paths' a:help='Space separated value paths to modify.'>" + 123 : "<attribute name='datatype'>" + 124 : "<value>tokens</value>" + 125 : "</attribute>" + 126 : "<text/>" + 127 : "</element>" + 128 : "<element name='Affects' a:help='An array of classes to affect.'>" + 129 : "<attribute name='datatype'>" + 130 : "<value>tokens</value>" + 131 : "</attribute>" + 132 : "<text/>" + 133 : "</element>" + 134 : "<choice>" + 135 : "<element name='Add'>" + 136 : "<data type='decimal' />" + 137 : "</element>" + 138 : "<element name='Multiply'>" + 139 : "<data type='decimal' />" + 140 : "</element>" + 141 : "<element name='Replace'>" + 142 : "<text/>" + 143 : "</element>" + 144 : "</choice>" + 145 : "</interleave>"; 146 : 147 : const ModificationsSchema = 148 72 : "<element name='Modifiers' a:help='List of modifiers.'>" + 149 : "<oneOrMore>" + 150 : "<element>" + 151 : "<anyName />" + 152 : ModificationSchema + 153 : "</element>" + 154 : "</oneOrMore>" + 155 : "</element>"; 156 : 157 : /** 158 : * Derives a single modification (to be applied to entities) from a given XML template. 159 : * 160 : * @param {Object} techTemplate - The XML template node to derive the modification from. 161 : * @return {Object} containing the relevant modification. 162 : */ 163 : function DeriveModificationFromXMLTemplate(template) 164 : { 165 3 : let effect = {}; 166 3 : if (template.Add) 167 1 : effect.add = +template.Add; 168 3 : if (template.Multiply) 169 1 : effect.multiply = +template.Multiply; 170 3 : if (template.Replace) 171 1 : effect.replace = template.Replace; 172 3 : effect.affects = template.Affects ? template.Affects._string.split(/\s/) : []; 173 : 174 3 : let ret = {}; 175 3 : for (let path of template.Paths._string.split(/\s/)) 176 : { 177 3 : ret[path] = [effect]; 178 : } 179 : 180 3 : return ret; 181 : } 182 : 183 : /** 184 : * Derives all modifications (to be applied to entities) from a given XML template. 185 : * 186 : * @param {Object} techTemplate - The XML template node to derive the modifications from. 187 : * @return {Object} containing the combined modifications. 188 : */ 189 : function DeriveModificationsFromXMLTemplate(template) 190 : { 191 3 : let ret = {}; 192 3 : for (let name in template) 193 : { 194 3 : let modification = DeriveModificationFromXMLTemplate(template[name]); 195 3 : for (let path in modification) 196 : { 197 3 : if (!ret[path]) 198 3 : ret[path] = []; 199 3 : ret[path].push(modification[path][0]); 200 : } 201 : } 202 3 : return ret; 203 : }