Ticket #3157: attackRequest.diff
File attackRequest.diff, 11.0 KB (added by , 9 years ago) |
---|
-
binaries/data/mods/public/gui/session/diplomacy_window.xml
65 65 <object name="diplomacyPlayerTributeMetal[n]" size="100%-50 0 100%-30 100%" type="button" style="iconButton" tooltip_style="sessionToolTipBold" hidden="true"> 66 66 <object name="diplomacyPlayerTributeMetalImage[n]" type="image" size="0 0 100% 100%" sprite="stretched:session/icons/resources/metal.png" ghost="true"/> 67 67 </object> 68 69 <object name="diplomacyAttackRequest[n]" size="100%-20 0 100% 100%" type="button" style="iconButton" tooltip_style="sessionToolTipBold" hidden="true"> 70 <object name="diplomacyAttackRequestImage[n]" type="image" size="0 0 100% 100%" sprite="stretched:session/icons/stances/aggressive.png" ghost="true"/> 71 </object> 68 72 </object> 69 73 </repeat> 70 74 </object> -
binaries/data/mods/public/gui/session/menu.js
261 261 Engine.PostNetworkCommand({"type": "tribute", "player": data.player, "amounts": data.amounts}); 262 262 } 263 263 264 function requestAttack(data) 265 { 266 Engine.PostNetworkCommand({"type": "aievent", "from": data.from, "action": data.action, "target": data.target}); 267 } 268 264 269 function openDiplomacy() 265 270 { 266 271 if (isTradeOpen) … … 301 306 // Hide the unused/unselectable options 302 307 for each (let a in ["TributeFood", "TributeWood", "TributeStone", "TributeMetal", "Ally", "Neutral", "Enemy"]) 303 308 Engine.GetGUIObjectByName("diplomacyPlayer"+a+"["+(i-1)+"]").hidden = true; 309 Engine.GetGUIObjectByName("diplomacyAttackRequest["+(i-1)+"]").hidden = true; 304 310 continue; 305 311 } 306 312 … … 341 347 button.tooltip = formatTributeTooltip(g_Players[i], resource, 100); 342 348 } 343 349 350 if (!g_IsNetworked) // TODO in multiplayer, should be done if some AIs 351 { 352 // Attack Request (used to communicate with AI) 353 let button = Engine.GetGUIObjectByName("diplomacyAttackRequest["+(i-1)+"]"); 354 button.hidden = !(g_Players[i].isEnemy[we]); 355 button.tooltip = "request for your AI allies to attack this enemy"; 356 button.onpress = (function(i, we){ return function() { requestAttack({"type": "aievent", "from": we, "action": "attack", "target": i}); } })(i, we); 357 } 358 344 359 // Skip our own teams on teams locked 345 360 if (g_Players[we].teamsLocked && g_Players[we].team != -1 && g_Players[we].team == g_Players[i].team) 346 361 continue; -
binaries/data/mods/public/simulation/ai/petra/attackManager.js
46 46 } 47 47 }; 48 48 49 m.AttackManager.prototype.checkEvents = function(gameState, events) 50 { 51 let PlayerEvents = events["PlayerMessage"]; 52 let answer = false; 53 let other = false; 54 let targetPlayer = undefined; 55 for (let evt of PlayerEvents) 56 { 57 if (evt.action !== "attack") 58 continue; 59 if (evt.from === PlayerID || !gameState.isPlayerAlly(evt.from) || !gameState.isPlayerEnemy(evt.target)) 60 continue; 61 targetPlayer = evt.target; 62 let available = 0; 63 for (let attackType in this.upcomingAttacks) 64 { 65 for (let attack of this.upcomingAttacks[attackType]) 66 { 67 if (attack.state === "completing") 68 { 69 if (attack.targetPlayer && attack.targetPlayer === targetPlayer) 70 available += attack.unitCollection.length; 71 else if (attack.targetPlayer && attack.targetPlayer !== targetPlayer) 72 other = true; 73 continue; 74 } 75 if (!attack.targetPlayer || attack.targetPlayer !== targetPlayer) 76 { 77 let oldTargetPlayer = attack.targetPlayer; 78 let oldTarget = attack.target; 79 attack.targetPlayer = targetPlayer; 80 attack.target = attack.getNearestTarget(gameState, attack.rallyPoint); 81 if (!attack.target) 82 { 83 attack.targetPlayer = oldTargetPlayer; 84 attack.target = oldTarget; 85 continue; 86 } 87 } 88 if (attack.targetPlayer && attack.targetPlayer === targetPlayer) 89 available += attack.unitCollection.length; 90 } 91 } 92 93 if (available > 12) // launch the attack immediately 94 { 95 for (let attackType in this.upcomingAttacks) 96 for (let attack of this.upcomingAttacks[attackType]) 97 if (attack.state !== "completing" && attack.targetPlayer && attack.targetPlayer === targetPlayer) 98 attack.forceStart(); 99 answer = true; 100 } 101 break; // take only the first attack request into account 102 } 103 if (targetPlayer) 104 m.chatAnswerRequestAttack(gameState, targetPlayer, answer, other); 105 }; 106 49 107 // Some functions are run every turn 50 108 // Others once in a while 51 109 m.AttackManager.prototype.update = function(gameState, queues, events) … … 64 122 API3.warn(" =================================="); 65 123 } 66 124 67 for (var attackType in this.upcomingAttacks) 125 this.checkEvents(gameState, events); 126 127 let unexecutedAttacks = {"Rush": 0, "Raid": 0, "Attack": 0, "HugeAttack": 0}; 128 for (let attackType in this.upcomingAttacks) 68 129 { 69 for ( vari = 0; i < this.upcomingAttacks[attackType].length; ++i)130 for (let i = 0; i < this.upcomingAttacks[attackType].length; ++i) 70 131 { 71 varattack = this.upcomingAttacks[attackType][i];132 let attack = this.upcomingAttacks[attackType][i]; 72 133 attack.checkEvents(gameState, events); 73 134 74 135 if (attack.isStarted()) 75 136 API3.warn("Petra problem in attackManager: attack in preparation has already started ???"); 76 137 77 varupdateStep = attack.updatePreparation(gameState);138 let updateStep = attack.updatePreparation(gameState); 78 139 // now we're gonna check if the preparation time is over 79 140 if (updateStep === 1 || attack.isPaused() ) 80 141 { 81 142 // just chillin' 143 if (attack.state === "unexecuted") 144 ++unexecutedAttacks[attackType]; 82 145 } 83 146 else if (updateStep === 0 || updateStep === 3) 84 147 { … … 96 159 if (this.Config.chat) 97 160 m.chatLaunchAttack(gameState, attack.targetPlayer); 98 161 this.startedAttacks[attackType].push(attack); 99 //Engine.PostCommand(PlayerID, {"type": "aievent", "from": PlayerID, "action": "attack", "target": attack.targetPlayer});162 Engine.PostCommand(PlayerID, {"type": "aievent", "from": PlayerID, "action": "attack", "target": attack.targetPlayer}); 100 163 } 101 164 else 102 165 attack.Abort(gameState); … … 129 192 130 193 if (this.rushNumber < this.maxRushes && gameState.countEntitiesByType(gameState.applyCiv("structures/{civ}_barracks"), true) >= 1) 131 194 { 132 if ( this.upcomingAttacks["Rush"].length=== 0)195 if (unexecutedAttacks["Rush"] === 0) 133 196 { 134 197 // we have a barracks and we want to rush, rush. 135 198 var data = { "targetSize": this.rushSize[this.rushNumber] }; … … 145 208 this.rushNumber++; 146 209 } 147 210 } 148 else if ( this.upcomingAttacks["Attack"].length === 0 && this.upcomingAttacks["HugeAttack"].length=== 0211 else if (unexecutedAttacks["Attack"] === 0 && unexecutedAttacks["HugeAttack"] === 0 149 212 && (this.startedAttacks["Attack"].length + this.startedAttacks["HugeAttack"].length < Math.round(gameState.getPopulationMax()/100))) 150 213 { 151 214 if ((gameState.countEntitiesByType(gameState.applyCiv("structures/{civ}_barracks"), true) >= 1 … … 172 235 } 173 236 } 174 237 175 if ( this.upcomingAttacks["Raid"].length=== 0 && gameState.ai.HQ.defenseManager.targetList.length)238 if (unexecutedAttacks["Raid"] === 0 && gameState.ai.HQ.defenseManager.targetList.length) 176 239 { 177 240 var target = undefined; 178 241 for (var targetId of gameState.ai.HQ.defenseManager.targetList) -
binaries/data/mods/public/simulation/ai/petra/attackPlan.js
266 266 return false; 267 267 }; 268 268 269 m.AttackPlan.prototype.forceStart = function() 270 { 271 for (let unitCat in this.unitStat) 272 { 273 let Unit = this.unitStat[unitCat]; 274 Unit["targetSize"] = 0; 275 Unit["minSize"] = 0; 276 } 277 }; 278 269 279 // Adds a build order. If resetQueue is true, this will reset the queue. 270 280 m.AttackPlan.prototype.addBuildOrder = function(gameState, name, unitStats, resetQueue) 271 281 { -
binaries/data/mods/public/simulation/ai/petra/chatHelper.js
14 14 Engine.PostCommand(PlayerID, chat); 15 15 }; 16 16 17 m.chatAnswerRequestAttack = function(gameState, player, answer, other) 18 { 19 var name = gameState.sharedScript.playersData[player].name; 20 if (answer) 21 { 22 var proba = Math.random(); 23 if (proba < 0.5) 24 var message = "/team " + markForTranslation("Let me regroup my army and I am with you against %(name)s."); 25 else 26 var message = "/team " + markForTranslation("I am doing the final preparation and I will attack %(name)s."); 27 } 28 else 29 { 30 if (other) 31 var message = "/team " + markForTranslation("I cannot help you against %(name)s for the time being, I have another attack foreseen."); 32 else 33 var message = "/team " + markForTranslation("Sorry, I have not enough soldiers to attack %(name)s right now, but my next attack will target him."); 34 } 35 36 var chat = { "type": "aichat", "message": message, "translateMessage": true, "translateParameters": ["name"], "parameters": { "name": name } }; 37 Engine.PostCommand(PlayerID, chat); 38 }; 39 17 40 m.chatSentTribute = function(gameState, player) 18 41 { 19 42 var name = gameState.sharedScript.playersData[player].name; -
binaries/data/mods/public/simulation/components/AIInterface.js
17 17 "OwnershipChanged", 18 18 "Garrison", 19 19 "UnGarrison", 20 "TributeExchanged" 20 "TributeExchanged", 21 "PlayerMessage" 21 22 ]; 22 23 23 24 AIInterface.prototype.Init = function() -
binaries/data/mods/public/simulation/helpers/Commands.js
644 644 } 645 645 } 646 646 }, 647 648 "aievent": function(player, cmd, data) 649 { 650 // Used to allow interaction between players and AIs: i.e. warn it of foreseen attacks 651 let cmpAIInterface = Engine.QueryInterface(SYSTEM_ENTITY, IID_AIInterface); 652 if (!cmpAIInterface) 653 return; 654 cmpAIInterface.PushEvent("PlayerMessage", cmd); 655 }, 656 647 657 "dialog-answer": function(player, cmd, data) 648 658 { 649 659 // Currently nothing. Triggers can read it anyway, and send this