Ticket #4220: 4220.diff

File 4220.diff, 6.8 KB (added by fatherbushido, 7 years ago)

bb's patch as a diff

  • binaries/data/mods/public/gui/session/unit_actions.js

    var unitActions =  
    133133        "getActionInfo": function(entState, targetState)
    134134        {
    135135            if (!entState.attack || !targetState.hitpoints)
    136136                return false;
    137137
    138             return {
    139                 "possible": Engine.GuiInterfaceCall("CanCapture", {
     138            return { "possible": Engine.GuiInterfaceCall("CanAttack", {
    140139                    "entity": entState.id,
    141                     "target": targetState.id
     140                    "target": targetState.id,
     141                    "types": ["Capture"]
    142142                })
    143143            };
    144144        },
    145145        "actionCheck": function(target)
    146146        {
    var unitActions =  
    181181                return false;
    182182
    183183            return {
    184184                "possible": Engine.GuiInterfaceCall("CanAttack", {
    185185                    "entity": entState.id,
    186                     "target": targetState.id
     186                    "target": targetState.id,
     187                    "types": ["Ranged", "Melee"]
    187188                })
    188189            };
    189190        },
    190191        "hotkeyActionCheck": function(target)
    191192        {
    var unitActions =  
    438439                "entity": selection[0]
    439440            });
    440441
    441442            return true;
    442443        },
    443         "getActionInfo":  function(entState, targetState)
     444        "getActionInfo": function(entState, targetState)
    444445        {
    445446            if (!targetState.resourceSupply)
    446447                return false;
    447448
    448449            let resource = findGatherType(entState, targetState.resourceSupply);
  • binaries/data/mods/public/simulation/components/Attack.js

    Attack.prototype.GetRestrictedClasses =  
    206206        return this.template[type].RestrictedClasses._string.split(/\s+/);
    207207
    208208    return [];
    209209};
    210210
    211 Attack.prototype.CanAttack = function(target)
     211Attack.prototype.CanAttack = function(target, wantedTypes)
    212212{
    213213    let cmpFormation = Engine.QueryInterface(target, IID_Formation);
    214214    if (cmpFormation)
    215215        return true;
    216216
    217217    let cmpThisPosition = Engine.QueryInterface(this.entity, IID_Position);
    218218    let cmpTargetPosition = Engine.QueryInterface(target, IID_Position);
    219219    if (!cmpThisPosition || !cmpTargetPosition || !cmpThisPosition.IsInWorld() || !cmpTargetPosition.IsInWorld())
    220220        return false;
    221221
    222     // Check if the relative height difference is larger than the attack range
    223     // If the relative height is bigger, it means they will never be able to
    224     // reach each other, no matter how close they come.
    225     let heightDiff = Math.abs(cmpThisPosition.GetHeightOffset() - cmpTargetPosition.GetHeightOffset());
    226 
    227222    const cmpIdentity = Engine.QueryInterface(target, IID_Identity);
    228223    if (!cmpIdentity)
    229224        return undefined;
    230225
     226    let cmpEntityPlayer = QueryOwnerInterface(this.entity);
     227    let cmpTargetPlayer = QueryOwnerInterface(target);
     228    if (!cmpTargetPlayer || !cmpEntityPlayer)
     229        return false;
     230
     231    let targetOwner = cmpEntityPlayer.GetPlayerID();
    231232    const targetClasses = cmpIdentity.GetClassesList();
     233    let cmpCapturable = QueryMiragedInterface(target, IID_Capturable);
     234    if (targetClasses.indexOf("Domestic") == -1 && !cmpEntityPlayer.IsEnemy(cmpTargetPlayer.GetPlayerID()) &&
     235       (!cmpCapturable || !cmpCapturable.CanCapture(targetOwner)))
     236        return false;
     237
     238    // Check if the relative height difference is larger than the attack range
     239    // If the relative height is bigger, it means they will never be able to
     240    // reach each other, no matter how close they come.
     241    let heightDiff = Math.abs(cmpThisPosition.GetHeightOffset() - cmpTargetPosition.GetHeightOffset());
    232242
    233243    for (let type of this.GetAttackTypes())
    234244    {
    235         if (type == "Capture" && !QueryMiragedInterface(target, IID_Capturable))
     245        if (wantedTypes && (wantedTypes.indexOf(type) == -1 || wantedTypes.indexOf("no" + type) != -1))
     246            continue;
     247
     248        if (type == "Capture" && (!cmpCapturable || !cmpCapturable.CanCapture(targetOwner)))
    236249            continue;
    237250
    238251        if (heightDiff > this.GetRange(type).max)
    239252            continue;
    240253
  • binaries/data/mods/public/simulation/components/GuiInterface.js

    GuiInterface.prototype.GetTradingDetails  
    18281828        result = { "type": "set first" };
    18291829    }
    18301830    return result;
    18311831};
    18321832
    1833 GuiInterface.prototype.CanCapture = function(player, data)
    1834 {
    1835     let cmpAttack = Engine.QueryInterface(data.entity, IID_Attack);
    1836     if (!cmpAttack)
    1837         return false;
    1838 
    1839     let owner = QueryOwnerInterface(data.entity).GetPlayerID();
    1840 
    1841     let cmpCapturable = QueryMiragedInterface(data.target, IID_Capturable);
    1842     if (cmpCapturable && cmpCapturable.CanCapture(owner) && cmpAttack.GetAttackTypes().indexOf("Capture") != -1)
    1843         return cmpAttack.CanAttack(data.target);
    1844 
    1845     return false;
    1846 };
    1847 
    18481833GuiInterface.prototype.CanAttack = function(player, data)
    18491834{
    18501835    let cmpAttack = Engine.QueryInterface(data.entity, IID_Attack);
    1851     if (!cmpAttack)
    1852         return false;
    1853 
    1854     let cmpEntityPlayer = QueryOwnerInterface(data.entity, IID_Player);
    1855     let cmpTargetPlayer = QueryOwnerInterface(data.target, IID_Player);
    1856     if (!cmpEntityPlayer || !cmpTargetPlayer)
    1857         return false;
    1858 
    1859     // if the owner is an enemy, it's up to the attack component to decide
    1860     if (cmpEntityPlayer.IsEnemy(cmpTargetPlayer.GetPlayerID()))
    1861         return cmpAttack.CanAttack(data.target);
    1862 
    1863     return false;
     1836    return cmpAttack && cmpAttack.CanAttack(data.target, data.types || undefined);
    18641837};
    18651838
    18661839/*
    18671840 * Returns batch build time.
    18681841 */
    let exposedFunctions = {  
    20031976    "PlaySound": 1,
    20041977    "FindIdleUnits": 1,
    20051978    "HasIdleUnits": 1,
    20061979    "GetTradingRouteGain": 1,
    20071980    "GetTradingDetails": 1,
    2008     "CanCapture": 1,
    20091981    "CanAttack": 1,
    20101982    "GetBatchTime": 1,
    20111983
    20121984    "IsMapRevealed": 1,
    20131985    "SetPathfinderDebugOverlay": 1,
  • binaries/data/mods/public/simulation/components/tests/test_Attack.js

    function attackComponentTest(defenderCla  
    2020        AddMock(SYSTEM_ENTITY, IID_PlayerManager, {
    2121            "GetPlayerByID": () => playerEnt1
    2222        });
    2323
    2424        AddMock(playerEnt1, IID_Player, {
    25             "GetPlayerID": () => 1
     25            "GetPlayerID": () => 1,
     26            "IsEnemy": () => true
    2627        });
    2728    }
    2829
    2930    let attacker = entityID;
    3031
    function attackComponentTest(defenderCla  
    9091    AddMock(defender, IID_Position, {
    9192        "IsInWorld": () => true,
    9293        "GetHeightOffset": () => 0
    9394    });
    9495
     96    AddMock(defender, IID_Ownership, {
     97        "GetOwner": () => 1
     98    });
     99
    95100    test_function(attacker, cmpAttack, defender);
    96101}
    97102
    98103// Validate template getter functions
    99104attackComponentTest(undefined, (attacker, cmpAttack, defender) => {