summaryrefslogblamecommitdiff
path: root/npc/magic/final.txt
blob: 49faa4da346b7e30486f832ef90933fa285cff7f (plain) (tree)










































                                                                                                                                                                                 
                               


























































































































































































































































































































































                                                                                                                  
          



























































                                                         
                                                      

                                   
                                                    

                                  

                                                       
     
                                          





                                              
                                     

                                                      

                                                                         
                                                      

         


                                                                   


           
// TMW2 scripts.
// Authors:
//    Jesusalva
//    TMW Org.
// Description:
//    HUB functions (Magic)
// HUB_SkillInvoke (  )
function	script	HUB_SkillInvoke	{
    // Something is... wrong
    if (!@skillId) {
        Exception("ILLEGAL SKILL PASSED TO HUB. It has been compromised, Jim.", RB_DEBUGMES|RB_IRCBROADCAST);
        debugmes "Legal Caster: %s", strcharinfo(0);
        debugmes "Effective Caster: %d", @skillCaster;
        return;
    }

    /* *********************************************************************** */
    // TODO: Detect what was script-cast and what was player-case. Then, readd RB_IRCBROADCAST
    // If you can't do this: You can't do this
    if (getskilllv(@skillId) < @skillLv && @skillId != BS_GREED)
        Exception("System ERROR, HSI."+@skillId+" INVALID CAST (got "+@skillLv+" expected "+getskilllv(@skillId)+", sub-LC."+(getcharid(3)-2000000)+")", RB_DEBUGMES|RB_ISFATAL);
    // You are AFK for over 3 minutes, that's crazy, disregard
    if (checkidle() > 180)
        return;

    // Record to database
    skillInvoke[@skillId] = skillInvoke[@skillId] + 1;

    // Script-based skills
    /* *********************************************************************** */
    switch (@skillId) {
        case TMW2_FAKESKILL:
            charcommand("@refresh"); // Possibly broken on too up-to-date Herc
            break;
        case EVOL_AREA_PROVOKE:
            if (@skillTargetX && @skillTargetY)
                massprovoke(1+@skillLv, getmap(), @skillTargetX, @skillTargetY);
            else
                massprovoke(1+@skillLv);
            // SC_PROVOKE ?
            GetManaExp(@skillId, rand2(1,3));
            break;
        ////////////////////////////////
        /* / XXX: Healing Class
        case TMW2_FIRSTAID:
            .@PW=90+(10*@skillLv);
            // First aid only works on you, so
            .@heal=max(AdjustSpellpower(.@PW), AdjustAttackpower(.@PW));
            heal .@heal, 0;
            GetManaExp(TMW2_HEALING, 1);
            break;
        case TMW2_HEALING:
            .@PW=130+(20*@skillLv);
            harm(@skillTarget, -AdjustSpellpower(.@PW), HARM_MISC);
            GetManaExp(TMW2_HEALING, 2);
            break;
        case TMW2_MAGNUSHEAL:
            // Area healing
            .@PW=200+(20*@skillLv);
            .@RG=4+(@skillLv/5);
            areaharm(@skillTarget, .@RG, -AdjustSpellpower(.@PW), HARM_MISC, "filter_friendly");
            GetManaExp(TMW2_HEALING, 3);
            break;
        ////////////////////////////////
        // XXX: Fire Class
        // (May burn targets for damage over time)
        case TMW2_FIREARROW:
            .@PW=140+(10*@skillLv);
            // 4% chance, 2.5s
            harm(@skillTarget, AdjustSpellpower(.@PW), HARM_MAGI, Ele_Fire);
            sc_start SC_BLOODING, 4500, 1, 400, SCFLAG_NONE, @skillTarget;
            GetManaExp(TMW2_FIREBALL, 1);
            break;
        case TMW2_FIREBALL:
            .@PW=140+(10*@skillLv);
            .@RG=2+(@skillLv/5);
            // 22% chance, 2.5s
            areaharm(@skillTarget, .@RG, AdjustSpellpower(.@PW), HARM_MAGI, Ele_Fire);
            sc_start SC_BLOODING, 2500, 1, 4200, SCFLAG_NONE, @skillTarget;
            GetManaExp(TMW2_FIREBALL, 2);
            break;
        case TMW2_ARMAGEDDON:
            .@PW=140+(10*@skillLv);
            .@RG=5+(@skillLv/5);
            // 18% chance, 3s, 3x3 radius
            areaharm(@skillTarget, .@RG, AdjustSpellpower(.@PW), HARM_MAGI, Ele_Fire);
            areasc(.@RG, 6000, SC_BLOODING, BL_MOB|BL_PC|BL_HOM|BL_MER, 1, "filter_hostile", @skillTarget, 1800);
            GetManaExp(TMW2_FIREBALL, 3);
            break;
        ////////////////////////////////
        // XXX: Holy Class
        // (Single DPS + AOE)
        case TMW2_NAPALMBEAT:
            .@PW=35+(5*@skillLv);
            .@dmg=AdjustSpellpower(.@PW);
            .@RG=2+(@skillLv/3);
            harm(@skillTarget, .@dmg/10, HARM_MAGI, Ele_Holy);
            areaharm(@skillTarget, .@RG, .@dmg, HARM_MAGI, Ele_Holy);
            GetManaExp(TMW2_HOLYLIGHT, 1);
            break;
        case TMW2_HOLYLIGHT:
            .@PW=125+(25*@skillLv);
            .@dmg=AdjustSpellpower(.@PW);
            harm(@skillTarget, .@dmg, HARM_MAGI, Ele_Holy);
            areaharm(@skillTarget, 1, .@dmg/5, HARM_MAGI, Ele_Holy);
            GetManaExp(TMW2_HOLYLIGHT, 2);
            break;
        case TMW2_JUDGMENT:
            .@PW=250+(50*@skillLv);
            .@SPW=60+(15*@skillLv);
            .@dmg=AdjustSpellpower(.@PW);
            .@dsub=AdjustSpellpower(.@SPW);
            .@RG=3+(@skillLv/5);
            harm(@skillTarget, .@dmg, HARM_MAGI, Ele_Holy);
            areaharm(@skillTarget, .@RG, .@dsub, HARM_MAGI, Ele_Holy);
            GetManaExp(TMW2_HOLYLIGHT, 3);
            break;
        ////////////////////////////////
        // XXX: Wind Class
        // (Smaller cooldown than others)
        case TMW2_MAGICSTRIKE:
            .@PW=125+(25*@skillLv);
            .@dmg=AdjustSpellpower(.@PW);
            harm(@skillTarget, .@dmg, HARM_MAGI, Ele_Wind);
            GetManaExp(TMW2_LIGHTNINGBOLT, 1);
            break;
        case TMW2_LIGHTNINGBOLT:
            .@PW=150+(50*@skillLv);
            .@dmg=AdjustSpellpower(.@PW);
            harm(@skillTarget, .@dmg, HARM_MAGI, Ele_Wind);
            GetManaExp(TMW2_LIGHTNINGBOLT, 2);
            break;
        case TMW2_TEMPEST:
            .@PW=125+(25*@skillLv);
            .@dmg=AdjustSpellpower(.@PW);
            .@RG=2+(@skillLv/5);
            areaharm(@skillTarget, .@RG, .@dmg, HARM_MAGI, Ele_Wind);
            GetManaExp(TMW2_LIGHTNINGBOLT, 3);
            break;
        ////////////////////////////////
        // XXX: Ice Class
        // (May freeze the targets)
        case TMW2_FROSTDIVER:
            .@PW=80+(10*@skillLv);
            // 22% chance, 2.5s
            harm(@skillTarget, AdjustSpellpower(.@PW), HARM_MAGI, Ele_Water);
            sc_start SC_FREEZE, 2500, 1, 2200, SCFLAG_NONE, @skillTarget;
            GetManaExp(TMW2_NILFHEIM, 1);
            break;
        case TMW2_FROSTNOVA:
            .@PW=80+(10*@skillLv);
            .@RG=2+(@skillLv/5);
            // 18% chance, 3s, 3x3 radius
            areaharm(@skillTarget, .@RG, AdjustSpellpower(.@PW), HARM_MAGI, Ele_Water);
            areasc(.@RG, 3000, SC_FREEZE, BL_MOB|BL_PC|BL_HOM|BL_MER, 1, "filter_hostile", @skillTarget, 1800);
            GetManaExp(TMW2_NILFHEIM, 2);
            break;
        case TMW2_NILFHEIM:
            // Nilfheim cast on self?
            .@PW=80+(10*@skillLv);
            .@RG=4+(@skillLv/5);
            areaharm(getcharid(3), .@RG*3/2, AdjustSpellpower(.@PW), HARM_MAGI, Ele_Water);
            areasc(.@RG, 15000, SC_FREEZE, BL_PC | BL_MOB | BL_MER | BL_HOM, 1, "filter_hostile");
            // Maybe filter_notme() would work better, indeed
            GetManaExp(TMW2_NILFHEIM, 3);
            break;
        ////////////////////////////////
        // XXX: Earth Class
        // DEF Effects at Gaia Break, more expensive
        case TMW2_METEORSTRIKE:
            .@PW=130+(20*@skillLv);
            .@dmg=AdjustSpellpower(.@PW);
            .@TM=1200+(@skillLv*300);
            harm(@skillTarget, .@dmg, HARM_MAGI, Ele_Earth);
            sc_start SC_STUN, .@TM, 1, 800, SCFLAG_NONE, @skillTarget;
            GetManaExp(TMW2_METEORSTRIKE, 1);
            break;
        case TMW2_METEORSHOWER:
            .@PW=130+(15*@skillLv);
            .@dmg=AdjustSpellpower(.@PW);
            .@RG=3+(@skillLv/5);
            .@TM=800+(@skillLv*200);
            areaharm(@skillTarget, .@RG, .@dmg, HARM_MAGI, Ele_Earth);
            areasc(.@RG, .@TM, SC_STUN, BL_MOB | BL_PC | BL_HOM | BL_MER, 1, "filter_hostile", @skillTarget, 800);
            GetManaExp(TMW2_METEORSTRIKE, 2);
            break;
        case TMW2_GAIABREAK:
            .@PWA=170+(30*@skillLv);
            .@PWB=110+(10*@skillLv);
            .@dmg=AdjustSpellpower(.@PWA);
            .@dsub=AdjustSpellpower(.@PWB);
            harm(@skillTarget, .@dmg, HARM_MAGI, Ele_Earth);
            rectharm(@skillTarget, 2, 5, .@dsub, HARM_MAGI, Ele_Earth);
            areasc(2, 5000, SC_INCDEFRATE, BL_PC, 10, "filter_friendly");
            GetManaExp(TMW2_METEORSTRIKE, 3);
            break;
        ////////////////////////////////
        // XXX: Physical Class (Regular)
        case TMW2_FALKONSTRIKE:
            .@PW=100+(25*@skillLv);
            .@ST=0+(10*@skillLv);
            .@TM=100+(90*@skillLv);
            harm(@skillTarget, AdjustAttackpower(.@PW), HARM_PHYS, Ele_Neutral);
            sc_start SC_STUN, .@TM, 1, .@ST, SCFLAG_NONE, @skillTarget;
            GetManaExp(@skillId, rand2(1,3));
            break;
        case TMW2_GROUNDSTRIKE:
            .@PW=50+(40*@skillLv);
            .@dmg=AdjustAttackpower(.@PW);
            .@RG=2+(@skillLv/5);
            .@TM=100+(@skillLv*200);
            .@ST=500+(100*@skillLv);
            .@EF=any(SC_STUN, SC_BLIND, SC_BLOODING, SC_BLIND, SC_BLOODING);
            areaharm(@skillTarget, .@RG, .@dmg, HARM_PHYS, Ele_Neutral);
            areasc(.@RG, .@TM, .@EF, BL_MOB | BL_PC | BL_HOM | BL_MER, 1, "filter_hostile", @skillTarget, .@ST);
            GetManaExp(@skillId, rand2(1,3));
            break;
        case TMW2_SUPREMEATTACK:
            .@PW=100+(50*@skillLv);
            harm(@skillTarget, AdjustAttackpower(.@PW), HARM_PHYS, Ele_Neutral);
            GetManaExp(@skillId, rand2(1,3));
            break;
        ////////////////////////////////
        // XXX: Physical Class (Archery)
        case TMW2_CHARGEDARROW:
            .@PW=100+(50*@skillLv);
            harm(@skillTarget, AdjustAttackpower(.@PW), HARM_PHYS, Ele_Neutral);
            GetManaExp(@skillId, rand2(1,3));
            break;
        case TMW2_ARROWSHOWER:
            .@PW=150+(10*@skillLv);
            .@dmg=AdjustAttackpower(.@PW);
            .@RG=1+(@skillLv/3);
            areaharm(@skillTarget, .@RG, .@dmg, HARM_PHYS, Ele_Neutral);
            GetManaExp(@skillId, rand2(1,3));
            break;
        ////////////////////////////////
        // XXX: Brawling Class
        case TMW2_BRAWLING:
            // 75x3 = 225
            .@PW=70+(5*@skillLv);
            // Using a shield, so power is halved
            if (getequipid(EQI_HAND_L) > 0)
                .@PW=.@PW/2;
            harm(@skillTarget, AdjustAttackpower(.@PW), HARM_PHYS, Ele_Neutral);
            sleep2(10);
            harm(@skillTarget, AdjustAttackpower(.@PW), HARM_PHYS, Ele_Neutral);
            sleep2(10);
            harm(@skillTarget, AdjustAttackpower(.@PW), HARM_PHYS, Ele_Neutral);
            break;
        case TMW2_BEARSTRIKE:
            // 60x5 = 300
            .@PW=55+(5*@skillLv);
            // Using a shield, so power is halved
            if (getequipid(EQI_HAND_L) > 0)
                .@PW=.@PW/2;
            harm(@skillTarget, AdjustAttackpower(.@PW), HARM_PHYS, Ele_Neutral);
            sleep2(10);
            harm(@skillTarget, AdjustAttackpower(.@PW), HARM_PHYS, Ele_Neutral);
            sleep2(10);
            harm(@skillTarget, AdjustAttackpower(.@PW), HARM_PHYS, Ele_Neutral);
            sleep2(10);
            harm(@skillTarget, AdjustAttackpower(.@PW), HARM_PHYS, Ele_Neutral);
            sleep2(10);
            harm(@skillTarget, AdjustAttackpower(.@PW), HARM_PHYS, Ele_Neutral);
            break;
        case TMW2_ALLINONE:
            // 45x8 = 360
            .@PW=40+(5*@skillLv);
            // Using a shield, so power is halved
            if (getequipid(EQI_HAND_L) > 0)
                .@PW=.@PW/2;
            //harm(@skillTarget, AdjustAttackpower(.@PW), HARM_PHYS, Ele_Neutral);
            harm(@skillTarget, AdjustAttackpower(.@PW), HARM_PHYS, Ele_Fire);
            sleep2(10);
            harm(@skillTarget, AdjustAttackpower(.@PW), HARM_PHYS, Ele_Water);
            sleep2(10);
            harm(@skillTarget, AdjustAttackpower(.@PW), HARM_PHYS, Ele_Earth);
            sleep2(10);
            harm(@skillTarget, AdjustAttackpower(.@PW), HARM_PHYS, Ele_Wind);
            sleep2(10);
            harm(@skillTarget, AdjustAttackpower(.@PW), HARM_PHYS, Ele_Holy);
            sleep2(10);
            harm(@skillTarget, AdjustAttackpower(.@PW), HARM_PHYS, Ele_Shadow);
            sleep2(10);
            harm(@skillTarget, AdjustAttackpower(.@PW), HARM_PHYS, Ele_Ghost);
            sleep2(10);
            // The main elemental-less blast hits all in same square,
            // and also hits behind (and on your square)
            rectharm(@skillTarget, 0, 1, AdjustAttackpower(.@PW/2), HARM_PHYS, Ele_Neutral);
            break;

        ////////////////////////////////
        // CLASS_OTHER
        case TMW2_PARUM:
            SK_parum();
            break;
        case TMW2_DEMURE:
            SK_Demure();
            break;
        case TMW2_DRAGOKIN:
            SK_Dragokin();
            break;
        // Summons which never fail
        case TMW2_ZARKOR:
            alignment_cansummon();
            SummonMagic(@skillId, CaveMaggot, 2, @skillLv);
            GetManaExp(@skillId, 1);
            break;
        // Summons which may fail
        case TMW2_KALWULF:
            SK_summon(Wolvern, 4, any(3,4));
            break;
        case TMW2_KALBOO:
            SK_summon(Mouboo, 4, any(2,3));
            break;
        case TMW2_KALSPIKE:
            SK_summon(PoisonSpikyMushroom, 4, any(2,3));
            break;
        case TMW2_CUTEHEART:
            SK_summon(Fluffy, 4, any(2,3));
            break;
        // Slightly more complex summons
        case TMW2_LIMERIZER:
            SK_summon(any(GreenSlime,AzulSlime,RedSlime,AngryYellowSlime), 2, any(3,4));
            break;
        case TMW2_FAIRYKINGDOM:
            SK_summon(any(FireFairy, EarthFairy, WaterFairy, WindFairy, PoisonFairy), 4, any(3,4));
            break;
        case TMW2_FAIRYEMPIRE:
            SK_summon(any(VanityPixie, HolyPixie, ShadowPixie, NulityPixie), 5, any(4,5));
            break;
        // More complex summons
        case TMW2_KALMURK:
            .@mobId=Maggot;
            if (abizit() > 4 &&
                GHMEMO[GHQ_GetQuestIDByMonsterID(Maggot)] >= 10000 &&
                MAGIC_LVL >= 3)
            {
                .@mobId=any(Maggot, Maggot, Maggot, Maggot, GiantMaggot);
            }
            SK_summon(.@mobId, (.@mobId == Maggot ? 2 : 4), any(1,2));
            break;
        case TMW2_HALHISS:
            .@mobId=Snake;
            if (abizit() > 3 &&
                GHMEMO[GHQ_GetQuestIDByMonsterID(MountainSnake)] >= 10000 &&
                rand2(1,3) == 2)
            {
                .@mobId=MountainSnake;
            }
            SK_summon(.@mobId, 4, any(3,4));
            break;
        case TMW2_FROZENHEART:
            .@mobId=Moggun;
            if (rand2(6,12) < (abizit()*2)+1)
            {
                .@mobId=Yeti;
            }
            SK_summon(.@mobId, 4, any(3,4));
            break;
        case TMW2_STONEHEART:
            .@mobId=Terranite;
            if (rand2(9,12) < (abizit()*2)+1 &&
                BaseLevel > 80)
            {
                .@mobId=TerraniteProtector;
            }
            SK_summon(.@mobId, 4, any(4,5));
            break;
        case TMW2_DUCKY:
            .@mobId=Duck;
            .@q=getq(LilitQuest_PiratesOfSARAH);
            if (!alignment_cansummon())
                break;
            if (abizit() > 4 &&
                .@q > 2 &&
                MAGIC_LVL >= 3)
            {
                // GHQ Complete: 33% chances
                // Otherwise: 8% chances
                if (GHMEMO[GHQ_GetQuestIDByMonsterID(Duck)] >= 10000)
                    .@mobId=any(Duck, Duck, EliteDuck);
                else
                    .@mobId=any(Duck, Duck, Duck, Duck,
                                Duck, Duck, Duck, Duck,
                                Duck, Duck, Duck, EliteDuck);
            }
            SummonMagic(@skillId, .@mobId, 2);
            GetManaExp(@skillId, 1);
            break;
        */

        // Experience only
        case KN_AUTOCOUNTER:
        case SN_SHARPSHOOTING:
        case HW_MAGICPOWER:
        case SM_PROVOKE:
        case SN_WINDWALK:
        case SO_FIREWALK:
        case TF_BACKSLIDING:
        case MG_FIREWALL:
        case ALL_FULL_THROTTLE:
        case GC_DARKILLUSION:
        case NV_TRICKDEAD:
            GetManaExp(@skillId, rand2(1,3));
            break;
    }

    // Debug
    if ($@GM_OVERRIDE)
        debugmes "Cast skill %d on level %d - Target %d",
                  @skillId, @skillLv, @skillTarget;

    // Cleanup (double-safe)
    @skillTarget = 0;
    return;

}





























// HUB_PCBonus ()
function	script	HUB_PCBonus	{
    /* Passive Skills */
    if (FOCUSING & FSKILL_ASTRAL_SOUL) {
        bonus bMatk, 10*getskilllv(SKILL_ASTRAL_SOUL);
    }
    if (FOCUSING & FSKILL_RAGING) {
        bonus bCritical, 2*getskilllv(SKILL_RAGING);
    }
    if (FOCUSING & FSKILL_SPEED) {
        bonus bSpeedAddRate, 1*getskilllv(SKILL_SPEED);
        bonus bAspd, 2*getskilllv(SKILL_SPEED);
    }
    if (FOCUSING & FSKILL_RESIST_POISON) {
        .@l=5*getskilllv(SKILL_RESIST_POISON);
        bonus2(bResEff, Eff_Silence, .@l);
        bonus2(bResEff, Eff_Poison,  .@l);
        bonus2(bResEff, Eff_Curse,   .@l);
        bonus2(bResEff, Eff_Blind,   .@l);
    }
    if (FOCUSING & FSKILL_BRAWLING) {
        if (getequipid(EQI_HAND_R) < 1) {
            bonus bAtk, 10*getskilllv(SKILL_BRAWLING);
        } else if (getiteminfo(
                   getequipid(EQI_HAND_R), ITEMINFO_SUBTYPE) == W_FIST) {
            bonus bAtk, 10*getskilllv(SKILL_BRAWLING);
        }
    }
    if (!(FOCUSING & FSKILL_MALLARDS_EYE)) {
		bonus bAtkRange, -(getskilllv(SKILL_MALLARDS_EYE));
    }
    return;
}