Ticket #3157: attackRequest-v2.diff
File attackRequest-v2.diff, 15.1 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
301 301 // Hide the unused/unselectable options 302 302 for each (let a in ["TributeFood", "TributeWood", "TributeStone", "TributeMetal", "Ally", "Neutral", "Enemy"]) 303 303 Engine.GetGUIObjectByName("diplomacyPlayer"+a+"["+(i-1)+"]").hidden = true; 304 Engine.GetGUIObjectByName("diplomacyAttackRequest["+(i-1)+"]").hidden = true; 304 305 continue; 305 306 } 306 307 … … 341 342 button.tooltip = formatTributeTooltip(g_Players[i], resource, 100); 342 343 } 343 344 345 // Attack Request 346 let button = Engine.GetGUIObjectByName("diplomacyAttackRequest["+(i-1)+"]"); 347 button.hidden = !(g_Players[i].isEnemy[we]); 348 button.tooltip = "request for your allies to attack this enemy"; 349 button.onpress = (function(i, we){ return function() { 350 Engine.PostNetworkCommand({"type": "attack-request", "source": we, "target": i}); 351 } })(i, we); 352 344 353 // Skip our own teams on teams locked 345 354 if (g_Players[we].teamsLocked && g_Players[we].team != -1 && g_Players[we].team == g_Players[i].team) 346 355 continue; -
binaries/data/mods/public/gui/session/messages.js
57 57 { 58 58 message["translateParameters"] = notification["translateParameters"]; 59 59 message["parameters"] = notification["parameters"]; 60 // special case for formatting of player names which are transmitted as _player_num 61 for (let param in message["parameters"]) 62 { 63 if (!message["parameters"][param].startsWith("_player_")) 64 continue; 65 let colorName = getUsernameAndColor(+message["parameters"][param].substr(8)); 66 message["parameters"][param] = "[color=\"" + colorName[1] + "\"]" + colorName[0] + "[/color]"; 67 } 60 68 } 61 69 var guid = findGuidForPlayerID(g_PlayerAssignments, player); 62 70 if (guid == undefined) -
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["AttackRequest"]; 52 let answer = false; 53 let other = undefined; 54 let targetPlayer = undefined; 55 for (let evt of PlayerEvents) 56 { 57 if (evt.source === PlayerID || !gameState.isPlayerAlly(evt.source) || !gameState.isPlayerEnemy(evt.target)) 58 continue; 59 targetPlayer = evt.target; 60 let available = 0; 61 for (let attackType in this.upcomingAttacks) 62 { 63 for (let attack of this.upcomingAttacks[attackType]) 64 { 65 if (attack.state === "completing") 66 { 67 if (attack.targetPlayer && attack.targetPlayer === targetPlayer) 68 available += attack.unitCollection.length; 69 else if (attack.targetPlayer && attack.targetPlayer !== targetPlayer) 70 other = attack.targetPlayer; 71 continue; 72 } 73 if (!attack.targetPlayer || attack.targetPlayer !== targetPlayer) 74 { 75 let oldTargetPlayer = attack.targetPlayer; 76 let oldTarget = attack.target; 77 attack.targetPlayer = targetPlayer; 78 attack.target = attack.getNearestTarget(gameState, attack.rallyPoint); 79 if (!attack.target) 80 { 81 attack.targetPlayer = oldTargetPlayer; 82 attack.target = oldTarget; 83 continue; 84 } 85 } 86 if (attack.targetPlayer && attack.targetPlayer === targetPlayer) 87 available += attack.unitCollection.length; 88 } 89 } 90 91 if (available > 12) // launch the attack immediately 92 { 93 for (let attackType in this.upcomingAttacks) 94 { 95 for (let attack of this.upcomingAttacks[attackType]) 96 { 97 if (attack.state !== "completing" && attack.targetPlayer && attack.targetPlayer === targetPlayer) 98 { 99 attack.forceStart(); 100 attack.requested = true; 101 } 102 } 103 } 104 answer = true; 105 } 106 break; // take only the first attack request into account 107 } 108 if (targetPlayer) 109 m.chatAnswerRequestAttack(gameState, targetPlayer, answer, other); 110 }; 111 49 112 // Some functions are run every turn 50 113 // Others once in a while 51 114 m.AttackManager.prototype.update = function(gameState, queues, events) … … 64 127 API3.warn(" =================================="); 65 128 } 66 129 67 for (var attackType in this.upcomingAttacks) 130 this.checkEvents(gameState, events); 131 132 let unexecutedAttacks = {"Rush": 0, "Raid": 0, "Attack": 0, "HugeAttack": 0}; 133 for (let attackType in this.upcomingAttacks) 68 134 { 69 for ( vari = 0; i < this.upcomingAttacks[attackType].length; ++i)135 for (let i = 0; i < this.upcomingAttacks[attackType].length; ++i) 70 136 { 71 varattack = this.upcomingAttacks[attackType][i];137 let attack = this.upcomingAttacks[attackType][i]; 72 138 attack.checkEvents(gameState, events); 73 139 74 140 if (attack.isStarted()) 75 141 API3.warn("Petra problem in attackManager: attack in preparation has already started ???"); 76 142 77 varupdateStep = attack.updatePreparation(gameState);143 let updateStep = attack.updatePreparation(gameState); 78 144 // now we're gonna check if the preparation time is over 79 145 if (updateStep === 1 || attack.isPaused() ) 80 146 { 81 147 // just chillin' 148 if (attack.state === "unexecuted") 149 ++unexecutedAttacks[attackType]; 82 150 } 83 151 else if (updateStep === 0 || updateStep === 3) 84 152 { … … 96 164 if (this.Config.chat) 97 165 m.chatLaunchAttack(gameState, attack.targetPlayer); 98 166 this.startedAttacks[attackType].push(attack); 99 // Engine.PostCommand(PlayerID, {"type": "aievent", "from": PlayerID, "action": "attack", "target": attack.targetPlayer});100 167 } 101 168 else 102 169 attack.Abort(gameState); … … 130 197 var barracksNb = gameState.getOwnEntitiesByClass("Barracks", true).filter(API3.Filters.isBuilt()).length; 131 198 if (this.rushNumber < this.maxRushes && barracksNb >= 1) 132 199 { 133 if ( this.upcomingAttacks["Rush"].length=== 0)200 if (unexecutedAttacks["Rush"] === 0) 134 201 { 135 202 // we have a barracks and we want to rush, rush. 136 203 var data = { "targetSize": this.rushSize[this.rushNumber] }; … … 146 213 this.rushNumber++; 147 214 } 148 215 } 149 else if ( this.upcomingAttacks["Attack"].length === 0 && this.upcomingAttacks["HugeAttack"].length=== 0216 else if (unexecutedAttacks["Attack"] === 0 && unexecutedAttacks["HugeAttack"] === 0 150 217 && (this.startedAttacks["Attack"].length + this.startedAttacks["HugeAttack"].length < Math.round(gameState.getPopulationMax()/100))) 151 218 { 152 219 if ((barracksNb >= 1 && (gameState.currentPhase() > 1 || gameState.isResearching(gameState.townPhase()))) … … 172 239 } 173 240 } 174 241 175 if ( this.upcomingAttacks["Raid"].length=== 0 && gameState.ai.HQ.defenseManager.targetList.length)242 if (unexecutedAttacks["Raid"] === 0 && gameState.ai.HQ.defenseManager.targetList.length) 176 243 { 177 244 var target = undefined; 178 245 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 { … … 465 475 if (this.type === "Raid") 466 476 this.maxCompletingTurn = gameState.ai.playedTurn + 20; 467 477 else 478 { 468 479 this.maxCompletingTurn = gameState.ai.playedTurn + 60; 480 // warn our allies so that they can help if possible 481 if (!this.requested) 482 Engine.PostCommand(PlayerID, {"type": "attack-request", "source": PlayerID, "target": this.targetPlayer}); 483 } 469 484 470 485 var rallyPoint = this.rallyPoint; 471 486 var rallyIndex = gameState.ai.accessibility.getAccessValue(rallyPoint); -
binaries/data/mods/public/simulation/ai/petra/chatHelper.js
3 3 4 4 m.chatLaunchAttack = function(gameState, player) 5 5 { 6 var name = gameState.sharedScript.playersData[player].name;7 6 var proba = Math.random(); 8 7 if (proba < 0.5) 9 8 var message = "/team " + markForTranslation("I am launching an attack against %(name)s."); … … 10 9 else 11 10 var message = "/team " + markForTranslation("I have just sent an army against %(name)s."); 12 11 13 var chat = { "type": "aichat", "message": message, "translateMessage": true, "translateParameters": ["name"], "parameters": { "name": name } }; 12 var chat = { 13 "type": "aichat", 14 "message": message, 15 "translateMessage": true, 16 "translateParameters": ["name"], 17 "parameters": {"name": "_player_" + player} 18 }; 14 19 Engine.PostCommand(PlayerID, chat); 15 20 }; 16 21 22 m.chatAnswerRequestAttack = function(gameState, player, answer, other) 23 { 24 if (answer) 25 { 26 var proba = Math.random(); 27 if (proba < 0.5) 28 var message = "/team " + markForTranslation("Let me regroup my army and I am with you against %(name)s."); 29 else 30 var message = "/team " + markForTranslation("I am doing the final preparation and I will attack %(name)s."); 31 } 32 else 33 { 34 if (other !== undefined) 35 var message = "/team " + markForTranslation("I cannot help you against %(name)s for the time being, as I have another attack foreseen against %(other)s."); 36 else 37 var message = "/team " + markForTranslation("Sorry, I have not enough soldiers currently, but my next attack will target %(name)s."); 38 } 39 40 var chat = { 41 "type": "aichat", 42 "message": message, 43 "translateMessage": true, 44 "translateParameters": ["name"], 45 "parameters": {"name": "_player_" + player} 46 }; 47 if (other !== undefined) 48 { 49 chat.translateParameters.push("other"); 50 chat.parameters.other = "_player_" + other; 51 } 52 Engine.PostCommand(PlayerID, chat); 53 }; 54 17 55 m.chatSentTribute = function(gameState, player) 18 56 { 19 var name = gameState.sharedScript.playersData[player].name;20 57 var proba = Math.random(); 21 58 if (proba < 0.5) 22 59 var message = "/team " + markForTranslation("Here is a gift for %(name)s, make a good use of it."); … … 23 60 else 24 61 var message = "/team " + markForTranslation("I see you are in a bad situation %(name)s, I hope this will help."); 25 62 26 var chat = { "type": "aichat", "message": message, "translateMessage": true, "translateParameters": ["name"], "parameters": { "name": name } }; 63 var chat = { 64 "type": "aichat", 65 "message": message, 66 "translateMessage": true, 67 "translateParameters": ["name"], 68 "parameters": {"name": "_player_" + player} 69 }; 27 70 Engine.PostCommand(PlayerID, chat); 28 71 }; 29 72 … … 35 78 else 36 79 var message = "/team " + markForTranslation("I would participate more efficiently in our common war effort if you could provide me some %(resource)s."); 37 80 38 var chat = { "type": "aichat", "message": message, "translateMessage": true, "translateParameters": ["resource"], "parameters": { "resource": resource } }; 81 var chat = { 82 "type": "aichat", 83 "message": message, 84 "translateMessage": true, 85 "translateParameters": ["resource"], 86 "parameters": {"resource": resource} 87 }; 39 88 Engine.PostCommand(PlayerID, chat); 40 89 }; 41 90 42 91 m.chatNewTradeRoute = function(gameState, player) 43 92 { 44 var name = gameState.sharedScript.playersData[player].name;45 93 var proba = Math.random(); 46 94 if (proba < 0.5) 47 95 var message = "/team " + markForTranslation("I have set up a new route with %(name)s. Trading will be profitable for all of us."); … … 48 96 else 49 97 var message = "/team " + markForTranslation("A new trade route is set up with %(name)s. Take your share of the profits"); 50 98 51 var chat = { "type": "aichat", "message": message, "translateMessage": true, "translateParameters": ["name"], "parameters": { "name": name } }; 99 var chat = { 100 "type": "aichat", 101 "message": message, 102 "translateMessage": true, 103 "translateParameters": ["name"], 104 "parameters": {"name": "_player_" + player} 105 }; 52 106 Engine.PostCommand(PlayerID, chat); 53 107 }; 54 108 -
binaries/data/mods/public/simulation/components/AIInterface.js
17 17 "OwnershipChanged", 18 18 "Garrison", 19 19 "UnGarrison", 20 "TributeExchanged" 20 "TributeExchanged", 21 "AttackRequest" 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 "attack-request": function(player, cmd, data) 649 { 650 // Send a chat message to human players 651 var cmpGuiInterface = Engine.QueryInterface(SYSTEM_ENTITY, IID_GuiInterface); 652 if (cmpGuiInterface) 653 { 654 var notification = { 655 "type": "aichat", 656 "players": [player], 657 "message": "/team " + markForTranslation("Attack against %(target)s requested."), 658 "translateParameters": ["target"], 659 "parameters": {"target": "_player_" + cmd.target} 660 }; 661 cmpGuiInterface.PushNotification(notification); 662 } 663 // And send an attackRequest event to the AIs 664 let cmpAIInterface = Engine.QueryInterface(SYSTEM_ENTITY, IID_AIInterface); 665 if (cmpAIInterface) 666 cmpAIInterface.PushEvent("AttackRequest", cmd); 667 }, 668 647 669 "dialog-answer": function(player, cmd, data) 648 670 { 649 671 // Currently nothing. Triggers can read it anyway, and send this