Implement emergency recognition for PetraAI.
First patch for an emergency mode. This implements a rudimentary detection strategy. The current effect is a shout-out for help. Patch by: @JCWasmx86 Differential revision: https://code.wildfiregames.com/D4645 Refs. #2195 This was SVN commit r27141.
This commit is contained in:
parent
4e52613ca2
commit
a315f90980
@ -132,6 +132,15 @@ PETRA.sendDiplomacyRequestMessages = {
|
||||
}
|
||||
};
|
||||
|
||||
PETRA.emergencyMessages = {
|
||||
"enter": [
|
||||
markForTranslation("My armies failed while defending my empire. Please honor our alliance and send help!")
|
||||
],
|
||||
"exit": [
|
||||
markForTranslation("My empire regained its old strength, now it is time to seek revenge together!")
|
||||
]
|
||||
};
|
||||
|
||||
PETRA.chatLaunchAttack = function(gameState, player, type)
|
||||
{
|
||||
Engine.PostCommand(PlayerID, {
|
||||
@ -234,3 +243,12 @@ PETRA.chatNewRequestDiplomacy = function(gameState, player, requestType, status)
|
||||
"parameters": { "_player_": player }
|
||||
});
|
||||
};
|
||||
|
||||
PETRA.chatEmergency = function(gameState, enable)
|
||||
{
|
||||
Engine.PostCommand(PlayerID, {
|
||||
"type": "aichat",
|
||||
"message": "/allies " + pickRandom(this.emergencyMessages[enable ? "enter" : "exit"]),
|
||||
"translateMessage": true
|
||||
});
|
||||
};
|
||||
|
@ -175,6 +175,33 @@ PETRA.Config = function(difficulty = PETRA.DIFFICULTY_MEDIUM, behavior)
|
||||
"Market/InternationalBonus",
|
||||
"Player/sharedDropsites"
|
||||
];
|
||||
|
||||
this.criticalPopulationFactors = [
|
||||
0.8,
|
||||
0.8,
|
||||
0.7,
|
||||
0.6,
|
||||
0.5,
|
||||
0.35
|
||||
];
|
||||
|
||||
this.criticalStructureFactors = [
|
||||
0.8,
|
||||
0.8,
|
||||
0.7,
|
||||
0.6,
|
||||
0.5,
|
||||
0.35
|
||||
];
|
||||
|
||||
this.criticalRootFactors = [
|
||||
0.8,
|
||||
0.8,
|
||||
0.67,
|
||||
0.5,
|
||||
0.35,
|
||||
0.2
|
||||
];
|
||||
};
|
||||
|
||||
PETRA.Config.prototype.setConfig = function(gameState)
|
||||
@ -287,6 +314,12 @@ PETRA.Config.prototype.setConfig = function(gameState)
|
||||
if (this.difficulty < PETRA.DIFFICULTY_EASY)
|
||||
this.Economy.workPhase3 = Infinity; // prevent the phasing to city phase
|
||||
|
||||
this.emergencyValues = {
|
||||
"population": this.criticalPopulationFactors[this.difficulty],
|
||||
"structures": this.criticalStructureFactors[this.difficulty],
|
||||
"roots": this.criticalRootFactors[this.difficulty],
|
||||
};
|
||||
|
||||
if (this.debug < 2)
|
||||
return;
|
||||
API3.warn(" >>> Petra bot: personality = " + uneval(this.personality));
|
||||
|
@ -0,0 +1,93 @@
|
||||
/**
|
||||
* Checks for emergencies and acts accordingly
|
||||
*/
|
||||
PETRA.EmergencyManager = function(Config)
|
||||
{
|
||||
this.Config = Config;
|
||||
this.referencePopulation = 0;
|
||||
this.referenceStructureCount = 0;
|
||||
this.numRoots = 0;
|
||||
this.hasEmergency = false;
|
||||
};
|
||||
|
||||
PETRA.EmergencyManager.prototype.init = function(gameState)
|
||||
{
|
||||
this.referencePopulation = gameState.getPopulation();
|
||||
this.referenceStructureCount = gameState.getOwnStructures().length;
|
||||
this.numRoots = this.rootCount(gameState);
|
||||
};
|
||||
|
||||
PETRA.EmergencyManager.prototype.update = function(gameState)
|
||||
{
|
||||
if (this.hasEmergency)
|
||||
{
|
||||
this.emergencyUpdate(gameState);
|
||||
return;
|
||||
}
|
||||
const pop = gameState.getPopulation();
|
||||
const nStructures = gameState.getOwnStructures().length;
|
||||
const nRoots = this.rootCount(gameState);
|
||||
const factors = this.Config.emergencyValues;
|
||||
if (((pop / this.referencePopulation) < factors.population || pop == 0) &&
|
||||
((nStructures / this.referenceStructureCount) < factors.structures || nStructures == 0))
|
||||
this.setEmergency(gameState, true);
|
||||
else if ((nRoots / this.numRoots) <= factors.roots || (nRoots == 0 && this.numRoots != 0))
|
||||
this.setEmergency(gameState, true);
|
||||
|
||||
if (pop > this.referencePopulation || this.hasEmergency)
|
||||
this.referencePopulation = pop;
|
||||
if (nStructures > this.referenceStructureCount || this.hasEmergency)
|
||||
this.referenceStructureCount = nStructures;
|
||||
if (nRoots > this.numRoots || this.hasEmergency)
|
||||
this.numRoots = nRoots;
|
||||
};
|
||||
|
||||
PETRA.EmergencyManager.prototype.emergencyUpdate = function(gameState)
|
||||
{
|
||||
const pop = gameState.getPopulation();
|
||||
const nStructures = gameState.getOwnStructures().length;
|
||||
const nRoots = this.rootCount(gameState);
|
||||
const factors = this.Config.emergencyValues;
|
||||
|
||||
if ((pop > this.referencePopulation * 1.2 &&
|
||||
nStructures > this.referenceStructureCount * 1.2) ||
|
||||
nRoots > this.numRoots)
|
||||
{
|
||||
this.setEmergency(gameState, false);
|
||||
this.referencePopulation = pop;
|
||||
this.referenceStructureCount = nStructures;
|
||||
this.numRoots = nRoots;
|
||||
}
|
||||
};
|
||||
|
||||
PETRA.EmergencyManager.prototype.rootCount = function(gameState)
|
||||
{
|
||||
let roots = 0;
|
||||
gameState.getOwnStructures().toEntityArray().forEach(ent => {
|
||||
if (ent?.get("TerritoryInfluence")?.Root === "true")
|
||||
roots++;
|
||||
});
|
||||
return roots;
|
||||
};
|
||||
|
||||
PETRA.EmergencyManager.prototype.setEmergency = function(gameState, enable)
|
||||
{
|
||||
this.hasEmergency = enable;
|
||||
PETRA.chatEmergency(gameState, enable);
|
||||
};
|
||||
|
||||
PETRA.EmergencyManager.prototype.Serialize = function()
|
||||
{
|
||||
return {
|
||||
"referencePopulation": this.referencePopulation,
|
||||
"referenceStructureCount": this.referenceStructureCount,
|
||||
"numRoots": this.numRoots,
|
||||
"hasEmergency": this.hasEmergency
|
||||
};
|
||||
};
|
||||
|
||||
PETRA.EmergencyManager.prototype.Deserialize = function(data)
|
||||
{
|
||||
for (const key in data)
|
||||
this[key] = data[key];
|
||||
};
|
@ -44,6 +44,7 @@ PETRA.HQ = function(Config)
|
||||
this.diplomacyManager = new PETRA.DiplomacyManager(this.Config);
|
||||
this.garrisonManager = new PETRA.GarrisonManager(this.Config);
|
||||
this.victoryManager = new PETRA.VictoryManager(this.Config);
|
||||
this.emergencyManager = new PETRA.EmergencyManager(this.Config);
|
||||
|
||||
this.capturableTargets = new Map();
|
||||
this.capturableTargetsTime = 0;
|
||||
@ -66,6 +67,7 @@ PETRA.HQ.prototype.init = function(gameState, queues)
|
||||
this.treasures.registerUpdates();
|
||||
this.currentPhase = gameState.currentPhase();
|
||||
this.decayingStructures = new Set();
|
||||
this.emergencyManager.init(gameState);
|
||||
};
|
||||
|
||||
/**
|
||||
@ -2190,6 +2192,7 @@ PETRA.HQ.prototype.baseAtIndex = function(territoryIndex)
|
||||
PETRA.HQ.prototype.update = function(gameState, queues, events)
|
||||
{
|
||||
Engine.ProfileStart("Headquarters update");
|
||||
this.emergencyManager.update(gameState);
|
||||
this.turnCache = {};
|
||||
this.territoryMap = PETRA.createTerritoryMap(gameState);
|
||||
this.canBarter = gameState.getOwnEntitiesByClass("Market", true).filter(API3.Filters.isBuilt()).hasEntities();
|
||||
@ -2337,6 +2340,7 @@ PETRA.HQ.prototype.Serialize = function()
|
||||
API3.warn(" diplomacyManager " + uneval(this.diplomacyManager.Serialize()));
|
||||
API3.warn(" garrisonManager " + uneval(this.garrisonManager.Serialize()));
|
||||
API3.warn(" victoryManager " + uneval(this.victoryManager.Serialize()));
|
||||
API3.warn(" emergencyManager " + uneval(this.emergencyManager.Serialize()));
|
||||
}
|
||||
|
||||
return {
|
||||
@ -2352,6 +2356,7 @@ PETRA.HQ.prototype.Serialize = function()
|
||||
"diplomacyManager": this.diplomacyManager.Serialize(),
|
||||
"garrisonManager": this.garrisonManager.Serialize(),
|
||||
"victoryManager": this.victoryManager.Serialize(),
|
||||
"emergencyManager": this.emergencyManager.Serialize(),
|
||||
};
|
||||
};
|
||||
|
||||
@ -2395,4 +2400,7 @@ PETRA.HQ.prototype.Deserialize = function(gameState, data)
|
||||
|
||||
this.victoryManager = new PETRA.VictoryManager(this.Config);
|
||||
this.victoryManager.Deserialize(data.victoryManager);
|
||||
|
||||
this.emergencyManager = new PETRA.EmergencyManager(this.Config);
|
||||
this.emergencyManager.Deserialize(data.emergencyManager);
|
||||
};
|
||||
|
Loading…
Reference in New Issue
Block a user