Ticket #2377: AIAuraTech.2.patch
File AIAuraTech.2.patch, 57.3 KB (added by , 10 years ago) |
---|
-
binaries/data/mods/public/simulation/ai/aegis/attack_plan.js
544 544 count++; 545 545 if (count > 1000){ 546 546 m.debug("No target with a valid position found"); 547 Engine.ProfileStop(); 548 Engine.ProfileStop(); 547 549 return false; 548 550 } 549 551 } -
binaries/data/mods/public/simulation/ai/aegis/base-manager.js
908 908 } 909 909 } 910 910 911 // auras/techs are buggy and the AI tries to repair healthy buildings.912 // TODO: reimplement once that's fixed.913 return;914 915 911 // don't repair if we're still under attack, unless it's like a vital (civcentre or wall) building that's getting destroyed. 916 912 for (var i in damagedBuildings) { 917 913 var target = damagedBuildings[i]; … … 955 951 956 952 Engine.ProfileStart("Assign builders"); 957 953 this.assignToFoundations(gameState); 958 Engine.ProfileStop() 954 Engine.ProfileStop(); 959 955 960 956 if (this.constructing && this.anchor) 961 957 { -
binaries/data/mods/public/simulation/ai/aegis/headquarters.js
1121 1121 this.checkEvents(gameState,events,queues); 1122 1122 //this.buildMoreHouses(gameState); 1123 1123 1124 //Engine.ProfileStart("Train workers and build farms, houses. Research techs.");1125 1124 this.trainMoreWorkers(gameState, queues); 1126 1125 1127 1126 // sandbox doesn't expand. -
binaries/data/mods/public/simulation/ai/common-api/entity.js
1 1 var API3 = function(m) 2 2 { 3 3 4 m.EntityTemplate = m.Class({ 4 // defines a template. 5 // It's completely raw data, except it's slightly cleverer now and then. 6 m.Template = m.Class({ 5 7 6 // techModifications should be the tech modifications of only one player. 7 // gamestates handle "GetTemplate" and should push the player's 8 // while entities should push the owner's 9 _init: function(template, techModifications) 8 _init: function(template) 10 9 { 11 this._techModifications = techModifications;12 10 this._template = template; 11 this._tpCache = {}; 13 12 }, 14 13 14 // helper function to return a template value, optionally adjusting for tech. 15 // TODO: there's no support for "_string" values here. 16 get: function(string) 17 { 18 var value = this._template; 19 if (this._auraTemplateModif && this._auraTemplateModif[string]) { 20 return this._auraTemplateModif[string]; 21 } else if (this._techModif && this._techModif[string]) { 22 return this._techModif[string]; 23 } else { 24 if (this._tpCache[string] === undefined) 25 { 26 var args = string.split("/"); 27 for (var i = 0; i < args.length; ++i) 28 if (value[args[i]]) 29 value = value[args[i]]; 30 else 31 { 32 value = undefined; 33 break; 34 } 35 this._tpCache[string] = value; 36 } 37 return this._tpCache[string]; 38 } 39 }, 40 15 41 genericName: function() { 16 if (!this. _template.Identity || !this._template.Identity.GenericName)42 if (!this.get("Identity") || !this.get("Identity/GenericName")) 17 43 return undefined; 18 return this. _template.Identity.GenericName;44 return this.get("Identity/GenericName"); 19 45 }, 20 46 21 47 rank: function() { 22 if (!this. _template.Identity)48 if (!this.get("Identity")) 23 49 return undefined; 24 return this. _template.Identity.Rank;50 return this.get("Identity/Rank"); 25 51 }, 26 52 27 53 classes: function() { 28 if (!this. _template.Identity || !this._template.Identity.Classes || !this._template.Identity.Classes._string)54 if (!this.get("Identity") || !this.get("Identity/Classes") || !this.get("Identity/Classes/_string")) 29 55 return undefined; 30 return this. _template.Identity.Classes._string.split(/\s+/);56 return this.get("Identity/Classes/_string").split(/\s+/); 31 57 }, 32 58 33 59 requiredTech: function() { 34 if (!this._template.Identity || !this._template.Identity.RequiredTechnology) 35 return undefined; 36 return this._template.Identity.RequiredTechnology; 60 return this.get("Identity/RequiredTechnology"); 37 61 }, 38 62 39 63 available: function(gameState) { 40 if (!this._template.Identity || !this._template.Identity.RequiredTechnology) 41 return true; 42 return gameState.isResearched(this._template.Identity.RequiredTechnology); 64 return gameState.isResearched(this.get("Identity/RequiredTechnology")); 43 65 }, 44 66 45 67 // specifically 46 68 phase: function() { 47 if (!this. _template.Identity || !this._template.Identity.RequiredTechnology)69 if (!this.get("Identity/RequiredTechnology")) 48 70 return 0; 49 if (this. template.Identity.RequiredTechnology== "phase_village")71 if (this.get("Identity/RequiredTechnology") == "phase_village") 50 72 return 1; 51 if (this. template.Identity.RequiredTechnology== "phase_town")73 if (this.get("Identity/RequiredTechnology") == "phase_town") 52 74 return 2; 53 if (this. template.Identity.RequiredTechnology== "phase_city")75 if (this.get("Identity/RequiredTechnology") == "phase_city") 54 76 return 3; 55 77 return 0; 56 78 }, … … 72 94 }, 73 95 74 96 civ: function() { 75 if (!this._template.Identity) 76 return undefined; 77 return this._template.Identity.Civ; 97 return this.get("Identity/Civ"); 78 98 }, 79 99 80 100 cost: function() { 81 if (!this. _template.Cost)101 if (!this.get("Cost")) 82 102 return undefined; 83 103 84 104 var ret = {}; 85 for (var type in this. _template.Cost.Resources)86 ret[type] = GetTechModifiedProperty(this._techModifications, this._template, "Cost/Resources/"+type, +this._template.Cost.Resources[type]);105 for (var type in this.get("Cost/Resources")) 106 ret[type] = +this.get("Cost/Resources/" + type); 87 107 return ret; 88 108 }, 89 109 90 110 costSum: function() { 91 if (!this. _template.Cost)111 if (!this.get("Cost")) 92 112 return undefined; 93 113 94 114 var ret = 0; 95 for (var type in this. _template.Cost.Resources)96 ret += +this. _template.Cost.Resources[type];115 for (var type in this.get("Cost/Resources")) 116 ret += +this.get("Cost/Resources/" + type); 97 117 return ret; 98 118 }, 99 119 … … 102 122 * obstruction shape, or undefined if no obstruction. 103 123 */ 104 124 obstructionRadius: function() { 105 if (!this. _template.Obstruction)125 if (!this.get("Obstruction")) 106 126 return undefined; 107 127 108 if (this. _template.Obstruction.Static)128 if (this.get("Obstruction/Static")) 109 129 { 110 var w = +this. _template.Obstruction.Static["@width"];111 var h = +this. _template.Obstruction.Static["@depth"];130 var w = +this.get("Obstruction/Static/@width"); 131 var h = +this.get("Obstruction/Static/@depth"); 112 132 return Math.sqrt(w*w + h*h) / 2; 113 133 } 114 134 115 if (this. _template.Obstruction.Unit)116 return +this. _template.Obstruction.Unit["@radius"];135 if (this.get("Obstruction/Unit")) 136 return +this.get("Obstruction/Unit/@radius"); 117 137 118 138 return 0; // this should never happen 119 139 }, 120 140 121 141 /** 122 142 * Returns the radius of a circle surrounding this entity's 123 143 * footprint. 124 144 */ 125 145 footprintRadius: function() { 126 if (!this. _template.Footprint)146 if (!this.get("Footprint")) 127 147 return undefined; 128 148 129 if (this. _template.Footprint.Square)149 if (this.get("Footprint/Square")) 130 150 { 131 var w = +this. _template.Footprint.Square["@width"];132 var h = +this. _template.Footprint.Square["@depth"];151 var w = +this.get("Footprint/Square/@width"); 152 var h = +this.get("Footprint/Square/@depth"); 133 153 return Math.sqrt(w*w + h*h) / 2; 134 154 } 135 155 136 if (this. _template.Footprint.Circle)137 return +this. _template.Footprint.Circle["@radius"];156 if (this.get("Footprint/Circle")) 157 return +this.get("Footprint/Circle/@radius"); 138 158 139 159 return 0; // this should never happen 140 160 }, 141 161 142 162 maxHitpoints: function() 143 163 { 144 if (this. _template.Health!== undefined)145 return GetTechModifiedProperty(this._techModifications, this._template, "Health/Max",+this._template.Health.Max);164 if (this.get("Health") !== undefined) 165 return +this.get("Health/Max"); 146 166 return 0; 147 167 }, 168 148 169 isHealable: function() 149 170 { 150 if (this. _template.Health!== undefined)151 return this. _template.Health.Unhealable!== "true";171 if (this.get("Health") !== undefined) 172 return this.get("Health/Unhealable") !== "true"; 152 173 return false; 153 174 }, 175 154 176 isRepairable: function() 155 177 { 156 if (this. _template.Health!== undefined)157 return this. _template.Health.Repairable=== "true";178 if (this.get("Health") !== undefined) 179 return this.get("Health/Repairable") === "true"; 158 180 return false; 159 181 }, 160 182 161 183 getPopulationBonus: function() { 162 if (!this._template.Cost || !this._template.Cost.PopulationBonus) 163 return undefined; 164 return this._template.Cost.PopulationBonus; 184 return this.get("Cost/PopulationBonus"); 165 185 }, 166 186 167 187 armourStrengths: function() { 168 if (!this. _template.Armour)188 if (!this.get("Armour")) 169 189 return undefined; 170 190 171 191 return { 172 hack: GetTechModifiedProperty(this._techModifications, this._template, "Armour/Hack", +this._template.Armour.Hack),173 pierce: GetTechModifiedProperty(this._techModifications, this._template, "Armour/Pierce", +this._template.Armour.Pierce),174 crush: GetTechModifiedProperty(this._techModifications, this._template, "Armour/Crush", +this._template.Armour.Crush)192 hack: +this.get("Armour/Hack"), 193 pierce: +this.get("Armour/Pierce"), 194 crush: +this.get("Armour/Crush") 175 195 }; 176 196 }, 177 197 178 198 attackTypes: function() { 179 if (!this. _template.Attack)199 if (!this.get("Attack")) 180 200 return undefined; 181 201 182 202 var ret = []; 183 for (var type in this. _template.Attack)203 for (var type in this.get("Attack")) 184 204 ret.push(type); 185 205 186 206 return ret; 187 207 }, 188 208 189 209 attackRange: function(type) { 190 if (!this. _template.Attack || !this._template.Attack[type])210 if (!this.get("Attack/" + type +"")) 191 211 return undefined; 192 212 193 213 return { 194 max: GetTechModifiedProperty(this._techModifications, this._template, "Attack/MaxRange", +this._template.Attack[type].MaxRange),195 min: GetTechModifiedProperty(this._techModifications, this._template, "Attack/MinRange", +(this._template.Attack[type].MinRange || 0))214 max: +this.get("Attack/" + type +"/MaxRange"), 215 min: +(this.get("Attack/" + type +"/MinRange") || 0) 196 216 }; 197 217 }, 198 218 199 219 attackStrengths: function(type) { 200 if (!this. _template.Attack || !this._template.Attack[type])220 if (!this.get("Attack/" + type +"")) 201 221 return undefined; 202 222 203 223 return { 204 hack: GetTechModifiedProperty(this._techModifications, this._template, "Attack/"+type+"/Hack", +(this._template.Attack[type].Hack || 0)),205 pierce: GetTechModifiedProperty(this._techModifications, this._template, "Attack/"+type+"/Pierce", +(this._template.Attack[type].Pierce || 0)),206 crush: GetTechModifiedProperty(this._techModifications, this._template, "Attack/"+type+"/Crush", +(this._template.Attack[type].Crush || 0))224 hack: +(this.get("Attack/" + type + "/Hack") || 0), 225 pierce: +(this.get("Attack/" + type + "/Pierce") || 0), 226 crush: +(this.get("Attack/" + type + "/Crush") || 0) 207 227 }; 208 228 }, 209 229 210 230 attackTimes: function(type) { 211 if (!this. _template.Attack || !this._template.Attack[type])231 if (!this.get("Attack/" + type +"")) 212 232 return undefined; 213 233 214 234 return { 215 prepare: GetTechModifiedProperty(this._techModifications, this._template, "Attack/"+type+"/PrepareTime", +(this._template.Attack[type].PrepareTime || 0)),216 repeat: GetTechModifiedProperty(this._techModifications, this._template, "Attack/"+type+"/RepeatTime", +(this._template.Attack[type].RepeatTime || 1000))235 prepare: +(this.get("Attack/" + type + "/PrepareTime") || 0), 236 repeat: +(this.get("Attack/" + type + "/RepeatTime") || 1000) 217 237 }; 218 238 }, 219 239 220 240 // returns the classes this templates counters: 221 // Return type is [ [-neededClasses- ] , multiplier].241 // Return type is [ [-neededClasses- , multiplier], … ]. 222 242 getCounteredClasses: function() { 223 if (!this. _template.Attack)243 if (!this.get("Attack")) 224 244 return undefined; 225 245 226 246 var Classes = []; 227 for (var i in this. _template.Attack) {228 if (!this. _template.Attack[i].Bonuses)247 for (var i in this.get("Attack")) { 248 if (!this.get("Attack/" + i + "/Bonuses")) 229 249 continue; 230 for (var o in this. _template.Attack[i].Bonuses)231 if (this. _template.Attack[i].Bonuses[o].Classes)232 Classes.push([this. _template.Attack[i].Bonuses[o].Classes.split(" "), +this._template.Attack[i].Bonuses[o].Multiplier]);250 for (var o in this.get("Attack/" + i + "/Bonuses")) 251 if (this.get("Attack/" + i + "/Bonuses/" + o + "/Classes")) 252 Classes.push([this.get("Attack/" + i +"/Bonuses/" + o +"/Classes").split(" "), +this.get("Attack/" + i +"/Bonuses" +o +"/Multiplier")]); 233 253 } 234 254 return Classes; 235 255 }, … … 237 257 // returns true if the entity counters those classes. 238 258 // TODO: refine using the multiplier 239 259 countersClasses: function(classes) { 240 if (!this. _template.Attack)260 if (!this.get("Attack")) 241 261 return false; 242 262 var mcounter = []; 243 for (var i in this. _template.Attack) {244 if (!this. _template.Attack[i].Bonuses)263 for (var i in this.get("Attack")) { 264 if (!this.get("Attack/" + i + "/Bonuses")) 245 265 continue; 246 for (var o in this. _template.Attack[i].Bonuses)247 if (this. _template.Attack[i].Bonuses[o].Classes)248 mcounter.concat(this. _template.Attack[i].Bonuses[o].Classes.split(" "));266 for (var o in this.get("Attack/" + i + "/Bonuses")) 267 if (this.get("Attack/" + i + "/Bonuses/" + o + "/Classes")) 268 mcounter.concat(this.get("Attack/" + i + "/Bonuses/" + o + "/Classes").split(" ")); 249 269 } 250 270 for (var i in classes) 251 271 { … … 257 277 258 278 // returns, if it exists, the multiplier from each attack against a given class 259 279 getMultiplierAgainst: function(type, againstClass) { 260 if (!this. _template.Attack || !this._template.Attack[type])280 if (!this.get("Attack/" + type +"")) 261 281 return undefined; 262 282 263 if (this. _template.Attack[type].Bonuses)264 for (var o in this. _template.Attack[type].Bonuses) {265 if (!this. _template.Attack[type].Bonuses[o].Classes)283 if (this.get("Attack/" + type + "/Bonuses")) 284 for (var o in this.get("Attack/" + type + "/Bonuses")) { 285 if (!this.get("Attack/" + type + "/Bonuses/" + o + "/Classes")) 266 286 continue; 267 var total = this. _template.Attack[type].Bonuses[o].Classes.split(" ");287 var total = this.get("Attack/" + type + "/Bonuses/" + o + "/Classes").split(" "); 268 288 for (var j in total) 269 289 if (total[j] === againstClass) 270 return this. _template.Attack[type].Bonuses[o].Multiplier;290 return this.get("Attack/" + type + "/Bonuses/" + o + "/Multiplier"); 271 291 } 272 292 return 1; 273 293 }, 274 294 275 295 // returns true if the entity can attack the given class 276 296 canAttackClass: function(saidClass) { 277 if (!this. _template.Attack)297 if (!this.get("Attack")) 278 298 return false; 279 299 280 for (var i in this. _template.Attack) {281 if (!this. _template.Attack[i].RestrictedClasses || !this._template.Attack[i].RestrictedClasses._string)300 for (var i in this.get("Attack")) { 301 if (!this.get("Attack/" + i + "/RestrictedClasses") || !this.get("Attack/" + i + "/RestrictedClasses/_string")) 282 302 continue; 283 var cannotAttack = this. _template.Attack[i].RestrictedClasses._string.split(" ");303 var cannotAttack = this.get("Attack/" + i + "/RestrictedClasses/_string").split(" "); 284 304 if (cannotAttack.indexOf(saidClass) !== -1) 285 305 return false; 286 306 } … … 288 308 }, 289 309 290 310 buildableEntities: function() { 291 if (!this._template.Builder) 292 return undefined; 293 if (!this._template.Builder.Entities._string) 311 if (!this.get("Builder/Entities/_string")) 294 312 return []; 295 313 var civ = this.civ(); 296 var templates = this. _template.Builder.Entities._string.replace(/\{civ\}/g, civ).split(/\s+/);314 var templates = this.get("Builder/Entities/_string").replace(/\{civ\}/g, civ).split(/\s+/); 297 315 return templates; // TODO: map to Entity? 298 316 }, 299 317 300 318 trainableEntities: function() { 301 if (!this. _template.ProductionQueue || !this._template.ProductionQueue.Entities || !this._template.ProductionQueue.Entities._string)319 if (!this.get("ProductionQueue/Entities/_string")) 302 320 return undefined; 303 321 var civ = this.civ(); 304 var templates = this. _template.ProductionQueue.Entities._string.replace(/\{civ\}/g, civ).split(/\s+/);322 var templates = this.get("ProductionQueue/Entities/_string").replace(/\{civ\}/g, civ).split(/\s+/); 305 323 return templates; 306 324 }, 307 325 308 326 researchableTechs: function() { 309 if (!this. _template.ProductionQueue || !this._template.ProductionQueue.Technologies || !this._template.ProductionQueue.Technologies._string)327 if (!this.get("ProductionQueue/Technologies/_string")) 310 328 return undefined; 311 var templates = this. _template.ProductionQueue.Technologies._string.split(/\s+/);329 var templates = this.get("ProductionQueue/Technologies/_string").split(/\s+/); 312 330 return templates; 313 331 }, 314 332 315 333 resourceSupplyType: function() { 316 if (!this. _template.ResourceSupply)334 if (!this.get("ResourceSupply")) 317 335 return undefined; 318 var [type, subtype] = this. _template.ResourceSupply.Type.split('.');336 var [type, subtype] = this.get("ResourceSupply/Type").split('.'); 319 337 return { "generic": type, "specific": subtype }; 320 338 }, 321 339 // will return either "food", "wood", "stone", "metal" and not treasure. 322 340 getResourceType: function() { 323 if (!this. _template.ResourceSupply)341 if (!this.get("ResourceSupply")) 324 342 return undefined; 325 var [type, subtype] = this. _template.ResourceSupply.Type.split('.');343 var [type, subtype] = this.get("ResourceSupply/Type").split('.'); 326 344 if (type == "treasure") 327 345 return subtype; 328 346 return type; 329 347 }, 330 348 331 349 resourceSupplyMax: function() { 332 if (!this. _template.ResourceSupply)350 if (!this.get("ResourceSupply")) 333 351 return undefined; 334 return +this. _template.ResourceSupply.Amount;352 return +this.get("ResourceSupply/Amount"); 335 353 }, 336 354 337 355 maxGatherers: function() 338 356 { 339 if (this. _template.ResourceSupply!== undefined)340 return +this. _template.ResourceSupply.MaxGatherers;357 if (this.get("ResourceSupply") !== undefined) 358 return +this.get("ResourceSupply/MaxGatherers"); 341 359 return 0; 342 360 }, 343 361 344 362 resourceGatherRates: function() { 345 if (!this. _template.ResourceGatherer)363 if (!this.get("ResourceGatherer")) 346 364 return undefined; 347 365 var ret = {}; 348 var baseSpeed = GetTechModifiedProperty(this._techModifications, this._template, "ResourceGatherer/BaseSpeed", +this._template.ResourceGatherer.BaseSpeed);349 for (var r in this. _template.ResourceGatherer.Rates)350 ret[r] = GetTechModifiedProperty(this._techModifications, this._template, "ResourceGatherer/Rates/"+r, +this._template.ResourceGatherer.Rates[r]) * baseSpeed;366 var baseSpeed = +this.get("ResourceGatherer/BaseSpeed"); 367 for (var r in this.get("ResourceGatherer/Rates")) 368 ret[r] = +this.get("ResourceGatherer/Rates/" + r) * baseSpeed; 351 369 return ret; 352 370 }, 353 371 354 372 resourceDropsiteTypes: function() { 355 if (!this. _template.ResourceDropsite)373 if (!this.get("ResourceDropsite")) 356 374 return undefined; 357 return this. _template.ResourceDropsite.Types.split(/\s+/);375 return this.get("ResourceDropsite/Types").split(/\s+/); 358 376 }, 359 377 360 378 361 379 garrisonableClasses: function() { 362 if (!this. _template.GarrisonHolder || !this._template.GarrisonHolder.List._string)380 if (!this.get("GarrisonHolder") || !this.get("GarrisonHolder/List/_string")) 363 381 return undefined; 364 return this. _template.GarrisonHolder.List._string.split(/\s+/);382 return this.get("GarrisonHolder/List/_string").split(/\s+/); 365 383 }, 366 384 367 385 garrisonMax: function() { 368 if (!this. _template.GarrisonHolder)386 if (!this.get("GarrisonHolder")) 369 387 return undefined; 370 return this. _template.GarrisonHolder.Max;388 return this.get("GarrisonHolder/Max"); 371 389 }, 372 390 373 391 /** … … 375 393 * (Any non domestic currently.) 376 394 */ 377 395 isUnhuntable: function() { 378 if (!this. _template.UnitAI || !this._template.UnitAI.NaturalBehaviour)396 if (!this.get("UnitAI") || !this.get("UnitAI/NaturalBehaviour")) 379 397 return false; 380 398 381 399 // only attack domestic animals since they won't flee nor retaliate. 382 return this. _template.UnitAI.NaturalBehaviour!== "domestic";400 return this.get("UnitAI/NaturalBehaviour") !== "domestic"; 383 401 }, 384 402 385 403 walkSpeed: function() { 386 if (!this. _template.UnitMotion || !this._template.UnitMotion.WalkSpeed)404 if (!this.get("UnitMotion") || !this.get("UnitMotion/WalkSpeed")) 387 405 return undefined; 388 return this. _template.UnitMotion.WalkSpeed;406 return this.get("UnitMotion/WalkSpeed"); 389 407 }, 390 408 391 409 buildCategory: function() { 392 if (!this. _template.BuildRestrictions || !this._template.BuildRestrictions.Category)410 if (!this.get("BuildRestrictions") || !this.get("BuildRestrictions/Category")) 393 411 return undefined; 394 return this. _template.BuildRestrictions.Category;412 return this.get("BuildRestrictions/Category"); 395 413 }, 396 414 397 415 buildTime: function() { 398 if (!this. _template.Cost || !this._template.Cost.BuildTime)416 if (!this.get("Cost") || !this.get("Cost/BuildTime")) 399 417 return undefined; 400 return this. _template.Cost.BuildTime;418 return this.get("Cost/BuildTime"); 401 419 }, 402 420 403 421 buildDistance: function() { 404 if (!this. _template.BuildRestrictions || !this._template.BuildRestrictions.Distance)422 if (!this.get("BuildRestrictions") || !this.get("BuildRestrictions/Distance")) 405 423 return undefined; 406 return this. _template.BuildRestrictions.Distance;424 return this.get("BuildRestrictions/Distance"); 407 425 }, 408 426 409 427 buildPlacementType: function() { 410 if (!this. _template.BuildRestrictions || !this._template.BuildRestrictions.PlacementType)428 if (!this.get("BuildRestrictions") || !this.get("BuildRestrictions/PlacementType")) 411 429 return undefined; 412 return this. _template.BuildRestrictions.PlacementType;430 return this.get("BuildRestrictions/PlacementType"); 413 431 }, 414 432 415 433 buildTerritories: function() { 416 if (!this. _template.BuildRestrictions || !this._template.BuildRestrictions.Territory)434 if (!this.get("BuildRestrictions") || !this.get("BuildRestrictions/Territory")) 417 435 return undefined; 418 return this. _template.BuildRestrictions.Territory.split(/\s+/);436 return this.get("BuildRestrictions/Territory").split(/\s+/); 419 437 }, 420 438 421 439 hasBuildTerritory: function(territory) { … … 424 442 }, 425 443 426 444 hasTerritoryInfluence: function() { 427 return (this. _template.TerritoryInfluence!== undefined);445 return (this.get("TerritoryInfluence") !== undefined); 428 446 }, 429 447 430 448 territoryInfluenceRadius: function() { 431 if (this. _template.TerritoryInfluence!== undefined)432 return (this. _template.TerritoryInfluence.Radius);449 if (this.get("TerritoryInfluence") !== undefined) 450 return (this.get("TerritoryInfluence/Radius")); 433 451 else 434 452 return -1; 435 453 }, 436 454 437 455 territoryInfluenceWeight: function() { 438 if (this. _template.TerritoryInfluence!== undefined)439 return (this. _template.TerritoryInfluence.Weight);456 if (this.get("TerritoryInfluence") !== undefined) 457 return (this.get("TerritoryInfluence/Weight")); 440 458 else 441 459 return -1; 442 460 }, 443 461 444 462 visionRange: function() { 445 if (!this._template.Vision) 446 return undefined; 447 return this._template.Vision.Range; 463 return this.get("Vision/Range"); 448 464 } 449 465 }); 450 466 451 467 452 468 // defines an entity, with a super Template. 469 // also redefines several of the template functions where the only change is applying aura and tech modifications. 453 470 m.Entity = m.Class({ 454 _super: m. EntityTemplate,471 _super: m.Template, 455 472 456 473 _init: function(sharedAI, entity) 457 474 { 458 this._super.call(this, sharedAI.GetTemplate(entity.template) , sharedAI._techModifications[entity.owner]);475 this._super.call(this, sharedAI.GetTemplate(entity.template)); 459 476 460 this._ai = sharedAI;461 477 this._templateName = entity.template; 462 478 this._entity = entity; 479 this._auraTemplateModif = {}; // template modification from auras. this is only for this entity. 480 this._ai = sharedAI; 481 if (!sharedAI._techModifications[entity.owner][this._templateName]) 482 sharedAI._techModifications[entity.owner][this._templateName] = {}; 483 this._techModif = sharedAI._techModifications[entity.owner][this._templateName]; // save a reference to the template tech modifications 463 484 }, 464 485 465 486 toString: function() { … … 477 498 /** 478 499 * Returns extra data that the AI scripts have associated with this entity, 479 500 * for arbitrary local annotations. 480 * (This data is notshared with any other AI scripts.)501 * (This data should not be shared with any other AI scripts.) 481 502 */ 482 503 getMetadata: function(player, key) { 483 504 return this._ai.getMetadata(player, this, key); … … 493 514 deleteAllMetadata: function(player) { 494 515 delete this._ai._entityMetadata[player][this.id()]; 495 516 }, 496 517 497 518 deleteMetadata: function(player, key) { 498 519 this._ai.deleteMetadata(player, this, key); 499 520 }, … … 508 529 509 530 unitAIState: function() { return this._entity.unitAIState; }, 510 531 unitAIOrderData: function() { return this._entity.unitAIOrderData; }, 511 hitpoints: function() { if (this._entity.hitpoints !== undefined) return this._entity.hitpoints; return undefined; }, 532 533 hitpoints: function() {if (this._entity.hitpoints !== undefined) return this._entity.hitpoints; return undefined; }, 512 534 isHurt: function() { return this.hitpoints() < this.maxHitpoints(); }, 513 535 healthLevel: function() { return (this.hitpoints() / this.maxHitpoints()); }, 514 536 needsHeal: function() { return this.isHurt() && this.isHealable(); }, … … 540 562 owner: function() { 541 563 return this._entity.owner; 542 564 }, 565 543 566 isOwn: function(player) { 544 567 if (typeof(this._entity.owner) === "undefined") 545 568 return false; 546 569 return this._entity.owner === player; 547 570 }, 571 548 572 isFriendly: function(player) { 549 573 return this.isOwn(player); // TODO: diplomacy 550 574 }, 575 551 576 isEnemy: function(player) { 552 577 return !this.isOwn(player); // TODO: diplomacy 553 578 }, … … 557 582 return undefined; 558 583 return this._entity.resourceSupplyAmount; 559 584 }, 560 585 561 586 resourceSupplyGatherers: function(player) 562 587 { 563 588 if (this._entity.resourceSupplyGatherers !== undefined) 564 return this._entity.resourceSupplyGatherers[player -1];589 return this._entity.resourceSupplyGatherers[player]; 565 590 return []; 566 591 }, 567 592 568 593 isFull: function(player) 569 594 { 570 595 if (this._entity.resourceSupplyGatherers !== undefined) 571 return (this.maxGatherers() === this._entity.resourceSupplyGatherers[player -1].length);596 return (this.maxGatherers() === this._entity.resourceSupplyGatherers[player].length); 572 597 573 598 return undefined; 574 599 }, … … 578 603 return undefined; 579 604 return this._entity.resourceCarrying; 580 605 }, 581 606 582 607 currentGatherRate: function() { 583 608 // returns the gather rate for the current target if applicable. 584 if (!this. _template.ResourceGatherer)609 if (!this.get("ResourceGatherer")); 585 610 return undefined; 586 611 587 612 if (this.unitAIOrderData().length && … … 599 624 600 625 var type = ress.resourceSupplyType(); 601 626 var tstring = type.generic + "." + type.specific; 602 627 603 628 if (type.generic == "treasure") 604 629 return 1000; 605 630 606 var speed = GetTechModifiedProperty(this._techModifications, this._template, "ResourceGatherer/BaseSpeed", +this._template.ResourceGatherer.BaseSpeed);607 speed *= GetTechModifiedProperty(this._techModifications, this._template, "ResourceGatherer/Rates/"+tstring, +this._template.ResourceGatherer.Rates[tstring]);608 631 var speed = +this.get("ResourceGatherer/BaseSpeed"); 632 speed *= +this.get("ResourceGatherer/Rates/" +tstring); 633 609 634 if (speed) 610 635 return speed; 611 636 return 0; … … 644 669 }, 645 670 646 671 unload: function(id) { 647 if (!this. _template.GarrisonHolder)672 if (!this.get("GarrisonHolder")) 648 673 return undefined; 649 674 Engine.PostCommand(PlayerID,{"type": "unload", "garrisonHolder": this.id(), "entities": [id]}); 650 675 return this; … … 652 677 653 678 // Unloads all owned units, don't unload allies 654 679 unloadAll: function() { 655 if (!this. _template.GarrisonHolder)680 if (!this.get("GarrisonHolder")) 656 681 return undefined; 657 682 Engine.PostCommand(PlayerID,{"type": "unload-all-own", "garrisonHolders": [this.id()]}); 658 683 return this; … … 751 776 }); 752 777 return this; 753 778 }, 754 779 755 780 research: function(template) { 756 781 Engine.PostCommand(PlayerID,{ "type": "research", "entity": this.id(), "template": template }); 757 782 return this; -
binaries/data/mods/public/simulation/ai/common-api/gamestate.js
126 126 if (!this.templates[type]) 127 127 return null; 128 128 129 return new m. EntityTemplate(this.templates[type], this.techModifications);129 return new m.Template(this.templates[type], this.techModifications); 130 130 }; 131 131 132 132 m.GameState.prototype.applyCiv = function(str) { -
binaries/data/mods/public/simulation/ai/common-api/shared.js
58 58 // Components that will be disabled in foundation entity templates. 59 59 // (This is a bit yucky and fragile since it's the inverse of 60 60 // CCmpTemplateManager::CopyFoundationSubset and only includes components 61 // that our EntityTemplate class currently uses.)61 // that our Template class currently uses.) 62 62 m.g_FoundationForbiddenComponents = { 63 63 "ProductionQueue": 1, 64 64 "ResourceSupply": 1, … … 119 119 // We need to now the initial state of the game for this, as we will use it. 120 120 // This is called right at the end of the map generation. 121 121 m.SharedScript.prototype.init = function(state) { 122 this.ApplyTemplatesDelta(state); 123 122 124 this.passabilityClasses = state.passabilityClasses; 123 125 this.passabilityMap = state.passabilityMap; 124 126 this.players = this._players; … … 127 129 this.timeElapsed = state.timeElapsed; 128 130 this.barterPrices = state.barterPrices; 129 131 130 for (var o in state.players)131 this._techModifications[o] = state.players[o].techModifications;132 133 132 this._entities = {}; 134 133 for (var id in state.entities) 135 134 this._entities[id] = new m.Entity(this, state.entities[id]); … … 166 165 return; 167 166 // deals with updating based on create and destroy messages. 168 167 this.ApplyEntitiesDelta(state); 168 this.ApplyTemplatesDelta(state); 169 169 170 170 Engine.ProfileStart("onUpdate"); 171 171 … … 178 178 this.timeElapsed = state.timeElapsed; 179 179 this.barterPrices = state.barterPrices; 180 180 181 for (var o in state.players)182 this._techModifications[o] = state.players[o].techModifications;183 184 181 for (var i in this.gameState) 185 182 this.gameState[i].update(this,state); 186 183 … … 313 310 this.updateEntityCollections(prop, this._entities[id]); 314 311 } 315 312 } 313 314 // apply per-entity aura-related changes. 315 // this supersedes tech-related changes. 316 for (var id in state.changedEntityTemplateInfo) 317 { 318 var changes = state.changedEntityTemplateInfo[id]; 319 for each (var change in changes) 320 this._entities[id]._auraTemplateModif[change.variable] = change.value; 321 } 316 322 Engine.ProfileStop(); 317 323 }; 318 324 325 m.SharedScript.prototype.ApplyTemplatesDelta = function(state) 326 { 327 Engine.ProfileStart("Shared ApplyTemplatesDelta"); 328 329 for (var player in state.changedTemplateInfo) 330 { 331 var playerDiff = state.changedTemplateInfo[player]; 332 for (var template in playerDiff) 333 { 334 var changes = playerDiff[template]; 335 if (!this._techModifications[player][template]) 336 this._techModifications[player][template] = {}; 337 for each (var change in changes) 338 this._techModifications[player][template][change.variable] = change.value; 339 } 340 } 341 Engine.ProfileStop(); 342 }; 343 319 344 m.SharedScript.prototype.registerUpdatingEntityCollection = function(entCollection, noPush) 320 345 { 321 346 if (!noPush) { -
binaries/data/mods/public/simulation/components/AIInterface.js
18 18 this.events["OwnershipChanged"] = []; 19 19 20 20 this.changedEntities = {}; 21 22 // cache for technology changes; 23 // this one is PlayerID->TemplateName->{StringForTheValue, ActualValue} 24 this.changedTemplateInfo = {}; 25 // this is for auras and is EntityID->{StringForTheValue, ActualValue} 26 this.changedEntityTemplateInfo = {}; 21 27 }; 22 28 23 AIInterface.prototype.Get Representation = function()29 AIInterface.prototype.GetNonEntityRepresentation = function() 24 30 { 25 31 var cmpGuiInterface = Engine.QueryInterface(SYSTEM_ENTITY, IID_GuiInterface); 26 32 27 33 // Return the same game state as the GUI uses 28 34 var state = cmpGuiInterface.GetExtendedSimulationState(-1); 29 35 30 36 // Add some extra AI-specific data 31 37 state.events = {}; 32 38 state.events["Create"] = this.events["Create"]; … … 39 45 state.events["PlayerDefeated"] = this.events["PlayerDefeated"]; 40 46 state.events["EntityRenamed"] = this.events["EntityRenamed"]; 41 47 state.events["OwnershipChanged"] = this.events["OwnershipChanged"]; 42 43 48 // Reset the event list for the next turn 44 49 this.events["Create"] = []; 45 50 this.events["Destroy"] = []; … … 51 56 this.events["PlayerDefeated"] = []; 52 57 this.events["EntityRenamed"] = []; 53 58 this.events["OwnershipChanged"] = []; 54 59 60 return state; 61 } 62 63 AIInterface.prototype.GetRepresentation = function() 64 { 65 var state = this.GetNonEntityRepresentation(); 66 55 67 // Add entity representations 56 68 Engine.ProfileStart("proxy representations"); 57 69 state.entities = {}; … … 64 76 this.changedEntities = {}; 65 77 Engine.ProfileStop(); 66 78 79 state.changedTemplateInfo = this.changedTemplateInfo; 80 this.changedTemplateInfo = {}; 81 state.changedEntityTemplateInfo = this.changedEntityTemplateInfo; 82 this.changedEntityTemplateInfo = {}; 83 67 84 return state; 68 85 }; 86 69 87 // Intended to be called first, during the map initialization: no caching 70 88 AIInterface.prototype.GetFullRepresentation = function(flushEvents) 71 { 72 var cmpGuiInterface = Engine.QueryInterface(SYSTEM_ENTITY, IID_GuiInterface); 73 74 // Return the same game state as the GUI uses 75 var state = cmpGuiInterface.GetExtendedSimulationState(-1); 76 77 // Add some extra AI-specific data 78 state.events = {}; 79 state.events["Create"] = this.events["Create"]; 80 state.events["Destroy"] = this.events["Destroy"]; 81 state.events["Attacked"] = this.events["Attacked"]; 82 state.events["RangeUpdate"] = this.events["RangeUpdate"]; 83 state.events["ConstructionFinished"] = this.events["ConstructionFinished"]; 84 state.events["TrainingFinished"] = this.events["TrainingFinished"]; 85 state.events["AIMetadata"] = this.events["AIMetadata"]; 86 state.events["PlayerDefeated"] = this.events["PlayerDefeated"]; 87 state.events["EntityRenamed"] = this.events["EntityRenamed"]; 88 state.events["OwnershipChanged"] = this.events["OwnershipChanged"]; 89 89 { 90 var state = this.GetNonEntityRepresentation(); 90 91 91 92 if (flushEvents) 92 93 { … … 102 103 state.events["OwnershipChanged"] = []; 103 104 } 104 105 105 // Reset the event list for the next turn106 this.events["Create"] = [];107 this.events["Destroy"] = [];108 this.events["Attacked"] = [];109 this.events["RangeUpdate"] = [];110 this.events["ConstructionFinished"] = [];111 this.events["TrainingFinished"] = [];112 this.events["AIMetadata"] = [];113 this.events["PlayerDefeated"] = [];114 this.events["EntityRenamed"] = [];115 this.events["OwnershipChanged"] = [];116 117 118 106 // Add entity representations 119 107 Engine.ProfileStart("proxy representations"); 120 108 state.entities = {}; … … 127 115 } 128 116 Engine.ProfileStop(); 129 117 118 state.changedTemplateInfo = this.changedTemplateInfo; 119 this.changedTemplateInfo = {}; 120 state.changedEntityTemplateInfo = this.changedEntityTemplateInfo; 121 this.changedEntityTemplateInfo = {}; 122 130 123 return state; 131 124 }; 132 125 … … 156 149 this.events["EntityRenamed"].push(msg); 157 150 }; 158 151 152 // When a new technology is researched, check which templates it affects, 153 // and send the updated values to the AI. 154 // this relies on the fact that any "value" in a technology can only ever change 155 // one template value, and that the naming is the same (with / in place of .) 156 // it's not incredibly fast but it's not incredibly slow. 157 AIInterface.prototype.OnTemplateModification = function(msg) 158 { 159 var cmpTemplateManager = Engine.QueryInterface(SYSTEM_ENTITY, IID_TemplateManager); 160 if (!this.templates) 161 this.templates = cmpTemplateManager.FindAllTemplates(false); 162 163 for each (var value in msg.valueNames) 164 { 165 for (var o = 0; o < this.templates.length; ++o) 166 { 167 var tmp = this.templates[o]; 168 var template = cmpTemplateManager.GetTemplateWithoutValidation(this.templates[o]); 169 // remove templates that we obviously don't care about. 170 if (!template || !template.Identity || ! template.Identity.Civ) 171 { 172 this.templates.splice(o--,1); 173 continue; 174 } 175 176 // let's get the base template value. 177 var strings = value.split("/"); 178 var item = template; 179 var ended = true; 180 for (var i = 0; i < strings.length; ++i) 181 { 182 if (item !== undefined && item[strings[i]] !== undefined) 183 item = item[strings[i]]; 184 else 185 ended = false; 186 } 187 if (!ended) 188 continue; 189 // item now contains the template value for this. 190 191 var newValue = ApplyValueModificationsToTemplate(value, +item, msg.player, template); 192 newValue = typeof(newValue) === "Number" ? Math.round(newValue) : newValue; 193 if(item != newValue) 194 { 195 if (!this.changedTemplateInfo[msg.player]) 196 this.changedTemplateInfo[msg.player] = {}; 197 if (!this.changedTemplateInfo[msg.player][this.templates[o]]) 198 this.changedTemplateInfo[msg.player][this.templates[o]] = [ { "variable" : value, "value" : newValue} ]; 199 else 200 this.changedTemplateInfo[msg.player][this.templates[o]].push({ "variable" : value, "value" : newValue }); 201 } 202 } 203 } 204 }; 205 206 AIInterface.prototype.OnValueModification = function(msg) 207 { 208 var ent = msg.entity; 209 var cmpTemplateManager = Engine.QueryInterface(SYSTEM_ENTITY, IID_TemplateManager); 210 var template = cmpTemplateManager.GetTemplateWithoutValidation(cmpTemplateManager.GetCurrentTemplateName(ent)); 211 for each (var value in msg.valueNames) 212 { 213 // let's get the base template value. 214 var strings = value.split("/"); 215 var item = template; 216 var ended = true; 217 for (var i = 0; i < strings.length; ++i) 218 { 219 if (item !== undefined && item[strings[i]] !== undefined) 220 item = item[strings[i]]; 221 else 222 ended = false; 223 } 224 if (!ended) 225 continue; 226 // "item" now contains the unmodified template value for this. 227 var newValue = ApplyValueModificationsToEntity(value, +item, ent); 228 newValue = typeof(newValue) === "Number" ? Math.round(newValue) : newValue; 229 if(item != newValue) 230 { 231 if (!this.changedEntityTemplateInfo[ent]) 232 this.changedEntityTemplateInfo[ent] = [{ "variable" : value, "value" : newValue }]; 233 else 234 this.changedEntityTemplateInfo[ent].push({ "variable" : value, "value" : newValue }); 235 } 236 } 237 }; 238 159 239 Engine.RegisterComponentType(IID_AIInterface, "AIInterface", AIInterface); -
binaries/data/mods/public/simulation/components/AIProxy.js
36 36 this.needsFullGet = true; 37 37 this.owner = -1; // for convenience now and then. 38 38 39 this.cmpAIInterface = Engine.QueryInterface(SYSTEM_ENTITY, IID_AIInterface); 40 39 41 // Let the AIInterface know that we exist and that it should query us 40 42 this.NotifyChange(); 41 43 }; 42 44 45 AIProxy.prototype.Serialize = null; // we have no dynamic state to save 46 43 47 AIProxy.prototype.GetRepresentation = function() 44 48 { 45 49 // Return the full representation the first time we're called … … 67 71 if (!this.changes) 68 72 { 69 73 this.changes = {}; 70 71 var cmpAIInterface = Engine.QueryInterface(SYSTEM_ENTITY, IID_AIInterface); 72 cmpAIInterface.ChangedEntity(this.entity); 74 this.cmpAIInterface.ChangedEntity(this.entity); 73 75 } 74 76 }; 75 77 … … 261 263 262 264 if (msg.from === -1) 263 265 { 264 var cmpAIInterface = Engine.QueryInterface(SYSTEM_ENTITY, IID_AIInterface); 265 cmpAIInterface.PushEvent("Create", {"entity" : msg.entity}); 266 this.cmpAIInterface.PushEvent("Create", {"entity" : msg.entity}); 266 267 return; 267 268 } else if (msg.to === -1) 268 269 { 269 var cmpAIInterface = Engine.QueryInterface(SYSTEM_ENTITY, IID_AIInterface); 270 cmpAIInterface.PushEvent("Destroy", {"entity" : msg.entity}); 270 this.cmpAIInterface.PushEvent("Destroy", {"entity" : msg.entity}); 271 271 return; 272 272 } 273 273 274 274 this.owner = msg.to; 275 275 this.changes.owner = msg.to; 276 276 277 var cmpAIInterface = Engine.QueryInterface(SYSTEM_ENTITY, IID_AIInterface); 278 cmpAIInterface.PushEvent("OwnershipChanged", msg); 277 this.cmpAIInterface.PushEvent("OwnershipChanged", msg); 279 278 }; 280 279 281 280 AIProxy.prototype.OnAttacked = function(msg) 282 281 { 283 var cmpAIInterface = Engine.QueryInterface(SYSTEM_ENTITY, IID_AIInterface); 284 cmpAIInterface.PushEvent("Attacked", msg); 282 this.cmpAIInterface.PushEvent("Attacked", msg); 285 283 }; 286 284 287 285 /* 288 286 Deactivated for actually not really being practical for most uses. 289 287 AIProxy.prototype.OnRangeUpdate = function(msg) 290 288 { 291 var cmpAIInterface = Engine.QueryInterface(SYSTEM_ENTITY, IID_AIInterface);292 289 msg.owner = this.owner; 293 290 this.cmpAIInterface.PushEvent("RangeUpdate", msg); 294 291 warn(uneval(msg)); 295 292 };*/ 296 293 297 294 AIProxy.prototype.OnConstructionFinished = function(msg) 298 295 { 299 var cmpAIInterface = Engine.QueryInterface(SYSTEM_ENTITY, IID_AIInterface); 300 cmpAIInterface.PushEvent("ConstructionFinished", msg); 296 this.cmpAIInterface.PushEvent("ConstructionFinished", msg); 301 297 }; 302 298 303 299 AIProxy.prototype.OnTrainingFinished = function(msg) 304 300 { 305 var cmpAIInterface = Engine.QueryInterface(SYSTEM_ENTITY, IID_AIInterface); 306 cmpAIInterface.PushEvent("TrainingFinished", msg); 301 this.cmpAIInterface.PushEvent("TrainingFinished", msg); 307 302 }; 308 303 309 304 AIProxy.prototype.OnAIMetadata = function(msg) 310 305 { 311 var cmpAIInterface = Engine.QueryInterface(SYSTEM_ENTITY, IID_AIInterface); 312 cmpAIInterface.PushEvent("AIMetadata", msg); 306 this.cmpAIInterface.PushEvent("AIMetadata", msg); 313 307 }; 314 308 315 309 Engine.RegisterComponentType(IID_AIProxy, "AIProxy", AIProxy); -
binaries/data/mods/public/simulation/components/AuraManager.js
46 46 this.modificationsCache[value][ent].add += data.add; 47 47 48 48 // post message to the entity to notify it about the change 49 Engine.PostMessage(ent, MT_ValueModification, { " component": value.split("/")[0] });49 Engine.PostMessage(ent, MT_ValueModification, { "entity":ent, "component": value.split("/")[0], "valueNames": [value] }); 50 50 }; 51 51 52 52 AuraManager.prototype.ApplyTemplateBonus = function(value, player, classes, data, key) … … 73 73 if (data.add) 74 74 this.templateModificationsCache[value][player][c][key].add += data.add; 75 75 76 warn ("pushing template"); 77 Engine.PostMessage(ent, MT_TemplateModification, { "player":player, "component": value.split("/")[0], "valueNames": [value] }); 76 78 } 77 79 }; 78 80 … … 98 100 this.modificationsCache[value][ent].multiply /= data.multiply; 99 101 100 102 // post message to the entity to notify it about the change 101 Engine.PostMessage(ent, MT_ValueModification, { "component": value.split("/")[0] }); 103 var effects = {}; 104 effects[value] = this.modificationsCache[value][ent]; 105 Engine.PostMessage(ent, MT_ValueModification, { "entity":ent, "component": value.split("/")[0], "valueNames": [value] }); 102 106 }; 103 107 104 108 AuraManager.prototype.RemoveTemplateBonus = function(value, player, classes, key) … … 119 123 this.templateModificationsCache[value][player][c][key].multiply = 1; 120 124 this.templateModificationsCache[value][player][c][key].add = 0; 121 125 } 126 warn ("pushing template"); 127 Engine.PostMessage(ent, MT_TemplateModification, { "player":player, "component": value.split("/")[0], "valueNames": [value] }); 122 128 }; 123 129 124 130 AuraManager.prototype.ApplyModifications = function(valueName, value, ent) -
binaries/data/mods/public/simulation/components/Auras.js
365 365 this.Clean(); 366 366 }; 367 367 368 Auras.prototype.OnTemplateModification = function(msg) 369 { 370 this.OnValueModification(msg); 371 }; 372 368 373 Engine.RegisterComponentType(IID_Auras, "Auras", Auras); -
binaries/data/mods/public/simulation/components/Cost.js
100 100 cmpPlayer.AddPopulationBonuses(popDifference); 101 101 }; 102 102 103 Cost.prototype.OnTemplateModification = function(msg) 104 { 105 this.OnValueModification(msg); 106 }; 107 103 108 Engine.RegisterComponentType(IID_Cost, "Cost", Cost); -
binaries/data/mods/public/simulation/components/GuiInterface.js
97 97 "entityLimits": cmpPlayerEntityLimits.GetLimits(), 98 98 "entityCounts": cmpPlayerEntityLimits.GetCounts(), 99 99 "entityLimitChangers": cmpPlayerEntityLimits.GetLimitChangers(), 100 "techModifications": cmpTechnologyManager.GetTechModifications(),101 100 "researchQueued": cmpTechnologyManager.GetQueuedResearch(), 102 101 "researchStarted": cmpTechnologyManager.GetStartedResearch(), 103 102 "researchedTechs": cmpTechnologyManager.GetResearchedTechs(), … … 475 474 { 476 475 ret.armour = { 477 476 "hack": ApplyValueModificationsToTemplate("Armour/Hack", +template.Armour.Hack, player, template), 478 "pierce": ApplyValueModificationsToTemplate("Armour/Pierce", +template.Armour. Hack, player, template),479 "crush": ApplyValueModificationsToTemplate("Armour/Crush", +template.Armour. Hack, player, template),477 "pierce": ApplyValueModificationsToTemplate("Armour/Pierce", +template.Armour.Pierce, player, template), 478 "crush": ApplyValueModificationsToTemplate("Armour/Crush", +template.Armour.Crush, player, template), 480 479 }; 481 480 } 482 481 -
binaries/data/mods/public/simulation/components/Health.js
348 348 this.CheckRegenTimer(); 349 349 }; 350 350 351 Health.prototype.OnTemplateModification = function(msg) 352 { 353 this.OnValueModification(msg); 354 }; 355 351 356 Health.prototype.OnHealthChanged = function() 352 357 { 353 358 this.CheckRegenTimer(); -
binaries/data/mods/public/simulation/components/ProductionQueue.js
774 774 this.CalculateEntitiesList(); 775 775 }; 776 776 777 ProductionQueue.prototype.OnTemplateModification = function(msg) 778 { 779 this.OnValueModification(msg); 780 }; 781 782 777 783 Engine.RegisterComponentType(IID_ProductionQueue, "ProductionQueue", ProductionQueue); -
binaries/data/mods/public/simulation/components/Promotion.js
139 139 this.IncreaseXp(0); 140 140 }; 141 141 142 Promotion.prototype.OnTemplateModification = function(msg) 143 { 144 this.OnValueModification(msg); 145 }; 146 142 147 Engine.RegisterComponentType(IID_Promotion, "Promotion", Promotion); 148 No newline at end of file -
binaries/data/mods/public/simulation/components/TechnologyManager.js
226 226 var modifications = this.modifications[name]; 227 227 var component = name.split("/")[0]; 228 228 for (var i in modifications) 229 if (!modifiedComponents[component] && DoesModificationApply(modifications[i], classes)) 230 modifiedComponents[component] = true; 229 if (DoesModificationApply(modifications[i], classes)) 230 { 231 if (!modifiedComponents[component]) 232 modifiedComponents[component] = []; 233 modifiedComponents[component].push(name); 234 } 231 235 } 232 236 233 237 // Send mesage(s) to the entity so it knows about researched techs 234 238 for (var component in modifiedComponents) 235 Engine.PostMessage(msg.entity, MT_ ValueModification, { "component": component});239 Engine.PostMessage(msg.entity, MT_TemplateModification, { "player": playerID, "component": component, "valueNames": modifiedComponents[component] }); 236 240 } 237 241 } 238 242 if (msg.from == playerID) … … 322 326 mod[j] = modification[j]; 323 327 324 328 this.modifications[modification.value].push(mod); 325 modifiedComponents[modification.value.split("/")[0]] = true; 329 var component = modification.value.split("/")[0]; 330 if (!modifiedComponents[component]) 331 modifiedComponents[component] = []; 332 modifiedComponents[component].push(modification.value); 326 333 this.modificationCache[modification.value] = {}; 327 334 } 328 335 } 329 336 330 337 this.UpdateAutoResearch(); 331 338 339 340 var player = +(+this.entity - 2); 341 // it appears that this.entity - 2 = playerID 342 // now this is just ugly but because of below's TODO it works. 332 343 // TODO: Handle technology broadcasting for autoresearch properly (some components might not be initialized currently) 333 344 for (var component in modifiedComponents) 334 Engine.BroadcastMessage(MT_ ValueModification, { "component": component});345 Engine.BroadcastMessage(MT_TemplateModification, { "player": player, "component": component, "valueNames": modifiedComponents[component]}); 335 346 }; 336 347 337 348 // Clears the cached data for an entity from the modifications cache -
binaries/data/mods/public/simulation/components/interfaces/AuraManager.js
1 1 Engine.RegisterInterface("AuraManager"); 2 3 // Message of the form { "value" : whatever }. 4 // intended for AIProxy so it won't clutter everything. 5 Engine.RegisterMessageType("AI_AuraChange"); -
binaries/data/mods/public/simulation/helpers/Commands.js
1 1 // Setting this to true will display some warnings when commands 2 2 // are likely to fail, which may be useful for debugging AIs 3 var g_DebugCommands = false;3 var g_DebugCommands = true; 4 4 5 5 function ProcessCommand(player, cmd) 6 6 { -
source/simulation2/MessageTypes.h
366 366 }; 367 367 368 368 /** 369 * Sent by value modification manager when a value of a certaincomponent is changed369 * Sent by aura manager when a value of a certain entity's component is changed 370 370 */ 371 371 class CMessageValueModification : public CMessage 372 372 { 373 373 public: 374 374 DEFAULT_MESSAGE_IMPL(ValueModification) 375 375 376 CMessageValueModification(std::wstring component) : 377 component(component) 376 CMessageValueModification(entity_id_t entity, std::wstring component, const std::vector<std::wstring>& valueNames) : 377 entity(entity), 378 component(component), 379 valueNames(valueNames) 378 380 { 379 381 } 380 382 383 entity_id_t entity; 384 std::wstring component; 385 std::vector<std::wstring> valueNames; 386 }; 387 388 /** 389 * Sent by aura and tech managers when a value of a certain template's component is changed 390 */ 391 class CMessageTemplateModification : public CMessage 392 { 393 public: 394 DEFAULT_MESSAGE_IMPL(TemplateModification) 395 396 CMessageTemplateModification(player_id_t player, std::wstring component, const std::vector<std::wstring>& valueNames) : 397 player(player), 398 component(component), 399 valueNames(valueNames) 400 { 401 } 402 403 player_id_t player; 381 404 std::wstring component; 405 std::vector<std::wstring> valueNames; 382 406 }; 383 407 384 408 /** -
source/simulation2/TypeList.h
48 48 MESSAGE(TerritoriesChanged) 49 49 MESSAGE(PathResult) 50 50 MESSAGE(ValueModification) 51 MESSAGE(TemplateModification) 51 52 MESSAGE(VisionRangeChanged) 52 53 MESSAGE(MinimapPing) 53 54 -
source/simulation2/components/CCmpTerritoryManager.cpp
67 67 componentManager.SubscribeGloballyToMessageType(MT_OwnershipChanged); 68 68 componentManager.SubscribeGloballyToMessageType(MT_PositionChanged); 69 69 componentManager.SubscribeGloballyToMessageType(MT_ValueModification); 70 componentManager.SubscribeGloballyToMessageType(MT_TemplateModification); 70 71 componentManager.SubscribeToMessageType(MT_TerrainChanged); 71 72 componentManager.SubscribeToMessageType(MT_Update); 72 73 componentManager.SubscribeToMessageType(MT_Interpolate); … … 165 166 MakeDirtyIfRelevantEntity(msgData.entity); 166 167 break; 167 168 } 168 case MT_ValueModification: 169 // those two should be safe to group as the message should cast similarly 170 case MT_ValueModification: case MT_TemplateModification: 169 171 { 170 172 const CMessageValueModification& msgData = static_cast<const CMessageValueModification&> (msg); 171 173 if (msgData.component == L"TerritoryInfluence") -
source/simulation2/components/CCmpUnitMotion.cpp
119 119 componentManager.SubscribeToMessageType(MT_RenderSubmit); // for debug overlays 120 120 componentManager.SubscribeToMessageType(MT_PathResult); 121 121 componentManager.SubscribeToMessageType(MT_ValueModification); 122 componentManager.SubscribeToMessageType(MT_TemplateModification); 122 123 } 123 124 124 125 DEFAULT_COMPONENT_ALLOCATOR(UnitMotion) … … 405 406 PathResult(msgData.ticket, msgData.path); 406 407 break; 407 408 } 408 case MT_ValueModification: 409 // those two should be safe to group as the message should cast similarly 410 case MT_ValueModification: case MT_TemplateModification: 409 411 { 410 412 const CMessageValueModification& msgData = static_cast<const CMessageValueModification&> (msg); 411 413 if (msgData.component != L"UnitMotion") -
source/simulation2/components/ICmpTemplateManager.cpp
23 23 24 24 BEGIN_INTERFACE_WRAPPER(TemplateManager) 25 25 DEFINE_INTERFACE_METHOD_1("GetTemplate", const CParamNode*, ICmpTemplateManager, GetTemplate, std::string) 26 DEFINE_INTERFACE_METHOD_1("GetTemplateWithoutValidation", const CParamNode*, ICmpTemplateManager, GetTemplateWithoutValidation, std::string) 26 27 DEFINE_INTERFACE_METHOD_1("GetCurrentTemplateName", std::string, ICmpTemplateManager, GetCurrentTemplateName, entity_id_t) 27 28 DEFINE_INTERFACE_METHOD_1("FindAllTemplates", std::vector<std::string>, ICmpTemplateManager, FindAllTemplates, bool) 28 29 DEFINE_INTERFACE_METHOD_1("GetEntitiesUsingTemplate", std::vector<entity_id_t>, ICmpTemplateManager, GetEntitiesUsingTemplate, std::string) -
source/simulation2/scripting/MessageTypeConversions.cpp
303 303 jsval CMessageValueModification::ToJSVal(ScriptInterface& scriptInterface) const 304 304 { 305 305 TOJSVAL_SETUP(); 306 SET_MSG_PROPERTY(entity); 306 307 SET_MSG_PROPERTY(component); 308 SET_MSG_PROPERTY(valueNames); 307 309 return OBJECT_TO_JSVAL(obj); 308 310 } 309 311 310 312 CMessage* CMessageValueModification::FromJSVal(ScriptInterface& scriptInterface, jsval val) 311 313 { 312 314 FROMJSVAL_SETUP(); 315 GET_MSG_PROPERTY(entity_id_t, entity); 313 316 GET_MSG_PROPERTY(std::wstring, component); 314 return new CMessageValueModification(component); 317 GET_MSG_PROPERTY(std::vector<std::wstring>, valueNames); 318 return new CMessageValueModification(entity, component, valueNames); 315 319 } 316 320 317 321 //////////////////////////////// 318 322 323 jsval CMessageTemplateModification::ToJSVal(ScriptInterface& scriptInterface) const 324 { 325 TOJSVAL_SETUP(); 326 SET_MSG_PROPERTY(player); 327 SET_MSG_PROPERTY(component); 328 SET_MSG_PROPERTY(valueNames); 329 return OBJECT_TO_JSVAL(obj); 330 } 331 332 CMessage* CMessageTemplateModification::FromJSVal(ScriptInterface& scriptInterface, jsval val) 333 { 334 FROMJSVAL_SETUP(); 335 GET_MSG_PROPERTY(player_id_t, player); 336 GET_MSG_PROPERTY(std::wstring, component); 337 GET_MSG_PROPERTY(std::vector<std::wstring>, valueNames); 338 return new CMessageTemplateModification(player, component, valueNames); 339 } 340 341 //////////////////////////////// 342 319 343 jsval CMessageVisionRangeChanged::ToJSVal(ScriptInterface& scriptInterface) const 320 344 { 321 345 TOJSVAL_SETUP();