Ticket #2377: AIAuraTech.patch
File AIAuraTech.patch, 51.8 KB (added by , 10 years ago) |
---|
-
Users/Lancelot/Desktop/0ad-svn/trunk/binaries/data/mods/public/simulation/ai/aegis/base-manager.js
86 86 this.anchor.setMetadata(PlayerID, "base", this.ID); 87 87 this.anchor.setMetadata(PlayerID, "baseAnchor", true); 88 88 this.buildings.updateEnt(this.anchor); 89 90 89 if (this.territoryBuildings.indexOf(this.anchor.id()) === -1) 91 90 this.territoryBuildings.push(this.anchor.id()); 92 91 return true; … … 908 907 } 909 908 } 910 909 911 // auras/techs are buggy and the AI tries to repair healthy buildings.912 // TODO: reimplement once that's fixed.913 return;914 915 910 // don't repair if we're still under attack, unless it's like a vital (civcentre or wall) building that's getting destroyed. 916 911 for (var i in damagedBuildings) { 917 912 var target = damagedBuildings[i]; … … 947 942 }; 948 943 949 944 m.BaseManager.prototype.update = function(gameState, queues, events) { 945 946 warn (this.anchor.hitpoints()); 947 948 950 949 Engine.ProfileStart("Base update - base " + this.ID); 951 950 var self = this; 952 951 -
Users/Lancelot/Desktop/0ad-svn/trunk/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; 13 11 }, 14 12 13 // helper function to return a template value, optionally adjusting for tech. 14 // TODO: there's no support for "_string" values here. 15 get: function(string) 16 { 17 var value = this._template; 18 if (this._auraTemplateModif && this._auraTemplateModif[string]) { 19 return this._auraTemplateModif[string]; 20 } else if (this._techModif && this._techModif[string]) { 21 return this._techModif[string]; 22 } else { 23 var args = string.split("/"); 24 for (var i = 0; i < args.length; ++i) 25 if (value[args[i]]) 26 value = value[args[i]]; 27 else 28 return undefined; 29 return value; 30 } 31 }, 32 15 33 genericName: function() { 16 if (!this. _template.Identity || !this._template.Identity.GenericName)34 if (!this.get("Identity") || !this.get("Identity/GenericName")) 17 35 return undefined; 18 return this. _template.Identity.GenericName;36 return this.get("Identity/GenericName"); 19 37 }, 20 38 21 39 rank: function() { 22 if (!this. _template.Identity)40 if (!this.get("Identity")) 23 41 return undefined; 24 return this. _template.Identity.Rank;42 return this.get("Identity/Rank"); 25 43 }, 26 44 27 45 classes: function() { 28 if (!this. _template.Identity || !this._template.Identity.Classes || !this._template.Identity.Classes._string)46 if (!this.get("Identity") || !this.get("Identity/Classes") || !this.get("Identity/Classes/_string")) 29 47 return undefined; 30 return this. _template.Identity.Classes._string.split(/\s+/);48 return this.get("Identity/Classes/_string").split(/\s+/); 31 49 }, 32 50 33 51 requiredTech: function() { 34 if (!this._template.Identity || !this._template.Identity.RequiredTechnology) 35 return undefined; 36 return this._template.Identity.RequiredTechnology; 52 return this.get("Identity/RequiredTechnology"); 37 53 }, 38 54 39 55 available: function(gameState) { 40 if (!this._template.Identity || !this._template.Identity.RequiredTechnology) 41 return true; 42 return gameState.isResearched(this._template.Identity.RequiredTechnology); 56 return gameState.isResearched(this.get("Identity/RequiredTechnology")); 43 57 }, 44 58 45 59 // specifically 46 60 phase: function() { 47 if (!this. _template.Identity || !this._template.Identity.RequiredTechnology)61 if (!this.get("Identity/RequiredTechnology")) 48 62 return 0; 49 if (this. template.Identity.RequiredTechnology== "phase_village")63 if (this.get("Identity/RequiredTechnology") == "phase_village") 50 64 return 1; 51 if (this. template.Identity.RequiredTechnology== "phase_town")65 if (this.get("Identity/RequiredTechnology") == "phase_town") 52 66 return 2; 53 if (this. template.Identity.RequiredTechnology== "phase_city")67 if (this.get("Identity/RequiredTechnology") == "phase_city") 54 68 return 3; 55 69 return 0; 56 70 }, … … 72 86 }, 73 87 74 88 civ: function() { 75 if (!this._template.Identity) 76 return undefined; 77 return this._template.Identity.Civ; 89 return this.get("Identity/Civ"); 78 90 }, 79 91 80 92 cost: function() { 81 if (!this. _template.Cost)93 if (!this.get("Cost")) 82 94 return undefined; 83 95 84 96 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]);97 for (var type in this.get("Cost/Resources")) 98 ret[type] = +this.get("Cost/Resources/" + type); 87 99 return ret; 88 100 }, 89 101 90 102 costSum: function() { 91 if (!this. _template.Cost)103 if (!this.get("Cost")) 92 104 return undefined; 93 105 94 106 var ret = 0; 95 for (var type in this. _template.Cost.Resources)96 ret += +this. _template.Cost.Resources[type];107 for (var type in this.get("Cost/Resources")) 108 ret += +this.get("Cost/Resources/" + type); 97 109 return ret; 98 110 }, 99 111 … … 102 114 * obstruction shape, or undefined if no obstruction. 103 115 */ 104 116 obstructionRadius: function() { 105 if (!this. _template.Obstruction)117 if (!this.get("Obstruction")) 106 118 return undefined; 107 119 108 if (this. _template.Obstruction.Static)120 if (this.get("Obstruction/Static")) 109 121 { 110 var w = +this. _template.Obstruction.Static["@width"];111 var h = +this. _template.Obstruction.Static["@depth"];122 var w = +this.get("Obstruction/Static/@width"); 123 var h = +this.get("Obstruction/Static/@depth"); 112 124 return Math.sqrt(w*w + h*h) / 2; 113 125 } 114 126 115 if (this. _template.Obstruction.Unit)116 return +this. _template.Obstruction.Unit["@radius"];127 if (this.get("Obstruction/Unit")) 128 return +this.get("Obstruction/Unit/@radius"); 117 129 118 130 return 0; // this should never happen 119 131 }, 120 132 121 133 /** 122 134 * Returns the radius of a circle surrounding this entity's 123 135 * footprint. 124 136 */ 125 137 footprintRadius: function() { 126 if (!this. _template.Footprint)138 if (!this.get("Footprint")) 127 139 return undefined; 128 140 129 if (this. _template.Footprint.Square)141 if (this.get("Footprint/Square")) 130 142 { 131 var w = +this. _template.Footprint.Square["@width"];132 var h = +this. _template.Footprint.Square["@depth"];143 var w = +this.get("Footprint/Square/@width"); 144 var h = +this.get("Footprint/Square/@depth"); 133 145 return Math.sqrt(w*w + h*h) / 2; 134 146 } 135 147 136 if (this. _template.Footprint.Circle)137 return +this. _template.Footprint.Circle["@radius"];148 if (this.get("Footprint/Circle")) 149 return +this.get("Footprint/Circle/@radius"); 138 150 139 151 return 0; // this should never happen 140 152 }, 141 153 142 154 maxHitpoints: function() 143 155 { 144 if (this. _template.Health!== undefined)145 return GetTechModifiedProperty(this._techModifications, this._template, "Health/Max",+this._template.Health.Max);156 if (this.get("Health") !== undefined) 157 return +this.get("Health/Max"); 146 158 return 0; 147 159 }, 160 148 161 isHealable: function() 149 162 { 150 if (this. _template.Health!== undefined)151 return this. _template.Health.Unhealable!== "true";163 if (this.get("Health") !== undefined) 164 return this.get("Health/Unhealable") !== "true"; 152 165 return false; 153 166 }, 167 154 168 isRepairable: function() 155 169 { 156 if (this. _template.Health!== undefined)157 return this. _template.Health.Repairable=== "true";170 if (this.get("Health") !== undefined) 171 return this.get("Health/Repairable") === "true"; 158 172 return false; 159 173 }, 160 174 161 175 getPopulationBonus: function() { 162 if (!this._template.Cost || !this._template.Cost.PopulationBonus) 163 return undefined; 164 return this._template.Cost.PopulationBonus; 176 return this.get("Cost/PopulationBonus"); 165 177 }, 166 178 167 179 armourStrengths: function() { 168 if (!this. _template.Armour)180 if (!this.get("Armour")) 169 181 return undefined; 170 182 171 183 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)184 hack: +this.get("Armour/Hack"), 185 pierce: +this.get("Armour/Pierce"), 186 crush: +this.get("Armour/Crush") 175 187 }; 176 188 }, 177 189 178 190 attackTypes: function() { 179 if (!this. _template.Attack)191 if (!this.get("Attack")) 180 192 return undefined; 181 193 182 194 var ret = []; 183 for (var type in this. _template.Attack)195 for (var type in this.get("Attack")) 184 196 ret.push(type); 185 197 186 198 return ret; 187 199 }, 188 200 189 201 attackRange: function(type) { 190 if (!this. _template.Attack || !this._template.Attack[type])202 if (!this.get("Attack/" + type +"")) 191 203 return undefined; 192 204 193 205 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))206 max: +this.get("Attack/" + type +"/MaxRange"), 207 min: +(this.get("Attack/" + type +"/MinRange") || 0) 196 208 }; 197 209 }, 198 210 199 211 attackStrengths: function(type) { 200 if (!this. _template.Attack || !this._template.Attack[type])212 if (!this.get("Attack/" + type +"")) 201 213 return undefined; 202 214 203 215 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))216 hack: +(this.get("Attack/" + type + "/Hack") || 0), 217 pierce: +(this.get("Attack/" + type + "/Pierce") || 0), 218 crush: +(this.get("Attack/" + type + "/Crush") || 0) 207 219 }; 208 220 }, 209 221 210 222 attackTimes: function(type) { 211 if (!this. _template.Attack || !this._template.Attack[type])223 if (!this.get("Attack/" + type +"")) 212 224 return undefined; 213 225 214 226 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))227 prepare: +(this.get("Attack/" + type + "/PrepareTime") || 0), 228 repeat: +(this.get("Attack/" + type + "/RepeatTime") || 1000) 217 229 }; 218 230 }, 219 231 220 232 // returns the classes this templates counters: 221 // Return type is [ [-neededClasses- ] , multiplier].233 // Return type is [ [-neededClasses- , multiplier], … ]. 222 234 getCounteredClasses: function() { 223 if (!this. _template.Attack)235 if (!this.get("Attack")) 224 236 return undefined; 225 237 226 238 var Classes = []; 227 for (var i in this. _template.Attack) {228 if (!this. _template.Attack[i].Bonuses)239 for (var i in this.get("Attack")) { 240 if (!this.get("Attack/" + i + "/Bonuses")) 229 241 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]);242 for (var o in this.get("Attack/" + i + "/Bonuses")) 243 if (this.get("Attack/" + i + "/Bonuses/" + o + "/Classes")) 244 Classes.push([this.get("Attack/" + i +"/Bonuses/" + o +"/Classes").split(" "), +this.get("Attack/" + i +"/Bonuses" +o +"/Multiplier")]); 233 245 } 234 246 return Classes; 235 247 }, … … 237 249 // returns true if the entity counters those classes. 238 250 // TODO: refine using the multiplier 239 251 countersClasses: function(classes) { 240 if (!this. _template.Attack)252 if (!this.get("Attack")) 241 253 return false; 242 254 var mcounter = []; 243 for (var i in this. _template.Attack) {244 if (!this. _template.Attack[i].Bonuses)255 for (var i in this.get("Attack")) { 256 if (!this.get("Attack/" + i + "/Bonuses")) 245 257 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(" "));258 for (var o in this.get("Attack/" + i + "/Bonuses")) 259 if (this.get("Attack/" + i + "/Bonuses/" + o + "/Classes")) 260 mcounter.concat(this.get("Attack/" + i + "/Bonuses/" + o + "/Classes").split(" ")); 249 261 } 250 262 for (var i in classes) 251 263 { … … 257 269 258 270 // returns, if it exists, the multiplier from each attack against a given class 259 271 getMultiplierAgainst: function(type, againstClass) { 260 if (!this. _template.Attack || !this._template.Attack[type])272 if (!this.get("Attack/" + type +"")) 261 273 return undefined; 262 274 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)275 if (this.get("Attack/" + type + "/Bonuses")) 276 for (var o in this.get("Attack/" + type + "/Bonuses")) { 277 if (!this.get("Attack/" + type + "/Bonuses/" + o + "/Classes")) 266 278 continue; 267 var total = this. _template.Attack[type].Bonuses[o].Classes.split(" ");279 var total = this.get("Attack/" + type + "/Bonuses/" + o + "/Classes").split(" "); 268 280 for (var j in total) 269 281 if (total[j] === againstClass) 270 return this. _template.Attack[type].Bonuses[o].Multiplier;282 return this.get("Attack/" + type + "/Bonuses/" + o + "/Multiplier"); 271 283 } 272 284 return 1; 273 285 }, 274 286 275 287 // returns true if the entity can attack the given class 276 288 canAttackClass: function(saidClass) { 277 if (!this. _template.Attack)289 if (!this.get("Attack")) 278 290 return false; 279 291 280 for (var i in this. _template.Attack) {281 if (!this. _template.Attack[i].RestrictedClasses || !this._template.Attack[i].RestrictedClasses._string)292 for (var i in this.get("Attack")) { 293 if (!this.get("Attack/" + i + "/RestrictedClasses") || !this.get("Attack/" + i + "/RestrictedClasses/_string")) 282 294 continue; 283 var cannotAttack = this. _template.Attack[i].RestrictedClasses._string.split(" ");295 var cannotAttack = this.get("Attack/" + i + "/RestrictedClasses/_string").split(" "); 284 296 if (cannotAttack.indexOf(saidClass) !== -1) 285 297 return false; 286 298 } … … 288 300 }, 289 301 290 302 buildableEntities: function() { 291 if (!this._template.Builder) 292 return undefined; 293 if (!this._template.Builder.Entities._string) 303 if (!this.get("Builder/Entities/_string")) 294 304 return []; 295 305 var civ = this.civ(); 296 var templates = this. _template.Builder.Entities._string.replace(/\{civ\}/g, civ).split(/\s+/);306 var templates = this.get("Builder/Entities/_string").replace(/\{civ\}/g, civ).split(/\s+/); 297 307 return templates; // TODO: map to Entity? 298 308 }, 299 309 300 310 trainableEntities: function() { 301 if (!this. _template.ProductionQueue || !this._template.ProductionQueue.Entities || !this._template.ProductionQueue.Entities._string)311 if (!this.get("ProductionQueue/Entities/_string")) 302 312 return undefined; 303 313 var civ = this.civ(); 304 var templates = this. _template.ProductionQueue.Entities._string.replace(/\{civ\}/g, civ).split(/\s+/);314 var templates = this.get("ProductionQueue/Entities/_string").replace(/\{civ\}/g, civ).split(/\s+/); 305 315 return templates; 306 316 }, 307 317 308 318 researchableTechs: function() { 309 if (!this. _template.ProductionQueue || !this._template.ProductionQueue.Technologies || !this._template.ProductionQueue.Technologies._string)319 if (!this.get("ProductionQueue/Technologies/_string")) 310 320 return undefined; 311 var templates = this. _template.ProductionQueue.Technologies._string.split(/\s+/);321 var templates = this.get("ProductionQueue/Technologies/_string").split(/\s+/); 312 322 return templates; 313 323 }, 314 324 315 325 resourceSupplyType: function() { 316 if (!this. _template.ResourceSupply)326 if (!this.get("ResourceSupply")) 317 327 return undefined; 318 var [type, subtype] = this. _template.ResourceSupply.Type.split('.');328 var [type, subtype] = this.get("ResourceSupply/Type").split('.'); 319 329 return { "generic": type, "specific": subtype }; 320 330 }, 321 331 // will return either "food", "wood", "stone", "metal" and not treasure. 322 332 getResourceType: function() { 323 if (!this. _template.ResourceSupply)333 if (!this.get("ResourceSupply")) 324 334 return undefined; 325 var [type, subtype] = this. _template.ResourceSupply.Type.split('.');335 var [type, subtype] = this.get("ResourceSupply/Type").split('.'); 326 336 if (type == "treasure") 327 337 return subtype; 328 338 return type; 329 339 }, 330 340 331 341 resourceSupplyMax: function() { 332 if (!this. _template.ResourceSupply)342 if (!this.get("ResourceSupply")) 333 343 return undefined; 334 return +this. _template.ResourceSupply.Amount;344 return +this.get("ResourceSupply/Amount"); 335 345 }, 336 346 337 347 maxGatherers: function() 338 348 { 339 if (this. _template.ResourceSupply!== undefined)340 return +this. _template.ResourceSupply.MaxGatherers;349 if (this.get("ResourceSupply") !== undefined) 350 return +this.get("ResourceSupply/MaxGatherers"); 341 351 return 0; 342 352 }, 343 353 344 354 resourceGatherRates: function() { 345 if (!this. _template.ResourceGatherer)355 if (!this.get("ResourceGatherer")) 346 356 return undefined; 347 357 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;358 var baseSpeed = +this.get("ResourceGatherer/BaseSpeed"); 359 for (var r in this.get("ResourceGatherer/Rates")) 360 ret[r] = +this.get("ResourceGatherer/Rates/" + r) * baseSpeed; 351 361 return ret; 352 362 }, 353 363 354 364 resourceDropsiteTypes: function() { 355 if (!this. _template.ResourceDropsite)365 if (!this.get("ResourceDropsite")) 356 366 return undefined; 357 return this. _template.ResourceDropsite.Types.split(/\s+/);367 return this.get("ResourceDropsite/Types").split(/\s+/); 358 368 }, 359 369 360 370 361 371 garrisonableClasses: function() { 362 if (!this. _template.GarrisonHolder || !this._template.GarrisonHolder.List._string)372 if (!this.get("GarrisonHolder") || !this.get("GarrisonHolder/List/_string")) 363 373 return undefined; 364 return this. _template.GarrisonHolder.List._string.split(/\s+/);374 return this.get("GarrisonHolder/List/_string").split(/\s+/); 365 375 }, 366 376 367 377 garrisonMax: function() { 368 if (!this. _template.GarrisonHolder)378 if (!this.get("GarrisonHolder")) 369 379 return undefined; 370 return this. _template.GarrisonHolder.Max;380 return this.get("GarrisonHolder/Max"); 371 381 }, 372 382 373 383 /** … … 375 385 * (Any non domestic currently.) 376 386 */ 377 387 isUnhuntable: function() { 378 if (!this. _template.UnitAI || !this._template.UnitAI.NaturalBehaviour)388 if (!this.get("UnitAI") || !this.get("UnitAI/NaturalBehaviour")) 379 389 return false; 380 390 381 391 // only attack domestic animals since they won't flee nor retaliate. 382 return this. _template.UnitAI.NaturalBehaviour!== "domestic";392 return this.get("UnitAI/NaturalBehaviour") !== "domestic"; 383 393 }, 384 394 385 395 walkSpeed: function() { 386 if (!this. _template.UnitMotion || !this._template.UnitMotion.WalkSpeed)396 if (!this.get("UnitMotion") || !this.get("UnitMotion/WalkSpeed")) 387 397 return undefined; 388 return this. _template.UnitMotion.WalkSpeed;398 return this.get("UnitMotion/WalkSpeed"); 389 399 }, 390 400 391 401 buildCategory: function() { 392 if (!this. _template.BuildRestrictions || !this._template.BuildRestrictions.Category)402 if (!this.get("BuildRestrictions") || !this.get("BuildRestrictions/Category")) 393 403 return undefined; 394 return this. _template.BuildRestrictions.Category;404 return this.get("BuildRestrictions/Category"); 395 405 }, 396 406 397 407 buildTime: function() { 398 if (!this. _template.Cost || !this._template.Cost.BuildTime)408 if (!this.get("Cost") || !this.get("Cost/BuildTime")) 399 409 return undefined; 400 return this. _template.Cost.BuildTime;410 return this.get("Cost/BuildTime"); 401 411 }, 402 412 403 413 buildDistance: function() { 404 if (!this. _template.BuildRestrictions || !this._template.BuildRestrictions.Distance)414 if (!this.get("BuildRestrictions") || !this.get("BuildRestrictions/Distance")) 405 415 return undefined; 406 return this. _template.BuildRestrictions.Distance;416 return this.get("BuildRestrictions/Distance"); 407 417 }, 408 418 409 419 buildPlacementType: function() { 410 if (!this. _template.BuildRestrictions || !this._template.BuildRestrictions.PlacementType)420 if (!this.get("BuildRestrictions") || !this.get("BuildRestrictions/PlacementType")) 411 421 return undefined; 412 return this. _template.BuildRestrictions.PlacementType;422 return this.get("BuildRestrictions/PlacementType"); 413 423 }, 414 424 415 425 buildTerritories: function() { 416 if (!this. _template.BuildRestrictions || !this._template.BuildRestrictions.Territory)426 if (!this.get("BuildRestrictions") || !this.get("BuildRestrictions/Territory")) 417 427 return undefined; 418 return this. _template.BuildRestrictions.Territory.split(/\s+/);428 return this.get("BuildRestrictions/Territory").split(/\s+/); 419 429 }, 420 430 421 431 hasBuildTerritory: function(territory) { … … 424 434 }, 425 435 426 436 hasTerritoryInfluence: function() { 427 return (this. _template.TerritoryInfluence!== undefined);437 return (this.get("TerritoryInfluence") !== undefined); 428 438 }, 429 439 430 440 territoryInfluenceRadius: function() { 431 if (this. _template.TerritoryInfluence!== undefined)432 return (this. _template.TerritoryInfluence.Radius);441 if (this.get("TerritoryInfluence") !== undefined) 442 return (this.get("TerritoryInfluence/Radius")); 433 443 else 434 444 return -1; 435 445 }, 436 446 437 447 territoryInfluenceWeight: function() { 438 if (this. _template.TerritoryInfluence!== undefined)439 return (this. _template.TerritoryInfluence.Weight);448 if (this.get("TerritoryInfluence") !== undefined) 449 return (this.get("TerritoryInfluence/Weight")); 440 450 else 441 451 return -1; 442 452 }, 443 453 444 454 visionRange: function() { 445 if (!this._template.Vision) 446 return undefined; 447 return this._template.Vision.Range; 455 return this.get("Vision/Range"); 448 456 } 449 457 }); 450 458 451 459 452 460 // defines an entity, with a super Template. 461 // also redefines several of the template functions where the only change is applying aura and tech modifications. 453 462 m.Entity = m.Class({ 454 _super: m. EntityTemplate,463 _super: m.Template, 455 464 456 465 _init: function(sharedAI, entity) 457 466 { 458 this._super.call(this, sharedAI.GetTemplate(entity.template) , sharedAI._techModifications[entity.owner]);467 this._super.call(this, sharedAI.GetTemplate(entity.template)); 459 468 460 this._ai = sharedAI;461 469 this._templateName = entity.template; 462 470 this._entity = entity; 471 this._auraTemplateModif = {}; // template modification from auras. this is only for this entity. 472 this._ai = sharedAI; 473 if (!sharedAI._techModifications[entity.owner][this._templateName]) 474 sharedAI._techModifications[entity.owner][this._templateName] = {}; 475 this._techModif = sharedAI._techModifications[entity.owner][this._templateName]; // save a reference to the template tech modifications 463 476 }, 464 477 465 478 toString: function() { … … 477 490 /** 478 491 * Returns extra data that the AI scripts have associated with this entity, 479 492 * for arbitrary local annotations. 480 * (This data is notshared with any other AI scripts.)493 * (This data should not be shared with any other AI scripts.) 481 494 */ 482 495 getMetadata: function(player, key) { 483 496 return this._ai.getMetadata(player, this, key); … … 493 506 deleteAllMetadata: function(player) { 494 507 delete this._ai._entityMetadata[player][this.id()]; 495 508 }, 496 509 497 510 deleteMetadata: function(player, key) { 498 511 this._ai.deleteMetadata(player, this, key); 499 512 }, … … 508 521 509 522 unitAIState: function() { return this._entity.unitAIState; }, 510 523 unitAIOrderData: function() { return this._entity.unitAIOrderData; }, 511 hitpoints: function() { if (this._entity.hitpoints !== undefined) return this._entity.hitpoints; return undefined; }, 524 525 hitpoints: function() {if (this._entity.hitpoints !== undefined) return this._entity.hitpoints; return undefined; }, 512 526 isHurt: function() { return this.hitpoints() < this.maxHitpoints(); }, 513 527 healthLevel: function() { return (this.hitpoints() / this.maxHitpoints()); }, 514 528 needsHeal: function() { return this.isHurt() && this.isHealable(); }, … … 540 554 owner: function() { 541 555 return this._entity.owner; 542 556 }, 557 543 558 isOwn: function(player) { 544 559 if (typeof(this._entity.owner) === "undefined") 545 560 return false; 546 561 return this._entity.owner === player; 547 562 }, 563 548 564 isFriendly: function(player) { 549 565 return this.isOwn(player); // TODO: diplomacy 550 566 }, 567 551 568 isEnemy: function(player) { 552 569 return !this.isOwn(player); // TODO: diplomacy 553 570 }, … … 557 574 return undefined; 558 575 return this._entity.resourceSupplyAmount; 559 576 }, 560 577 561 578 resourceSupplyGatherers: function(player) 562 579 { 563 580 if (this._entity.resourceSupplyGatherers !== undefined) 564 return this._entity.resourceSupplyGatherers[player -1];581 return this._entity.resourceSupplyGatherers[player]; 565 582 return []; 566 583 }, 567 584 568 585 isFull: function(player) 569 586 { 570 587 if (this._entity.resourceSupplyGatherers !== undefined) 571 return (this.maxGatherers() === this._entity.resourceSupplyGatherers[player -1].length);588 return (this.maxGatherers() === this._entity.resourceSupplyGatherers[player].length); 572 589 573 590 return undefined; 574 591 }, … … 578 595 return undefined; 579 596 return this._entity.resourceCarrying; 580 597 }, 581 598 582 599 currentGatherRate: function() { 583 600 // returns the gather rate for the current target if applicable. 584 if (!this. _template.ResourceGatherer)601 if (!this.get("ResourceGatherer")); 585 602 return undefined; 586 603 587 604 if (this.unitAIOrderData().length && … … 599 616 600 617 var type = ress.resourceSupplyType(); 601 618 var tstring = type.generic + "." + type.specific; 602 619 603 620 if (type.generic == "treasure") 604 621 return 1000; 605 622 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 623 var speed = +this.get("ResourceGatherer/BaseSpeed"); 624 speed *= +this.get("ResourceGatherer/Rates/" +tstring); 625 609 626 if (speed) 610 627 return speed; 611 628 return 0; … … 644 661 }, 645 662 646 663 unload: function(id) { 647 if (!this. _template.GarrisonHolder)664 if (!this.get("GarrisonHolder")) 648 665 return undefined; 649 666 Engine.PostCommand(PlayerID,{"type": "unload", "garrisonHolder": this.id(), "entities": [id]}); 650 667 return this; … … 652 669 653 670 // Unloads all owned units, don't unload allies 654 671 unloadAll: function() { 655 if (!this. _template.GarrisonHolder)672 if (!this.get("GarrisonHolder")) 656 673 return undefined; 657 674 Engine.PostCommand(PlayerID,{"type": "unload-all-own", "garrisonHolders": [this.id()]}); 658 675 return this; … … 751 768 }); 752 769 return this; 753 770 }, 754 771 755 772 research: function(template) { 756 773 Engine.PostCommand(PlayerID,{ "type": "research", "entity": this.id(), "template": template }); 757 774 return this; -
Users/Lancelot/Desktop/0ad-svn/trunk/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) { -
Users/Lancelot/Desktop/0ad-svn/trunk/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 344 m.SharedScript.prototype.registerUpdatingEntityCollection = function(entCollection, noPush) 345 { 346 if (!noPush) { 347 this._entityCollections.push(entCollection); 348 } 349 entCollection.setUID(this._entityCollectionsUID); 350 for each (var prop in entCollection.dynamicProperties()) 351 { 352 this._entityCollectionsByDynProp[prop] = this._entityCollectionsByDynProp[prop] || []; 353 this._entityCollectionsByDynProp[prop].push(entCollection); 354 } 355 this._entityCollectionsUID++; 356 }; 357 358 m.SharedScript.prototype.removeUpdatingEntityCollection = function(entCollection) 359 { 360 for (var i in this._entityCollections) 361 { 362 if (this._entityCollections[i].getUID() === entCollection.getUID()) 363 { 364 this._entityCollections.splice(i, 1); 365 } 366 } 367 368 for each (var prop in entCollection.dynamicProperties()) 369 { 370 for (var i in this._entityCollectionsByDynProp[prop]) 371 { 372 if (this._entityCollectionsByDynProp[prop][i].getUID() === entCollection.getUID()) 373 { 374 this._entityCollectionsByDynProp[prop].splice(i, 1); 375 } 376 } 377 } 378 }; 319 379 m.SharedScript.prototype.registerUpdatingEntityCollection = function(entCollection, noPush) 320 380 { 321 381 if (!noPush) { -
Users/Lancelot/Desktop/0ad-svn/trunk/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.OnValueModification = function(msg) 158 { 159 var cmpTemplateManager = Engine.QueryInterface(SYSTEM_ENTITY, IID_TemplateManager); 160 if (!this.templates) 161 this.templates = cmpTemplateManager.FindAllTemplates(false); 162 for (var o = 0; o < this.templates.length; ++o) 163 { 164 var tmp = this.templates[o]; 165 var template = cmpTemplateManager.GetTemplateWithoutValidation(this.templates[o]); 166 // remove templates that we obviously don't care about. 167 if (!template || !template.Identity || ! template.Identity.Civ) 168 { 169 this.templates.splice(o--,1); 170 continue; 171 } 172 for each (var value in msg.valueNames) 173 { 174 // let's get the base template value. 175 var strings = value.split("/"); 176 var item = template; 177 var ended = true; 178 for (var i = 0; i < strings.length; ++i) 179 { 180 if (item !== undefined && item[strings[i]] !== undefined) 181 item = item[strings[i]]; 182 else 183 ended = false; 184 } 185 if (!ended) 186 continue; 187 // item now contains the template value for this. 188 var newValue = ApplyValueModificationsToTemplate(value, +item, msg.player, template); 189 newValue = typeof(newValue) === "Number" ? Math.round(newValue) : newValue; 190 if(item != newValue) 191 { 192 if (!this.changedTemplateInfo[msg.player]) 193 this.changedTemplateInfo[msg.player] = {}; 194 if (!this.changedTemplateInfo[msg.player][this.templates[o]]) 195 this.changedTemplateInfo[msg.player][this.templates[o]] = [ { "variable" : value, "value" : newValue} ]; 196 else 197 this.changedTemplateInfo[msg.player][this.templates[o]].push({ "variable" : value, "value" : newValue }); 198 } 199 } 200 } 201 }; 202 203 AIInterface.prototype.AuraChange = function(msg, ent) 204 { 205 var cmpTemplateManager = Engine.QueryInterface(SYSTEM_ENTITY, IID_TemplateManager); 206 var template = cmpTemplateManager.GetTemplateWithoutValidation(cmpTemplateManager.GetCurrentTemplateName(ent)); 207 for each (var value in msg.valueNames) 208 { 209 // let's get the base template value. 210 var strings = value.split("/"); 211 var item = template; 212 var ended = true; 213 for (var i = 0; i < strings.length; ++i) 214 { 215 if (item !== undefined && item[strings[i]] !== undefined) 216 item = item[strings[i]]; 217 else 218 ended = false; 219 } 220 if (!ended) 221 continue; 222 // "item" now contains the unmodified template value for this. 223 var newValue = ApplyValueModificationsToEntity(value, +item, ent); 224 newValue = typeof(newValue) === "Number" ? Math.round(newValue) : newValue; 225 if(item != newValue) 226 { 227 if (!this.changedEntityTemplateInfo[ent]) 228 this.changedEntityTemplateInfo[ent] = [{ "variable" : value, "value" : newValue }]; 229 else 230 this.changedEntityTemplateInfo[ent].push({ "variable" : value, "value" : newValue }); 231 } 232 } 233 }; 234 159 235 Engine.RegisterComponentType(IID_AIInterface, "AIInterface", AIInterface); -
Users/Lancelot/Desktop/0ad-svn/trunk/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 }; … … 67 69 if (!this.changes) 68 70 { 69 71 this.changes = {}; 70 71 var cmpAIInterface = Engine.QueryInterface(SYSTEM_ENTITY, IID_AIInterface); 72 cmpAIInterface.ChangedEntity(this.entity); 72 this.cmpAIInterface.ChangedEntity(this.entity); 73 73 } 74 74 }; 75 75 … … 261 261 262 262 if (msg.from === -1) 263 263 { 264 var cmpAIInterface = Engine.QueryInterface(SYSTEM_ENTITY, IID_AIInterface); 265 cmpAIInterface.PushEvent("Create", {"entity" : msg.entity}); 264 this.cmpAIInterface.PushEvent("Create", {"entity" : msg.entity}); 266 265 return; 267 266 } else if (msg.to === -1) 268 267 { 269 var cmpAIInterface = Engine.QueryInterface(SYSTEM_ENTITY, IID_AIInterface); 270 cmpAIInterface.PushEvent("Destroy", {"entity" : msg.entity}); 268 this.cmpAIInterface.PushEvent("Destroy", {"entity" : msg.entity}); 271 269 return; 272 270 } 273 271 274 272 this.owner = msg.to; 275 273 this.changes.owner = msg.to; 276 274 277 var cmpAIInterface = Engine.QueryInterface(SYSTEM_ENTITY, IID_AIInterface); 278 cmpAIInterface.PushEvent("OwnershipChanged", msg); 275 this.cmpAIInterface.PushEvent("OwnershipChanged", msg); 279 276 }; 280 277 281 278 AIProxy.prototype.OnAttacked = function(msg) 282 279 { 283 var cmpAIInterface = Engine.QueryInterface(SYSTEM_ENTITY, IID_AIInterface); 284 cmpAIInterface.PushEvent("Attacked", msg); 280 this.cmpAIInterface.PushEvent("Attacked", msg); 285 281 }; 286 282 287 283 /* 288 284 Deactivated for actually not really being practical for most uses. 289 285 AIProxy.prototype.OnRangeUpdate = function(msg) 290 286 { 291 var cmpAIInterface = Engine.QueryInterface(SYSTEM_ENTITY, IID_AIInterface);292 287 msg.owner = this.owner; 293 288 this.cmpAIInterface.PushEvent("RangeUpdate", msg); 294 289 warn(uneval(msg)); 295 290 };*/ 296 291 297 292 AIProxy.prototype.OnConstructionFinished = function(msg) 298 293 { 299 var cmpAIInterface = Engine.QueryInterface(SYSTEM_ENTITY, IID_AIInterface); 300 cmpAIInterface.PushEvent("ConstructionFinished", msg); 294 this.cmpAIInterface.PushEvent("ConstructionFinished", msg); 301 295 }; 302 296 303 297 AIProxy.prototype.OnTrainingFinished = function(msg) 304 298 { 305 var cmpAIInterface = Engine.QueryInterface(SYSTEM_ENTITY, IID_AIInterface); 306 cmpAIInterface.PushEvent("TrainingFinished", msg); 299 this.cmpAIInterface.PushEvent("TrainingFinished", msg); 307 300 }; 308 301 309 302 AIProxy.prototype.OnAIMetadata = function(msg) 310 303 { 311 var cmpAIInterface = Engine.QueryInterface(SYSTEM_ENTITY, IID_AIInterface); 312 cmpAIInterface.PushEvent("AIMetadata", msg); 304 this.cmpAIInterface.PushEvent("AIMetadata", msg); 305 }; 306 307 AIProxy.prototype.OnAI_AuraChange = function(msg) 308 { 309 this.cmpAIInterface.AuraChange(msg, this.entity); 313 310 }; 314 311 315 312 Engine.RegisterComponentType(IID_AIProxy, "AIProxy", AIProxy); -
Users/Lancelot/Desktop/0ad-svn/trunk/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_AI_AuraChange, { "valueNames": [value] }); 50 Engine.PostMessage(ent, MT_ValueModification, { "player": 0, "component": value.split("/")[0], "valueNames": [value] }); 50 51 }; 51 52 52 53 AuraManager.prototype.ApplyTemplateBonus = function(value, player, classes, data, key) … … 98 99 this.modificationsCache[value][ent].multiply /= data.multiply; 99 100 100 101 // post message to the entity to notify it about the change 101 Engine.PostMessage(ent, MT_ValueModification, { "component": value.split("/")[0] }); 102 var effects = {}; 103 effects[value] = this.modificationsCache[value][ent]; 104 Engine.PostMessage(ent, MT_AI_AuraChange, { "valueNames": [value] }); 105 Engine.PostMessage(ent, MT_ValueModification, { "player": Engine.QueryInterface(ent, IID_Ownership).GetOwner(), "component": value.split("/")[0], "valueNames": [value] }); 102 106 }; 103 107 104 108 AuraManager.prototype.RemoveTemplateBonus = function(value, player, classes, key) -
Users/Lancelot/Desktop/0ad-svn/trunk/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 -
Users/Lancelot/Desktop/0ad-svn/trunk/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_ValueModification, { "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_ValueModification, { "player": player, "component": component, "valueNames": modifiedComponents[component]}); 335 346 }; 336 347 337 348 // Clears the cached data for an entity from the modifications cache -
Users/Lancelot/Desktop/0ad-svn/trunk/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"); -
Users/Lancelot/Desktop/0ad-svn/trunk/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 { -
Users/Lancelot/Desktop/0ad-svn/trunk/source/simulation2/MessageTypes.h
373 373 public: 374 374 DEFAULT_MESSAGE_IMPL(ValueModification) 375 375 376 CMessageValueModification(std::wstring component) : 377 component(component) 376 CMessageValueModification(player_id_t player, std::wstring component, const std::vector<std::wstring>& valueNames) : 377 player(player), 378 component(component), 379 valueNames(valueNames) 378 380 { 379 381 } 380 382 383 player_id_t player; 381 384 std::wstring component; 385 std::vector<std::wstring> valueNames; 382 386 }; 383 387 384 388 /** -
Users/Lancelot/Desktop/0ad-svn/trunk/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) -
Users/Lancelot/Desktop/0ad-svn/trunk/source/simulation2/scripting/MessageTypeConversions.cpp
303 303 jsval CMessageValueModification::ToJSVal(ScriptInterface& scriptInterface) const 304 304 { 305 305 TOJSVAL_SETUP(); 306 SET_MSG_PROPERTY(player); 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(player_id_t, player); 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(player, component, valueNames); 315 319 } 316 320 317 321 ////////////////////////////////