Ticket #4142: 4142_petra_regicide_support_v1.5.patch
File 4142_petra_regicide_support_v1.5.patch, 8.7 KB (added by , 7 years ago) |
---|
-
binaries/data/mods/public/simulation/ai/common-api/entity.js
745 745 garrisoned: function() { return this._entity.garrisoned; }, 746 746 canGarrisonInside: function() { return this._entity.garrisoned.length < this.garrisonMax(); }, 747 747 748 "canGuard": function() { return this.get("UnitAI/CanGuard") === "true"; }, 749 748 750 move: function(x, z, queued = false) { 749 751 Engine.PostCommand(PlayerID,{"type": "walk", "entities": [this.id()], "x": x, "z": z, "queued": queued }); 750 752 return this; … … 929 931 if (item.progress < percentToStopAt) 930 932 Engine.PostCommand(PlayerID,{ "type": "stop-production", "entity": this.id(), "id": item.id }); 931 933 return this; 934 }, 935 936 "guard": function(target, queued = false) { 937 Engine.PostCommand(PlayerID, { "type": "guard", "entities": [this.id()], "target": target.id(), "queued": queued }); 938 return this; 939 }, 940 941 "removeGuard": function() { 942 Engine.PostCommand(PlayerID, { "type": "remove-guard", "entities": [this.id()] }); 943 return this; 932 944 } 933 945 }); 934 946 -
binaries/data/mods/public/simulation/ai/petra/gameTypeManager.js
3 3 4 4 /** 5 5 * Handle events that are important to specific gameTypes 6 * In regicide, train and manage healer guards for the hero 6 7 * TODO: Handle when there is more than one hero in regicide 7 8 * TODO: Assign military units to guard the hero in regicide 8 9 */ 9 10 10 m.GameTypeManager = function( )11 m.GameTypeManager = function(Config) 11 12 { 13 this.Config = Config; 12 14 this.heroGarrisonEmergency = false; 15 this.healersAssignedToHero = 0; // Accounts for healers being trained as well 16 this.heroGuards = []; // Holds ents currently guarding the hero 13 17 }; 14 18 15 19 /** … … 80 84 } 81 85 } 82 86 83 if (!this.heroGarrisonEmergency) 84 return; 87 // check if new healers/guards need to be assigned to the hero 88 for (let evt of events.Destroy) 89 { 90 if (!evt.entityObj || evt.entityObj.owner() !== PlayerID || 91 this.heroGuards.indexOf(evt.entityObj.id()) === -1) 92 continue; 85 93 94 this.heroGuards.splice(this.heroGuards.indexOf(evt.entityObj.id()), 1); 95 if (evt.entityObj.hasClass("Healer")) 96 --this.healersAssignedToHero; 97 } 98 99 for (let evt of events.TrainingFinished) 100 for (let entId of evt.entities) 101 { 102 let ent = gameState.getEntityById(entId); 103 if (!ent || !ent.isOwn(PlayerID) || ent.getMetadata(PlayerID, "role") !== "regicideHealer") 104 continue; 105 106 this.assignGuardToRegicideHero(gameState, ent); 107 } 108 86 109 for (let evt of events.Garrison) 87 if (gameState.getEntityById(evt.entity).hasClass("Hero")) 110 { 111 let ent = gameState.getEntityById(evt.entity); 112 if (!ent || !ent.isOwn(PlayerID) || !ent.hasClass("Hero")) 113 continue; 114 115 if (this.heroGarrisonEmergency) 88 116 this.heroGarrisonEmergency = false; 117 118 if (!gameState.getEntityById(evt.holder).hasClass("Ship")) 119 continue; 120 121 // If the hero is garrisoned on a ship, remove its guards 122 for (let guardId of this.heroGuards) 123 gameState.getEntityById(guardId).removeGuard(); 124 125 this.heroGuards = []; 126 } 127 128 for (let evt of events.UnGarrison) 129 { 130 let ent = gameState.getEntityById(evt.entity); 131 if (!ent || !ent.isOwn(PlayerID)) 132 continue; 133 134 // If this ent travelled to a hero's accessValue, try again to assign as a guard 135 if (ent.getMetadata(PlayerID, "role") === "regicideHealer" && 136 this.heroGuards.indexOf(evt.entity) === -1) 137 { 138 this.assignGuardToRegicideHero(gameState, ent); 139 continue; 140 } 141 142 if (!ent.hasClass("Hero")) 143 continue; 144 145 // If this is the hero, try to assign ents that should be guarding it, but couldn't previously 146 let regicideHealers = gameState.getOwnUnits().filter(API3.Filters.byMetadata(PlayerID, "role", "regicideHealer")); 147 for (let healer of regicideHealers.values()) 148 { 149 if (this.heroGuards.indexOf(healer.id()) !== -1) 150 continue; 151 152 this.assignGuardToRegicideHero(gameState, healer); 153 } 154 } 89 155 }; 90 156 91 157 m.GameTypeManager.prototype.buildWonder = function(gameState, queues) … … 116 182 heroEnt.move(basePos.anchor.position()[0], basePos.anchor.position()[1]); 117 183 }; 118 184 185 m.GameTypeManager.prototype.trainRegicideHealer = function(gameState, queues) 186 { 187 if (gameState.ai.HQ.saveResources || !gameState.getOwnEntitiesByClass("Temple", true).hasEntities()) 188 return; 189 190 let template = gameState.applyCiv("units/{civ}_support_healer_b"); 191 192 queues.villager.addPlan(new m.TrainingPlan(gameState, template, { "role": "regicideHealer", "base": 0 }, 1, 1)); 193 ++this.healersAssignedToHero; 194 }; 195 196 /** 197 * Only send the guard command if the guard's accessIndex is the same as the hero 198 * and the hero has a position (i.e. not garrisoned) 199 * request a transport if the accessIndex value is different 200 */ 201 m.GameTypeManager.prototype.assignGuardToRegicideHero = function(gameState, ent) 202 { 203 let heroEnt = gameState.getOwnEntitiesByClass("Hero", true).toEntityArray()[0]; 204 if (!heroEnt || !heroEnt.position() || !ent.position() || !ent.canGuard()) 205 return; 206 207 let entAccess = gameState.ai.accessibility.getAccessValue(ent.position()); 208 let heroAccess = gameState.ai.accessibility.getAccessValue(heroEnt.position()); 209 if (entAccess && entAccess === heroAccess) 210 { 211 ent.guard(heroEnt); 212 this.heroGuards.push(ent.id()); 213 return; 214 } 215 gameState.ai.HQ.navalManager.requireTransport(gameState, ent, entAccess, heroAccess, heroEnt.position()); 216 }; 217 119 218 m.GameTypeManager.prototype.update = function(gameState, events, queues) 120 219 { 121 220 this.checkEvents(gameState, events); … … 122 221 123 222 if (gameState.getGameType() === "wonder") 124 223 this.buildWonder(gameState, queues); 125 else if (gameState.getGameType() === "regicide" && gameState.ai.playedTurn % 50 === 0) 224 225 if (gameState.getGameType() !== "regicide") 226 return; 227 228 if (gameState.ai.playedTurn % 50 === 0) 126 229 { 127 230 let heroEnt = gameState.getOwnEntitiesByClass("Hero", true).toEntityArray()[0]; 128 231 if (heroEnt && heroEnt.healthLevel() > 0.7) 129 232 heroEnt.setStance("aggressive"); 130 233 } 234 235 if (this.healersAssignedToHero < 2 + Math.round(this.Config.personality.defensive * 2)) 236 this.trainRegicideHealer(gameState, queues); 131 237 }; 132 238 133 239 m.GameTypeManager.prototype.Serialize = function() 134 240 { 135 return { "heroGarrisonEmergency": this.heroGarrisonEmergency }; 241 return { 242 "heroGarrisonEmergency": this.heroGarrisonEmergency, 243 "healersAssignedToHero": this.healersAssignedToHero, 244 "heroGuards": this.heroGuards 245 }; 136 246 }; 137 247 138 248 m.GameTypeManager.prototype.Deserialize = function(data) -
binaries/data/mods/public/simulation/ai/petra/garrisonManager.js
215 215 { 216 216 ent.stopMoving(); 217 217 this.leaveGarrison(ent); 218 let holderId = ent.getMetadata(PlayerI d, "garrisonHolder");218 let holderId = ent.getMetadata(PlayerID, "garrisonHolder"); 219 219 if (!holderId || !this.holders.has(holderId)) 220 220 return; 221 221 let list = this.holders.get(holderId); -
binaries/data/mods/public/simulation/ai/petra/headquarters.js
51 51 this.researchManager = new m.ResearchManager(this.Config); 52 52 this.diplomacyManager = new m.DiplomacyManager(this.Config); 53 53 this.garrisonManager = new m.GarrisonManager(); 54 this.gameTypeManager = new m.GameTypeManager( );54 this.gameTypeManager = new m.GameTypeManager(this.Config); 55 55 }; 56 56 57 57 /** More initialisation for stuff that needs the gameState */ … … 1268 1268 gameState.getOwnEntitiesByClass("Temple", true).hasEntities() || 1269 1269 !gameState.getOwnEntitiesByClass("BarterMarket", true).hasEntities()) 1270 1270 return; 1271 if (gameState.currentPhase() < 3) 1271 // Try to build a temple earlier if in regicide to recruit healer guards 1272 if (gameState.currentPhase() < 3 && gameState.getGameType() !== "regicide") 1272 1273 { 1273 1274 if (gameState.currentPhase() < 2 || this.econState !== "cityPhasing") 1274 1275 return; … … 2279 2280 this.garrisonManager = new m.GarrisonManager(); 2280 2281 this.garrisonManager.Deserialize(data.garrisonManager); 2281 2282 2282 this.gameTypeManager = new m.GameTypeManager( );2283 this.gameTypeManager = new m.GameTypeManager(this.Config); 2283 2284 this.gameTypeManager.Deserialize(data.gameTypeManager); 2284 2285 }; 2285 2286