Ticket #4142: 4142_petra_regicide_support_v1.4.patch

File 4142_petra_regicide_support_v1.4.patch, 5.7 KB (added by Sandarac, 7 years ago)

Healers will be assigned to guard the hero.

  • binaries/data/mods/public/simulation/ai/common-api/entity.js

     
    929929            if (item.progress < percentToStopAt)
    930930                Engine.PostCommand(PlayerID,{ "type": "stop-production", "entity": this.id(), "id": item.id });
    931931        return this;
     932    },
     933
     934    "canGuard": function() { return this.get("UnitAI/CanGuard") === "true"; },
     935
     936    "guard": function(target, queued = false) {
     937        Engine.PostCommand(PlayerID, { "type": "guard", "entities": [this.id()], "target": target.id(), "queued": queued });
     938        return this;
     939    },
     940
     941    "removeGuard": function() {
     942        Engine.PostCommand(PlayerID, { "type": "remove-guard", "entities": [this.id()] });
     943        return this;
    932944    }
    933945});
    934946
  • binaries/data/mods/public/simulation/ai/petra/gameTypeManager.js

     
    77 * TODO: Assign military units to guard the hero in regicide
    88 */
    99
    10 m.GameTypeManager = function()
     10m.GameTypeManager = function(Config)
    1111{
     12    this.Config = Config;
    1213    this.heroGarrisonEmergency = false;
     14    this.healersAssignedToHero = 0;
     15    this.heroGuards = [];
    1316};
    1417
    1518/**
     
    8083        }
    8184    }
    8285
    83     if (!this.heroGarrisonEmergency)
    84         return;
     86    // check if new healers/guards need to be assigned to the hero
     87    for (let evt of events.Destroy)
     88    {
     89        if (!evt.entityObj || evt.entityObj.owner() !== PlayerID ||
     90            this.heroGuards.indexOf(evt.entityObj) === -1)
     91            continue;
    8592
     93        this.heroGuards.splice(this.heroGuards.indexOf(evt.entityObj), 1);
     94        if (evt.entityObj.hasClass("Healer"))
     95            --this.healersAssignedToHero;
     96    }
     97
     98    for (let evt of events.TrainingFinished)
     99        for (let entId of evt.entities)
     100        {
     101            let ent = gameState.getEntityById(entId);
     102            if (!ent || !ent.isOwn(PlayerID) || ent.getMetadata(PlayerID, "role") !== "regicideHealer")
     103                continue;
     104
     105            let heroEnt = gameState.getOwnEntitiesByClass("Hero", true).toEntityArray()[0];
     106            let access = gameState.ai.accessibility.getAccessValue(ent.position());
     107
     108            if (heroEnt && heroEnt.position() && ent.canGuard() &&
     109                access === gameState.ai.accessibility.getAccessValue(heroEnt.position()))
     110            {
     111                ent.guard(heroEnt);
     112                this.heroGuards.push(ent);
     113            }
     114        }
     115
    86116    for (let evt of events.Garrison)
    87         if (gameState.getEntityById(evt.entity).hasClass("Hero"))
     117    {
     118        let ent = gameState.getEntityById(evt.entity)
     119        if (!ent || !ent.isOwn(PlayerID) || !ent.hasClass("Hero"))
     120            continue;
     121
     122        if (this.heroGarrisonEmergency)
    88123            this.heroGarrisonEmergency = false;
     124
     125        if (!gameState.getEntityById(evt.holder).hasClass("Ship"))
     126            continue;
     127
     128        // If the hero is garrisoned on a ship, remove its guards
     129        for (let guardEnt of this.heroGuards)
     130            if (guardEnt)
     131                guardEnt.removeGuard();
     132    }
    89133};
    90134
    91135m.GameTypeManager.prototype.buildWonder = function(gameState, queues)
     
    116160        heroEnt.move(basePos.anchor.position()[0], basePos.anchor.position()[1]);
    117161};
    118162
     163m.GameTypeManager.prototype.assignHealerToRegicideHero = function(gameState, queues)
     164{
     165    if (gameState.ai.HQ.saveResources || !gameState.getOwnEntitiesByClass("Temple", true).hasEntities())
     166        return;
     167
     168    let template = gameState.applyCiv("units/{civ}_support_healer_b");
     169
     170    queues.villager.addPlan(new m.TrainingPlan(gameState, template, { "role": "regicideHealer", "base": 0 }, 1, 1));
     171    ++this.healersAssignedToHero;
     172};
     173
    119174m.GameTypeManager.prototype.update = function(gameState, events, queues)
    120175{
    121176    this.checkEvents(gameState, events);
     
    122177
    123178    if (gameState.getGameType() === "wonder")
    124179        this.buildWonder(gameState, queues);
    125     else if (gameState.getGameType() === "regicide" && gameState.ai.playedTurn % 50 === 0)
     180
     181    if (gameState.getGameType() !== "regicide")
     182        return;
     183
     184    if (gameState.ai.playedTurn % 50 === 0)
    126185    {
    127186        let heroEnt = gameState.getOwnEntitiesByClass("Hero", true).toEntityArray()[0];
    128187        if (heroEnt && heroEnt.healthLevel() > 0.7)
    129188            heroEnt.setStance("aggressive");
    130189    }
     190
     191    if (this.healersAssignedToHero < Math.min(Math.round(this.Config.personality.defensive * 10), 4))
     192        this.assignHealerToRegicideHero(gameState, queues);
    131193};
    132194
    133195m.GameTypeManager.prototype.Serialize = function()
    134196{
    135     return { "heroGarrisonEmergency": this.heroGarrisonEmergency };
     197    return {
     198        "heroGarrisonEmergency": this.heroGarrisonEmergency,
     199        "healersAssignedToHero": this.healersAssignedToHero,
     200        "heroGuards": this.heroGuards
     201    };
    136202};
    137203
    138204m.GameTypeManager.prototype.Deserialize = function(data)
  • binaries/data/mods/public/simulation/ai/petra/headquarters.js

     
    5151    this.researchManager = new m.ResearchManager(this.Config);
    5252    this.diplomacyManager = new m.DiplomacyManager(this.Config);
    5353    this.garrisonManager = new m.GarrisonManager();
    54     this.gameTypeManager = new m.GameTypeManager();
     54    this.gameTypeManager = new m.GameTypeManager(this.Config);
    5555};
    5656
    5757/** More initialisation for stuff that needs the gameState */
     
    22792279    this.garrisonManager = new m.GarrisonManager();
    22802280    this.garrisonManager.Deserialize(data.garrisonManager);
    22812281
    2282     this.gameTypeManager = new m.GameTypeManager();
     2282    this.gameTypeManager = new m.GameTypeManager(this.Config);
    22832283    this.gameTypeManager.Deserialize(data.gameTypeManager);
    22842284};
    22852285