Ticket #4431: 4431_petra_neutral_requests_v0.1.patch
File 4431_petra_neutral_requests_v0.1.patch, 13.7 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 { 464 let attack = this.upcomingAttacks[attackType][i]; 465 if (attack.targetPlayer === player) 466 { 467 attack.Abort(gameState); 468 this.upcomingAttacks[attackType].splice(i--, 1); 469 } 470 } 471 472 for (let attackType in this.startedAttacks) 473 for (let i = 0; i < this.startedAttacks[attackType].length; ++i) 474 { 475 let attack = this.startedAttacks[attackType][i]; 476 if (attack.targetPlayer === player) 477 { 478 attack.Abort(gameState); 479 this.startedAttacks[attackType].splice(i--, 1); 480 } 481 } 482 }; 483 458 484 m.AttackManager.prototype.Serialize = function() 459 485 { 460 486 let properties = { -
binaries/data/mods/public/simulation/ai/petra/chatHelper.js
81 81 markForTranslation("%(_player_)s, you must send me a tribute of %(_amount_)s %(_resource_)s for me to accept an alliance.") 82 82 ], 83 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.") 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 markForTranslation("%(_player_)s, if you do not send me part of the %(_amount_)s %(_resource_)s tribute soon, I will break off our negotiations.") 85 86 ] 86 87 }; 87 88 89 m.answerNeutralRequestMessages = { 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 }; 110 88 111 m.chatLaunchAttack = function(gameState, player, type) 89 112 { 90 113 Engine.PostCommand(PlayerID, { … … 162 185 }); 163 186 }; 164 187 165 m.chatAnswerRequest Ally = function(gameState, player, response, requiredTribute)188 m.chatAnswerRequestDiplomacy = function(gameState, player, response, requestType, requiredTribute) 166 189 { 167 190 Engine.PostCommand(PlayerID, { 168 191 "type": "aichat", 169 192 "message": "/msg " + gameState.sharedScript.playersData[player].name + " " + 170 pickRandom( this.answerAllyRequestMessages[response]),193 pickRandom(requestType === "ally" ? this.answerAllyRequestMessages[response] : this.answerNeutralRequestMessages[response]), 171 194 "translateMessage": true, 172 195 "translateParameters": requiredTribute ? ["_amount_", "_resource_", "_player_"] : ["_player_"], 173 196 "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 /** … … 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.handle AllyRequest(gameState, i);47 this.handleDiplomacyRequest(gameState, i, "ally"); 45 48 } 46 49 }; 47 50 … … 114 117 // or if our allies attack enemies inside our territory 115 118 for (let evt of events.TributeExchanged) 116 119 { 117 if (evt.to === PlayerID && !gameState.isPlayerAlly(evt.from) && this. allyRequests.has(evt.from))120 if (evt.to === PlayerID && !gameState.isPlayerAlly(evt.from) && this.diplomacyRequests.has(evt.from)) 118 121 { 119 let request = this. allyRequests.get(evt.from);122 let request = this.diplomacyRequests.get(evt.from); 120 123 if (request.status === "waitingForTribute") 121 124 { 122 125 request.wanted -= evt.amounts[request.type]; … … 126 129 if (this.Config.debug > 1) 127 130 API3.warn("Player " + uneval(evt.from) + " has sent the required tribute amount"); 128 131 129 this.changePlayerDiplomacy(gameState, evt.from, "ally");132 this.changePlayerDiplomacy(gameState, evt.from, request.requestType); 130 133 request.status = "accepted"; 131 134 } 132 135 else … … 172 175 if (evt.otherPlayer !== PlayerID) 173 176 continue; 174 177 175 if (this. allyRequests.has(evt.player) && !gameState.sharedScript.playersData[evt.player].isAlly[PlayerID])178 if (this.diplomacyRequests.has(evt.player) && !gameState.sharedScript.playersData[evt.player].isAlly[PlayerID]) 176 179 { 177 180 // a player that had requested to be allies changed their stance with us 178 let request = this. allyRequests.get(evt.player);181 let request = this.diplomacyRequests.get(evt.player); 179 182 if (request.status === "accepted") 180 183 request.status = "allianceBroken"; 181 184 else if (request.status !== "allianceBroken") … … 182 185 request.status = "declinedRequest"; 183 186 } 184 187 else if (gameState.sharedScript.playersData[evt.player].isAlly[PlayerID] && gameState.isPlayerEnemy(evt.player)) 185 m.chatAnswerRequest Ally(gameState, evt.player, "declineSuggestNeutral");188 m.chatAnswerRequestDiplomacy(gameState, evt.player, "declineSuggestNeutral", "ally"); 186 189 else if (gameState.sharedScript.playersData[evt.player].isAlly[PlayerID] && gameState.isPlayerNeutral(evt.player)) 187 this.handleAllyRequest(gameState, evt.player); 190 this.handleDiplomacyRequest(gameState, evt.player, "ally"); 191 else if (gameState.sharedScript.playersData[evt.player].isNeutral[PlayerID] && gameState.isPlayerEnemy(evt.player)) 192 this.handleDiplomacyRequest(gameState, evt.player, "neutral"); 188 193 } 189 194 }; 190 195 191 196 /** 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 197 * If the "Last Man Standing" option is enabled, check if the only remaining players are allies or neutral. 202 198 * If so, turn against the strongest first, but be more likely to first turn against neutral players, if there are any. 203 199 */ … … 253 249 } 254 250 255 251 if (playerToTurnAgainst) 252 { 256 253 this.changePlayerDiplomacy(gameState, playerToTurnAgainst, "enemy"); 254 let request = this.diplomacyRequests.get(playerToTurnAgainst); 255 if (request && request.status !== "allianceBroken") 256 { 257 if (request.status === "waitingForTribute") 258 m.chatAnswerRequestDiplomacy(gameState, player, "decline", request.requestType); 259 request.status = request.status === "accepted" ? "allianceBroken" : "declinedRequest"; 260 } 261 } 257 262 this.betrayLapseTime = -1; 258 263 this.waitingToBetray = false; 259 264 }; … … 260 265 261 266 /** 262 267 * Do not become allies with a player if the game would be over. 263 * Overall, be reluctant to become allies with any one player .268 * Overall, be reluctant to become allies with any one player, but be more likely to accept neutral requests. 264 269 */ 265 m.DiplomacyManager.prototype.handle AllyRequest = function(gameState, player)270 m.DiplomacyManager.prototype.handleDiplomacyRequest = function(gameState, player, requestType) 266 271 { 267 272 let response; 268 273 let requiredTribute; 269 let request = this. allyRequests.get(player);274 let request = this.diplomacyRequests.get(player); 270 275 271 // For any given ally request be likely to permanently decline276 // For any given diplomacy request be likely to permanently decline 272 277 if (!request && gameState.getPlayerCiv() !== gameState.getPlayerCiv(player) && Math.random() > 0.4 || 273 278 gameState.getEnemies().length < gameState.getMutualAllies().length || 274 279 gameState.ai.HQ.attackManager.currentEnemyPlayer === player) 275 280 { 276 this. allyRequests.set(player, {"status": "declinedRequest" });281 this.diplomacyRequests.set(player, { "requestType": requestType, "status": "declinedRequest" }); 277 282 response = "decline"; 278 283 } 279 else if (request )284 else if (request && request.status !== "accepted" && request.requestType !== "ally") 280 285 { 281 286 if (request.status === "declinedRequest") 282 287 response = "decline"; … … 288 293 requiredTribute = request; 289 294 } 290 295 } 291 else if ( gameState.getEntities(player).length < gameState.getOwnEntities().length && Math.random() > 0.6)296 else if (requestType === "ally" && gameState.getEntities(player).length < gameState.getOwnEntities().length && Math.random() > 0.6) 292 297 { 293 298 response = "accept"; 294 this.changePlayerDiplomacy(gameState, player, "ally");295 this. allyRequests.set(player, {"status": "accepted" });299 this.changePlayerDiplomacy(gameState, player, requestType); 300 this.diplomacyRequests.set(player, { "requestType": requestType, "status": "accepted" }); 296 301 } 297 302 else 298 303 { 299 304 response = "acceptWithTribute"; 300 305 requiredTribute = gameState.ai.HQ.pickMostNeededResources(gameState)[0]; 301 requiredTribute.wanted = Math.max(1000, gameState.getOwnUnits().length * 10);302 this. allyRequests.set(player, {306 requiredTribute.wanted = Math.max(1000, gameState.getOwnUnits().length * requestType === "ally" ? 10 : 5) 307 this.diplomacyRequests.set(player, { 303 308 "status": "waitingForTribute", 304 309 "wanted": requiredTribute.wanted, 305 310 "type": requiredTribute.type, 306 311 "warnTime": gameState.ai.elapsedTime + 60, 307 "sentWarning": false 312 "sentWarning": false, 313 "requestType": requestType 308 314 }); 309 315 } 310 m.chatAnswerRequest Ally(gameState, player, response, requiredTribute);316 m.chatAnswerRequestDiplomacy(gameState, player, response, requestType, requiredTribute); 311 317 }; 312 318 313 319 m.DiplomacyManager.prototype.changePlayerDiplomacy = function(gameState, player, newDiplomaticStance) 314 320 { 321 if (gameState.isPlayerEnemy(player) && (newDiplomaticStance === "ally" || newDiplomaticStance === "neutral")) 322 gameState.ai.HQ.attackManager.cancelAttacksAgainstPlayer(player); 315 323 Engine.PostCommand(PlayerID, { "type": "diplomacy", "player": player, "to": newDiplomaticStance }); 316 324 if (this.Config.debug > 1) 317 325 API3.warn("diplomacy stance with player " + player + " is now " + newDiplomaticStance); … … 321 329 322 330 m.DiplomacyManager.prototype.checkRequestedTributes = function(gameState) 323 331 { 324 for (let [player, data] of this. allyRequests.entries())332 for (let [player, data] of this.diplomacyRequests.entries()) 325 333 if (data.status === "waitingForTribute" && gameState.ai.elapsedTime > data.warnTime) 326 334 { 327 335 if (data.sentWarning) 328 336 { 329 this. allyRequests.delete(player);330 m.chatAnswerRequest Ally(gameState, player, "decline");337 this.diplomacyRequests.delete(player); 338 m.chatAnswerRequestDiplomacy(gameState, player, "decline", data.requestType); 331 339 } 332 340 else 333 341 { 334 342 data.sentWarning = true; 335 343 data.warnTime = gameState.ai.elapsedTime + 60; 336 m.chatAnswerRequest Ally(gameState, player, "waitingForTribute", {344 m.chatAnswerRequestDiplomacy(gameState, player, data.requestType, "waitingForTribute", { 337 345 "wanted": data.wanted, 338 346 "type": data.type 339 347 }); … … 361 369 "nextTributeRequest": this.nextTributeRequest, 362 370 "betrayLapseTime": this.betrayLapseTime, 363 371 "waitingToBetray": this.waitingToBetray, 364 " allyRequests": this.allyRequests372 "diplomacyRequests": this.diplomacyRequests 365 373 }; 366 374 }; 367 375 -
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 /**