Ticket #4431: 4431_petra_neutral_requests_v0.2.patch
File 4431_petra_neutral_requests_v0.2.patch, 16.1 KB (added by , 7 years ago) |
---|
-
binaries/data/mods/public/simulation/ai/petra/attackManager.js
455 455 return enemyPlayer; 456 456 }; 457 457 458 /** f.e. if we have changed diplomacy with another player. */ 459 m.AttackManager.prototype.cancelAttacksAgainstPlayer = function(player) 460 { 461 for (let attackType in this.upcomingAttacks) 462 for (let i = 0; i < this.upcomingAttacks[attackType].length; ++i) 463 if (this.upcomingAttacks[attackType][i].targetPlayer === player) 464 this.upcomingAttacks[attackType][i].targetPlayer = undefined; 465 466 for (let attackType in this.startedAttacks) 467 for (let i = 0; i < this.startedAttacks[attackType].length; ++i) 468 { 469 let attack = this.startedAttacks[attackType][i]; 470 if (attack.targetPlayer === player) 471 { 472 attack.Abort(gameState); 473 this.startedAttacks[attackType].splice(i--, 1); 474 } 475 } 476 }; 477 458 478 m.AttackManager.prototype.Serialize = function() 459 479 { 460 480 let properties = { -
binaries/data/mods/public/simulation/ai/petra/chatHelper.js
63 63 ] 64 64 }; 65 65 66 m.answerAllyRequestMessages = { 67 "decline": [ 68 markForTranslation("I cannot accept your offer to be allies %(_player_)s.") 69 ], 70 "declineSuggestNeutral": [ 71 markForTranslation("I will not ally with you %(_player_)s, but I will consider a neutrality pact.") 72 ], 73 "declineRepeatedOffer": [ 74 markForTranslation("%(_player_)s, our previous alliance did not work out, so I must decline your offer.") 75 ], 76 "accept": [ 77 markForTranslation("I will accept your offer to become allies %(_player_)s. We will both benefit from this alliance.") 78 ], 79 "acceptWithTribute": [ 80 markForTranslation("I will ally with you %(_player_)s, but only if you send me a tribute of %(_amount_)s %(_resource_)s."), 81 markForTranslation("%(_player_)s, you must send me a tribute of %(_amount_)s %(_resource_)s for me to accept an alliance.") 82 ], 83 "waitingForTribute": [ 84 markForTranslation("%(_player_)s, my offer still stands. I will ally with you if you send me a tribute of %(_amount_)s %(_resource_)s.") 85 ] 66 m.answerDiplomacyRequestMessages = { 67 "ally": { 68 "decline": [ 69 markForTranslation("I cannot accept your offer to be allies %(_player_)s.") 70 ], 71 "declineSuggestNeutral": [ 72 markForTranslation("I will not ally with you %(_player_)s, but I will consider a neutrality pact.") 73 ], 74 "declineRepeatedOffer": [ 75 markForTranslation("%(_player_)s, our previous alliance did not work out, so I must decline your offer.") 76 ], 77 "accept": [ 78 markForTranslation("I will accept your offer to become allies %(_player_)s. We will both benefit from this alliance.") 79 ], 80 "acceptWithTribute": [ 81 markForTranslation("I will ally with you %(_player_)s, but only if you send me a tribute of %(_amount_)s %(_resource_)s."), 82 markForTranslation("%(_player_)s, you must send me a tribute of %(_amount_)s %(_resource_)s for me to accept an alliance.") 83 ], 84 "waitingForTribute": [ 85 markForTranslation("%(_player_)s, my offer still stands. I will ally with you if you send me a tribute of %(_amount_)s %(_resource_)s."), 86 markForTranslation("%(_player_)s, if you do not send me part of the %(_amount_)s %(_resource_)s tribute soon, I will break off our negotiations.") 87 ] 88 }, 89 "neutral": { 90 "decline": [ 91 markForTranslation("I will not become neutral with you %(_player_)s."), 92 markForTranslation("%(_player_)s, I must decline your request for a neutrality pact.") 93 ], 94 "declineRepeatedOffer": [ 95 markForTranslation("Our previous neutrality agreement ended in failure %(_player_)s; I will not consider another one.") 96 ], 97 "accept": [ 98 markForTranslation("I welcome your request for peace between our civilizations %(_player_)s. I will accept."), 99 markForTranslation("%(_player_)s, I will accept your neutrality request. May both our civilizations benefit.") 100 ], 101 "acceptWithTribute": [ 102 markForTranslation("If you tribute me %(_amount_)s %(_resource_)s, I will accept your neutrality request %(_player_)s."), 103 markForTranslation("%(_player_)s, if you send me %(_amount_)s %(_resource_)s, I will accept a neutrality pact.") 104 ], 105 "waitingForTribute": [ 106 markForTranslation("%(_player_)s, I will not accept your neutrality request unless you tribute me %(_amount_)s %(_resource_)s soon."), 107 markForTranslation("%(_player_)s, if you do not send me part of the %(_amount_)s %(_resource_)s tribute soon, I will break off our negotiations.") 108 ] 109 } 86 110 }; 87 111 88 112 m.chatLaunchAttack = function(gameState, player, type) … … 162 186 }); 163 187 }; 164 188 165 m.chatAnswerRequest Ally = function(gameState, player, response, requiredTribute)189 m.chatAnswerRequestDiplomacy = function(gameState, player, requestType, response, requiredTribute) 166 190 { 167 191 Engine.PostCommand(PlayerID, { 168 192 "type": "aichat", 169 193 "message": "/msg " + gameState.sharedScript.playersData[player].name + " " + 170 pickRandom(this.answer AllyRequestMessages[response]),194 pickRandom(this.answerDiplomacyRequestMessages[requestType][response]), 171 195 "translateMessage": true, 172 196 "translateParameters": requiredTribute ? ["_amount_", "_resource_", "_player_"] : ["_player_"], 173 197 "parameters": requiredTribute ? -
binaries/data/mods/public/simulation/ai/petra/diplomacyManager.js
10 10 */ 11 11 12 12 /** 13 * If a player sends us an ally request, an Object in this.allyRequests will be created13 * If a player sends us an ally or neutral request, an Object in this.diplomacyRequests will be created 14 14 * that includes the request status, and the amount and type of the resource tribute (if any) 15 15 * that they must send in order for us to accept their request. 16 16 * In addition, a message will be sent if the player has not sent us a tribute within a minute. … … 24 24 this.nextTributeRequest.set("all", 240); 25 25 this.betrayLapseTime = -1; 26 26 this.waitingToBetray = false; 27 this. allyRequests = new Map();27 this.diplomacyRequests = new Map(); 28 28 }; 29 29 30 30 /** 31 * If there are any players that are allied with us but we are not alliedwith them,32 * treat this situation like an ally request.31 * If there are any players that are allied/neutral with us but we are not allied/neutral with them, 32 * treat this situation like an ally/neutral request. 33 33 */ 34 34 m.DiplomacyManager.prototype.init = function(gameState) 35 35 { 36 if (!gameState.getAlliedVictory() && !gameState.isCeasefireActive()) 37 this.lastManStandingCheck(gameState); 38 36 39 for (let i = 1; i < gameState.sharedScript.playersData.length; ++i) 37 40 { 38 41 if (i === PlayerID) … … 39 42 continue; 40 43 41 44 if (gameState.isPlayerMutualAlly(i)) 42 this. allyRequests.set(i, {"status": "accepted" });45 this.diplomacyRequests.set(i, { "requestType": "ally", "status": "accepted" }); 43 46 else if (gameState.sharedScript.playersData[i].isAlly[PlayerID]) 44 this.handleAllyRequest(gameState, i); 47 this.handleDiplomacyRequest(gameState, i, "ally"); 48 else if (gameState.sharedScript.playersData[i].isNeutral[PlayerID] && gameState.isPlayerEnemy(i)) 49 this.handleDiplomacyRequest(gameState, i, "neutral"); 45 50 } 46 51 }; 47 52 … … 114 119 // or if our allies attack enemies inside our territory 115 120 for (let evt of events.TributeExchanged) 116 121 { 117 if (evt.to === PlayerID && !gameState.isPlayerAlly(evt.from) && this. allyRequests.has(evt.from))122 if (evt.to === PlayerID && !gameState.isPlayerAlly(evt.from) && this.diplomacyRequests.has(evt.from)) 118 123 { 119 let request = this. allyRequests.get(evt.from);124 let request = this.diplomacyRequests.get(evt.from); 120 125 if (request.status === "waitingForTribute") 121 126 { 122 127 request.wanted -= evt.amounts[request.type]; … … 126 131 if (this.Config.debug > 1) 127 132 API3.warn("Player " + uneval(evt.from) + " has sent the required tribute amount"); 128 133 129 this.changePlayerDiplomacy(gameState, evt.from, "ally");134 this.changePlayerDiplomacy(gameState, evt.from, request.requestType); 130 135 request.status = "accepted"; 131 136 } 132 else 137 else if (evt.amounts[request.type] > 0) 133 138 { 134 139 // Reset the warning sent to the player that reminds them to speed up the tributes 135 140 request.warnTime = gameState.ai.elapsedTime + 60; … … 172 177 if (evt.otherPlayer !== PlayerID) 173 178 continue; 174 179 175 if (this. allyRequests.has(evt.player) && !gameState.sharedScript.playersData[evt.player].isAlly[PlayerID])180 if (this.diplomacyRequests.has(evt.player) && !gameState.sharedScript.playersData[evt.player].isAlly[PlayerID]) 176 181 { 177 182 // a player that had requested to be allies changed their stance with us 178 let request = this. allyRequests.get(evt.player);183 let request = this.diplomacyRequests.get(evt.player); 179 184 if (request.status === "accepted") 180 185 request.status = "allianceBroken"; 181 186 else if (request.status !== "allianceBroken") … … 182 187 request.status = "declinedRequest"; 183 188 } 184 189 else if (gameState.sharedScript.playersData[evt.player].isAlly[PlayerID] && gameState.isPlayerEnemy(evt.player)) 185 m.chatAnswerRequest Ally(gameState, evt.player, "declineSuggestNeutral");190 m.chatAnswerRequestDiplomacy(gameState, evt.player, "ally", "declineSuggestNeutral"); 186 191 else if (gameState.sharedScript.playersData[evt.player].isAlly[PlayerID] && gameState.isPlayerNeutral(evt.player)) 187 this.handleAllyRequest(gameState, evt.player); 192 this.handleDiplomacyRequest(gameState, evt.player, "ally"); 193 else if (gameState.sharedScript.playersData[evt.player].isNeutral[PlayerID] && gameState.isPlayerEnemy(evt.player)) 194 this.handleDiplomacyRequest(gameState, evt.player, "neutral"); 188 195 } 189 196 }; 190 197 191 198 /** 192 * Check the diplomacy at the start of the game193 */194 m.DiplomacyManager.prototype.diplomacyCheck = function(gameState)195 {196 if (!gameState.getAlliedVictory() && !gameState.isCeasefireActive())197 this.lastManStandingCheck(gameState);198 };199 200 /**201 199 * If the "Last Man Standing" option is enabled, check if the only remaining players are allies or neutral. 202 200 * If so, turn against the strongest first, but be more likely to first turn against neutral players, if there are any. 203 201 */ … … 253 251 } 254 252 255 253 if (playerToTurnAgainst) 254 { 256 255 this.changePlayerDiplomacy(gameState, playerToTurnAgainst, "enemy"); 256 let request = this.diplomacyRequests.get(playerToTurnAgainst); 257 if (request && request.status !== "allianceBroken") 258 { 259 if (request.status === "waitingForTribute") 260 m.chatAnswerRequestDiplomacy(gameState, player, request.requestType, "decline"); 261 request.status = request.status === "accepted" ? "allianceBroken" : "declinedRequest"; 262 } 263 } 257 264 this.betrayLapseTime = -1; 258 265 this.waitingToBetray = false; 259 266 }; … … 260 267 261 268 /** 262 269 * Do not become allies with a player if the game would be over. 263 * Overall, be reluctant to become allies with any one player .270 * Overall, be reluctant to become allies with any one player, but be more likely to accept neutral requests. 264 271 */ 265 m.DiplomacyManager.prototype.handle AllyRequest = function(gameState, player)272 m.DiplomacyManager.prototype.handleDiplomacyRequest = function(gameState, player, requestType) 266 273 { 267 274 let response; 268 275 let requiredTribute; 269 let request = this.allyRequests.get(player); 276 let request = this.diplomacyRequests.get(player); 277 let moreEnemiesThanAllies = gameState.getEnemies().length > gameState.getMutualAllies().length; 270 278 271 // For any given ally request be likely to permanently decline279 // For any given diplomacy request be likely to permanently decline 272 280 if (!request && gameState.getPlayerCiv() !== gameState.getPlayerCiv(player) && Math.random() > 0.4 || 273 gameState.getEnemies().length < gameState.getMutualAllies().length || 274 gameState.ai.HQ.attackManager.currentEnemyPlayer === player) 281 !moreEnemiesThanAllies || gameState.ai.HQ.attackManager.currentEnemyPlayer === player) 275 282 { 276 this. allyRequests.set(player, {"status": "declinedRequest" });283 this.diplomacyRequests.set(player, { "requestType": requestType, "status": "declinedRequest" }); 277 284 response = "decline"; 278 285 } 279 else if (request )286 else if (request && request.status !== "accepted" && request.requestType !== "ally") 280 287 { 281 288 if (request.status === "declinedRequest") 282 289 response = "decline"; … … 288 295 requiredTribute = request; 289 296 } 290 297 } 291 else if (gameState.getEntities(player).length < gameState.getOwnEntities().length && Math.random() > 0.6) 298 else if (requestType === "ally" && gameState.getEntities(player).length < gameState.getOwnEntities().length && 299 Math.random() > 0.6 || requestType === "neutral" && moreEnemiesThanAllies && Math.random() > 0.2) 292 300 { 293 301 response = "accept"; 294 this.changePlayerDiplomacy(gameState, player, "ally");295 this. allyRequests.set(player, {"status": "accepted" });302 this.changePlayerDiplomacy(gameState, player, requestType); 303 this.diplomacyRequests.set(player, { "requestType": requestType, "status": "accepted" }); 296 304 } 297 305 else 298 306 { 299 307 response = "acceptWithTribute"; 300 308 requiredTribute = gameState.ai.HQ.pickMostNeededResources(gameState)[0]; 301 requiredTribute.wanted = Math.max(1000, gameState.getOwnUnits().length * 10);302 this. allyRequests.set(player, {309 requiredTribute.wanted = Math.max(1000, gameState.getOwnUnits().length * requestType === "ally" ? 10 : 5) 310 this.diplomacyRequests.set(player, { 303 311 "status": "waitingForTribute", 304 312 "wanted": requiredTribute.wanted, 305 313 "type": requiredTribute.type, 306 314 "warnTime": gameState.ai.elapsedTime + 60, 307 "sentWarning": false 315 "sentWarning": false, 316 "requestType": requestType 308 317 }); 309 318 } 310 m.chatAnswerRequest Ally(gameState, player, response, requiredTribute);319 m.chatAnswerRequestDiplomacy(gameState, player, requestType, response, requiredTribute); 311 320 }; 312 321 313 322 m.DiplomacyManager.prototype.changePlayerDiplomacy = function(gameState, player, newDiplomaticStance) 314 323 { 324 if (gameState.isPlayerEnemy(player) && (newDiplomaticStance === "ally" || newDiplomaticStance === "neutral")) 325 gameState.ai.HQ.attackManager.cancelAttacksAgainstPlayer(player); 315 326 Engine.PostCommand(PlayerID, { "type": "diplomacy", "player": player, "to": newDiplomaticStance }); 316 327 if (this.Config.debug > 1) 317 328 API3.warn("diplomacy stance with player " + player + " is now " + newDiplomaticStance); … … 321 332 322 333 m.DiplomacyManager.prototype.checkRequestedTributes = function(gameState) 323 334 { 324 for (let [player, data] of this. allyRequests.entries())335 for (let [player, data] of this.diplomacyRequests) 325 336 if (data.status === "waitingForTribute" && gameState.ai.elapsedTime > data.warnTime) 326 337 { 327 338 if (data.sentWarning) 328 339 { 329 this. allyRequests.delete(player);330 m.chatAnswerRequest Ally(gameState, player, "decline");340 this.diplomacyRequests.delete(player); 341 m.chatAnswerRequestDiplomacy(gameState, player, data.requestType, "decline"); 331 342 } 332 343 else 333 344 { 334 345 data.sentWarning = true; 335 346 data.warnTime = gameState.ai.elapsedTime + 60; 336 m.chatAnswerRequest Ally(gameState, player, "waitingForTribute", {347 m.chatAnswerRequestDiplomacy(gameState, player, data.requestType, "waitingForTribute", { 337 348 "wanted": data.wanted, 338 349 "type": data.type 339 350 }); … … 361 372 "nextTributeRequest": this.nextTributeRequest, 362 373 "betrayLapseTime": this.betrayLapseTime, 363 374 "waitingToBetray": this.waitingToBetray, 364 " allyRequests": this.allyRequests375 "diplomacyRequests": this.diplomacyRequests 365 376 }; 366 377 }; 367 378 -
binaries/data/mods/public/simulation/ai/petra/startingStrategy.js
55 55 // configure our first base strategy 56 56 if (this.baseManagers.length > 1) 57 57 this.configFirstBase(gameState); 58 59 this.diplomacyManager.diplomacyCheck(gameState);60 58 }; 61 59 62 60 /**