Page 1 of 1

Armor Ignore problems

Posted: Thu Jun 17, 2021 3:16 am
by dragon slayer
Here is my scripts

first is abilities.js
function onSpecialMove(pUser, abilityID)
{
    if (!CheckMana(pUser, abilityID))
        return true;

    switch (abilityID)
    {
        case 0x01: // Armor Ignore
            HandleArmorIgnore(pUser, abilityID);
            break;
        default:
            break;
    }
    return true;
}

function CheckMana(pUser, abilityID)
{
    var Mana = 30;
    if (pUser.mana <= Mana)
    {
        pUser.TextMessage("You need " + Mana + " mana to perform that attack"); // 1060181 mana.ToString() You need ~1_MANA_REQUIREMENT~ mana to perform that attack
        DeactivateSpecialMove(pUser.socket, abilityID);
        return false;
    }
    else
        pUser.mana -= Mana;
    return true;
}

function HandleArmorIgnore(pUser, abilityID)
{
    TriggerEvent(401, "ArmorIgnore", pUser.pAttacker, pUser.pDefender, abilityID);
    //onAttack(pUser.pAttacker, pUser.pDefender, abilityID)
    pUser.StartTimer(5000, abilityID, true);
}

/*function onAttack(pAttacker, pDefender, abilityID)
{
    pAttacker.TextMessage("Your attack penetrates their armor!");
    pDefender.health -= 9;
    pDefender.TextMessage("The blow penetrated your armor!");

    pDefender.SoundEffect(0x0056, true);
    pDefender.StaticEffect(0x3728, 0x09, 0x06);
    DeactivateSpecialMove(pAttacker.socket, abilityID);
}*/


function DeactivateSpecialMove(pSocket, abilityID)
{
    var toSend = new Packet;
    toSend.ReserveSize(7)
    toSend.WriteByte(0, 0xbf); // Packet
    toSend.WriteShort(1, 0x07); // Length
    toSend.WriteShort(3, 0x21); // SubCmd
    toSend.WriteByte(5, abilityID); // Ability ID
    toSend.WriteByte(6, 0); // On/off
    pSocket.Send(toSend);
    toSend.Free();
}

function onTimer(timerObj, timerID)
{
    //Toggle ability off after 2 second timer has elapsed
    var toSend = new Packet;
    toSend.ReserveSize(7)
    toSend.WriteByte(0, 0xbf); // Packet
    toSend.WriteShort(1, 0x07); // Length
    toSend.WriteShort(3, 0x21); // SubCmd
    toSend.WriteByte(5, timerID); // Ability ID
    toSend.WriteByte(6, 0); // On/off
    timerObj.socket.Send(toSend);
    toSend.Free();
}
That code should then call this script to open
ArmorIgnore.js
function onAttack(pAttacker, pDefender, abilityID)
{
    pAttacker.TextMessage("Your attack penetrates their armor!");
    pDefender.health -= 9;
    pDefender.TextMessage("The blow penetrated your armor!");

    pDefender.SoundEffect(0x0056, true);
    pDefender.StaticEffect(0x3728, 0x09, 0x06);
    DeactivateSpecialMove(pAttacker.socket, abilityID);
}

function DeactivateSpecialMove(pSocket, abilityID)
{
    var toSend = new Packet;
    toSend.ReserveSize(7)
    toSend.WriteByte(0, 0xbf); // Packet
    toSend.WriteShort(1, 0x07); // Length
    toSend.WriteShort(3, 0x21); // SubCmd
    toSend.WriteByte(5, abilityID); // Ability ID
    toSend.WriteByte(6, 0); // On/off
    pSocket.Send(toSend);
    toSend.Free();
}

This line is giving me a error
TriggerEvent(401, "ArmorIgnore", pUser.pAttacker, pUser.pDefender, abilityID);

Re: Armor Ignore problems

Posted: Thu Jun 17, 2021 8:22 am
by Xuri
You didn't include the actual error :) though I'm guessing it's because your TriggerEvent line calls upon the name of the script, but instead should call upon the name of the function you want to execute in the script. The script reference itself is already handled via the scriptID (401 in this case), but UOX3 needs to know which function you intend to run in the script.

I suspect you don't really need the TriggerEvent at all in this case though. What you need, is to - in your first script - set a flag on the character that activates the special ability, and then check for that flag in the onAttack event in the second script.

For example, if you change your HandleArmorIgnore function to this:
function HandleArmorIgnore(pUser, abilityID)
{
    pUser.SetTag( "ArmorIgnore", true );
    pUser.StartTimer(5000, abilityID, true);
}
Then change your onAttack function in ArmorIgnore.js to this:
function onAttack(pAttacker, pDefender, abilityID)
{
    if( pUser.GetTag( "ArmorIgnore" ))
    {
        pAttacker.TextMessage("Your attack penetrates their armor!");
        pDefender.TextMessage("The blow penetrated your armor!");

        pDefender.SoundEffect(0x0056, true);
        pDefender.StaticEffect(0x3728, 0x09, 0x06);
        DeactivateSpecialMove(pAttacker.socket, abilityID);
    }
}
Also add a onCombatDamageCalc event to the initial script (same script as onSpecialMove), to handle the calculation of damage if armor strike is enabled:
function onCombatDamageCalc( pAttacker, pDefender, fightSkill, hitLoc )
{
    var baseDamage = pAttacker.attack;

    if( baseDamage == -1 )  // No damage if weapon breaks
        return 0;

    var damage = ApplyDamageBonuses( 1, pAttacker, pDefender, fightSkill, hitLoc, baseDamage );

    if( damage < 1 )
        return 0;

    // Check if attacker has armor ignore enabled
    if( !pAttacker.GetTag( "ArmorIgnore" ))
    {
        // Armor Ignore ignores defense modifiers, but deals only 90% of potential damage
        damage *= 0.9;

        if( fightSkill == 31 ) // Archery
        {
            // Cap damage from Armor Strike attack at 30 for archery weapons
            if( damage > 30 )
                damage = 30;
        }
        else
        {
            // For all othe rfighting skills, cap damage from Armor Strike at 35
            if( damage > 35 )
                damage = 35;
        }
    }
    else
    {
        // Otherwise, apply normal defense modifiers
        damage = ApplyDefenseModifiers( 1, pAttacker, pDefender, fightSkill, hitLoc, damage, true);
    }

    // If damage after defense modifiers is below 0, do a small random amount of damage still
    if( damage <= 0 )
        damage = RandomNumber( 0, 4 );

    // If defender is a player, damage is divided by this modifier from uox.ini
    if( !pDefender.npc )
        damage /= GetServerSetting( "NPCDAMAGERATE" );

    return damage;
}
The onCombatDamageCalc() event essentially overrides, but uses the exact same setup as hard code for calculating combat damage, but here with the addition of the armor strike special move taken into account. Note that this requires a small update to the combat code, which I will commit to develop shortly have committed to develop, which moves hitloc calculation and hit messages out of the calcDamage function in code, so these can still happen even if that function is overridden by this JS event.

Final note, be sure to set the ArmorIgnore tag to false when deactivating the special ability in the onTimer event in your first script!