summaryrefslogblamecommitdiff
path: root/npc/functions/hub.txt
blob: 01e2f2b90abe10003dab1d458a2078098c43265d (plain) (tree)
1
2
3
4


                
                












                                                
                               
                                                       

                                     
                            
                                                     

                                 
                                
                                                


                                          
                                                           


                                                 
                                               



                                        

                                       





                                                                                                                                                                                                                                                                   
                                                                    
                                


                                                        
                                             
                            

                                                                     
             

                                     
                                                                             
 

                                                    
                                   

                                                   
                                      


                                                         
                                                                                                     

                                                                               

                                          

                                        



                                                                                                                                                

                               

                              

         






                                         
                                              
 

                              






                                                              
                     
                                                   
                         

                                                          




                                                                                                               
                
                                      
                                  


                                                          
                                                               


                                                       
                             
                                                                       
                                                

                                         
                                          

                                    









                                                   
                                        


                                                                                   
                                                               
                                  
                                            

                              
                                                 
                          
                                              

                                                                                                                                    






                                                        







                                                                                  







                                                                                  
                                            
                                                  






                                                                                                   

                                              
                                              

                                                                



                                            





                                                               
                                                                   
                                  



                                                         







                                 
                                 
     




                                                              
                                  

                                      
                                             



                                                                                                            
                                               
                                   

                                         










                                                       
     



                                                  


                                                









                                                                         
                                         
                                     
                                              









                                                         
              


                                                                                                                              
                                     



                                              
                                               




                                                                                                             
                           
                                                                                   




                                                       

                     












                                                                                                                                                          
                           
                  
                                      
                                    
                           

                                                   
                                                  
                                                     
                                                  
                                                     
                                                   

                                                     
                          

                           
                                             


                                                                    
                                     





                                                               

         

                                             


           

                                         
                            
                       
                                                                                                             

                                                      


               






                                                                                                                       




                                                                                 

                                                                                                         
                                 
                  
                             
                                                     


                                                   







                                                                                      
                          
                                 
                                                                                              

                                                                          
                                                              


                                                                    


                            





                                                                                        





                                                                                     









                                                                                                            

                                                                                         


                                                                
                                                                         
                                             


                                                                             









                                                                             
                                                                                            






                                                                                 





































                                                                                                                




                                                                                 
                                                                                              
                                              







                                                                                                                                                                                     


                                                              

                         
                                                      
                               

                          
                                                                                 



                                  





                             


                          


                          


                                        
                        
                                   
                  
                               



                                                                                
                           
                                             
                  

                            
                                           

                           
                              
                                           


                           
                                           


                                
                                           


                           
                                           


                            
                                           


                                
                                           


                               
                                           


                              
                                           
                  
                                 
                           
                                                                                   
                                                                          
                  
                                        
                   





                                                                
                                                                         
                 
                                    
                  
                                        
                             
                           
                                  
                                              
                                                                        


                                                       
                           
                                        

                          
                                   


                                                                                
                                                                   
                                        

                             
                           
                                   

                                                                                                
                                        
                  
                                        




                                                 
                          
                                                  
                            
                                   
                              
                                                                          
                                                                            
                                         

                           
                                   
                                
                               
                                                                           
                                                                                      
                                         

                             
                                   
                                
                                         
                                                                                                                 
                                                                                      
                                         
                  



                                        

                                         
                                
                                                                     
                                                              
                                          
                  
                            

                                         
                                                                    
                                                           
                                          
                  
                           



                                           
                                
                                                                      
                                                           
                                          
                  

                                        
                                         
                              

                                         
                                                           
                                              
                  
                                

                                         
                                                           
                                              
                  
                          

                                         

                                                                     
                                              
                  





                                        
                                                                         
                                                                             
                                         




                                         
                                                                                                               
                                                                                       
                                         




                                     
                                                                                                  
                                                                                           
                                                             
                                         
                  

                                        
                                                    


                                         
                                     
                                                                      
                                                            


                                             
                                   

                                         
                                    
                                                                                                                  
                                                                      






                                             
                                                                         

                                                                       

                                             
          













                                                                                             
 
                                       





                                                                            

                        
                                              


                        
                                   

                                                                



                                                                                   

                                    
                  

                                   
                  
 


 
 

                                            
                                
                                                             






















                                            
 
 


















                                                                              
                                                 


                                                     

                               
                                 
                                                                                
                                             
                  
                                




                                                      

                                        

                                                                                
                                             
                  
                                






                                                      

                                        

                                                                                
                                             
                  
                       








                                                      

                                        

                                                                                
                                             
                  
                             










                                                      

                                        

                                                                             
                                             
                  
 

                                        




                                        
                                                                       
                                                                                








                                                                            
                                                                                                                
                                                                        





















                                                                                
                              

                           
                                 


                                                 
                                                                                
                       
                                                                                
                       
                                                                                


                             
                                 


                                                 
                                                                                
                       
                                                                                
                       
                                                                                
                       
                                                                                
                       
                                                                                


                           
                                 


                                                 
                                                                                  
                                                                             
                       
                                                                              
                       
                                                                              
                       
                                                                             
                       
                                                                             
                       
                                                                               
                       
                                                                              
                       

                                                                     
                                                                                                                                             
                  













                                                                                

                                        
                      


                        


                         


                           
                                   
                         
                                  

                                                           
                  
                                 








                                                        


                                           
                                        


                                                                                        
                               

                                                                                                   


                                                                                          
                               









                                                                         





                                                                            
                                      
             

                                            







                                             







                                               
                  
                        

                                                
                                       
                      













                                                                     

                                    




                                        

                          
                            
                              

                           
                         
                         






                                             


            
                      




                                                         


           



 


                                                                             







                                      
                                             

                                                      
                  
                               
 
                                  
                         
                          
                           
                           

                                            
                                                            

                                             

         


                                                        
                                                                                                                                                                     

         


                                     
                        
                                        
                             

                                               

     


                                                                



                                                                        














                                                                                 
                               

                                                                            
         







                                                                       



                                         



                                 
                        






























                                  
                          















                                       


                                     


                                    








                                                        

                                                        

                                                                    
                                       
                                                                   
 


           
// TMW2 scripts.
// Authors:
//    Jesusalva
//    dangerDuck
//    TMW Org.
// Description:
//    HUB functions (Login, Logout, Death)

// HUB_Login ()
function	script	HUB_Login	{
    getmapxy(.@mapa$, .@a,.@b, 0);

    // Login on Blue Sage Workshop/Library
    if (.@mapa$ == "020-7-1") {
        addtimer(1000, "#BlueSageHUB::OnCycle");
    }

    // Random Treasure cleaning
    if (CHAREG_CLEANUP < gettimetick(2)-CHEST_WAITTIME)
        deletearray RNGTREASURE_DATE;

    // PVP Cooldown cleaning
    if (CHAREG_CLEANUP < gettimetick(2)-PVP_WAITTIME)
        deletearray PVP_COOLDOWN;

    // Mirror Lake functionality
    if (getvaultid() && !getstatus(SC_JAILED)) {
        // Christmas 2021
        if ($EVENT$ == "Christmas") {
            if (#XMAS2021 < ##01_TMWEXP) {
                getexp (##01_TMWEXP-#XMAS2021) * 7 / 10, 0;
                #XMAS2021 = ##01_TMWEXP;
            } else if (#XMAS2021 > ##01_TMWEXP) {
                // You leveled up?
                getexp ##01_TMWEXP * 7 / 10, 0;
                #XMAS2021 = ##01_TMWEXP;
            }
        }

        .@gto=get_byte(##00_INFO, 3);
        .@mlp=get_nibble(##00_INFO, 5);
        /*debugmes "INFO: %d", ##00_INFO;
        debugmes "BYTE: %d/%d/%d/%d", get_byte(##00_INFO, 0), get_byte(##00_INFO, 1), get_byte(##00_INFO, 2), get_byte(##00_INFO, 3);
        debugmes "NIBBLE: %d/%d/%d/%d/%d/%d/%d/%d", get_nibble(##00_INFO, 0), get_nibble(##00_INFO, 1), get_nibble(##00_INFO, 2), get_nibble(##00_INFO, 3), get_nibble(##00_INFO, 4), get_nibble(##00_INFO, 5), get_nibble(##00_INFO, 6), get_nibble(##00_INFO, 7);
        debugmes "Your Vault ID: %d", getvaultid();
        debugmes "VAULT LOGIN, GTO is %d MLP is %d", .@gto, .@mlp;
        */
        // Work only on new chars, or chars which cleared Tulimshar.
        if (.@gto == WORLD_ID &&
            (!getq(General_Narrator) ||
            (getq(General_Narrator) && BaseLevel > 20)))
            {
            // Warp to the proper Mirror Lake
            switch (.@mlp) {
            case 1: warp "018-7-1", 90, 47; LOCATION$ = "LoF"; break;
            default: warp "014-4", 28, 31; LOCATION$ = "LoF"; break;
            }

            // Send debug information
            debugmes("Vault User %d moved to lake %d.", getvaultid(), .@mlp);

            // Handle new user (non-native) accounts
            if (!getq(General_Narrator)) {
                adddefaultskills();
                getitembound MirrorLakeArmor, 1, 4;
                equip(MirrorLakeArmor);
                percentheal(100, 100);
                TUTORIAL=true;
                //BaseLevel = get_byte(##00_INFO, 0) + 1;
                // TODO: Display quick tutorial
                dispbottom l("Mirror Lake : Created temporary character; It'll be reset on logout.");
                dispbottom l("Mirror Lake : Obtain help with %s.", b("@info"));
            }

            // Unset the target lake/world
            set_byte(##00_INFO, 3, 0);
            set_nibble(##00_INFO, 5, 0);
        } else if (.@gto) {
            // Heading somewhere which is not here!
            mesc l("WARNING: If you use any Mirror Lake feature on this world, the current Mirror Lake Quest will be marked as \"Failed\"."), 1;
            mesc l("If this is undesired, select the correct world, and if needed create a new char on it."), 1;
            ##VAULT_GOTO=.@gto;
            ##VAULT_MLTO=.@mlp;
            next;
            closeclientdialog;
        }
    }
    return;
}

// HUB_Logout ( {dead} )
function	script	HUB_Logout	{
    .@dead=getarg(0, false);
    getmapxy(.@mapa$, .@a,.@b, 0);
    .@zone$=getmapinfo(MAPINFO_ZONE, .@mapa$);

    // Hardcore Server
    if ($HARDCORE && .@dead) {
        // Update Absolutions
        if (ABSOLVE_DAY != gettimeparam(GETTIME_DAYOFMONTH)) {
            ABSOLVE_DAY=gettimeparam(GETTIME_DAYOFMONTH);
            ABSOLVE_CNT=0;
        }

        // Main Loop
        if (@grace) {
            // Grace is upon you (ie. script death)
            @grace=false;
        } else if (.@zone$ == "MMO" && ABSOLVE_CNT <= 3) {
            // Absolve (limited attempts)
            ABSOLVE_CNT+=1;
            dispbottom l("This is a special map so your death is not counted.");
            dispbottom b(l("You have %d non-counting deaths remaining today.", 3-ABSOLVE_CNT));
            if (ABSOLVE_CNT == 3)
                dispbottom col(l("WARNING: if you die again today in a special map it will be PERMANENT."), 1);
        } else {
            // Meet your final demise!
            atcommand("@dropall");
            makeitem CoinBag, Zeny/500, .@mapa$, .@a, .@b;
            Zeny=0;
            //resetlvl(2); // FIXME: Split the exp
            // TODO: Warp back to Candor or it'll be unplayable
            // TODO: It could be @jail, but it is buggy
            atcommand("@jailfor 1d "+strcharinfo(0));
        }
    // Vanished on Cindy Cave
    } else if (.@mapa$ == "021-4" && strcharinfo(0) == $@CINDY_HERO$) {
        donpcevent("Cindy#Outside::OnReckless");
        recovery(getcharid(3));
        warp any("010-1", "010-2"), 0, 0;
        sc_start2 SC_POISON, 1, 90, 10000;
        die();
        if (!$HARDCORE) heal -1, -1;
    } else if (.@mapa$ == "021-4") {
        .@pl = getmapusers("021-4")-1;
        if (.@pl < 1)
            donpcevent("Cindy#Outside::OnCleanUp");
        recovery(getcharid(3));
        warp "Save", 0, 0;
    }
    // Logout while donating blood
    if (getq(HurnscaldQuest_BloodDonor) == 2) {
        slide 35, 28;
        setpcblock(PCBLOCK_SOFT, false);
        setq HurnscaldQuest_BloodDonor, 0, gettimetick(2)+3600; // one hour penalty
    }
    // Logout/Death on Nard's ship hold
    if (compare(.@mapa$, "002-2") || compare(.@mapa$,"nard")) {
        setq2 ShipQuests_Peter, 0;
        setq3 ShipQuests_Peter, 0; // Bugfix
    }
    // Logout on botcheck area
    if (compare(.@mapa$,"botcheck") && !.@dead) {
        if (!is_staff()) {
            atcommand "@jail "+strcharinfo(0);
            rodex_sendmail(getcharid(0), "TMW2 Team", "Error detected!", "Please contact GM Team, error code: BOTCHECK-AUTOJAILED");
        }
    }
    // Died on Terranite Cave where exp penalty is lower
    if (.@mapa$ == "015-6" && .@dead) {
        @deathpenalty_override=2;
        @deathpenalty_realvalue=readparam(BaseExp);
        @deathpenalty_realvaljob=readparam(JobExp);
    }
    // Died or logged out at Tulimshar Arena (FIXME)
    if (compare(.@mapa$, "ARENA")) {
        if ('UDTf) {
            'UDTf=0;
            killmonster(getmap(), instance_npcname("Arnea#003-13")+"::OnGladius");
            deltimer(instance_npcname("Arnea#003-13")+"::OnVerify");
        }
    }
    // Died or logged out at Candor Battle
    if (.@mapa$ == "006-1") {
        if (@crazypoints > CRAZYPOINTS) {
            CRAZYPOINTS=@crazypoints;
            dispbottom l("Crazyfefe Cave: New Highscore: @@ points", CRAZYPOINTS);
            @crazypoints=0;
        }
    }
    // Died or logged out at Candor Survival
    if (.@mapa$ == "006-9" && $@SURVIVAL_CANDOR) {
        .@score = gettimetick(2)-$@SURVIVAL_CANDOR;
        if (.@score > SCANDORPTS) {
            SCANDORPTS=.@score;
            dispbottom l("Candor Survival : New Highscore: %s", FuzzyTime(gettimetick(2)+.@score));
        }
        warp "005-1", 66, 63;
    }
    // Died or logged during Bandit Lord fight
    if (.@mapa$ == "015-2") {
        if (isin("015-2", 228, 227, 282, 280))
            killmonster("015-2", "#BanditLordDen::OnLordDeath");
    }
    // Died or logged out on Blue Sage House
    if (.@mapa$ == "020-7-1") {
        callfunc("BSClearNest", @nestid);
    }
    // Died or logged out on Player Story 2 - Magic School Port
    if (compare(.@mapa$, "0030")) {
        if (@ASSASSIN > 0)
            delcells "MQ2Wall"+getcharid(0);
        killmonsterall(getmap());
    }
    // Died or logged out on Player Story 5 - Forgotten Throne Room
    if (compare(.@mapa$, "hmc")) {
        if (@instid > 0)
            .@n$=instance_npcname("#Core02331", @instid);
        else
            .@n$=instance_npcname("#Core02331");
        deltimer(.@n$+"::OnW01");
        deltimer(.@n$+"::OnW02");
        deltimer(.@n$+"::OnE07");
        deltimer(.@n$+"::OnE08");
        deltimer(.@n$+"::OnE09");
        deltimer(.@n$+"::OnE10");
        deltimer(.@n$+"::OnE11");
        deltimer(.@n$+"::OnE12");
        killmonsterall(getmap());
    }
    // Died or logged out on Player Story 6 - Forgotten Shrine
    if (compare(.@mapa$, "brb3")) {
        //.@n$=instance_npcname("#Core02331");
        .@q=getq(LoFQuest_Barbara);
        // Reset quest to: Forgotten Chamber Puzzle incomplete
        if (.@q < 4 && .@q >= 2) {
            setq1 LoFQuest_Barbara, 1;
            setq3 LoFQuest_Barbara, 1;
            // FIXME: Enable Mana Stone#01863
            dispbottom col(l("WARNING: You died at Forgotten Shrine and the Shrine defense triggered."), 1);
            dispbottom col(l("WARNING: Your progress on the quest was lost!"), 1);
        }
    }
    // Died or logged out during Sagratha Fight
    if (compare(.@mapa$, "sgt2")) {
        setq1 HurnscaldQuest_Sagratha, 3;
        setq3 HurnscaldQuest_Sagratha, 0;
        deltimer("#SaggyDungeonCore::OnW01");
        deltimer("#SaggyDungeonCore::OnW02");
        deltimer("#SaggyDungeonCore::OnW03");
        deltimer("#SaggyDungeonCore::OnW04");
        if (instance_id() >= 0) {
            .@n$=instance_npcname("#SaggyDungeonCore");
            deltimer(.@n$+"::OnW01");
            deltimer(.@n$+"::OnW02");
            deltimer(.@n$+"::OnW03");
            deltimer(.@n$+"::OnW04");
        }
    }
    // Died or logged out during a Boss Raid event
    if (compare(.@mapa$, "fyrb")) {
        doevent "sBossRaid::OnDie";
    }
    // Died or logged out during Yeti King Fight
    if (getq(HurnscaldQuest_Celestia) > 1)
        setq HurnscaldQuest_Celestia, 1;
    // First death produces a warning message
    if (PC_DIE_COUNTER <= 1 && .@dead) {
        dispbottom l("Dying outside a town square will cause EXP loss.");
    }
    // If you were travelling and died/logged out, cleaning is needed
    if (@timer_navio_running) {
        @timer_navio_running=0;
        // Logged out? Correct your position to inside the ship
        // Of course, this is messy... But still better than Save Point
        if (!.@dead) {
            if (compare(.@mapa$, "016-"))
                warp "016-1", 28, 27;
            else if (compare(.@mapa$, "002-"))
                warp "002-1", 55, 40;
            else
                warp "Save", 0, 0;
        }
    }
    // Crazyfefe hot fix
    if (.@dead) {
        // It was PK
        if (killerrid > 2000000 && killerrid < 2100000) {
            // PVP flag was off
            /*
            if (!getmapflag(.@mapa$, mf_pvp) && !getmapflag(.@mapa$, mf_pvp_noparty) && !getmapflag(.@mapa$, mf_pvpnoguild)) {
                recovery(getcharid(3));
                warp .@mapa$, .@a, .@b;
                percentheal 100, 100;
                dispbottom l("REVENGE TIME!");
                .@trueid=getcharid(3);
                //detachrid();
                attachrid(killerrid);
                setpcblock(PCBLOCK_SOFT, true);
                sc_start SC_WALKSPEED,120000,50;
                sc_end SC_CASH_PLUSEXP;
                sc_end SC_OVERLAPEXPUP;
                sc_start SC_OVERLAPEXPUP, 300000, -20;
                dispbottom l("For cowardingly killing in a \"secure\" area, you will be severely punished.");
                //Karma+=1;
                sc_start SC_STUN, 15000, 1, 10000, SCFLAG_NOAVOID|SCFLAG_FIXEDTICK;
                addtimer(15000, "#mobptsys::OnUnlock");
                percentheal -88, -100;
                detachrid();
                attachrid(.@trueid);
            }
            */
            HONOR+=1;
        }
    }

    // This allows code to override death penalty, just once:
    // @deathpenalty_override
    // Valid values: 1- No penalty. 2- Halved penalty.
    // You must also set: @deathpenalty_realvalue and @deathpenalty_realvaljob
    if (@deathpenalty_override && .@dead) {
        if (is_staff())
            debugmes("Old values: %d %d Current Values: %d %d", @deathpenalty_realvalue, @deathpenalty_realvaljob, readparam(BaseExp), readparam(JobExp));
        addtimer(300, "#QuirinoHUB::OnNoPenaltyCommand");
    }

    // Register logout time
    if (!.@dead) {
        CHAREG_CLEANUP=gettimetick(2);
        // Send updates to Vault API
        if (getvaultid()) {
            .@api$=json_encode("UID", ##VAULT,
                               "GID", getcharid(3),
                               "VAR1N", "MLQUEST",
                               "VAR1V", ##02_MLQUEST,
                               "VAR2N", "MLWORLD",
                               "VAR2V", ##02_MLWORLD,
                               "VEXP", ##VAULT_EXP,
                               "GOTO", ##VAULT_GOTO,
                               "MLTO", ##VAULT_MLTO);
            ##VAULT_EXP=0;
            ##VAULT_GOTO=0;
            ##VAULT_MLTO=0;
            api_send(API_FLUSHVAULT, .@api$);
            // Destroy temporary characters
            if (countitem(MirrorLakeArmor)) {
                delitem MirrorLakeArmor, countitem(MirrorLakeArmor);
                //clearitem(); // Hm.
                resetlvl(2);
                resetstatus();
                resetskill();
                warp "000-0", 22, 24;
                debugmes("Vault User %d reset!", getvaultid());
            }
        }
    }

    callfunc "02524_Avenge_BlackBox", .@dead;
    return;
}

// HUB_SkillInvoke (  )
function	script	HUB_SkillInvoke	{
    // Something is... wrong
    if (@skillId < 1) {
        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;
    }

    // Missing Skill Target - Don't ask me, something went wrong.
    if (@skillTarget < 1) {
        //@skillTarget = getcharid(3);
        consolewarn("Skill %d has no target!", @skillId);
        consolewarn("Skill Data - Name \"%s\" Level %d User \"%s\"", getskillname(@skillId), @skillLv, strcharinfo(0));
    }

    // Homunculus Cycle
    /* *********************************************************************** */
    //debugmes "Skill caster %d", @skillCaster;
    if (@skillCaster != getcharid(3)) {
        switch (@skillId) {
        case TMW2_SKILLX:
            sc_start SC_RICHMANKIM, 180000, @skillLv+rand2(9*@skillLv), 10000, SCFLAG_NONE, @skillTarget;
            gethomunexp @skillLv;
            break;
        case TMW2_HOMUN_HEAL:
            .@heal=gethominfo(6)*(5+rand2(@skillLv));
            heal .@heal, 0;
            harm(@skillCaster, -.@heal, HARM_MISC);
            break;
        case TMW2_LITTLE_WONDERS:
            sc_end SC_POISON;
            sc_end SC_CURSE;
            sc_end SC_SILENCE;
            sc_end SC_CONFUSION;
            sc_end SC_BLIND;
            sc_start SC_CURSE, rand2(3500, 5000), 1, 10000, SCFLAG_NONE, @skillCaster;
            break;
        case TMW2_CAPRICE:
            .@gid = @skillCaster;
            .@ak1 = max(getunitdata(.@gid, UDT_MATKMIN), getunitdata(.@gid, UDT_INT) * 4 / 3);
            .@ak2 = max(getunitdata(.@gid, UDT_MATKMAX), .@ak1 * 12 / 10);
            /* FIXME: Validate if mob is still alive after each hit */
            for (.@i=0; .@i < limit(1, @skillLv, 10); .@i++) {
                .@dmg=rand2(.@ak1, .@ak2);
                .@ele=any(Ele_Fire, Ele_Water, Ele_Wind, Ele_Earth);
                harm(@skillTarget, .@dmg, HARM_MAGI, .@ele, .@gid);
                sleep2(100);
            }
            break;
        case TMW2_AVOID:
            .@t = 44 - (@skillLv * 4);
            .@p = 105+(@skillLv * 5);
            SC_Bonus(.@t, SC_WALKSPEED, .@p);
            sc_start SC_WALKSPEED, .@t * 1000, .@p, 10000, SCFLAG_NOAVOID, @skillCaster;
            break;
        case TMW2_HDEFENCE:
            .@t = 43 - (@skillLv * 3);
            .@p = 4+(@skillLv * 6);
            SC_Bonus(.@t, SC_INCVIT, .@p);
            sc_start SC_INCVIT, .@t * 1000, .@p, 10000, SCFLAG_NOAVOID, @skillCaster;
            break;
        case TMW2_BLOODLUST:
            // SC_HAMI_BLOODLUST (val1, % ATK Bonus, % Drain Cth, % Drain Rate)
            .@t = (50 + (@skillLv * 10)) * 1000;
            .@atk = 10+(@skillLv * 10);
            .@drc = 2 * @skillLv;
            .@drn = 15 + @skillLv;
            sc_start4 SC_HAMI_BLOODLUST, .@t, 100, .@atk, .@drc, .@drn, 10000, SCFLAG_NOAVOID, @skillCaster;
            break;
        case TMW2_MOON:
            .@gid = @skillCaster; // gethominfo(0);
            .@ak1 = max(getunitdata(.@gid, UDT_ATKMIN), getunitdata(.@gid, UDT_STR) * 3);
            .@ak2 = max(getunitdata(.@gid, UDT_ATKMAX), .@ak1 * 12 / 10);
            .@hit = 1 + (@skillLv / 2);
            .@dmg = rand2(.@ak1, .@ak2) / .@hit;
            .@dmg += .@dmg * @skillLv / 3; // +33% DMG per level
            .@dmx = max(.@dmg * 5 / 4, .@dmg + 10); // ~ +25% DMG on crit
            for (.@i=0; .@i < .@hit; .@i++) {
                // 10% special "crit" chance
                if (rand2(10) == 7)
                    harm(@skillTarget, .@dmx, HARM_MISC, Ele_Neutral, .@gid);
                else
                    harm(@skillTarget, .@dmg, HARM_MAGI, Ele_Neutral, .@gid);
                sleep2(100);
            }
            break;
        case TMW2_FLEET:
            // SC_HLIF_FLEET (val1, % ASPD, % ATK)
            .@t = (65 - (@skillLv * 5)) * 1000;
            .@atk = 5+(@skillLv * 5);
            .@asp = 3 * @skillLv;
            sc_start2 SC_HLIF_FLEET, .@t, .@asp, .@atk, 10000, SCFLAG_NOAVOID, @skillCaster;
            break;
        case TMW2_SPEED:
            // SC_INCFLEE (int flee)
            .@t = (65 - (@skillLv * 5)) * 1000;
            .@val = 15+(@skillLv * 10);
            sc_start SC_INCFLEE, .@t, .@val, 10000, SCFLAG_NOAVOID, @skillCaster;
            break;
        case TMW2_POISONMIST:
            // SC_BLIND
            .@ak1 = max(getunitdata(.@gid, UDT_MATKMIN), getunitdata(.@gid, UDT_INT) * 4 / 3);
            .@ak2 = max(getunitdata(.@gid, UDT_MATKMAX), .@ak1 * 12 / 10);
            .@dmg = rand2(.@ak1, .@ak2) + gethominfo(6);
            .@dmg += .@dmg * @skillLv * 2 / 3; // +67% DMG per level
            .@dur = (3 + (@skillLv * 2)) * 1000;
            .@cth = 2000 + (1000 * @skillLv);

            /* First strike (magic) */
            areaharm(@skillTarget, 7, .@dmg, HARM_MAGI, Ele_Earth);
            areasc(7, .@dur, SC_BLIND, BL_MOB|BL_PC|BL_HOM|BL_MER, 1, "filter_hostile", @skillTarget, .@cth);

            sleep2(500);

            /* Delayed strike (physical) */
            areaharm(@skillTarget, 7, .@dmg, HARM_PHYS, Ele_Wind);
            areasc(7, .@dur, SC_BLIND, BL_MOB|BL_PC|BL_HOM|BL_MER, 1, "filter_hostile", @skillTarget, .@cth);
            break;
        case TMW2_GOLDENFERSE:
            // SC_GOLDENE_FERSE (val1, % MaxHP, % Aspd, % Holy Cth)
            .@t = (50 + (@skillLv * 10)) * 1000;
            .@mhp = @skillLv;
            .@asp = 6 + (4 * @skillLv);
            .@hol = 40 + (10 * @skillLv);
            sc_start4 SC_GOLDENE_FERSE, .@t, .@mhp, .@asp, .@hol, 0, 10000, SCFLAG_NOAVOID, @skillCaster;
            break;
        case TMW2_STAHLHORN:
            .@ak1 = max(getunitdata(.@gid, UDT_ATKMIN), getunitdata(.@gid, UDT_STR) * 3);
            .@ak2 = max(getunitdata(.@gid, UDT_ATKMAX), .@ak1 * 12 / 10);
            .@dmg = rand2(.@ak1, .@ak2) * 2; // 200% DMG
            .@dmg += rand2(.@ak1, .@ak2) * @skillLv; // +100% per level
            .@rng = 5 + (@skillLv / 2);
            .@dur = 500 * @skillLv;
            .@cth = 500 + (400 * @skillLv); // 5% + 4% per level (starts at 9%)
            areaharm(@skillTarget, .@rng, .@dmg, HARM_MAGI, Ele_Holy);
            areasc(.@rng, .@dur, SC_STUN, BL_MOB|BL_PC|BL_HOM|BL_MER, 1, "filter_hostile", @skillTarget, .@cth);
            break;
        }
        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) {
        // Is this ignorable?
        if (@scriptsk) {
            @scriptsk=false;
        } else {
            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;
    callfunc "FYE_Olympics_SK";

    // Script-based skills
    /* *********************************************************************** */
    switch (@skillId) {
        case TMW2_FAKESKILL:
            atcommand("@refresh");
            break;
        case TMW2_FAKESKILL2:
            CMD_toevent();
            break;
        case TMW2_CRAFT:
            UserCtrlPanel();
            break;
        case TMW2_OVHFIRE:
            SK_OVHFire();
            break;
        case TMW2_MPREGEN:
            SK_mpregen();
            break;
        case TMW2_MPTRANSFER:
            SK_transfermp(@skillTarget);
            break;
        case TMW2_STUDY:
            SK_study(@skillTarget);
            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;
        case TMW2_GD_INCALL:
            GD_allboost();
            GetManaExp(GD_DEVELOPMENT, 10);
            break;
        case TMW2_GD_REGEN:
            GD_regenerating();
            GetManaExp(GD_DEVELOPMENT, 10);
            break;
        case TMW2_GD_DEFUP:
            GD_defboost();
            GetManaExp(GD_DEVELOPMENT, 10);
            break;
        case TMW2_GD_BATTLEPLAN:
            GD_atkboost();
            GetManaExp(GD_DEVELOPMENT, 10);
            break;
        case TMW2_GD_ATKUP:
            GD_atkboost2();
            GetManaExp(GD_DEVELOPMENT, 10);
            break;
        case TMW2_GD_CRITUP:
            GD_critboost();
            GetManaExp(GD_DEVELOPMENT, 10);
            break;
        case TMW2_GD_AUTOREVIVE:
            GD_autorevive();
            GetManaExp(GD_DEVELOPMENT, 10);
            break;
        case TMW2_GDP_MAXPOWER:
            SK_maximizepower();
            GetManaExp(GD_DEVELOPMENT, 10);
            break;
        case TMW2_GDP_SPREGEN:
            SK_spregen();
            GetManaExp(GD_DEVELOPMENT, 10);
            break;
        // Weapon Overload attack
        case TMW2_OVERLOAD:
            .@PW=200+(@skillLv > 3 ? @skillLv : 0)+(@skillLv > 7 ? @skillLv*2 : 0);
            areaharm(@skillTarget, 0, AdjustAttackpower(.@PW), HARM_MISC);
            break;
        ////////////////////////////////
        // Magic v3
        // The basic offensive skill from Trickmaster
        case TMW2_MANABOMB:
            // This skill takes 100% mana for a 1:1 ratio damage
            // And is a trick. Each level improves ratio in 1
            // Has no cooldown, so it is powerful with pots
            // And is a good starter offensive skill
            areaharm(@skillTarget, 0, Sp*@skillLv, HARM_MISC, Ele_Ghost);
            Sp=0;
            GetManaExp(@skillId, 1);
            break;
        ////////////////////////////////
        // XXX: Healing Class
        case TMW2_FIRSTAID:
            .@PW=90+(10*@skillLv);
            // First aid only works on you, so
            .@heal=max(AdjustSpellpower(.@PW), AdjustAttackpower(.@PW));
            // Penalty if you have HALT_REGEN on (-80%)
            if (getstatus(SC_HALT_REGENERATION))
                .@heal /= 5;
            heal .@heal, 0;
            GetManaExp(TMW2_HEALING, 1);
            break;
        case TMW2_HEALING:
            .@PW=130+(20*@skillLv);
            // Penalty if you have HALT_REGEN on and trying to self heal
            if (getstatus(SC_HALT_REGENERATION) && @skillTarget == getcharid(3))
                .@heal /= 3;
            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: Revive Class
        case TMW2_RESURRECT:
            SK_resurrect(@skillLv, @skillTarget);
            break;
        ////////////////////////////////
        // XXX: Fire Class
        // (May burn targets for damage over time)
        case TMW2_FIREARROW:
            .@PW=140+(10*@skillLv);
            // 4% chance, 2.5s
            sc_start SC_BLOODING, 4500, 1, 400, SCFLAG_NONE, @skillTarget;
            harm(@skillTarget, AdjustSpellpower(.@PW), HARM_MAGI, Ele_Fire);
            GetManaExp(TMW2_FIREBALL, 1);
            break;
        case TMW2_FIREBALL:
            .@PW=140+(10*@skillLv);
            .@RG=2+(@skillLv/5);
            // 22% chance, 2.5s
            sc_start SC_BLOODING, 2500, 1, 4200, SCFLAG_NONE, @skillTarget;
            areaharm(@skillTarget, .@RG, AdjustSpellpower(.@PW), HARM_MAGI, Ele_Fire);
            GetManaExp(TMW2_FIREBALL, 2);
            break;
        case TMW2_ARMAGEDDON:
            .@PW=140+(10*@skillLv);
            .@RG=5+(@skillLv/5);
            // 18% chance, 3s, 3x3 radius
            areasc(.@RG, 6000, SC_BLOODING, BL_MOB|BL_PC|BL_HOM|BL_MER, 1, "filter_hostile", @skillTarget, 1800);
            areaharm(@skillTarget, .@RG, AdjustSpellpower(.@PW), HARM_MAGI, Ele_Fire);
            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);
            areaharm(@skillTarget, .@RG, .@dmg, HARM_MAGI, Ele_Holy);
            harm(@skillTarget, .@dmg/10, HARM_MAGI, Ele_Holy);
            GetManaExp(TMW2_HOLYLIGHT, 1);
            break;
        case TMW2_HOLYLIGHT:
            .@PW=125+(25*@skillLv);
            .@dmg=AdjustSpellpower(.@PW);
            areaharm(@skillTarget, 1, .@dmg/5, HARM_MAGI, Ele_Holy);
            harm(@skillTarget, .@dmg, 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);
            areaharm(@skillTarget, .@RG, .@dsub, HARM_MAGI, Ele_Holy);
            harm(@skillTarget, .@dmg, 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
            sc_start SC_FREEZE, 2500, 1, 2200, SCFLAG_NONE, @skillTarget;
            harm(@skillTarget, AdjustSpellpower(.@PW), HARM_MAGI, Ele_Water);
            GetManaExp(TMW2_NILFHEIM, 1);
            break;
        case TMW2_FROSTNOVA:
            .@PW=80+(10*@skillLv);
            .@RG=2+(@skillLv/5);
            // 18% chance, 3s, 3x3 radius
            areasc(.@RG, 3000, SC_FREEZE, BL_MOB|BL_PC|BL_HOM|BL_MER, 1, "filter_hostile", @skillTarget, 1800);
            areaharm(@skillTarget, .@RG, AdjustSpellpower(.@PW), HARM_MAGI, Ele_Water);
            GetManaExp(TMW2_NILFHEIM, 2);
            break;
        case TMW2_NILFHEIM:
            // Nilfheim cast on self?
            .@PW=80+(10*@skillLv);
            .@RG=4+(@skillLv/5);
            areasc(.@RG, 15000, SC_FREEZE, BL_PC | BL_MOB | BL_MER | BL_HOM, 1, "filter_hostile");
            areaharm(getcharid(3), .@RG*3/2, AdjustSpellpower(.@PW), HARM_MAGI, Ele_Water);
            // 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);
            sc_start SC_STUN, .@TM, 1, 800, SCFLAG_NONE, @skillTarget;
            harm(@skillTarget, .@dmg, HARM_MAGI, Ele_Earth);
            GetManaExp(TMW2_METEORSTRIKE, 1);
            break;
        case TMW2_METEORSHOWER:
            .@PW=130+(15*@skillLv);
            .@dmg=AdjustSpellpower(.@PW);
            .@RG=3+(@skillLv/5);
            .@TM=800+(@skillLv*200);
            areasc(.@RG, .@TM, SC_STUN, BL_MOB | BL_PC | BL_HOM | BL_MER, 1, "filter_hostile", @skillTarget, 800);
            areaharm(@skillTarget, .@RG, .@dmg, HARM_MAGI, Ele_Earth);
            GetManaExp(TMW2_METEORSTRIKE, 2);
            break;
        case TMW2_GAIABREAK:
            .@PWA=170+(30*@skillLv);
            .@PWB=110+(10*@skillLv);
            .@dmg=AdjustSpellpower(.@PWA);
            .@dsub=AdjustSpellpower(.@PWB);
            areasc(2, 5000, SC_INCDEFRATE, BL_PC, 10, "filter_friendly");
            rectharm(@skillTarget, 2, 5, .@dsub, HARM_MAGI, Ele_Earth);
            harm(@skillTarget, .@dmg, HARM_MAGI, Ele_Earth);
            GetManaExp(TMW2_METEORSTRIKE, 3);
            break;
        /*
        ////////////////////////////////
        // XXX: Assassinate
        // » Assassinate: Instantly kills a monster weaker than you.
        // » Assassinated monsters give no experience.
        // » You'll be stunned for 3 seconds as a penalty.
        // » Does not work on boss. Base Success Chance is 100%.
        case TMW2_ASSASSINATE:
            .@lv = getunitdata(@skillTarget, UDT_LEVEL);
            if ((.@lv+10-@skillLv) < (BaseLevel+(REBIRTH*2)) && filter_notboss(@skillTarget))
                sc_start SC_COMA, 90000, 1, 10000, SCFLAG_NONE, @skillTarget;
            else
                dispbottom l("Assassination failed - target is stronger than you");
            SC_Bonus(3, SC_STUN, 1);
            break;

        // TODO: Ultimate Skills (T5/0)
        // Sanctum: AoE resurrection, HP like Resurrect, 30min+ cooldown and
        // inflict ailment on caster.
        // [Ultimate] revives the whole map, like @raisemap
        case TMW2_SANCTUM:
            SK_sanctum();
            break;

        // Support magic
        // STATUS: Awaiting for Alchemy rework
        // TODO: Debuffs
        // TODO: Buffs

        // XXX: Resurrection skills
        // [MAPZONE] Need special care because scripts
        // [WIP] Maybe a custom recovery and a flag @canRevive ?
        // ---------------------------------------------
        // Revive: Makes char alive with 5% HP/Lvl
        // Resurrect: Makes char alive with ±80% HP and give a protection SC (lvl)
        // Redemption: AoE resurrection (HP works like revive, though)
        case TMW2_REVIVE:
            SK_revive(@skillTarget);
            break;
        case TMW2_RESSURECT:
            SK_ressurect(@skillLv);
            break;





        // Physical Class - mostly builtin
        // TODO: Archery effect-absorb skill
        case TMW2_ARROWOFDEVOUR:
            //.@x=getstatus(SC_POISON)+getstatus(SC_DPOISON);
            // if SC_POISON or SC_DPOISON
            break;
        case TMW2_ARROWOFURGES:
            // if SC_SILENCE or SC_FEAR
            break;
        case TMW2_ULTIMATEARROW:
            // if SC_BLIND or SC_BLOODING
            break;
        case TMW2_EXECUTION:
            // if SC_CURSE or SC_FEAR
            break;
        case TMW2_SHATTERARROW:
            // if SC_STONE or SC_STUN
            break;
        case TMW2_ARROWOFADVANTAGE:
            // IF SC_BURNING or SC_CONFUSION
            break;
        case TMW2_WAKENINGARROW:
            // if SC_SLEEP or SC_DEEP_SLEEP
            break;
        case TMW2_BURNINGARROW:
            // if SC_FREEZE or SC_COLD
            break;



        case TMW2_SNARE:
            // 100.00% inflict STUN/SLEEP/whatever
            // Does not work on boss monsters
            // (Maybe the one which makes next hit critical?)
            // Was it SC_STONE?
            break;
        // Arrow pierce? (Maybe arrow shot disregarding defense, HARM_MISC ?)


        case TMW2_RICHNESS:
            // Passive, bonus2 bAddGetZenyNum, 5, 100; - Better not
            break;
        // TODO: Effect resisting passives?
        // Windwalker... No wait.
        // Immunity to knockback? Meeeeh. Easier to have a trait-giving quest.
        // After all, we have about 20 traits and you can only pick 5.


        // XXX: Sword skills are a 5-skills combo
        // No cast time, but cooldown present
        // DEF lowers as cast, damage based on combo.
        case TMW2_HORIZONTALSLASH:
            .@PW=100;
            .@PW+=(5*@skillLv);
            @SCombo=@skillTarget;
            harm(@skillTarget, AdjustAttackpower(.@PW), HARM_PHYS, Ele_Neutral);
            GetManaExp(@skillId, rand2(1,3));
            break;
        case TMW2_DIAGONALSLASH:
            .@PW=100;
            if (LAST_SKILL[0] == TMW2_HORIZONTALSLASH)
                .@PW+=20;
            if (.@PW >= 120)
                .@PW+=30;
            if (@SCombo != @skillTarget)
                .@PW=100;
            .@PW+=(5*@skillLv);
            harm(@skillTarget, AdjustAttackpower(.@PW), HARM_PHYS, Ele_Neutral);
            GetManaExp(@skillId, rand2(1,3));
            break;
        case TMW2_VERTICALSLASH:
            .@PW=100;
            if (LAST_SKILL[0] == TMW2_DIAGONALSLASH)
                .@PW+=30;
            if (LAST_SKILL[1] == TMW2_HORIZONTALSLASH)
                .@PW+=20;
            if (.@PW >= 150)
                .@PW+=100;
            if (@SCombo != @skillTarget)
                .@PW=100;
            .@PW+=(5*@skillLv);
            harm(@skillTarget, AdjustAttackpower(.@PW), HARM_PHYS, Ele_Neutral);
            GetManaExp(@skillId, rand2(1,3));
            break;
        case TMW2_STAB:
            .@PW=100;
            if (LAST_SKILL[0] == TMW2_VERTICALSLASH)
                .@PW+=40;
            if (LAST_SKILL[1] == TMW2_DIAGONALSLASH)
                .@PW+=30;
            if (LAST_SKILL[2] == TMW2_HORIZONTALSLASH)
                .@PW+=20;
            if (.@PW >= 190)
                .@PW+=200;
            if (@SCombo != @skillTarget)
                .@PW=100;
            .@PW+=(5*@skillLv);
            harm(@skillTarget, AdjustAttackpower(.@PW), HARM_PHYS, Ele_Neutral);
            GetManaExp(@skillId, rand2(1,3));
            break;
        case TMW2_GRANDBLAST:
            .@PW=100;
            if (LAST_SKILL[0] == TMW2_STAB)
                .@PW+=50;
            if (LAST_SKILL[1] == TMW2_VERTICALSLASH)
                .@PW+=40;
            if (LAST_SKILL[2] == TMW2_DIAGONALSLASH)
                .@PW+=30;
            if (LAST_SKILL[3] == TMW2_HORIZONTALSLASH)
                .@PW+=20;
            if (.@PW >= 200)
                .@PW+=300;
            if (@SCombo != @skillTarget)
                .@PW=100;
            .@PW+=(5*@skillLv);
            harm(@skillTarget, AdjustAttackpower(.@PW), HARM_PHYS, Ele_Holy);
            GetManaExp(@skillId, rand2(2,3));
            break;

        */
        ////////////////////////////////
        // XXX: Physical Class (Regular)
        case TMW2_FALKONSTRIKE:
            .@PW=100+(25*@skillLv);
            .@ST=0+(10*@skillLv);
            .@TM=100+(90*@skillLv);
            sc_start SC_STUN, .@TM, 1, .@ST, SCFLAG_NONE, @skillTarget;
            harm(@skillTarget, AdjustAttackpower(.@PW), HARM_PHYS, Ele_Neutral);
            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);
            areasc(.@RG, .@TM, .@EF, BL_MOB | BL_PC | BL_HOM | BL_MER, 1, "filter_hostile", @skillTarget, .@ST);
            areaharm(@skillTarget, .@RG, .@dmg, HARM_PHYS, Ele_Neutral);
            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); // FIXME: May not fire (properly) if target dies
            break;
        case TMW2_STUNNINGSTRIKE:
            // 70x3 = 210
            .@PW=65+(5*@skillLv);
            .@TM=1600+(@skillLv*200);
            // 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);
            sc_start SC_STUN, .@TM, 1, 3333, SCFLAG_NONE, @skillTarget;
            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;

        // Special exception
        case TMW2_TRANSMIGRATION:
            doevent("sk#mkpot::OnCall");
            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;

}




// When you kill a player, some special care is needed
// Only a few maps will give you experience for PK: Tulimshar's Guards Arena,
// Frostia Imperial PVP Arena, Call Of Dusty, Arena Quirino Voraz.
// HUB_PvP ( ) - killedrid must be set
function	script	HUB_PvP	{
    // Update global PK count
    $PLAYERS_KILLED+=1;

    // Prepare local variables
    .@atk=get_BR(getcharid(3));
    .@def=get_BR(killedrid);
    .@honor=calc_HR(getcharid(3), killedrid);
    .@bxp=max(readparam(BaseLevel, killedrid), .@def);
    .@jxp=readparam(JobLevel, killedrid);
    .@m$=getmap();
    .@gm=getgroupid(killedrid);

    // This is an official PVP Map
    if (ispvpmap(.@m$)) {
        // Honorable Death
        if (.@honor >= 0) {
            HONOR+=.@honor;
        } else {
            // Dishonorable... But... Legit?
            if (is_bandit(killedrid) || getmap() == "001-8")
                .@honor=1;
            HONOR+=.@honor; // It's negative.
        }

        // PvP, and a GM was slain
        if (.@gm >= 80) {
            rentitem MurdererCrown, (86400*7); // 1 week
            kamibroadcast(strcharinfo(0)+" killed Game Master \""+strcharinfo(0, "", killedrid)+"\", and now may wear a "+getitemlink(MurdererCrown)+" for a week.");
        }

    // It was a duel!
    } else {
        // Honorable Duel: HONOR +30%
        if (.@honor > 0)
            HONOR+=max(1, .@honor*3/10);
        else if (.@honor < 0)
            HONOR+=1;
        // ^ Dishonorable duel, but was a duel!
    }

    // Report about honor
    dispbottom l("%d vs %d: Honor (%d)", .@atk, .@def, .@honor);

    // TODO: Start using readparam2() to read if the opponent was worthy
    // That is, read total attack, defense, HP, evasion and hit chance
    // And compare with your own readparam2(), then use a % and a table
    // based on your (assassin's) level.
    if (compare(.@m$, "001-8")) {
        // Quirino Voraz PVP Arena
        // You get 5 times killed player level, and 1 time job level
        getexp .@bxp*5, .@jxp;
    } else if (compare(.@m$, "ARENA") || compare(.@m$, "003-13")) {
        // Tulimshar Duel Arena
        // You get 3 times killed player level, and 2 times job level
        getexp .@bxp*3, .@jxp*2;
    } else if (compare(.@m$, "001-10")) {
        // Call Of Dusty
        // You get 3 times killed player level, and 3 times job level
        getexp .@bxp*3, .@jxp*3;
    } else if (compare(.@m$, "001-10-1")) {
        // Call Of Dusty Boss Room
        // You _may_ get a Bottled Dusty at random, but dead player status affect
        if (.@def > .@atk/10) {
            if (rand2(0,250) < readparam2(bLuk)+readparam2(bLuk, killedrid))
                getitem BottledDust, any(1,1,2);
        }
    } else {
        // Anywhere else
        // You get 0.5 times killed player level, and 0 times job level
        getexp (.@bxp/2), 0;
    }
    return;
}



// HUB_PCBonus ()
function	script	HUB_PCBonus	{
    /* Rebirth Passives */
    if (REBIRTH)
        bonus bAllStats, REBIRTH;

    /* Rebirth Traits */
    if (PCBONUS & PCB_ATKBONUS) {
        bonus bAtk, 25;
    }
    if (PCBONUS & PCB_MATKBONUS) {
        bonus bMatk, 25;
    }
    if (PCBONUS & PCB_DEFBONUS) {
        bonus bDef, 20;
    }
    if (PCBONUS & PCB_MDEFBONUS) {
        bonus bMdef, 20;
    }
    if (PCBONUS & PCB_EVDBONUS) {
        bonus bFlee, 20;
    }
    if (PCBONUS & PCB_HITBONUS) {
        bonus bHit, 25;
    }
    if (PCBONUS & PCB_CRITBONUS) {
        bonus bCritical, 5;
    }
    if (PCBONUS & PCB_DOUBLEATK) {
        bonus bDoubleAddRate, 5;
    }
    if (PCBONUS & PCB_ALLSTATS) {
        bonus bAllStats, 1;
    }
    if (PCBONUS & PCB_HPBONUS) {
        bonus bMaxHP, 500;
    }
    if (PCBONUS & PCB_MPBONUS) {
        bonus bMaxSP, 200;
    }
    if (PCBONUS & PCB_ASPDBONUS) {
        bonus bAspd, 10;
    }
    if (PCBONUS & PCB_WSPDBONUS) {
        bonus bSpeedAddRate, 5;
    }
    if (PCBONUS & PCB_WEIGHTBONUS) {
        bonus bAddMaxWeight, 1000;
    }
    if (PCBONUS & PCB_EXPBONUS) {
        bonus2 bExpAddRace, RC_All, 10;
    }
    if (PCBONUS & PCB_NOKNOCKBACK) {
        bonus bNoKnockback, 1;
    }
    if (PCBONUS & PCB_SPLASHMASTER) {
        bonus bSplashRange, 1;
    }
    if (PCBONUS & PCB_RANGEMASTER) {
        bonus bAtkRange, 1;
    }
    if (Class != Savior && !(PCBONUS & PCB_LEGENDARY)) {
        bonus2 bCriticalAddRace, RC_Legendary, -25;
        bonus2 bSPDrainValueRace, RC_Legendary, -5;
        bonus2 bAddRace, RC_Legendary, -40;
        bonus2 bMagicAddRace, RC_Legendary, -20;
    }
    if (PCBONUS & PCB_LEGENDARY) {
        bonus bDefRatioAtkRace, RC_Legendary;
    }
    /* Passive Skills */
    bonus2 bSubRace, RC_Legendary, getskilllv(AL_DP)-10;
    if (getq(LoFQuest_Barbara) >= 4 || getq(General_Narrator) >= 19)
        bonus bMaxSP, 40;
    if (getq(HalinarzoQuest_Speed) > 1)
        bonus bSpeedAddRate, min(getq(HalinarzoQuest_Speed)-1, 10);

    return;
}