summaryrefslogblamecommitdiff
path: root/npc/functions/hub.txt
blob: b1e34f5b15d6c35e1976c6329ea60eeb754f997b (plain) (tree)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16















                                                
                               
                                                       

                                     
                            
                                                     

                                 






                                         
                                              
 

                              






                                                              
                     
                                                   
                         

                                                          




                                                                                                               
                
                                      
                                  


                                                          
                                                               


                                                       
                             
                                                                       
                                                

                                         
                                          

                                    









                                                   
                                                                                     


                                                                                   
                                                               



                                   
                                                 








                                                        







                                                                                  







                                                                                  

                                              
                                              

                                                                



                                            





                                                               
                                                                   
                                  



                                                         







                                 
                                 
     




                                                              
                                  

                                      
                                             



                                                                                                            
                                               
                                   


                                         









                                                                         
                                         
                                     
                                              









                                                         
              


                                                                                                                              
                                     



                                              
                                                                                                




                                                                                                             
                           
                                                                                   




                                                       

                     












                                                                                                                                                          

                           
                                      


           

                                         
                                       
                                                                                              

                                              
                                                                                                                                                                                 

                         
                                                      





                                  





                             


                          
                               
                                    
                  



                            
                              





















                                


                           


                                                                                                 
                                        
                  


                        




                                 
                          
                                           
                  









                                                        


                                                                                        




                                                                                                   





                                                                            
                                      
             

                                            







                                             







                                               
                  




                                        




                                                                 


           



 


                                                                             







                                      
                                             

                                                      
                  
                               
 
                                  
                         
                          
                           
                           

                                            
                                     
                         

                                                 

         





                                                                                                                                                                        


                                     
                        
                                        
                             

                                               

     


                                                                



                                                                        














                                                                                 
                               

                                                                            
         







                                                                       
// TMW2 scripts.
// Authors:
//    Jesusalva
//    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;

    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_ATTACK|PCBLOCK_SKILL|PCBLOCK_USEITEM|PCBLOCK_MOVE, 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, -1;
    }
    // Logout on botcheck area
    if (compare(.@mapa$,"botcheck") && !.@dead) {
        if (!is_staff())
            atcommand "@jail "+strcharinfo(0);
    }
    // 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 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;
    }
    // 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_ATTACK|PCBLOCK_SKILL|PCBLOCK_USEITEM|PCBLOCK_COMMANDS, 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);
    return;
}

// HUB_SkillInvoke (  )
function	script	HUB_SkillInvoke	{
    debugmes "Cast skill %d", @skillId;
    // 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)
        Exception("System ERROR, HSI."+@skillId+" INVALID CAST (got "+@skillLv+" expected "+getskilllv(@skillId)+", sub-LC."+(getcharid(3)-2000000)+")", RB_DEBUGMES|RB_ISFATAL);

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

    // Script-based skills
    switch (@skillId) {
        case TMW2_FAKESKILL:
            atcommand("@refresh");
            break;
        case TMW2_FAKESKILL2:
            CMD_toevent();
            break;
        case TMW2_CRAFT:
            UserCtrlPanel();
            break;
        case TMW2_MPREGEN:
            SK_mpregen();
            break;
        case EVOL_AREA_PROVOKE:
            massprovoke(1+@skillLv);
            break;
        case TMW2_GD_INCALL:
            GD_allboost();
            break;
        case TMW2_GD_REGEN:
            GD_regenerating();
            break;
        case TMW2_GD_DEFUP:
            GD_defboost();
            break;
        case TMW2_GD_BATTLEPLAN:
            GD_atkboost();
            break;
        case TMW2_GD_ATKUP:
            GD_atkboost2();
            break;
        case TMW2_GD_CRITUP:
            GD_critboost();
            break;
        case TMW2_GD_AUTOREVIVE:
            GD_autorevive();
            break;
        case TMW2_GDP_MAXPOWER:
            SK_maximizepower();
            break;
        case TMW2_GDP_SPREGEN:
            SK_spregen();
            break;
        case TMW2_NILFHEIM:
            SK_nilfheim();
            break;
        case TMW2_JUDGMENT:
            debugmes "Target: %d (%d,%d)", @skillTarget, @skillTargetX, @skillTargetY;
            areasc2(getmap(), @skillTargetX, @skillTargetY, 2, 10000, SC_BLOODING, BL_MOB|BL_PC);
            harm(@skillTarget, 1000, 1);
            break;
        case TMW2_PARUM:
            SK_parum();
            break;
        // Highly complex summons
        case TMW2_ZARKOR:
            SK_zarkor();
            break;
        // Less complex summons
        case TMW2_KALMURK:
            SK_summon(Maggot, 2, any(1,2));
            break;
        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;
        // Slightly more complex summons
        case TMW2_LIMERIZER:
            SK_summon(any(GreenSlime,AzulSlime,RedSlime,AngryYellowSlime), 2, any(3,4));
            break;
        case TMW2_FAIRYKINGDOM:
            // TODO: Allow Pixie summoning
            SK_summon(any(FireFairy, EarthFairy, WaterFairy, WindFairy, PoisonFairy), 4, any(3,4));
            break;
        // More complex summons
        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;

        // Special exception
        case TMW2_TRANSMIGRATION:
            doevent("sk#mkpot::OnCall");
            break;
    }

    // Debug
    if ($@GM_OVERRIDE || debug)
        debugmes "Cast skill %d on level %d", @skillId, @skillLv;
    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))
                HONOR+=1;
            else
                HONOR+=.@honor; // It's negative.
        }

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

    // 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;
}