summaryrefslogblamecommitdiff
path: root/npc/config/magic.txt
blob: f30ca146d4c567213b95cb0e9b5ce3902565569e (plain) (tree)
1
2
3
4
5
6
7
8



                                     
  

                                                                            
                       





                                                          
 







                                                                       

                                                                              












                                                                        
 

                                         
                   
                   
                                               


                                           

                              



                                    
                           
     

                       
                                     
           
 
 


                                                           

                                         
                    




                      

                             
                 

                     




                                                                       

                 



                      


             
 
                                                         

                                         


                                    



                                                                                              


            
                   

                                                                                                
                                                                       
                                                        



                                                                      
                                             

                                           

                                                             


                                                       
                                           
           
 
 













                                                                          
                                                    

                                                                              



                                        
                                        
                                                   
                                                             
     


           
 


























                                                                                  








                                             

                                         



                                        
                                                    
                              
                         
                                                                                 
                              
                                                                              
                              
                                                                                
                              
                                                                                                
                            
                                                                              
        
                                                                                  


           
 














                                                                     




                                         
                                                                           
 
                                   
                               

               
                              
                                                
                                                                            









                                                                                








                                                                          
                                         
                                                                                 





                                         



                           









                               

                                          




                                            

                                                              
 
 




 
                                        






                                                        
                                                      
                                              
                        
                                                   
                                              
 
                    


                                                                   
              




                                                                              








                                                                        





 
                                              




                                                         
                   

                                                                
                     

                                                                    
                     

                                                                
 







                                                                    





 
                                              














































                                                                               






 
                                        


















                                                              





 
                                              






 
                                        
                   

                                                    
 


        
// TMW2 script
// Author: Jesusalva <admin@tmw2.org>
//
// Magic Script Core Functions
//
// Used for our pseudo-magic.
// These are only helpers, you can add more restrictions and effects freely.
// Important Variables:
//  MAGIC_EXP
//      Current mana magic experience
//  LAST_SKILL
//      Last Mana Skill used
//  MAGIC_LVL
//      Maximum tier of usable magic, capped by Mana Stone

// AdjustSpellpower(power=100, {target=@skillTarget{, type=HARM_MAGI}})
function	script	AdjustSpellpower	{
    .@power=getarg(0, 100);
    .@target=getarg(1, @skillTarget);
    .@type=getarg(2, HARM_MAGI);
    .@src=getcharid(3);

    .@dmg=calcdmg(.@src, .@target, .@type);
    // Abizit Influence (80%~130% at best, worst shot at perfect ctrl is 105%)
    .@dmg = .@dmg * (80 + abizit() * rand2(5,10)) / 100;
    .@dmg = .@dmg * .@power / 100;
    return .@dmg;
}

// An alias for simplification
// AdjustAttackpower(power=100, {target=@skillTarget{, type=HARM_PHYS}})
function	script	AdjustAttackpower	{
    .@power=getarg(0, 100);
    .@target=getarg(1, @skillTarget);
    .@type=getarg(2, HARM_PHYS);
    return AdjustSpellpower(.@power, .@target, .@type);
}


// SkillID, EXP Points
function	script	GetManaExp	{
    .@sk=getarg(0);
    .@pt=getarg(1);
    .@bonus=rand2(0,getskilllv(TMW2_SAGE)*3/2);
    if (LAST_SKILL == .@sk) {
        .@pt=limit(0, (.@pt+.@bonus)/3, 1);
        .@bonus=0;
    } else {
        // Update skill memory
        LAST_SKILL[4]=LAST_SKILL[3];
        LAST_SKILL[3]=LAST_SKILL[2];
        LAST_SKILL[2]=LAST_SKILL[1];
        LAST_SKILL[1]=LAST_SKILL[0];
        LAST_SKILL[0]=.@sk;
    }

    // Update Magic EXP
    MAGIC_EXP=MAGIC_EXP+.@pt+.@bonus;
    return;
}


// DEPRECATED: Please do not use in newer scripts.
// It is for Transmigration skill only (@sk-trans needs it)
// SkillID, Mana{, MP per level}
function	script	MagicCheck	{
    // PRE EXECUTION
    // Load Variables
    .@sk=getarg(0);
    .@mp=getarg(1);
    .@amp=getarg(2,0);

    // Check Skill
    if (getskilllv(.@sk) < 1)
        return 0;

    // Load mana cost
    .@mp=.@mp+getskilllv(.@sk)*.@amp-.@amp;

    // Check mana
    if (readparam(Sp) < .@mp) {
        dispbottom l("Insufficient mana: @@/@@.", readparam(Sp), .@mp);
        return 0;
    }

    // Apply mana cost
    heal 0, 0-.@mp;

    return 1;
}


// SkillID, MobID{, SkillLevelPerMob=2{, Level Override}}
function	script	SummonMagic	{
    .@sk=getarg(0);
    .@id=getarg(1);
    .@adj=getarg(2,2);
    .@lv=getarg(3,getskilllv(.@sk));

    if (.@adj < 1) {
        debugmes "\033[31mInvalid MobPerSkillLevel for SummonMagic (.@adj): "+.@adj+"\033[0m";
        dispbottom l("Invalid parameter specified, blame saulc.");
        end;
    }

    // Cause effect
    // Summoned monsters live from 45 to 60 seconds, and each skill levels grants 10s extra life
    // The 35~50 is not a defect, remember skill starts at level 1...
    // PS. Abizit makes a variation from 80% to 130% of official values
    for (.@i = 0; .@i < (.@lv+(.@adj-1))/.@adj; .@i++) {
        .@lifetime=rand(35,50)+.@lv*10;
        // Abizit makes lifetime vary (like AdjustSpellpower)
        .@lifetime = .@lifetime * (80 + abizit() * rand2(5,10)) / 100;
    	.@mids=summon("Summoned Monster", .@id, .@lifetime);
        .@bhp=getunitdata(.@mids, UDT_MAXHP);
        // Each skill level raises HP in 5%
        .@lvx=max(0, (.@lv-1)*.@bhp/20);
        // Abizit makes bonus HP vary (like AdjustSpellpower)
        .@lvx = .@lvx * (80 + abizit() * rand2(5,10)) / 100;
        setunitdata(.@mids, UDT_MAXHP,    .@bhp+.@lvx);
        setunitdata(.@mids, UDT_HP,       .@bhp+.@lvx);
    }
    dispbottom l("All monsters summoned!");
    return;
}

// areaharm(target, range, DMG, {type, element, filter, bl})
// Defaults to HARM_MISC, Ele_Neutral, filter filter_hostile and all BLs
// Valid BL: BL_MOB | BL_PC | BL_HOM | BL_MER
// Do not use: NPC, PET, ELEM
// Range centers on caster (player), implement and use areaharm2 elsewhere
function	script	areaharm	{
    .@t=getarg(0);
    .@r=getarg(1);
    .@d=getarg(2);
    .@h=getarg(3, HARM_MISC);
    .@e=getarg(4, Ele_Neutral);
    .@f$=getarg(5, "filter_hostile");
    .@b=getarg(6, BL_PC | BL_MOB | BL_MER | BL_HOM);

    getmapxy(.@m$, .@x, .@y, getunittype(.@t), .@t);

    .@c=getunits(.@b, .@mbs, false, .@m$, .@x-.@r, .@y-.@r, .@x+.@r, .@y+.@r);
    for (.@i = 0; .@i < .@c; .@i++) {
        // Filtering
        if (!callfunc(.@f$, .@mbs[.@i]))
            continue;
        harm(.@mbs[.@i], .@d, .@t, .@e);
        specialeffect(FX_ATTACK, AREA, .@mbs[.@i]);
        // TODO: Handle MobPt to don't overload timer system?
    }
    return;
}


// rectharm(target, x, y, DMG, {type, element, filter, bl})
// Same as areaharm() but causes a rectangle in (x,y) size, instead of a square
function	script	rectharm	{
    .@t=getarg(0);
    .@rx=getarg(1);
    .@ry=getarg(2);
    .@d=getarg(3);
    .@h=getarg(4, HARM_MISC);
    .@e=getarg(5, Ele_Neutral);
    .@f$=getarg(6, "filter_hostile");
    .@b=getarg(7, BL_PC | BL_MOB | BL_MER | BL_HOM);

    getmapxy(.@m$, .@x, .@y, getunittype(.@t), .@t);

    .@c=getunits(.@b, .@mbs, false, .@m$, .@x-.@rx, .@y-.@ry, .@x+.@rx, .@y+.@ry);
    for (.@i = 0; .@i < .@c; .@i++) {
        // Filtering
        if (!callfunc(.@f$, .@mbs[.@i]))
            continue;
        harm(.@mbs[.@i], .@d, .@t, .@e);
        specialeffect(FX_ATTACK, AREA, .@mbs[.@i]);
        // TODO: Handle MobPt to don't overload timer system?
    }
    return;
}


// mescordialog(text, color, {dialog=1})
function	script	mescordialog	{
    if (getarg(2, true))
        mesc getarg(0), getarg(1);
    else
        dispbottom col(getarg(0), getarg(1));
    return;
}

// ShowAbizit({dialog=1})
function	script	ShowAbizit	{
    .@dial=getarg(0, true);
    if (.@dial)
        mesn l("Current Magic Control");

    .@val=MAGIC_EXP+rand(-MAGIC_LVL*5, MAGIC_LVL*5);
    .@base=((MAGIC_LVL*2)**3);
    if (.@val > .@base*5)
        mescordialog l("You are perfectly in control of your magic."), 3, .@dial;
    else if (.@val > .@base*4)
        mescordialog l("You are mostly in control of your magic."), 2, .@dial;
    else if (.@val > .@base*3)
        mescordialog l("You are somewhat in control of your magic."), 4, .@dial;
    else if (.@val > .@base*2)
        mescordialog l("Your magic is more powerful than you, but you can control."), 7, .@dial;
    else if (.@val > .@base)
        mescordialog l("You still are overwhelmed by your magic."), 6, .@dial;
    else
        mescordialog l("You are completly overwhelmed by your magic."), 1, .@dial;
    return;
}


// alignment_cansummon()
function	script	alignment_cansummon	{
    if (alignment() < 0 && !isequippedcnt(AegisShield)) {
        if (!@hatesummon) {
            dispbottom l("Nature itself express hate against you!");
            getmapxy(.@m$, .@x, .@y, 0);
            .@opo=monster(.@m$, .@x, .@y, "Failed summon", .@mob, 1);
            unitattack(.@opo, getcharid(3));
            @hatesummon=true;
        }
        return false;
    }
    return true;
}

// SK_summon(ID, amount, mexp)
function	script	SK_summon	{
    .@mob=getarg(0);
    .@amt=getarg(1);
    .@mex=getarg(2);
    if ($@GM_OVERRIDE || debug) debugmes "Skill "+@skillId+" Lv "+@skillLv;

    // Blocked from summoning magic
    if (!alignment_cansummon())
        return;

    if (rand2(5) < abizit()) {
        // Summon Magic (with magic level bonus)
        SummonMagic(@skillId, .@mob, .@amt, MAGIC_LVL+@skillLv-1, @skillLv);
    } else if (rand2(5) < abizit()) {
        // Re-roll
        dispbottom l("You cannot complete the casting correctly!");
        SummonMagic(@skillId, .@mob, 1, 1, 1);
    } else if (abizit() <= 1 && any(true, false, false)) {
        // Spell overwhelms you, causing it to be spawned as aggro vs you. (33%)
        dispbottom l("The spell takes a mind of its own backfires!");
        getmapxy(.@m$, .@x, .@y, 0);
        .@opo=monster(.@m$, .@x, .@y, "Failed summon", .@mob, 1);
        unitattack(.@opo, getcharid(3));
    } else {
        dispbottom l("The spell fails!");
    }

    // Get a single mana experience point (this is NOT used by Mana Stone)
    GetManaExp(@sk, .@mex);
    return;
}

/////////////////////////////////////////
// RegisterMagic(MSP, Skill, MaxLv, Item, Amount, Class, Cost, {PreReq, PostReq})
function	script	RegisterMagic	{
    .@msp=getarg(0);
    .@ski=getarg(1);
    .@max=getarg(2);
    .@ite=getarg(3);
    .@amo=getarg(4);
    .@cla=getarg(5);
    .@cos=getarg(6);
    .@pre=getarg(7, false);
    .@pos=getarg(8, false);

    $@MSK_MSPCOST[.@ski]=.@msp;
    $@MSK_MAXLV[.@ski]=.@max;

    $@MSK_ITEM[.@ski]=.@ite;
    $@MSK_AMOUNT[.@ski]=.@amo;
    $@MSK_COST[.@ski]=.@cos;

    $@MSK_PREREQ[.@ski]=.@pre;
    $@MSK_POSTREQ[.@ski]=.@pos;

    array_push($@MSK_CLASS[.@cla], .@ski);
    return;
}

-	script	Magic Load	NPC_HIDDEN,{
OnInit:
    /* RegisterMagic(MSP, Skill, MaxLv, Item, Amount,
                            Class, Cost, {PreReq, PostReq}) */







    //////////////////////// Scholarship
    // Mana Wisdom
    RegisterMagic(1, TMW2_SAGE, 5, SpellBookPage, 1,
                        CLASS_SCHOLARSHIP, 0);
    // Accumulate Power
    RegisterMagic(1, HW_MAGICPOWER, 5, SpellBookPage, 1,
                        CLASS_SCHOLARSHIP, 0);
    // Windwalker
    RegisterMagic(2, SN_WINDWALK, 3, SpellBookPage, 1,
                        CLASS_SCHOLARSHIP, 0);
    // Last Standing Man
    RegisterMagic(2, CR_TRUST, 3, SpellBookPage, 1,
                        CLASS_SCHOLARSHIP, 0);

    /* Skillchain */
    // First Aid
    RegisterMagic(1, TMW2_FIRSTAID, 10, SpellBookPage, 1,
                        CLASS_SCHOLARSHIP, 0, false, TMW2_HEALING);
    // Healing
    RegisterMagic(2, TMW2_HEALING, 10, SpellBookPage, 1,
                        CLASS_SCHOLARSHIP, 0, TMW2_FIRSTAID, TMW2_MAGNUSHEAL);
    // Magnus Healing
    RegisterMagic(3, TMW2_MAGNUSHEAL, 10, SpellBookPage, 1,
                        CLASS_SCHOLARSHIP, 0, TMW2_HEALING, false);

    /* Skillchain */
    // Provoke
    RegisterMagic(1, SM_PROVOKE, 1, SpellBookPage, 1,
                        CLASS_SCHOLARSHIP, 0, false, EVOL_AREA_PROVOKE);
    // Mass Provoke
    RegisterMagic(2, EVOL_AREA_PROVOKE, 10, SpellBookPage, 1,
                        CLASS_SCHOLARSHIP, 0, SM_PROVOKE, false);







    //////////////////////// Physical Sciences
    // Ground Strike
    RegisterMagic(2, ASC_METEORASSAULT, 3, FluoPowder, 3,
                        CLASS_PHYSICAL, 0);

    /* Skillchain */
    // Falkon Punch
    RegisterMagic(1, SM_BASH, 10, FluoPowder, 3,
                        CLASS_PHYSICAL, 0, false, MC_MAMMONITE);
    // Supreme Attack
    RegisterMagic(1, MC_MAMMONITE, 10, FluoPowder, 3,
                        CLASS_PHYSICAL, 0, SM_BASH, KN_AUTOCOUNTER);
    // Counter Attack
    RegisterMagic(2, KN_AUTOCOUNTER, 5, FluoPowder, 3,
                        CLASS_PHYSICAL, 0, MC_MAMMONITE, false);

    /* Skillchain */
    // Arrow Shower
    RegisterMagic(3, AC_SHOWER, 10, FluoPowder, 3,
                        CLASS_PHYSICAL, 0, false, SN_SHARPSHOOTING);
    // Sharpshooter
    RegisterMagic(3, SN_SHARPSHOOTING, 1, FluoPowder, 3,
                        CLASS_PHYSICAL, 0, AC_SHOWER, false);







    //////////////////////// Destructive Magic
    // Fire Walk
    RegisterMagic(2, SO_FIREWALK, 2, Quill, 1,
                        CLASS_DESTRUCTION, 0);

    /* Skillchain */
    // Fire Arrow
    RegisterMagic(1, TMW2_FIREARROW, 10, Quill, 1,
                        CLASS_DESTRUCTION, 0, false, TMW2_FIREBALL);
    // Fire Ball
    RegisterMagic(2, TMW2_FIREBALL, 10, Quill, 2,
                        CLASS_DESTRUCTION, 0, TMW2_FIREARROW, TMW2_ARMAGEDDON);
    // Armageddon
    RegisterMagic(3, TMW2_ARMAGEDDON, 5, Quill, 3,
                        CLASS_DESTRUCTION, 0, TMW2_FIREBALL, false);

    /* Skillchain */
    // Napalm Beat
    RegisterMagic(1, TMW2_NAPALMBEAT, 10, Quill, 1,
                        CLASS_DESTRUCTION, 0, false, TMW2_HOLYLIGHT);
    // Holy Light
    RegisterMagic(2, TMW2_HOLYLIGHT, 10, Quill, 2,
                        CLASS_DESTRUCTION, 0, TMW2_NAPALMBEAT, TMW2_JUDGMENT);
    // Judgement
    RegisterMagic(3, TMW2_JUDGMENT, 5, Quill, 3,
                        CLASS_DESTRUCTION, 0, TMW2_HOLYLIGHT, false);

    /* Skillchain */
    // Frost Diver
    RegisterMagic(1, TMW2_FROSTDIVER, 10, Quill, 1,
                        CLASS_DESTRUCTION, 0, false, TMW2_FROSTNOVA);
    // Frost Nova
    RegisterMagic(2, TMW2_FROSTNOVA, 10, Quill, 2,
                        CLASS_DESTRUCTION, 0, TMW2_FROSTDIVER, TMW2_NILFHEIM);
    // Nilfheim
    RegisterMagic(3, TMW2_NILFHEIM, 5, Quill, 3,
                        CLASS_DESTRUCTION, 0, TMW2_FROSTNOVA, false);

    /* Skillchain */
    // Magic Strike
    RegisterMagic(1, TMW2_MAGICSTRIKE, 10, Quill, 1,
                        CLASS_DESTRUCTION, 0, false, TMW2_LIGHTNINGBOLT);
    // Lightning Bolt
    RegisterMagic(2, TMW2_LIGHTNINGBOLT, 10, Quill, 2,
                        CLASS_DESTRUCTION, 0, TMW2_MAGICSTRIKE, TMW2_TEMPEST);
    // Tempest
    RegisterMagic(3, TMW2_TEMPEST, 5, Quill, 3,
                        CLASS_DESTRUCTION, 0, TMW2_LIGHTNINGBOLT, false);







    //////////////////////// Trickmaster
    /* RegisterMagic(MSP, Skill, MaxLv, Item, Amount,
                            Class, Cost, {PreReq, PostReq}) */
    RegisterMagic(1, TMW2_MANABOMB, 10, SulfurPowder, 1,
                        CLASS_TRICKS, 0);
    RegisterMagic(1, TF_BACKSLIDING, 1, Lockpicks, 1,
                        CLASS_TRICKS, 0);
    RegisterMagic(1, MG_FIREWALL, 10, Lockpicks, 1,
                        CLASS_TRICKS, 0);
    RegisterMagic(1, AC_VULTURE, 1, Lockpicks, 1,
                        CLASS_TRICKS, 0);
    RegisterMagic(1, SA_FREECAST, 1, Lockpicks, 1,
                        CLASS_TRICKS, 0);
    RegisterMagic(1, ALL_FULL_THROTTLE, 1, Lockpicks, 1,
                        CLASS_TRICKS, 0);
    RegisterMagic(2, GC_DARKILLUSION, 3, Lockpicks, 1,
                        CLASS_TRICKS, 0);
    RegisterMagic(2, NV_TRICKDEAD, 1, Lockpicks, 1,
                        CLASS_TRICKS, 0);







    //////////////////////// Other: Summonning







    //////////////////////// Other: Misc
    // Charged Shot
    RegisterMagic(0, AC_CHARGEARROW, 1,
                        CLASS_OTHER, NPCEyes, 1, 0);

    end;
}