Changeset View
Changeset View
Standalone View
Standalone View
binaries/data/mods/public/simulation/ai/petra/defenseManager.js
Show First 20 Lines • Show All 600 Lines • ▼ Show 20 Lines | for (let evt of events.Attacked) | ||||
} | } | ||||
// If inside a started attack plan, let the plan deal with this unit. | // If inside a started attack plan, let the plan deal with this unit. | ||||
let plan = target.getMetadata(PlayerID, "plan"); | let plan = target.getMetadata(PlayerID, "plan"); | ||||
if (plan !== undefined && plan >= 0) | if (plan !== undefined && plan >= 0) | ||||
{ | { | ||||
let attack = gameState.ai.HQ.attackManager.getPlan(plan); | let attack = gameState.ai.HQ.attackManager.getPlan(plan); | ||||
if (attack && attack.state != "unexecuted") | if (attack && attack.state != PETRA.AttackPlan.STATE_UNEXECUTED) | ||||
continue; | continue; | ||||
} | } | ||||
// Signal this attacker to our defense manager, except if we are in enemy territory. | // Signal this attacker to our defense manager, except if we are in enemy territory. | ||||
// TODO treat ship attack. | // TODO treat ship attack. | ||||
if (attacker && attacker.position() && attacker.getMetadata(PlayerID, "PartOfArmy") === undefined && | if (attacker && attacker.position() && attacker.getMetadata(PlayerID, "PartOfArmy") === undefined && | ||||
!attacker.hasClasses(["Structure", "Ship"])) | !attacker.hasClasses(["Structure", "Ship"])) | ||||
{ | { | ||||
▲ Show 20 Lines • Show All 129 Lines • ▼ Show 20 Lines | if (data.attacker) | ||||
let dist = API3.SquareVectorDistance(data.attacker.position(), target.position()); | let dist = API3.SquareVectorDistance(data.attacker.position(), target.position()); | ||||
let range = target.attackRange("Ranged").max; | let range = target.attackRange("Ranged").max; | ||||
if (dist >= range*range) | if (dist >= range*range) | ||||
return false; | return false; | ||||
} | } | ||||
let access = PETRA.getLandAccess(gameState, target); | let access = PETRA.getLandAccess(gameState, target); | ||||
let garrisonManager = gameState.ai.HQ.garrisonManager; | let garrisonManager = gameState.ai.HQ.garrisonManager; | ||||
let garrisonArrowClasses = target.getGarrisonArrowClasses(); | let garrisonArrowClasses = target.getGarrisonArrowClasses(); | ||||
let typeGarrison = data.type || "protection"; | const typeGarrison = data.type || PETRA.GarrisonManager.TYPE_PROTECTION; | ||||
let allowMelee = gameState.ai.HQ.garrisonManager.allowMelee(target); | let allowMelee = gameState.ai.HQ.garrisonManager.allowMelee(target); | ||||
if (allowMelee === undefined) | if (allowMelee === undefined) | ||||
{ | { | ||||
// Should be kept in sync with garrisonManager to avoid garrisoning-ungarrisoning some units. | // Should be kept in sync with garrisonManager to avoid garrisoning-ungarrisoning some units. | ||||
if (data.attacker) | if (data.attacker) | ||||
allowMelee = data.attacker.hasClass("Structure") ? data.attacker.attackRange("Ranged") : !PETRA.isSiegeUnit(data.attacker); | allowMelee = data.attacker.hasClass("Structure") ? data.attacker.attackRange("Ranged") : !PETRA.isSiegeUnit(data.attacker); | ||||
else | else | ||||
allowMelee = true; | allowMelee = true; | ||||
} | } | ||||
let units = gameState.getOwnUnits().filter(ent => { | let units = gameState.getOwnUnits().filter(ent => { | ||||
if (!ent.position()) | if (!ent.position()) | ||||
return false; | return false; | ||||
if (!ent.hasClasses(garrisonArrowClasses)) | if (!ent.hasClasses(garrisonArrowClasses)) | ||||
return false; | return false; | ||||
if (typeGarrison != "decay" && !allowMelee && ent.attackTypes().indexOf("Melee") != -1) | if (typeGarrison != PETRA.GarrisonManager.TYPE_DECAY && !allowMelee && ent.attackTypes().indexOf("Melee") != -1) | ||||
return false; | return false; | ||||
if (ent.getMetadata(PlayerID, "transport") !== undefined) | if (ent.getMetadata(PlayerID, "transport") !== undefined) | ||||
return false; | return false; | ||||
let army = ent.getMetadata(PlayerID, "PartOfArmy") ? this.getArmy(ent.getMetadata(PlayerID, "PartOfArmy")) : undefined; | let army = ent.getMetadata(PlayerID, "PartOfArmy") ? this.getArmy(ent.getMetadata(PlayerID, "PartOfArmy")) : undefined; | ||||
if (!army && (ent.getMetadata(PlayerID, "plan") == -2 || ent.getMetadata(PlayerID, "plan") == -3)) | if (!army && (ent.getMetadata(PlayerID, "plan") == -2 || ent.getMetadata(PlayerID, "plan") == -3)) | ||||
return false; | return false; | ||||
if (ent.getMetadata(PlayerID, "plan") !== undefined && ent.getMetadata(PlayerID, "plan") >= 0) | if (ent.getMetadata(PlayerID, "plan") !== undefined && ent.getMetadata(PlayerID, "plan") >= 0) | ||||
{ | { | ||||
let subrole = ent.getMetadata(PlayerID, "subrole"); | let subrole = ent.getMetadata(PlayerID, "subrole"); | ||||
// When structure decaying (usually because we've just captured it in enemy territory), also allow units from an attack plan. | // When structure decaying (usually because we've just captured it in enemy territory), also allow units from an attack plan. | ||||
if (typeGarrison != "decay" && subrole && (subrole == "completing" || subrole == "walking" || subrole == "attacking")) | if (typeGarrison != PETRA.GarrisonManager.TYPE_DECAY && subrole && (subrole == "completing" || subrole == "walking" || subrole == "attacking")) | ||||
return false; | return false; | ||||
} | } | ||||
if (PETRA.getLandAccess(gameState, ent) != access) | if (PETRA.getLandAccess(gameState, ent) != access) | ||||
return false; | return false; | ||||
return true; | return true; | ||||
}).filterNearest(target.position()); | }).filterNearest(target.position()); | ||||
let ret = false; | let ret = false; | ||||
Show All 37 Lines | if (PETRA.getLandAccess(gameState, ent) != unitAccess) | ||||
continue; | continue; | ||||
let dist = API3.SquareVectorDistance(ent.position(), unit.position()); | let dist = API3.SquareVectorDistance(ent.position(), unit.position()); | ||||
if (dist > distmin) | if (dist > distmin) | ||||
continue; | continue; | ||||
distmin = dist; | distmin = dist; | ||||
nearest = ent; | nearest = ent; | ||||
} | } | ||||
if (nearest) | if (nearest) | ||||
garrisonManager.garrison(gameState, unit, nearest, "protection"); | garrisonManager.garrison(gameState, unit, nearest, PETRA.GarrisonManager.TYPE_PROTECTION); | ||||
return nearest !== undefined; | return nearest !== undefined; | ||||
}; | }; | ||||
/** | /** | ||||
* Garrison a hurt unit inside a player-owned or allied structure. | * Garrison a hurt unit inside a player-owned or allied structure. | ||||
* If emergency is true, the unit will be garrisoned in the closest possible structure. | * If emergency is true, the unit will be garrisoned in the closest possible structure. | ||||
* Otherwise, it will garrison in the closest healing structure. | * Otherwise, it will garrison in the closest healing structure. | ||||
*/ | */ | ||||
Show All 24 Lines | for (let ent of gameState.getAllyStructures().values()) | ||||
distmin = dist; | distmin = dist; | ||||
nearest = ent; | nearest = ent; | ||||
} | } | ||||
if (!nearest) | if (!nearest) | ||||
return false; | return false; | ||||
if (!emergency) | if (!emergency) | ||||
{ | { | ||||
garrisonManager.garrison(gameState, unit, nearest, "protection"); | garrisonManager.garrison(gameState, unit, nearest, PETRA.GarrisonManager.TYPE_PROTECTION); | ||||
return true; | return true; | ||||
} | } | ||||
if (garrisonManager.numberOfGarrisonedSlots(nearest) >= nearest.garrisonMax()) // make room for this ent | if (garrisonManager.numberOfGarrisonedSlots(nearest) >= nearest.garrisonMax()) // make room for this ent | ||||
nearest.unload(nearest.garrisoned()[0]); | nearest.unload(nearest.garrisoned()[0]); | ||||
garrisonManager.garrison(gameState, unit, nearest, nearest.buffHeal() ? "protection" : "emergency"); | garrisonManager.garrison(gameState, unit, nearest, nearest.buffHeal() ? PETRA.GarrisonManager.TYPE_PROTECTION : PETRA.GarrisonManager.TYPE_EMERGENCY); | ||||
return true; | return true; | ||||
}; | }; | ||||
/** | /** | ||||
* Be more inclined to help an ally attacked by several enemies. | * Be more inclined to help an ally attacked by several enemies. | ||||
*/ | */ | ||||
PETRA.DefenseManager.prototype.GetCooperationLevel = function(ally) | PETRA.DefenseManager.prototype.GetCooperationLevel = function(ally) | ||||
{ | { | ||||
▲ Show 20 Lines • Show All 63 Lines • Show Last 20 Lines |
Wildfire Games · Phabricator