This Trac instance is not used for development anymore!

We migrated our development workflow to git and Gitea.
To test the future redirection, replace trac by ariadne in the page URL.

Ticket #2160: regicide_early_attack_v2.patch

File regicide_early_attack_v2.patch, 30.1 KB (added by elexis, 8 years ago)
  • binaries/data/mods/public/gui/gamesetup/gamesetup.js

    function initRadioButtons()  
    496496    let options = {
    497497        "RevealMap": "revealMap",
    498498        "ExploreMap": "exploreMap",
    499499        "DisableTreasures": "disableTreasures",
    500500        "LockTeams": "lockTeams",
    501         "LastManStanding" : "lastManStanding",
     501        "LastManStanding": "lastManStanding",
     502        "RegicideEarlyAttack": "regicideEarlyAttack",
    502503        "CheatsEnabled": "enableCheats"
    503504    };
    504505
    505506    Object.keys(options).forEach(attribute => {
    506507        Engine.GetGUIObjectByName(options[attribute]).onPress = function() {
    function selectMap(name)  
    11811182
    11821183    if (g_GameAttributes.mapType == "scenario")
    11831184    {
    11841185        delete g_GameAttributes.settings.WonderDuration;
    11851186        delete g_GameAttributes.settings.LastManStanding;
     1187        delete g_GameAttributes.settings.RegicideEarlyAttack;
    11861188    }
    11871189
    11881190    if (mapSettings.PlayerData)
    11891191        sanitizePlayerData(mapSettings.PlayerData);
    11901192
    function updateGUIObjects()  
    13781380    setGUIBoolean("disableTreasures", "disableTreasuresText", !!mapSettings.DisableTreasures);
    13791381    setGUIBoolean("exploreMap", "exploreMapText", !!mapSettings.ExploreMap);
    13801382    setGUIBoolean("revealMap", "revealMapText", !!mapSettings.RevealMap);
    13811383    setGUIBoolean("lockTeams", "lockTeamsText", !!mapSettings.LockTeams);
    13821384    setGUIBoolean("lastManStanding", "lastManStandingText", !!mapSettings.LastManStanding);
     1385    setGUIBoolean("regicideEarlyAttack", "regicideEarlyAttackText", !!mapSettings.RegicideEarlyAttack);
    13831386    setGUIBoolean("enableRating", "enableRatingText", !!mapSettings.RatingEnabled);
    13841387
    13851388    Engine.GetGUIObjectByName("optionWonderDuration").hidden =
    13861389        g_GameAttributes.settings.GameType &&
    13871390        g_GameAttributes.settings.GameType != "wonder";
    13881391    Engine.GetGUIObjectByName("optionLastManStanding").hidden = mapSettings.LockTeams;
     1392    Engine.GetGUIObjectByName("optionRegicideEarlyAttack").hidden =
     1393        g_GameAttributes.settings.GameType &&
     1394        g_GameAttributes.settings.GameType != "regicide";
    13891395
    13901396    Engine.GetGUIObjectByName("cheatWarningText").hidden = !g_IsNetworked || !mapSettings.CheatsEnabled;
    13911397
    13921398    Engine.GetGUIObjectByName("enableCheats").enabled = !mapSettings.RatingEnabled;
    13931399    Engine.GetGUIObjectByName("lockTeams").enabled = !mapSettings.RatingEnabled;
    function updateGUIObjects()  
    14011407
    14021408    let notScenario = g_GameAttributes.mapType != "scenario" && g_IsController ;
    14031409
    14041410    for (let ctrl of ["victoryCondition", "wonderDuration", "populationCap",
    14051411                      "startingResources", "ceasefire", "revealMap",
    1406                       "exploreMap", "disableTreasures", "lockTeams", "lastManStanding"])
     1412                      "exploreMap", "disableTreasures", "lockTeams",
     1413                      "lastManStanding", "regicideEarlyAttack"])
    14071414        hideControl(ctrl, ctrl + "Text", notScenario);
    14081415
    14091416    Engine.GetGUIObjectByName("civResetButton").hidden = !notScenario;
    14101417    Engine.GetGUIObjectByName("teamResetButton").hidden = !notScenario;
    14111418
  • binaries/data/mods/public/gui/gamesetup/gamesetup.xml

     
    333333                    <object name="wonderDuration" size="40%+10 0 100% 28" type="dropdown" style="ModernDropDown" hidden="true" tooltip_style="onscreenToolTip">
    334334                        <translatableAttribute id="tooltip">Number of minutes that the player has to keep the wonder in order to win.</translatableAttribute>
    335335                    </object>
    336336                </object>
    337337
    338                 <object name="optionPopulationCap" size="14 98 94% 126">
     338                <object name="optionRegicideEarlyAttack" size="14 98 94% 126">
     339                    <object size="0 0 40% 28" type="text" style="ModernRightLabelText">
     340                        <translatableAttribute id="caption">Early Hero Attack:</translatableAttribute>
     341                    </object>
     342                    <object name="regicideEarlyAttackText" size="40% 0 100% 28" type="text" style="ModernLeftLabelText"/>
     343                    <object name="regicideEarlyAttack" size="40%+10 5 40%+30 100%-5" type="checkbox" style="ModernTickBox" hidden="true" tooltip_style="onscreenToolTip">
     344                        <translatableAttribute id="tooltip">Toggle whether heroes can attack from the start of the game, or from City Phase.</translatableAttribute>
     345                    </object>
     346                </object>
     347
     348                <object name="optionPopulationCap" size="14 128 94% 156">
    339349                    <object size="0 0 40% 28" type="text" style="ModernRightLabelText">
    340350                        <translatableAttribute id="caption">Population Cap:</translatableAttribute>
    341351                    </object>
    342352                    <object name="populationCapText" size="40% 0 100% 100%" type="text" style="ModernLeftLabelText"/>
    343353                    <object name="populationCap" size="40%+10 0 100% 28" type="dropdown" style="ModernDropDown" hidden="true" tooltip_style="onscreenToolTip">
    344354                        <translatableAttribute id="tooltip">Select population cap.</translatableAttribute>
    345355                    </object>
    346356                </object>
    347357
    348                 <object name="optionStartingResources" size="14 128 94% 156">
     358                <object name="optionStartingResources" size="14 158 94% 186">
    349359                    <object size="0 0 40% 28" type="text" style="ModernRightLabelText">
    350360                        <translatableAttribute id="caption">Starting Resources:</translatableAttribute>
    351361                    </object>
    352362                    <object name="startingResourcesText" size="40% 0 100% 100%" type="text" style="ModernLeftLabelText"/>
    353363                    <object name="startingResources" size="40%+10 0 100% 28" type="dropdown" style="ModernDropDown" hidden="true" tooltip_style="onscreenToolTip">
    354364                        <translatableAttribute id="tooltip">Select the game's starting resources.</translatableAttribute>
    355365                    </object>
    356366                </object>
    357367
    358                 <object name="optionCeasefire" size="14 158 94% 186">
     368                <object name="optionCeasefire" size="14 188 94% 216">
    359369                    <object size="0 0 40% 28" type="text" style="ModernRightLabelText">
    360370                        <translatableAttribute id="caption">Ceasefire:</translatableAttribute>
    361371                    </object>
    362372                    <object name="ceasefireText" size="40% 0 100% 100%" type="text" style="ModernLeftLabelText"/>
    363373                    <object name="ceasefire" size="40%+10 0 100% 28" type="dropdown" style="ModernDropDown" hidden="true" tooltip_style="onscreenToolTip">
     
    438448                <!-- Hide More Options Button -->
    439449                <object
    440450                    name="hideMoreOptions"
    441451                    type="button"
    442452                    style="StoneButton"
    443                     size="50%-70 428 50%+70 456"
     453                    size="50%-70 458 50%+70 486"
    444454                    tooltip_style="onscreenToolTip"
    445455                    hotkey="cancel"
    446456                >
    447457                    <translatableAttribute id="caption">OK</translatableAttribute>
    448458                    <translatableAttribute id="tooltip">Close more game options window</translatableAttribute>
  • binaries/data/mods/public/gui/session/selection_panels.js

    g_SelectionPanels.Training = {  
    990990        tooltips.push(
    991991            "[color=\"" + g_HotkeyColor + "\"]" +
    992992            formatBatchTrainingString(buildingsCountToTrainFullBatch, fullBatchSize, remainderBatch) +
    993993            "[/color]");
    994994
     995        let productionQueueEnabled = Engine.GuiInterfaceCall("GetProductionQueueEnabled", {
     996            "player": data.unitEntState.player,
     997            "ents": data.selection
     998        });
     999
     1000        if (!productionQueueEnabled)
     1001            tooltips.push(sprintf(translate("The Production Queue is disabled for this entity")));
     1002
    9951003        if (!technologyEnabled)
    9961004            tooltips.push(sprintf(translate("Requires %(technology)s"), {
    9971005                "technology": getEntityNames(GetTechnologyData(template.requiredTechnology))
    9981006            }));
    9991007
    g_SelectionPanels.Training = {  
    10011009            tooltips.push(getNeededResourcesTooltip(neededResources));
    10021010
    10031011        data.button.tooltip = tooltips.filter(tip => tip).join("\n");
    10041012
    10051013        let modifier = "";
    1006         if (!technologyEnabled || limits.canBeAddedCount == 0)
     1014        if (!technologyEnabled || limits.canBeAddedCount == 0 || !productionQueueEnabled)
    10071015        {
    10081016            data.button.enabled = false;
    10091017            modifier = "color:0 0 0 127:grayscale:";
    10101018        }
    10111019        else if (neededResources)
  • binaries/data/mods/public/maps/scripts/Regicide.js

    Trigger.prototype.InitRegicideGame = fun  
    4747        return 0;
    4848    };
    4949
    5050    // Attempt to spawn one hero per player
    5151    let cmpRangeManager = Engine.QueryInterface(SYSTEM_ENTITY, IID_RangeManager);
     52    let cmpEndGameManager = Engine.QueryInterface(SYSTEM_ENTITY, IID_EndGameManager);
     53    this.regicideEarlyAttack = cmpEndGameManager.GetGameTypeSettings().regicideEarlyAttack;
     54
    5255    for (let playerID = 1; playerID < TriggerHelper.GetNumberOfPlayers(); ++playerID)
    5356    {
    5457        let spawnPoints = cmpRangeManager.GetEntitiesByPlayer(playerID).sort((entity1, entity2) =>
    5558            getSpawnPreference(entity2) - getSpawnPreference(entity1));
    5659
    5760        this.regicideHeroes[playerID] = this.SpawnRegicideHero(playerID, heroTemplates[playersCivs[playerID]], spawnPoints);
     61
     62        if (!this.regicideEarlyAttack)
     63            this.SetRegicideEarlyAttack(this.regicideHeroes[playerID], false);
    5864    }
    5965};
    6066
    6167/**
    6268 * Spawn a random hero at one of the given locations (which are checked in order).
    Trigger.prototype.SpawnRegicideHero = fu  
    100106
    101107    error("Couldn't spawn hero for player " + playerID);
    102108    return undefined;
    103109};
    104110
     111Trigger.prototype.CheckRegicideCityPhase = function(data)
     112{
     113    if (data.tech.indexOf("phase_city") == -1 || this.regicideEarlyAttack)
     114        return;
     115
     116    this.SetRegicideEarlyAttack(this.regicideHeroes[data.player], true);
     117};
     118
     119Trigger.prototype.SetRegicideEarlyAttack(hero, enabled)
     120{
     121    let cmpAttack = Engine.QueryInterface(heor, IID_Attack);
     122    if (cmpAttack)
     123        cmpAttack.SetEnabled(enabled);
     124
     125    let cmpAuras = Engine.QueryInterface(hero, IID_Auras);
     126    if (cmpAuras)
     127        cmpAuras.SetEnabled(enabled);
     128
     129    let cmpProductionQueue = Engine.QueryInterface(hero, IID_ProductionQueue);
     130    if (cmpProductionQueue)
     131        cmpProductionQueue.SetEnabled(enabled);
     132};
     133
    105134let cmpTrigger = Engine.QueryInterface(SYSTEM_ENTITY, IID_Trigger);
    106135cmpTrigger.regicideHeroes = [];
     136cmpTrigger.regicideEarlyAttack = false;
    107137cmpTrigger.DoAfterDelay(0, "InitRegicideGame", {});
    108138cmpTrigger.RegisterTrigger("OnOwnershipChanged", "CheckRegicideDefeat", { "enabled": true });
     139cmpTrigger.RegisterTrigger("OnResearchFinished", "CheckRegicideCityPhase", { "enabled": true });
  • binaries/data/mods/public/simulation/components/Attack.js

    Attack.prototype.Schema =  
    200200        "</element>" +
    201201    "</optional>";
    202202
    203203Attack.prototype.Init = function()
    204204{
     205    this.enabled = true;
    205206};
    206207
    207208Attack.prototype.Serialize = null; // we have no dynamic state to save
    208209
     210Attack.prototype.GetEnabled = function()
     211{
     212    return this.enabled;
     213};
     214
     215Attack.prototype.SetEnabled = function(enabled)
     216{
     217    this.enabled = enabled;
     218};
     219
    209220Attack.prototype.GetAttackTypes = function()
    210221{
    211222    return ["Melee", "Ranged", "Capture"].filter(type => !!this.template[type]);
    212223};
    213224
    Attack.prototype.GetRestrictedClasses =  
    229240    return [];
    230241};
    231242
    232243Attack.prototype.CanAttack = function(target)
    233244{
     245    if (!this.enabled)
     246        return false;
     247
    234248    let cmpFormation = Engine.QueryInterface(target, IID_Formation);
    235249    if (cmpFormation)
    236250        return true;
    237251
    238252    let cmpThisPosition = Engine.QueryInterface(this.entity, IID_Position);
    Attack.prototype.GetBestAttackAgainst =  
    339353    // check if the target is capturable
    340354    let captureIndex = types.indexOf("Capture");
    341355    if (captureIndex != -1)
    342356    {
    343357        let cmpCapturable = QueryMiragedInterface(target, IID_Capturable);
    344 
    345358        let cmpPlayer = QueryOwnerInterface(this.entity);
     359
    346360        if (allowCapture && cmpPlayer && cmpCapturable && cmpCapturable.CanCapture(cmpPlayer.GetPlayerID()))
    347361            return "Capture";
     362
    348363        // not captureable, so remove this attack
    349364        types.splice(captureIndex, 1);
    350365    }
    351366
    352367    let isPreferred = className => attack.GetPreferredClasses(className).some(isTargetClass);
  • binaries/data/mods/public/simulation/components/Auras.js

    Auras.prototype.Schema =  
    66    "</attribute>" +
    77    "<text a:help='A whitespace-separated list of aura files, placed under simulation/data/auras/'/>";
    88
    99Auras.prototype.Init = function()
    1010{
     11    this.enabled = true;
    1112    let cmpDataTemplateManager = Engine.QueryInterface(SYSTEM_ENTITY, IID_DataTemplateManager);
    1213    this.auras = {};
    1314    this.affectedPlayers = {};
    1415    let auraNames = this.GetAuraNames();
    1516    for (let name of auraNames)
    Auras.prototype.Init = function()  
    2021    // In case of autogarrisoning, this component can be called before ownership is set.
    2122    // So it needs to be completely initialised from the start.
    2223    this.Clean();
    2324};
    2425
     26Auras.prototype.GetEnabled = function()
     27{
     28    return this.enabled;
     29};
     30
     31Auras.prototype.SetEnabled = function(enabled)
     32{
     33    this.enabled = enabled;
     34    this.Clean();
     35};
     36
    2537// We can modify identifier if we want stackable auras in some case.
    2638Auras.prototype.GetModifierIdentifier = function(name)
    2739{
    2840    if (this.auras[name].stackable)
    2941        return name + this.entity;
    Auras.prototype.CalculateAffectedPlayers  
    107119    }
    108120};
    109121
    110122Auras.prototype.CanApply = function(name)
    111123{
     124    if (!this.enabled)
     125        return false;
    112126    if (!this.auras[name].requiredTechnology)
    113127        return true;
    114128    let cmpTechnologyManager = QueryOwnerInterface(this.entity, IID_TechnologyManager);
    115129    if (!cmpTechnologyManager)
    116130        return false;
  • binaries/data/mods/public/simulation/components/Formation.js

    Formation.prototype.SetMembers = functio  
    302302        var cmpUnitAI = Engine.QueryInterface(ent, IID_UnitAI);
    303303        cmpUnitAI.SetFormationController(this.entity);
    304304        cmpUnitAI.SetLastFormationTemplate(templateName);
    305305
    306306        var cmpAuras = Engine.QueryInterface(ent, IID_Auras);
    307         if (cmpAuras && cmpAuras.HasFormationAura())
     307        if (cmpAuras && cmpAuras.HasFormationAura() && cmpAuras.GetEnabled())
    308308        {
    309309            this.formationMembersWithAura.push(ent);
    310310            cmpAuras.ApplyFormationBonus(ents);
    311311        }
    312312    }
    Formation.prototype.AddMembers = functio  
    385385    {
    386386        var cmpUnitAI = Engine.QueryInterface(ent, IID_UnitAI);
    387387        cmpUnitAI.SetFormationController(this.entity);
    388388       
    389389        var cmpAuras = Engine.QueryInterface(ent, IID_Auras);
    390         if (cmpAuras && cmpAuras.HasFormationAura())
     390        if (cmpAuras && cmpAuras.HasFormationAura() && cmpAuras.GetEnabled())
    391391        {
    392392            this.formationMembersWithAura.push(ent);
    393393            cmpAuras.ApplyFormationBonus(ents);
    394394        }
    395395    }
  • binaries/data/mods/public/simulation/components/GarrisonHolder.js

    GarrisonHolder.prototype.PerformGarrison  
    273273    var cmpProductionQueue = Engine.QueryInterface(entity, IID_ProductionQueue);
    274274    if (cmpProductionQueue)
    275275        cmpProductionQueue.PauseProduction();
    276276
    277277    var cmpAura = Engine.QueryInterface(entity, IID_Auras);
    278     if (cmpAura && cmpAura.HasGarrisonAura())
     278    if (cmpAura && cmpAura.HasGarrisonAura() && cmpAura.GetEnabled())
    279279        cmpAura.ApplyGarrisonBonus(this.entity);
    280280
    281281    Engine.PostMessage(this.entity, MT_GarrisonedUnitsChanged, { "added" : [entity], "removed": [] });
    282282
    283283    var cmpUnitAI = Engine.QueryInterface(entity, IID_UnitAI);
    GarrisonHolder.prototype.Eject = functio  
    346346    var cmpProductionQueue = Engine.QueryInterface(entity, IID_ProductionQueue);
    347347    if (cmpProductionQueue)
    348348        cmpProductionQueue.UnpauseProduction();
    349349
    350350    var cmpAura = Engine.QueryInterface(entity, IID_Auras);
    351     if (cmpAura && cmpAura.HasGarrisonAura())
     351    if (cmpAura && cmpAura.HasGarrisonAura() && cmpAura.GetEnabled())
    352352        cmpAura.RemoveGarrisonBonus(this.entity);
    353353
    354354
    355355    cmpNewPosition.JumpTo(pos.x, pos.z);
    356356    cmpNewPosition.SetHeightOffset(0);
  • binaries/data/mods/public/simulation/components/GuiInterface.js

    GuiInterface.prototype.GetTimeNotificati  
    755755    let time = Engine.QueryInterface(SYSTEM_ENTITY, IID_Timer).GetTime();
    756756    // filter on players and time, since the delete timer might be executed with a delay
    757757    return this.timeNotifications.filter(n => n.players.indexOf(player) != -1 && n.endTime > time);
    758758};
    759759
     760GuiInterface.prototype.GetProductionQueueEnabled = function(player, data)
     761{
     762    for (let ent of data.ents)
     763    {
     764        let cmpProductionQueue = Engine.QueryInterface(ent, IID_ProductionQueue);
     765        if (!cmpProductionQueue)
     766            continue;
     767        else
     768            return cmpProductionQueue.GetEnabled();
     769    }
     770    return false;
     771};
     772
    760773GuiInterface.prototype.PushNotification = function(notification)
    761774{
    762775    if (!notification.type || notification.type == "text")
    763776        this.AddTimeNotification(notification);
    764777    else
    let exposedFunctions = {  
    19591972    "GetBattleState": 1,
    19601973    "GetIncomingAttacks": 1,
    19611974    "GetNeededResources": 1,
    19621975    "GetNotifications": 1,
    19631976    "GetTimeNotifications": 1,
     1977    "GetProductionQueueEnabled": 1,
    19641978
    19651979    "GetAvailableFormations": 1,
    19661980    "GetFormationRequirements": 1,
    19671981    "CanMoveEntsIntoFormation": 1,
    19681982    "IsFormationSelected": 1,
  • binaries/data/mods/public/simulation/components/ProductionQueue.js

    ProductionQueue.prototype.Schema =  
    4040        "</interleave>" +
    4141    "</element>";
    4242
    4343ProductionQueue.prototype.Init = function()
    4444{
     45    this.enabled = true;
    4546    this.nextID = 1;
    4647
    4748    this.queue = [];
    4849    // Queue items are:
    4950    //   {
    ProductionQueue.prototype.Init = functio  
    7677    this.spawnNotified = false;
    7778   
    7879    this.alertRaiser = undefined;
    7980};
    8081
     82ProductionQueue.prototype.GetEnabled = function()
     83{
     84    return this.enabled;
     85};
     86
     87ProductionQueue.prototype.SetEnabled = function(enabled)
     88{
     89    this.enabled = enabled;
     90};
     91
    8192ProductionQueue.prototype.PutUnderAlert = function(raiser)
    8293{
    8394    this.alertRaiser = raiser;
    8495};
    8596
    ProductionQueue.prototype.IsTechnologyRe  
    258269ProductionQueue.prototype.AddBatch = function(templateName, type, count, metadata)
    259270{
    260271    // TODO: there should probably be a limit on the number of queued batches
    261272    // TODO: there should be a way for the GUI to determine whether it's going
    262273    // to be possible to add a batch (based on resource costs and length limits)
     274    if (!this.enabled)
     275        return;
    263276    var cmpPlayer = QueryOwnerInterface(this.entity);
    264277
    265278    if (this.queue.length < MAX_QUEUE_SIZE)
    266279    {
    267280       
    ProductionQueue.prototype.SpawnUnits = f  
    656669            "entities": createdEnts,
    657670            "owner": cmpOwnership.GetOwner(),
    658671            "metadata": metadata,
    659672        });
    660673       
    661         if(this.alertRaiser && spawnedEnts.length > 0)
     674        if (this.alertRaiser && spawnedEnts.length > 0)
    662675        {
    663676            var cmpAlertRaiser = Engine.QueryInterface(this.alertRaiser, IID_AlertRaiser);
    664             if(cmpAlertRaiser)
     677            if (cmpAlertRaiser)
    665678                cmpAlertRaiser.UpdateUnits(spawnedEnts);
    666679        }
    667680    }
    668681   
    669682    return createdEnts.length;
  • binaries/data/mods/public/simulation/components/tests/test_Attack.js

     
     1Engine.LoadHelperScript("Player.js");
     2Engine.LoadHelperScript("ValueModification.js");
     3Engine.LoadComponentScript("interfaces/Auras.js");
     4Engine.LoadComponentScript("interfaces/AuraManager.js");
     5Engine.LoadComponentScript("interfaces/Capturable.js");
     6Engine.LoadComponentScript("interfaces/TechnologyManager.js");
     7Engine.LoadComponentScript("interfaces/Formation.js");
     8Engine.LoadComponentScript("Formation.js");
     9Engine.LoadComponentScript("interfaces/Attack.js");
     10Engine.LoadComponentScript("Attack.js");
     11
     12function TS_ASSERT_EQUAL_OBJECTS(obj1, obj2)
     13{
     14    TS_ASSERT_EQUALS(typeof obj1, typeof obj2);
     15
     16    if (typeof obj1 == "object")
     17    {
     18        TS_ASSERT_EQUALS(Object.keys(obj1).toString(), Object.keys(obj2).toString());
     19
     20        for (let prop in obj1)
     21            TS_ASSERT_EQUAL_OBJECTS(obj1[prop], obj2[prop]);
     22    }
     23    else
     24        TS_ASSERT_EQUALS(obj1, obj2);
     25}
     26
     27// Initialize player
     28{
     29    let playerEnt1 = 5;
     30
     31    AddMock(SYSTEM_ENTITY, IID_PlayerManager, {
     32        "GetPlayerByID": () => playerEnt1
     33    });
     34
     35    AddMock(playerEnt1, IID_Player, {
     36        "GetPlayerID": () => 1
     37    });
     38}
     39
     40// Create attacker
     41let entityID = 903;
     42let attacker = ++entityID;
     43
     44AddMock(attacker, IID_Position, {
     45    "IsInWorld": () => true,
     46    "GetHeightOffset": () => 5
     47});
     48
     49AddMock(attacker, IID_Ownership, {
     50    "GetOwner": owner => 1
     51});
     52
     53let cmpAttack = ConstructComponent(attacker, "Attack", {
     54    "Melee" : {
     55        "Hack": 11,
     56        "Pierce": 5,
     57        "Crush": 0,
     58        "MinRange": 3,
     59        "MaxRange": 5,
     60        "PreferredClasses": {
     61            "_string": "Female"
     62        },
     63        "RestrictedClasses": {
     64            "_string": "Elephant Archer"
     65        }
     66    },
     67    "Ranged" : {
     68        "Hack": 0,
     69        "Pierce": 10,
     70        "Crush": 0,
     71        "MinRange": 10,
     72        "MaxRange": 80,
     73        "PrepareTime": 300,
     74        "RepeatTime": 500,
     75        "PreferredClasses": {
     76            "_string": "Archer"
     77        },
     78        "RestrictedClasses": {
     79            "_string": "Elephant"
     80        }
     81    },
     82    "Capture" : {
     83        "Value": 8,
     84        "MaxRange": 10,
     85    },
     86    "Slaughter": {}
     87});
     88
     89TS_ASSERT_EQUAL_OBJECTS(cmpAttack.GetAttackTypes(), ["Melee", "Ranged", "Capture"]);
     90TS_ASSERT_EQUAL_OBJECTS(cmpAttack.GetPreferredClasses("Melee"), ["Female"]);
     91TS_ASSERT_EQUAL_OBJECTS(cmpAttack.GetRestrictedClasses("Melee"), ["Elephant", "Archer"]);
     92TS_ASSERT_EQUAL_OBJECTS(cmpAttack.GetFullAttackRange(), { "min": 0, "max": 80 });
     93TS_ASSERT_EQUAL_OBJECTS(cmpAttack.GetAttackStrengths("Capture"), { "value": 8 });
     94
     95TS_ASSERT_EQUAL_OBJECTS(cmpAttack.GetAttackStrengths("Ranged"), {
     96    "hack": 0,
     97    "pierce": 10,
     98    "crush": 0,
     99});
     100
     101TS_ASSERT_EQUAL_OBJECTS(cmpAttack.GetTimers("Ranged"), {
     102    "prepare": 300,
     103    "repeat": 500,
     104    "recharge": 200
     105});
     106
     107TS_ASSERT_EQUAL_OBJECTS(cmpAttack.GetTimers("Capture"), {
     108    "prepare": 0,
     109    "repeat": 1000,
     110    "recharge": 1000
     111});
     112
     113// Create elephant to ensure CanAttack takes restricted classes into account and rejects
     114{
     115    let innocentElephant = ++entityID;
     116
     117    AddMock(innocentElephant, IID_Identity, {
     118        "GetClassesList": () => ["Elephant"]
     119    });
     120
     121    AddMock(innocentElephant, IID_Position, {
     122        "IsInWorld": () => true,
     123        "GetHeightOffset": () => 8
     124    });
     125
     126    TS_ASSERT_EQUALS(cmpAttack.CanAttack(innocentElephant), false);
     127
     128    cmpAttack.SetEnabled(true);
     129    TS_ASSERT_EQUALS(cmpAttack.CanAttack(innocentElephant), false);
     130}
     131
     132// Create woman to test SetEnabled, GetEnabled, CanAttack and GetBestAttackAgainst
     133{
     134    let helplessWoman = ++entityID;
     135
     136    AddMock(helplessWoman, IID_Identity, {
     137        "GetClassesList": () => ["Female"]
     138    });
     139
     140    AddMock(helplessWoman, IID_Position, {
     141        "IsInWorld": () => true,
     142        "GetHeightOffset": () => 2
     143    });
     144
     145    TS_ASSERT_EQUALS(cmpAttack.GetEnabled(helplessWoman), true);
     146    TS_ASSERT_EQUALS(cmpAttack.CanAttack(helplessWoman), true);
     147    TS_ASSERT_EQUALS(cmpAttack.GetBestAttackAgainst(helplessWoman), "Melee");
     148
     149    for (let value of [true, false, true])
     150    {
     151        cmpAttack.SetEnabled(value);
     152        TS_ASSERT_EQUALS(cmpAttack.GetEnabled(helplessWoman), value);
     153        TS_ASSERT_EQUALS(cmpAttack.CanAttack(helplessWoman), value);
     154    }
     155}
     156
     157// Create archer to test CanAttack and GetBestAttackAgainst
     158{
     159    let archer = ++entityID;
     160
     161    AddMock(archer, IID_Identity, {
     162        "GetClassesList": () => ["Archer"]
     163    });
     164
     165    AddMock(archer, IID_Position, {
     166        "IsInWorld": () => true,
     167        "GetHeightOffset": () => 4
     168    });
     169
     170    TS_ASSERT_EQUALS(cmpAttack.CanAttack(archer), true);
     171    TS_ASSERT_EQUALS(cmpAttack.GetBestAttackAgainst(archer), "Ranged");
     172}
     173
     174// Create building to test CanAttack and GetBestAttackAgainst with capturing
     175{
     176    let darkFortress = ++entityID;
     177
     178    AddMock(darkFortress, IID_Identity, {
     179        "GetClassesList": () => ["Structure"]
     180    });
     181
     182    AddMock(darkFortress, IID_Position, {
     183        "IsInWorld": () => true,
     184        "GetHeightOffset": () => 4
     185    });
     186
     187    AddMock(darkFortress, IID_Capturable, {
     188        "CanCapture": playerID => {
     189            TS_ASSERT_EQUALS(playerID, 1);
     190            return true;
     191        }
     192    });
     193
     194    TS_ASSERT_EQUALS(cmpAttack.CanAttack(darkFortress), true);
     195    TS_ASSERT_EQUALS(cmpAttack.GetBestAttackAgainst(darkFortress, true), "Capture");
     196}
     197
     198// Slaughter sheep
     199{
     200    let sheep = ++entityID;
     201
     202    AddMock(sheep, IID_Identity, {
     203        "GetClassesList": () => ["Domestic"]
     204    });
     205
     206    AddMock(sheep, IID_Position, {
     207        "IsInWorld": () => true,
     208        "GetHeightOffset": () => 2
     209    });
     210
     211    TS_ASSERT_EQUALS(cmpAttack.CanAttack(sheep), true);
     212    TS_ASSERT_EQUALS(cmpAttack.GetBestAttackAgainst(sheep, true), "Slaughter");
     213}
  • binaries/data/mods/public/simulation/components/tests/test_Auras.js

    Property changes on: binaries/data/mods/public/simulation/components/tests/test_Attack.js
    ___________________________________________________________________
    Added: svn:eol-style
    ## -0,0 +1 ##
    +native
    \ No newline at end of property
    AddMock(SYSTEM_ENTITY, IID_RangeManager,  
    2121    },
    2222    EnableActiveQuery: function(id) { },
    2323    ResetActiveQuery: function(id) { if (mode == 0) return []; else return [enemy]; },
    2424    DisableActiveQuery: function(id) { },
    2525    GetEntityFlagMask: function(identifier) { },
     26    "DestroyActiveQuery": () => {}
    2627});
    2728
    2829AddMock(SYSTEM_ENTITY, IID_DataTemplateManager, {
    2930    GetAuraTemplate: function(name) {
    3031        if (name == "test1")
    var auras = ConstructComponent(auraEnt,  
    7172
    7273// send the rangeManager message
    7374auras.OnRangeUpdate({"tag": 1, "added": [30], "removed": []});
    7475
    7576TS_ASSERT_EQUALS(ApplyValueModificationsToEntity("Component/Value", 1, targetEnt), 2);
     77TS_ASSERT_EQUALS(auras.GetEnabled(), true);
     78
     79auras.SetEnabled(false)
     80TS_ASSERT_EQUALS(auras.GetEnabled(), false);
     81
     82auras.SetEnabled(true)
     83TS_ASSERT_EQUALS(auras.GetEnabled(), true);
  • binaries/data/mods/public/simulation/components/tests/test_GarrisonHolder.js

     
     1Engine.LoadHelperScript("Player.js");
     2Engine.LoadComponentScript("interfaces/GarrisonHolder.js");
     3Engine.LoadComponentScript("interfaces/Health.js");
     4Engine.LoadComponentScript("GarrisonHolder.js");
     5Engine.LoadComponentScript("Identity.js");
     6
     7let garrisonEnt = 15;
     8let unitEnt = 33;
     9let entHP = 1000;
     10
     11AddMock(garrisonEnt, IID_Health, {
     12    "GetHitpoints": () => entHP,
     13    "Decrease": hp => {
     14        entHP = Math.max(entHP - hp, 0);
     15    },
     16});
     17
     18let cmpGarrisonHolder = ConstructComponent(garrisonEnt, "GarrisonHolder", {
     19    "LoadingRange": "2.0",
     20    "Max": "20",
     21    "List": "Support"
     22});
     23
     24TS_ASSERT_EQUALS(cmpGarrisonHolder.GetGarrisonedEntitiesCount(), 0);
     25TS_ASSERT_EQUALS(cmpGarrisonHolder.entities.length, 0);
     26TS_ASSERT_EQUALS(cmpGarrisonHolder.visibleGarrisonPoints.length, 0);
     27TS_ASSERT_EQUALS(+cmpGarrisonHolder.template.Max, 20);
     28TS_ASSERT_EQUALS(cmpGarrisonHolder.GetLoadingRange().max, 2.0);
  • binaries/data/mods/public/simulation/components/tests/test_ProductionQueue.js

    Property changes on: binaries/data/mods/public/simulation/components/tests/test_GarrisonHolder.js
    ___________________________________________________________________
    Added: svn:eol-style
    ## -0,0 +1 ##
    +native
    \ No newline at end of property
     
     1Engine.LoadHelperScript("Player.js");
     2Engine.LoadHelperScript("ValueModification.js");
     3Engine.LoadComponentScript("interfaces/ProductionQueue.js");
     4Engine.LoadComponentScript("interfaces/TechnologyManager.js");
     5Engine.LoadComponentScript("interfaces/Player.js");
     6Engine.LoadComponentScript("ProductionQueue.js");
     7Engine.LoadComponentScript("TechnologyManager.js");
     8Engine.LoadComponentScript("Player.js");
     9
     10let playerEntity = 1;
     11let productionEnt = 31;
     12let trainTemplate = "units/athen_infantry_spearman_b";
     13
     14AddMock(SYSTEM_ENTITY, IID_PlayerManager, {
     15    "GetPlayerByID": id => playerEntity,
     16    "GetCheatTimeMultiplier": () => 20,
     17});
     18
     19AddMock(SYSTEM_ENTITY, IID_TemplateManager, {
     20    "GetTemplate": trainTemplate => trainTemplate,
     21});
     22
     23let cmpProductionQueue = ConstructComponent(productionEnt, "ProductionQueue", {
     24    "BatchTimeModifier": "0.7",
     25    "Entities": "units/athen_infantry_spearman_b"
     26});
     27
     28TS_ASSERT_EQUALS(cmpProductionQueue.GetEnabled(), true);
     29
     30cmpProductionQueue.SetEnabled(false);
     31TS_ASSERT_EQUALS(cmpProductionQueue.GetEnabled(), false);
     32
     33cmpProductionQueue.SetEnabled(true);
     34TS_ASSERT_EQUALS(cmpProductionQueue.GetEnabled(), true);
     35
     36cmpProductionQueue.PutUnderAlert(productionEnt);
     37TS_ASSERT_EQUALS(cmpProductionQueue.alertRaiser, productionEnt);
     38
     39cmpProductionQueue.ResetAlert();
     40TS_ASSERT_EQUALS(cmpProductionQueue.alertRaiser, undefined);
     41TS_ASSERT_EQUALS(cmpProductionQueue.GetQueue().length, 0);