Ticket #4431: petra_ally_requests_v0.1.patch
File petra_ally_requests_v0.1.patch, 9.3 KB (added by , 7 years ago) |
---|
-
binaries/data/mods/public/gui/session/messages.js
175 175 g_IsObserver, 176 176 177 177 "/msg": (senderID, addresseeGUID) => 178 addresseeGUID == Engine.GetPlayerGUID()178 addresseeGUID == (Engine.GetPlayerGUID() || "local") 179 179 }; 180 180 181 181 /** -
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.civ = function( )149 m.GameState.prototype.civ = function(player) 150 150 { 151 return this.playerData.civ; 151 if (player === undefined) 152 return this.playerData.civ; 153 154 return this.sharedScript.playersData[player].civ; 152 155 }; 153 156 154 157 m.GameState.prototype.currentPhase = function() -
binaries/data/mods/public/simulation/ai/petra/chatHelper.js
128 128 }); 129 129 }; 130 130 131 m.chatNewDiplomacy = function(gameState, player, enemy)131 m.chatNewDiplomacy = function(gameState, player, newStance) 132 132 { 133 let message = enemy ? 134 markForTranslation("%(_player_)s and I are now enemies.") : 135 markForTranslation("%(_player_)s and I are now allies."); 133 let message; 134 if (newStance === "enemy") 135 message = markForTranslation("%(_player_)s and I are now enemies."); 136 else if (newStance === "ally") 137 message = markForTranslation("%(_player_)s and I are now allies."); 138 else if (newStance === "neutral") 139 message = markForTranslation("%(_player_)s and I are now neutral."); 136 140 137 141 Engine.PostCommand(PlayerID, { 138 142 "type": "aichat", … … 143 147 }); 144 148 }; 145 149 150 m.chatAnswerRequestAlly = function(gameState, player, response, requiredTribute) 151 { 152 let message; 153 if (response === 0) 154 message = markForTranslation("I cannot accept your offer to be allies %(_player_)s."); 155 else if (response === 1) 156 message = markForTranslation("%(_player_)s, our previous alliance did not work out, so I must decline your offer."); 157 else if (response === 2) 158 message = markForTranslation("I will accept your offer to become allies %(_player_)s. We will both benefit from this alliance"); 159 else if (response === 3) 160 { 161 let proba = Math.random(); 162 if (proba < 0.5) 163 message = markForTranslation("I will ally with you %(_player_)s, but only if you send me a tribute of %(_amount_)s %(_resource_)s."); 164 else 165 message = markForTranslation("%(_player_)s, you must send me a tribute of %(_amount_)s %(_resource_)s for me to consider an alliance"); 166 } 167 else if (response === 4) 168 message = markForTranslation("%(_player_)s, my offer still stands. I will ally with you if you send me a tribute of %(_amount_)s %(_resource_)s."); 169 170 let chat = { 171 "type": "aichat", 172 "message": "/msg " + gameState.sharedScript.playersData[player].name + " " + message, 173 "translateMessage": true, 174 "translateParameters": ["_player_"], 175 "parameters": {"_player_": player} 176 }; 177 if (response >= 3) 178 { 179 chat.translateParameters.push("_amount_"); 180 chat.translateParameters.push("_resource_"); 181 chat.parameters._amount_ = requiredTribute.wanted; 182 chat.parameters._resource_ = requiredTribute.type; 183 } 184 Engine.PostCommand(PlayerID, chat); 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 10 12 m.DiplomacyManager = function(Config) … … 15 17 this.nextTributeRequest.set("all", 240); 16 18 this.betrayLapseTime = -1; 17 19 this.waitingToBetray = false; 20 this.allyRequests = new Map(); 21 this.allyLapseTime = -1; 18 22 }; 19 23 20 24 /** … … 86 90 // or if our allies attack enemies inside our territory 87 91 for (let evt of events.TributeExchanged) 88 92 { 93 if (evt.to === PlayerID && !gameState.isPlayerAlly(evt.from) && this.allyRequests.has(evt.from)) 94 { 95 let newAllyData = this.allyRequests.get(evt.from); 96 if (newAllyData === -1 || newAllyData === -2) 97 continue; 98 99 newAllyData.wanted -= evt.amounts[newAllyData.type]; 100 101 if (newAllyData.wanted <= 0) 102 { 103 if (this.Config.debug > 1) 104 API3.warn("Player " + uneval(evt.from) + " has sent all requested tributes"); 105 if (gameState.sharedScript.playersData[evt.from].isAlly[PlayerID]) 106 { 107 this.changePlayerDiplomacy(gameState, evt.from, "ally"); 108 // if this new ally turns on us later and requests to ally again, we will decline 109 this.allyRequests.set(evt.from, -2); 110 } 111 else 112 this.allyRequests.set(evt.from, -1); 113 this.allyLapseTime = gameState.ai.elapsedTime + 120; 114 } 115 } 116 89 117 if (evt.to !== PlayerID || !gameState.isPlayerAlly(evt.from)) 90 118 continue; 91 119 let tributes = 0; … … 114 142 115 143 if (events.DiplomacyChanged.length || events.PlayerDefeated.length || events.CeasefireEnded.length) 116 144 this.lastManStandingCheck(gameState); 145 146 for (let evt of events.DiplomacyChanged) 147 if (evt.otherPlayer === PlayerID && !gameState.isPlayerAlly(evt.player) && 148 gameState.sharedScript.playersData[evt.player].isAlly[PlayerID]) 149 this.handleAllyRequest(gameState, evt.player); 117 150 }; 118 151 119 152 /** … … 181 214 } 182 215 183 216 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 } 217 this.changePlayerDiplomacy(gameState, playerToTurnAgainst, "enemy"); 191 218 this.betrayLapseTime = -1; 192 219 this.waitingToBetray = false; 193 220 }; 194 221 222 /** 223 * Do not become allies with a player if the game would be over, or if we recently became allies with another player 224 * Overall, be reluctant to become allies with any one player, but accept if the player has more entites than us 225 * Demand a tribute if the requesting player is not as strong as us. 226 */ 227 m.DiplomacyManager.prototype.handleAllyRequest = function(gameState, player) 228 { 229 // 0 for decline, 1 for decline (already tried being allies), 2 for accept, 3 for demand tribute, 4 for waiting for required tributes 230 let response = 0; 231 let requiredTribute; 232 let newAllyData = this.allyRequests.get(player); 233 234 // for any given ally request be likely to permanently decline 235 if (gameState.ai.elapsedTime < this.allyLapseTime || newAllyData === undefined && 236 gameState.civ() !== gameState.civ(player) && Math.random() > 0.4) 237 { 238 this.allyRequests.set(player, -1); 239 response = 0; 240 } 241 else if (newAllyData !== undefined) 242 { 243 if (newAllyData === -1) 244 response = 0; 245 else if (newAllyData === -2) // we had become allies with this player and the alliance was broken, so decline 246 response = 1; 247 else if (newAllyData !== -1 && newAllyData !== -2 && 248 newAllyData.wanted >= 0) // already sent ally request, and has not yet sent the required tributes 249 { 250 response = 4; 251 requiredTribute = newAllyData; 252 } 253 } 254 else if (gameState.getEnemies().length < 3 || gameState.ai.HQ.attackManager.currentEnemyPlayer === player) 255 response = 0; 256 else if (gameState.getEntities(player).length < gameState.getOwnEntities().length) 257 { 258 response = 3; 259 requiredTribute = gameState.ai.HQ.pickMostNeededResources(gameState)[0]; 260 requiredTribute.wanted = Math.max(1000, gameState.getOwnUnits().length * 10); 261 this.allyRequests.set(player, requiredTribute); 262 } 263 else // a stronger player wants to ally with us 264 { 265 response = 2; 266 this.changePlayerDiplomacy(gameState, player, "ally"); 267 this.allyRequests.set(player, -2); 268 this.allyLapseTime = gameState.ai.elapsedTime + 120; 269 } 270 m.chatAnswerRequestAlly(gameState, player, response, requiredTribute); 271 }; 272 273 /** 274 * Change the diplomacy stance with a player, and send a chat message 275 */ 276 m.DiplomacyManager.prototype.changePlayerDiplomacy = function(gameState, player, newStance) 277 { 278 Engine.PostCommand(PlayerID, { "type": "diplomacy", "player": player, "to": newStance }); 279 if (this.Config.debug > 1) 280 API3.warn("diplomacy stance with player " + player + " is now " + newStance); 281 if (this.Config.chat) 282 m.chatNewDiplomacy(gameState, player, newStance); 283 }; 284 195 285 m.DiplomacyManager.prototype.update = function(gameState, events) 196 286 { 197 287 this.checkEvents(gameState, events); … … 209 299 "nextTributeUpdate": this.nextTributeUpdate, 210 300 "nextTributeRequest": this.nextTributeRequest, 211 301 "betrayLapseTime": this.betrayLapseTime, 212 "waitingToBetray": this.waitingToBetray 302 "waitingToBetray": this.waitingToBetray, 303 "allyRequests": this.allyRequests, 304 "allyLapseTime": this.allyLapseTime 213 305 }; 214 306 }; 215 307