Changeset View
Changeset View
Standalone View
Standalone View
binaries/data/mods/public/simulation/ai/petra/garrisonManager.js
/** | /** | ||||
* Manage the garrisonHolders | * Manage the garrisonHolders | ||||
* When a unit is ordered to garrison, it must be done through this.garrison() function so that | * When a unit is ordered to garrison, it must be done through this.garrison() function so that | ||||
* an object in this.holders is created. This object contains an array with the entities | * an object in this.holders is created. This object contains an array with the entities | ||||
* in the process of being garrisoned. To have all garrisoned units, we must add those in holder.garrisoned(). | * in the process of being garrisoned. To have all garrisoned units, we must add those in holder.garrisoned(). | ||||
* Futhermore garrison units have a metadata garrisonType describing its reason (protection, transport, ...) | * Futhermore garrison units have a metadata garrisonType describing its reason (protection, transport, ...) | ||||
*/ | */ | ||||
Silier: line | |||||
PETRA.GarrisonManager = function(Config) | PETRA.GarrisonManager = function(Config) | ||||
{ | { | ||||
this.Config = Config; | this.Config = Config; | ||||
this.holders = new Map(); | this.holders = new Map(); | ||||
this.decayingStructures = new Map(); | this.decayingStructures = new Map(); | ||||
}; | }; | ||||
PETRA.GarrisonManager.TYPE_FORCE = "force"; | |||||
Done Inline Actionsremove this one and leave undefined as it was Silier: remove this one and leave undefined as it was | |||||
Not Done Inline Actions^ Not addressed? Freagarach: ^ Not addressed? | |||||
Done Inline ActionsIt was addressed, but I forgot to add the constant ;D JCWasmx86: It was addressed, but I forgot to add the constant ;D | |||||
PETRA.GarrisonManager.TYPE_TRADE = "trade"; | |||||
PETRA.GarrisonManager.TYPE_PROTECTION = "protection"; | |||||
PETRA.GarrisonManager.TYPE_DECAY = "decay"; | |||||
PETRA.GarrisonManager.TYPE_EMERGENCY = "emergency"; | |||||
PETRA.GarrisonManager.prototype.update = function(gameState, events) | PETRA.GarrisonManager.prototype.update = function(gameState, events) | ||||
{ | { | ||||
// First check for possible upgrade of a structure | // First check for possible upgrade of a structure | ||||
for (let evt of events.EntityRenamed) | for (let evt of events.EntityRenamed) | ||||
{ | { | ||||
for (let id of this.holders.keys()) | for (let id of this.holders.keys()) | ||||
{ | { | ||||
if (id != evt.entity) | if (id != evt.entity) | ||||
▲ Show 20 Lines • Show All 165 Lines • ▼ Show 20 Lines | PETRA.GarrisonManager.prototype.update = function(gameState, events) | ||||
// Warning new garrison orders (as in the following lines) should be done after having updated the holders | // Warning new garrison orders (as in the following lines) should be done after having updated the holders | ||||
// (or TODO we should add a test that the garrison order is from a previous turn when updating) | // (or TODO we should add a test that the garrison order is from a previous turn when updating) | ||||
for (let [id, gmin] of this.decayingStructures.entries()) | for (let [id, gmin] of this.decayingStructures.entries()) | ||||
{ | { | ||||
let ent = gameState.getEntityById(id); | let ent = gameState.getEntityById(id); | ||||
if (!ent || ent.owner() !== PlayerID) | if (!ent || ent.owner() !== PlayerID) | ||||
this.decayingStructures.delete(id); | this.decayingStructures.delete(id); | ||||
else if (this.numberOfGarrisonedSlots(ent) < gmin) | else if (this.numberOfGarrisonedSlots(ent) < gmin) | ||||
gameState.ai.HQ.defenseManager.garrisonUnitsInside(gameState, ent, { "min": gmin, "type": "decay" }); | gameState.ai.HQ.defenseManager.garrisonUnitsInside(gameState, ent, { "min": gmin, "type": PETRA.GarrisonManager.TYPE_DECAY }); | ||||
} | } | ||||
}; | }; | ||||
/** TODO should add the units garrisoned inside garrisoned units */ | /** TODO should add the units garrisoned inside garrisoned units */ | ||||
PETRA.GarrisonManager.prototype.numberOfGarrisonedUnits = function(holder) | PETRA.GarrisonManager.prototype.numberOfGarrisonedUnits = function(holder) | ||||
{ | { | ||||
if (!this.holders.has(holder.id())) | if (!this.holders.has(holder.id())) | ||||
return holder.garrisoned().length; | return holder.garrisoned().length; | ||||
▲ Show 20 Lines • Show All 73 Lines • ▼ Show 20 Lines | PETRA.GarrisonManager.prototype.cancelGarrison = function(ent) | ||||
if (index !== -1) | if (index !== -1) | ||||
list.splice(index, 1); | list.splice(index, 1); | ||||
}; | }; | ||||
PETRA.GarrisonManager.prototype.keepGarrisoned = function(ent, holder, around) | PETRA.GarrisonManager.prototype.keepGarrisoned = function(ent, holder, around) | ||||
{ | { | ||||
switch (ent.getMetadata(PlayerID, "garrisonType")) | switch (ent.getMetadata(PlayerID, "garrisonType")) | ||||
{ | { | ||||
case 'force': // force the ungarrisoning | case PETRA.GarrisonManager.TYPE_FORCE: // force the ungarrisoning | ||||
return false; | return false; | ||||
case 'trade': // trader garrisoned in ship | case PETRA.GarrisonManager.TYPE_TRADE: // trader garrisoned in ship | ||||
return true; | return true; | ||||
case 'protection': // hurt unit for healing or infantry for defense | case PETRA.GarrisonManager.TYPE_PROTECTION: // hurt unit for healing or infantry for defense | ||||
if (holder.buffHeal() && ent.isHealable() && ent.healthLevel() < this.Config.garrisonHealthLevel.high) | if (holder.buffHeal() && ent.isHealable() && ent.healthLevel() < this.Config.garrisonHealthLevel.high) | ||||
return true; | return true; | ||||
let capture = ent.capturePoints(); | let capture = ent.capturePoints(); | ||||
if (capture && capture[PlayerID] / capture.reduce((a, b) => a + b) < 0.8) | if (capture && capture[PlayerID] / capture.reduce((a, b) => a + b) < 0.8) | ||||
return true; | return true; | ||||
if (ent.hasClasses(holder.getGarrisonArrowClasses())) | if (ent.hasClasses(holder.getGarrisonArrowClasses())) | ||||
{ | { | ||||
if (around.unit || around.defenseStructure) | if (around.unit || around.defenseStructure) | ||||
return true; | return true; | ||||
if (around.meleeSiege || around.rangeSiege) | if (around.meleeSiege || around.rangeSiege) | ||||
return ent.attackTypes().indexOf("Melee") === -1 || ent.healthLevel() < this.Config.garrisonHealthLevel.low; | return ent.attackTypes().indexOf("Melee") === -1 || ent.healthLevel() < this.Config.garrisonHealthLevel.low; | ||||
return false; | return false; | ||||
} | } | ||||
if (ent.attackTypes() && ent.attackTypes().indexOf("Melee") !== -1) | if (ent.attackTypes() && ent.attackTypes().indexOf("Melee") !== -1) | ||||
return false; | return false; | ||||
if (around.unit) | if (around.unit) | ||||
return ent.hasClass("Support") || PETRA.isSiegeUnit(ent); // only ranged siege here and below as melee siege already released above | return ent.hasClass("Support") || PETRA.isSiegeUnit(ent); // only ranged siege here and below as melee siege already released above | ||||
if (PETRA.isSiegeUnit(ent)) | if (PETRA.isSiegeUnit(ent)) | ||||
return around.meleeSiege; | return around.meleeSiege; | ||||
return holder.buffHeal() && ent.needsHeal(); | return holder.buffHeal() && ent.needsHeal(); | ||||
case 'decay': | case PETRA.GarrisonManager.TYPE_DECAY: | ||||
return this.decayingStructures.has(holder.id()); | return this.decayingStructures.has(holder.id()); | ||||
case 'emergency': // f.e. hero in regicide mode | case PETRA.GarrisonManager.TYPE_EMERGENCY: // f.e. hero in regicide mode | ||||
if (holder.buffHeal() && ent.isHealable() && ent.healthLevel() < this.Config.garrisonHealthLevel.high) | if (holder.buffHeal() && ent.isHealable() && ent.healthLevel() < this.Config.garrisonHealthLevel.high) | ||||
return true; | return true; | ||||
if (around.unit || around.defenseStructure || around.meleeSiege || | if (around.unit || around.defenseStructure || around.meleeSiege || | ||||
around.rangeSiege && ent.healthLevel() < this.Config.garrisonHealthLevel.high) | around.rangeSiege && ent.healthLevel() < this.Config.garrisonHealthLevel.high) | ||||
return true; | return true; | ||||
return holder.buffHeal() && ent.needsHeal(); | return holder.buffHeal() && ent.needsHeal(); | ||||
default: | default: | ||||
if (ent.getMetadata(PlayerID, "onBoard") === "onBoard") // transport is not (yet ?) managed by garrisonManager | if (ent.getMetadata(PlayerID, "onBoard") === "onBoard") // transport is not (yet ?) managed by garrisonManager | ||||
return true; | return true; | ||||
API3.warn("unknown type in garrisonManager " + ent.getMetadata(PlayerID, "garrisonType") + | API3.warn("unknown type in garrisonManager " + ent.getMetadata(PlayerID, "garrisonType") + | ||||
" for " + ent.genericName() + " id " + ent.id() + | " for " + ent.genericName() + " id " + ent.id() + | ||||
" inside " + holder.genericName() + " id " + holder.id()); | " inside " + holder.genericName() + " id " + holder.id()); | ||||
ent.setMetadata(PlayerID, "garrisonType", "protection"); | ent.setMetadata(PlayerID, "garrisonType", PETRA.GarrisonManager.TYPE_PROTECTION); | ||||
return true; | return true; | ||||
} | } | ||||
}; | }; | ||||
/** Add this holder in the list managed by the garrisonManager */ | /** Add this holder in the list managed by the garrisonManager */ | ||||
PETRA.GarrisonManager.prototype.registerHolder = function(gameState, holder) | PETRA.GarrisonManager.prototype.registerHolder = function(gameState, holder) | ||||
{ | { | ||||
if (this.holders.has(holder.id())) // already registered | if (this.holders.has(holder.id())) // already registered | ||||
▲ Show 20 Lines • Show All 41 Lines • Show Last 20 Lines |
Wildfire Games · Phabricator
line