Ticket #3102: t3102_survival_2.diff

File t3102_survival_2.diff, 11.2 KB (added by bb, 3 years ago)
  • binaries/data/mods/public/maps/random/survivalofthefittest_triggers.js

     
    1 var treasures =
    2 [
     1/*
     2 * This is the Script containing all the Triggers for the "Survival of the Fittest" Map.
     3 */
     4
     5var treasures = [
    36    "gaia/special_treasure_food_barrel",
    47    "gaia/special_treasure_food_bin",
    58    "gaia/special_treasure_food_crate",
     
    1013    "gaia/special_treasure_wood",
    1114    "gaia/special_treasure_wood"
    1215];
    13 var attackerEntityTemplates =
    14 [
     16
     17var resourceLoopCount = 0;
     18
     19var resourceLoopTime = 1.25; // Time in minutes when resources are distributed periodically without random offset.
     20var resourceLoopOffset = 14 + 2 * Math.random(); // Time in minutes after which resources are distributed periodically.
     21
     22// These are the templates of the attacking units, sorted by civ
     23var attackerEntityTemplates = [
    1524    [
    1625        "units/athen_champion_infantry",
    1726        "units/athen_champion_marine",
    1827        "units/athen_champion_ranged",
    19         "units/athen_siege_lithobolos_packed",
    20         "units/athen_siege_oxybeles_packed",
     28        "units/athen_mechanical_siege_lithobolos_packed",
     29        "units/athen_mechanical_siege_oxybeles_packed"
    2130    ],
    2231    [
    2332        "units/brit_champion_cavalry",
    2433        "units/brit_champion_infantry",
    25         "units/brit_mechanical_siege_ram",
     34        "units/brit_mechanical_siege_ram"
    2635    ],
    2736    [
    2837        "units/cart_champion_cavalry",
    2938        "units/cart_champion_elephant",
    3039        "units/cart_champion_infantry",
    31         "units/cart_champion_pikeman",
     40        "units/cart_champion_pikeman"
    3241    ],
    3342    [
    3443        "units/gaul_champion_cavalry",
    3544        "units/gaul_champion_fanatic",
    3645        "units/gaul_champion_infantry",
    37         "units/gaul_mechanical_siege_ram",
     46        "units/gaul_mechanical_siege_ram"
    3847    ],
    3948    [
    4049        "units/iber_champion_cavalry",
    4150        "units/iber_champion_infantry",
    42         "units/iber_mechanical_siege_ram",
     51        "units/iber_mechanical_siege_ram"
    4352    ],
    4453    [
    4554        "units/mace_champion_cavalry",
     
    4655        "units/mace_champion_infantry_a",
    4756        "units/mace_champion_infantry_e",
    4857        "units/mace_mechanical_siege_lithobolos_packed",
    49         "units/mace_mechanical_siege_oxybeles_packed",
     58        "units/mace_mechanical_siege_oxybeles_packed"
    5059    ],
    5160    [
    5261        "units/maur_champion_chariot",
     
    5362        "units/maur_champion_elephant",
    5463        "units/maur_champion_infantry",
    5564        "units/maur_champion_maiden",
    56         "units/maur_champion_maiden_archer",
     65        "units/maur_champion_maiden_archer"
    5766    ],
    5867    [
    5968        "units/pers_champion_cavalry",
    60         "units/pers_champion_infantry",
    6169        "units/pers_champion_elephant",
     70        "units/pers_champion_infantry"
     71
    6272    ],
    6373    [
    6474        "units/ptol_champion_cavalry",
    65         "units/ptol_champion_elephant",
     75        "units/ptol_champion_elephant"
    6676    ],
    6777    [
    6878        "units/rome_champion_cavalry",
    6979        "units/rome_champion_infantry",
    7080        "units/rome_mechanical_siege_ballista_packed",
    71         "units/rome_mechanical_siege_scorpio_packed",
     81        "units/rome_mechanical_siege_scorpio_packed"
    7282    ],
    7383    [
    7484        "units/sele_champion_cavalry",
     
    7585        "units/sele_champion_chariot",
    7686        "units/sele_champion_elephant",
    7787        "units/sele_champion_infantry_pikeman",
    78         "units/sele_champion_infantry_swordsman",
     88        "units/sele_champion_infantry_swordsman"
    7989    ],
    8090    [
    8191        "units/spart_champion_infantry_pike",
    8292        "units/spart_champion_infantry_spear",
    8393        "units/spart_champion_infantry_sword",
    84         "units/spart_mechanical_siege_ram",
     94        "units/spart_mechanical_siege_ram"
    8595    ],
    8696];
    8797
     
    93103    let nextTime = Math.round(120000 + Math.random() * 60000);
    94104    let attackerCount = Math.round(cmpTimer.GetTime() / nextTime / attackerEntities.length);
    95105
    96     // spawn attackers
    97     let attackers =  [];
     106    // Spawn attackers
     107    let attackers = [];
    98108    for (let attackerEntity of attackerEntities)
    99109        attackers.push(TriggerHelper.SpawnUnitsFromTriggerPoints("A", attackerEntity, attackerCount, 0));
    100110
     
    103113        for (let origin in entityType)
    104114        {
    105115            let cmpPlayer = QueryOwnerInterface(+origin, IID_Player);
    106             if (cmpPlayer.GetState() != "active")
     116            if (!cmpPlayer || !cmpTrigger.playerCivicCenter[cmpPlayer.GetPlayerID()])
    107117                continue;
    108118
    109             let cmpPosition =  Engine.QueryInterface(this.playerCivicCenter[cmpPlayer.GetPlayerID()], IID_Position);
    110             // this shouldn't happen if the player is still active
     119            let cmpPosition = Engine.QueryInterface(cmpTrigger.playerCivicCenter[cmpPlayer.GetPlayerID()], IID_Position);
     120            // This shouldn't happen if the player is still active
    111121            if (!cmpPosition || !cmpPosition.IsInWorld)
    112122                continue;
    113123
    114             // store the x and z coordinates in the command
     124            // Store the x and z coordinates in the command
    115125            let cmd = cmpPosition.GetPosition();
    116126            cmd.type = "attack-walk";
    117127            cmd.entities = entityType[origin];
    118128            cmd.queued = true;
    119129            cmd.targetClasses = undefined;
    120             // send the attack-walk command
     130            // Send the attack-walk command
    121131            ProcessCommand(0, cmd);
    122132        }
    123133    }
     
    130140    cmpTrigger.DoAfterDelay(nextTime, "StartAnEnemyWave", {}); // The next wave will come in 3 minutes
    131141};
    132142
     143/*
     144 * The main init function, called at the start
     145 */
    133146Trigger.prototype.InitGame = function()
    134147{
    135148    let numberOfPlayers = TriggerHelper.GetNumberOfPlayers();
    136     // Find all of the civic centers, disable some structures
     149    // Find all of the civic centers and females, disable some structures, setup activity watch
    137150    for (let i = 1; i < numberOfPlayers; ++i)
    138151    {
     152        /*// At first, determine how many players are actually playing (humans)
     153        let cmpPlayer = TriggerHelper.GetPlayerComponent(i);
     154        warn(cmpPlayer.GetState());*/
     155
     156        // Now handle the other stuff
    139157        let cmpRangeManager = Engine.QueryInterface(SYSTEM_ENTITY, IID_RangeManager);
    140158        let playerEntities = cmpRangeManager.GetEntitiesByPlayer(i); // Get all of each player's entities
    141159
    142160        for (let entity of playerEntities)
     161        {
    143162            if (TriggerHelper.EntityHasClass(entity, "CivilCentre"))
    144163                cmpTrigger.playerCivicCenter[i] = entity;
     164            if (TriggerHelper.EntityHasClass(entity, "Female"))
     165            {
     166                let cmpDamageReceiver = Engine.QueryInterface(entity, IID_DamageReceiver);
     167                cmpDamageReceiver.SetInvulnerability(true);
     168
     169                let cmpHealth = Engine.QueryInterface(entity, IID_Health);
     170                cmpHealth.SetUndeletability(true);
     171            }
     172        }
    145173    }
    146174
    147175    // Fix alliances
     
    183211    let triggerPoints = cmpTrigger.GetTriggerPoints(point);
    184212    for (let point of triggerPoints)
    185213    {
    186         let template = treasures[Math.floor(Math.random() * treasures.length)]
    187         TriggerHelper.SpawnUnits(point, template, 1, 0);
     214        let template = treasures[Math.floor(Math.random() * treasures.length)];
     215        let cmpPosition = Engine.QueryInterface(point, IID_Position);
     216        let ent = Engine.AddEntity(template);
     217
     218        let cmpEntOwnership = Engine.QueryInterface(ent, IID_Ownership);
     219        let cmpEntPosition = Engine.QueryInterface(ent, IID_Position);
     220
     221        if (cmpEntOwnership)
     222            cmpEntOwnership.SetOwner(0);
     223
     224        let xOffset = RandomInt(0,23);
     225        let zOffset = RandomInt(0,23);
     226
     227        if (Math.random() >= 0.8 )
     228        {
     229            xOffset += RandomInt(5,8);
     230            zOffset += RandomInt(5,8);
     231        }
     232
     233        if (Math.round(Math.random()) == 1)
     234            xOffset = xOffset * -1;
     235
     236        if (Math.round(Math.random()) == 1)
     237            zOffset = zOffset * -1;
     238
     239        cmpEntPosition.JumpTo(cmpPosition.GetPosition().x + xOffset, cmpPosition.GetPosition().z - zOffset);
    188240    }
    189     cmpTrigger.DoAfterDelay(4*60*1000, "PlaceTreasures", {}); //Place more treasures after 4 minutes
     241    let time = (3 + Math.random()) * 60 * 1000; // Place more treasures after 3-4 minutes
     242    cmpTrigger.DoAfterDelay(time, "PlaceTreasures", {});
     243
     244    let cmpGUIInterface = Engine.QueryInterface(SYSTEM_ENTITY, IID_GuiInterface);
     245    cmpGUIInterface.PushNotification({
     246        "message": markForTranslation("New treasures have been placed!"),
     247        "translateMessage": true
     248    });
    190249};
    191250
     251/*
     252 * This function starts the timer for the waves
     253 */
    192254Trigger.prototype.InitializeEnemyWaves = function()
    193255{
    194256    let time = (5 + Math.round(Math.random() * 10)) * 60 * 1000;
    195257    let cmpGUIInterface = Engine.QueryInterface(SYSTEM_ENTITY, IID_GuiInterface);
     258    cmpGUIInterface.PushNotification({
     259        "message": markForTranslation("Welcome to Survival of the Fittest"),
     260        "translateMessage": true
     261    });
     262    cmpGUIInterface.PushNotification({
     263        "message": markForTranslation("Collect treasures with your woman to prepare for the enemies."),
     264        "translateMessage": true
     265    });
    196266    cmpGUIInterface.AddTimeNotification({
    197267        "message": markForTranslation("The first wave will start in %(time)s!"),
    198268        "translateMessage": true
    199269    }, time);
     270
    200271    cmpTrigger.DoAfterDelay(time, "StartAnEnemyWave", {});
    201272};
    202273
     274/*
     275 * DefeatPlayerOnceCCIsDestroyed occurs when a unit dies, and checks for anything to be done in case its a civic center
     276 */
    203277Trigger.prototype.DefeatPlayerOnceCCIsDestroyed = function(data)
    204278{
    205279    // Defeat a player that has lost his civic center
    206     if (data.entity == cmpTrigger.playerCivicCenter[data.from])
     280    if (data.entity == cmpTrigger.playerCivicCenter[data.from] && data.to == -1)
    207281    {
    208282        TriggerHelper.DefeatPlayer(data.from);
    209283
     
    224298    }
    225299};
    226300
     301/*
     302 * This function is constantly Looping and provides resources to all players.
     303 * It starts after resourceLoopOffset
     304 */
     305Trigger.prototype.ResourceLoop = function(data)
     306{
     307    ++resourceLoopCount;
     308
     309    if (resourceLoopCount == 1)
     310    {
     311        let cmpGUIInterface = Engine.QueryInterface(SYSTEM_ENTITY, IID_GuiInterface);
     312        cmpGUIInterface.PushNotification({
     313            "message": markForTranslation("From now on, all players will receive some resources from time to time"),
     314            "translateMessage": true
     315        });
     316    }
     317
     318    let numberOfPlayers = TriggerHelper.GetNumberOfPlayers();
     319    for (let i = 1; i < numberOfPlayers; ++i)
     320    {
     321        let cmpPlayer = QueryPlayerIDInterface(i);
     322        cmpPlayer.AddResources({
     323            "wood": 100,
     324            "stone": 100,
     325            "metal": 100,
     326            "food": 100
     327        });
     328    }
     329    cmpTrigger.DoAfterDelay((resourceLoopTime + Math.random() / 2) * 60 * 1000, "ResourceLoop" , {});
     330};
     331
    227332var cmpTrigger = Engine.QueryInterface(SYSTEM_ENTITY, IID_Trigger);
    228333cmpTrigger.playerCivicCenter = {};
     334
    229335cmpTrigger.DoAfterDelay(0, "InitGame", {});
    230336cmpTrigger.DoAfterDelay(1000, "InitializeEnemyWaves", {});
     337cmpTrigger.DoAfterDelay(resourceLoopOffset * 60 * 1000, "ResourceLoop" , {});
    231338
    232339cmpTrigger.RegisterTrigger("OnOwnershipChanged", "DefeatPlayerOnceCCIsDestroyed", { "enabled": true });
  • binaries/data/mods/public/simulation/components/Health.js

     
    6363    this.hitpoints = +(this.template.Initial || this.GetMaxHitpoints());
    6464    this.regenRate = ApplyValueModificationsToEntity("Health/RegenRate", +this.template.RegenRate, this.entity);
    6565    this.idleRegenRate = ApplyValueModificationsToEntity("Health/IdleRegenRate", +this.template.IdleRegenRate, this.entity);
     66    this.undeletable = this.template.Undeletable;
    6667    this.CheckRegenTimer();
    6768    this.UpdateActor();
    6869};
     
    123124
    124125Health.prototype.IsUndeletable = function()
    125126{
    126     return this.template.Undeletable == "true";
     127    return this.undeletable;
    127128};
    128129
     130Health.prototype.SetUndeletability = function(undeletability)
     131{
     132    this.undeletable = undeletability;
     133};
     134
    129135Health.prototype.GetIdleRegenRate = function()
    130136{
    131137    return this.idleRegenRate;