Ticket #4431: petra_ally_requests_v0.2.patch
File petra_ally_requests_v0.2.patch, 9.8 KB (added by , 7 years ago) |
---|
-
binaries/data/mods/public/gui/session/messages.js
185 185 g_IsObserver, 186 186 187 187 "/msg": (senderID, addresseeGUID) => 188 addresseeGUID == Engine.GetPlayerGUID()188 addresseeGUID == (Engine.GetPlayerGUID() || "local") 189 189 }; 190 190 191 191 /** -
binaries/data/mods/public/simulation/ai/common-api/gamestate.js
146 146 return str.replace(/\{civ\}/g, this.playerData.civ); 147 147 }; 148 148 149 m.GameState.prototype.getPlayerCiv = function(player) 150 { 151 if (player === undefined) 152 return this.playerData.civ; 153 154 return this.sharedScript.playersData[player].civ; 155 } 156 149 157 m.GameState.prototype.civ = function() 150 158 { 151 return this. playerData.civ;159 return this.getPlayerCiv(); 152 160 }; 153 161 154 162 m.GameState.prototype.currentPhase = function() -
binaries/data/mods/public/simulation/ai/petra/chatHelper.js
1 1 var PETRA = function(m) 2 2 { 3 3 4 m.chatNewDiplomacyMessages = { 5 "enemy": [ 6 markForTranslation("%(_player_)s and I are now enemies.") 7 ], 8 "ally": [ 9 markForTranslation("%(_player_)s and I are now allies.") 10 ], 11 "neutral": [ 12 markForTranslation("%(_player_)s and I are now neutral.") 13 ] 14 }; 15 16 m.chatAnswerAllyRequestMessages = { 17 "decline": [ 18 markForTranslation("I cannot accept your offer to be allies %(_player_)s.") 19 ], 20 "declineRepeatedOffer": [ 21 markForTranslation("%(_player_)s, our previous alliance did not work out, so I must decline your offer.") 22 ], 23 "accept": [ 24 markForTranslation("I will accept your offer to become allies %(_player_)s. We will both benefit from this alliance.") 25 ], 26 "acceptWithTribute": [ 27 markForTranslation("I will ally with you %(_player_)s, but only if you send me a tribute of %(_amount_)s %(_resource_)s."), 28 markForTranslation("%(_player_)s, you must send me a tribute of %(_amount_)s %(_resource_)s for me to consider an alliance.") 29 ], 30 "waitingForTribute": [ 31 markForTranslation("%(_player_)s, my offer still stands. I will ally with you if you send me a tribute of %(_amount_)s %(_resource_)s.") 32 ] 33 }; 34 4 35 m.chatLaunchAttack = function(gameState, player, type) 5 36 { 6 37 let message; … … 128 159 }); 129 160 }; 130 161 131 m.chatNewDiplomacy = function(gameState, player, enemy)162 m.chatNewDiplomacy = function(gameState, player, newDiplomaticStance) 132 163 { 133 let message = enemy ?134 markForTranslation("%(_player_)s and I are now enemies.") :135 markForTranslation("%(_player_)s and I are now allies.");136 137 164 Engine.PostCommand(PlayerID, { 138 165 "type": "aichat", 139 "message": message,166 "message": API3.PickRandom(this.chatNewDiplomacyMessages[newDiplomaticStance]), 140 167 "translateMessage": true, 141 168 "translateParameters": ["_player_"], 142 "parameters": { "_player_": player}169 "parameters": { "_player_": player } 143 170 }); 144 171 }; 145 172 173 m.chatAnswerRequestAlly = function(gameState, player, response, requiredTribute) 174 { 175 Engine.PostCommand(PlayerID, { 176 "type": "aichat", 177 "message": "/msg " + gameState.sharedScript.playersData[player].name + " " + 178 API3.PickRandom(this.chatAnswerAllyRequestMessages[response]), 179 "translateMessage": true, 180 "translateParameters": requiredTribute ? ["_amount_", "_resource_", "_player_"] : ["_player_"], 181 "parameters": requiredTribute ? 182 {"_amount_": requiredTribute.wanted, "_resource_": requiredTribute.type, "_player_": player } : 183 { "_player_": player } 184 }); 185 }; 186 146 187 return m; 147 188 }(PETRA); -
binaries/data/mods/public/simulation/ai/petra/diplomacyManager.js
5 5 * Manage the diplomacy: 6 6 * update our cooperative trait 7 7 * sent tribute to allies 8 * decide which player to turn against in "Last Man Standing" mode 9 * respond to diplomacy requests 8 10 */ 9 11 12 /** 13 * If a player sends us an ally request, an Object in this.allyRequests will be created 14 * containing the request status, and the amount and type of the resource tribute (if any) 15 * that they must send in order for us to accept their request. 16 * f.e. { "status": 1, "type": "metal", "wanted": 1000 }. 17 * Status is -1 for decline, -2 for decline repeated request, 1 for waiting for tributes. 18 */ 10 19 m.DiplomacyManager = function(Config) 11 20 { 12 21 this.Config = Config; … … 15 24 this.nextTributeRequest.set("all", 240); 16 25 this.betrayLapseTime = -1; 17 26 this.waitingToBetray = false; 27 this.allyRequests = new Map(); 18 28 }; 19 29 20 30 /** … … 86 96 // or if our allies attack enemies inside our territory 87 97 for (let evt of events.TributeExchanged) 88 98 { 99 if (evt.to === PlayerID && !gameState.isPlayerAlly(evt.from) && this.allyRequests.has(evt.from)) 100 { 101 let request = this.allyRequests.get(evt.from); 102 if (request.status === -1 || request.status === -2) 103 continue; 104 105 request.wanted -= evt.amounts[request.type]; 106 107 if (request.wanted <= 0) 108 { 109 if (this.Config.debug > 1) 110 API3.warn("Player " + uneval(evt.from) + " has sent the required tribute amount"); 111 112 this.changePlayerDiplomacy(gameState, evt.from, "ally"); 113 // if this new ally turns on us later and requests to ally again, we will decline 114 request.status = -2; 115 } 116 } 117 89 118 if (evt.to !== PlayerID || !gameState.isPlayerAlly(evt.from)) 90 119 continue; 91 120 let tributes = 0; … … 114 143 115 144 if (events.DiplomacyChanged.length || events.PlayerDefeated.length || events.CeasefireEnded.length) 116 145 this.lastManStandingCheck(gameState); 146 147 if (gameState.getAlliedVictory()) 148 return; 149 150 for (let evt of events.DiplomacyChanged) 151 if (evt.otherPlayer === PlayerID && !gameState.isPlayerAlly(evt.player)) 152 if (gameState.sharedScript.playersData[evt.player].isAlly[PlayerID]) 153 this.handleAllyRequest(gameState, evt.player); 154 else if (this.allyRequests.has(evt.player)) // a player that had requested to be allies changed their stance with us 155 this.allyRequests.get(evt.player).status = -2; 117 156 }; 118 157 119 158 /** … … 181 220 } 182 221 183 222 if (playerToTurnAgainst) 184 { 185 Engine.PostCommand(PlayerID, { "type": "diplomacy", "player": playerToTurnAgainst, "to": "enemy" }); 186 if (this.Config.debug > 1) 187 API3.warn("player " + playerToTurnAgainst + " is now an enemy"); 188 if (this.Config.chat) 189 m.chatNewDiplomacy(gameState, playerToTurnAgainst, true); 190 } 223 this.changePlayerDiplomacy(gameState, playerToTurnAgainst, "enemy"); 191 224 this.betrayLapseTime = -1; 192 225 this.waitingToBetray = false; 193 226 }; 194 227 228 /** 229 * Do not become allies with a player if the game would be over. 230 * Overall, be reluctant to become allies with any one player; be more likely to 231 * demand a tribute if the requesting player is not as strong as us. 232 */ 233 m.DiplomacyManager.prototype.handleAllyRequest = function(gameState, player) 234 { 235 let response; 236 let requiredTribute; 237 let request = this.allyRequests.get(player); 238 239 // for any given ally request be likely to permanently decline 240 if (!request && gameState.getPlayerCiv() !== gameState.getPlayerCiv(player) && Math.random() > 0.4) 241 { 242 this.allyRequests.set(player, { "status": -1 }); 243 response = "decline"; 244 } 245 else if (request) 246 { 247 if (request.status === -1) 248 response = "decline"; 249 else if (request.status === -2) // we had become allies with this player and the alliance was broken, so decline 250 response = "declineRepeatedOffer"; 251 else if (request.wanted > 0) // already sent ally request, and has not yet sent the required tributes 252 { 253 response = "waitingForTribute"; 254 requiredTribute = request; 255 } 256 } 257 else if (gameState.getEnemies().length < 3 || gameState.ai.HQ.attackManager.currentEnemyPlayer === player) 258 { 259 response = "decline"; 260 this.allyRequests.set(player, { "status": -1 }); 261 } 262 else if (gameState.getEntities(player).length < gameState.getOwnEntities().length && Math.random() > 0.6) 263 { 264 // if this player has less entities than us, be less likely to demand a tribute 265 response = "accept"; 266 this.changePlayerDiplomacy(gameState, player, "ally"); 267 this.allyRequests.set(player, { "status": -2 }); 268 } 269 else 270 { 271 response = "acceptWithTribute"; 272 requiredTribute = gameState.ai.HQ.pickMostNeededResources(gameState)[0]; 273 requiredTribute.wanted = Math.max(1000, gameState.getOwnUnits().length * 10); 274 this.allyRequests.set(player, { 275 "status": 1, 276 "wanted": requiredTribute.wanted, 277 "type": requiredTribute.type, 278 }); 279 } 280 m.chatAnswerRequestAlly(gameState, player, response, requiredTribute); 281 }; 282 283 /** 284 * Change our diplomacy stance with a player, and send a chat message 285 */ 286 m.DiplomacyManager.prototype.changePlayerDiplomacy = function(gameState, player, newDiplomaticStance) 287 { 288 Engine.PostCommand(PlayerID, { "type": "diplomacy", "player": player, "to": newDiplomaticStance }); 289 if (this.Config.debug > 1) 290 API3.warn("diplomacy stance with player " + player + " is now " + newDiplomaticStance); 291 if (this.Config.chat) 292 m.chatNewDiplomacy(gameState, player, newDiplomaticStance); 293 }; 294 195 295 m.DiplomacyManager.prototype.update = function(gameState, events) 196 296 { 197 297 this.checkEvents(gameState, events); … … 209 309 "nextTributeUpdate": this.nextTributeUpdate, 210 310 "nextTributeRequest": this.nextTributeRequest, 211 311 "betrayLapseTime": this.betrayLapseTime, 212 "waitingToBetray": this.waitingToBetray 312 "waitingToBetray": this.waitingToBetray, 313 "allyRequests": this.allyRequests 213 314 }; 214 315 }; 215 316