summaryrefslogblamecommitdiff
path: root/npc/soren/main.txt
blob: 845c662d0c301230fa2b83bf8609bc35f33a5988 (plain) (tree)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18

















                                                                                    
                                                                            



                                                                        
  
                                                                 



                                                                                




                                                           

                                                                         
                                                                      
                                              
                         
                                                     
                                          



                                         





                                                                                                                                            
                                                                                                  

              
        



                                                                          
                                         




                                       

                                          
     








                                        
        





 
                                                               










                                                                                                    
                                                 


                                
                                                                                 
                     



                                                                         
     
          
 
                                      




             

             









                                                                       




                                                                           




                                                               
 

                       

                                                                 
                                                                  
                       

                       
 
                                     

                  

                                                               





                                                 
                                               
               
               
                                                
               
               
                                                                                      
                           
                                                                     

               
                        




                                         
               
                                                                
               
               
                                                 

               
                                              
               
                

                                               
                                                  
                
                                                            
                           
                                                                 

              



                      

                    
                                                                                                                                                                            
                      

                               
                   

                                                  

                                                                               
                          
     



                   
                  
 
                                                          
                                                                                       
                                         






        











 
                                                       










                                                                                                    
                                                 




                                                                                 



                                                                     



                                      






             














                                                                           




                                                               






                                                                     

                       
 
                                     

                                    

                                                                 





                                                 
                                               
               
               
                                                
               
               
                                                                                      
                           
                                                                     








                                              
                                                                











                                                 
                                                            
                           
                                                                 
     
                                                   



                       
                                                                                                                                                                            


                               
                                                  


                                                                               



                   
                  

                                                      
                                                                                            
                                         







        
























                                                                                                    
                                                 




                                                                                 



                                                                      



                                      






             














                                                                           




                                                               






                                                                     

                       
 
                                     

                                                                        

                                                                 





                                                 
                                               
               
               
                                                
               
               
                                                                                      
                           
                                                                     








                                         
                                                                











                                                 
                                                            
                           
                                                                 







                      
                                                                                                                                                                            


                               
                                                  


                                                                               

        
 

                   
                  

                                                      
                                                                                            
                                         



        

                                                                                 
// TMW2 Scripts
// Author:
//   Jesusalva
// Description:
//   Celestia Yeti King's quest. This controls Soren's House and the three keysigns.
//   Key #1
//      Perform the rite at the Fountain
//   Key #2
//      Perform the rite at the south lake
//   Key #3
//      Perform the rite at the Button Area
//
//   If the same player performs the rite on different places, HE'LL BE PENALIZED.
//   Performing the rite spawn monsters, so watch out.

// Notes:
//      I had two options:
//          getvariableofnpc(<variable>, "<npc name>")
//              This way, each summon point would have .caster and .lifetime
//          getvariableofpc(<variable>, <account id>{, <default value>})
//              This way, I could use @cast_places to control stuff.
//
//      Obviously NPC variables was more sane.
//
//      The use of         compareandsetq HurnscaldQuest_Celestia
//      Ensures you're NOT capable of skipping to final stage in order to finish
//      the quest. Nice attempt, but that won't work. The scripts will advance,
//      but you'll stay at the same quest state, and when it's checked, you will
//      be with bound hands.

soren,105,57,0	script	Soren's House	NPC_NO_SPRITE,0,0,{
    end;

OnTouch:
    .@st1=getvariableofnpc(.lifetime, "Soren's Fountain")-gettimetick(2);
    .@st2=getvariableofnpc(.lifetime, "Soren's Lake")-gettimetick(2);
    .@st3=getvariableofnpc(.lifetime, "Soren's Gizmo")-gettimetick(2);
    if (.@st1 > 0 && .@st2 > 0 && .@st3 > 0) {
        @soren_penalty=0;
        compareandsetq HurnscaldQuest_Celestia, 3, 4;
        doevent("#SorenSanctum::OnStart");
        warp "soren-2", 32, 36;
        end;
    } else {
        mesn l("Soren's House Tutorial");
        mesc l("There's a strong magic barrier. We need to disarm it in order to enter there.");
        mesc l("There are three singularities on this island. If I disarm more than one, I'll have a penalty.");
        mesc l("I should have full mana before attempting to disarm one.");
        mesc l("Also, if I move away from the singularity during disarm process, it'll be lost.");
        mesc l("The singularities keep arming themselves up again, so I have roughly five minutes between first disarm and entering here.");
        mesc l("We should split our team, and have someone to protect our backs. Otherwise, we might not do it.");
        // Protip: stock Elixir Of Life if you need to do this quest with less than 3 team members
        close;
    }
    end;

// Some cleanup might be needed to don't raise difficulty infinitely
// So every day, at 03:23 AM, if no one is trying the quest, it'll get rid
// of the non-permanent monsters on Soren Village & Soren House.
// FIXME: It also clears up Groata Grotto
OnClock0323:
    if (getareausers("soren") == 0 &&
        getareausers("soren-2") == 0 &&
        getareausers("001-6") == 0 &&
        getareausers("001-7") == 0) {
            killmonster("soren", "all");
            killmonster("soren-2", "all");
    }
    if ($@GROTTO &&
        getareausers("006-0") == 0 &&
        getareausers("006-3") == 0 &&
        getareausers("006-5") == 0) {
            killmonster("006-5", "all");
            $@GROATA = 0;
            $@GROTTO = 0;
            enablenpc "#006-5_49_54";
    }
    end;
}





soren,105,92,0	script	Soren's Fountain	NPC_NO_SPRITE,{
    // Initial Checks
    if (.lifetime > gettimetick(2)) {
        npctalk l("This singularity will remain disarmed for @@ more!", FuzzyTime(.lifetime, 2, 2));
        end;
    }
    if (.st) {
        npctalk l("A disarm process is already running.");
        end;
    }

    // Main menu
    mesc l("Attempt to disarm the singularity?");
    if (askyesno() == ASK_YES) {
        .casterId=getcharid(3);
        .st=1;
        npctalk l("@@ started disarm process. Please stand by.", strcharinfo(0));
        initnpctimer;
        if (getvariableofnpc(.casterId, "Soren's Fountain") == .casterId)
            @sorenp=10;
        else
            @sorenp=0;
    }
    close;

// Waves (total: 6 waves + 1 optional)
OnTimer5000:
OnTimer10300:
OnTimer14000:
OnTimer18000:
OnTimer25000:
OnTimer28000:
OnTimer31000:
    if (!attachrid(.casterId)) {
        npctalk "Disarm process aborted: Disarmer is gone.";
        stopnpctimer; .st=0;
        end;
    }
    if (!reachable(.x, .y, .distance)) {
        npctalk l("Disarm process aborted: Disarmer is out of reach.");
        stopnpctimer; .st=0;
        end;
    }
    if (Sp < MaxSp/100*15) {
        npctalk l("Disarm process aborted: Insufficient mana to proceed.");
        stopnpctimer; .st=0;
        end;
    }
    if (ispcdead()) {
        npctalk l("Disarm process aborted: Disarmer is dead.");
        stopnpctimer; .st=0;
        end;
    }

    // Penalty Handler.
    .@val=-2;
    if (getvariableofnpc(.casterId, "Soren's Lake") == .casterId)
        .@val=.@val-10;
    if (getvariableofnpc(.casterId, "Soren's Gizmo") == .casterId)
        .@val=.@val-10;
    if (@sorenp)
        .@val-=@sorenp;

    percentheal (.@val/2), -13+.@val;

    // Monster Gen
    .@amount=rand2(.st/3+1, .st/2+1)+getareausers("soren", 12);
    .@mid=rand2(1,3)+.st;
    switch (.@mid) {
        case 1:
        case 2:
                .@monsterId = CaveMaggot ; break;
        case 3:
        case 4:
                .@monsterId = RedSlime ; break;
        case 5:
        case 6:
                .@monsterId = LavaSlime ; break;
        case 7:
        case 8:
                .@monsterId = any(Snake, GrassSnake, OldSnake, MountainSnake) ; break;
        default: // case 9:
                .@monsterId = any(Yeti, Yeti, MountainSnake) ; break;
    }
    // Item Gen
    .@mid=rand(1,7)+.st;
    switch (.@mid) {
        case 1:
        case 2:
                .@itemId = Acorn ; break;
        case 3:
        case 4:
                .@itemId = any(BugLeg, ChocolateMouboo) ; break;
        case 5:
        case 6:
                .@itemId = OrangeCupcake ; break;
        case 7:
        case 8:
                .@itemId = CherryCake ; break;
        case 9:
        case 10:
                .@itemId = Chagashroom ; break;
        case 11:
                .@itemId = GingerBreadMan ; break;
        case 12:
                .@itemId = rand2(Diamond, Amethyst) ; break;
        default: // case 13
                .@itemId = rand2(CopperOre, TitaniumOre) ; break;
    }
    // Defines
    .@lx=.x-.distance;
    .@ly=.y-.distance;
    .@ux=.x+.distance;
    .@uy=.y+.distance;

    // Core function
    areamonster .map$, .@lx, .@ly, .@ux, .@uy, strmobinfo(1, .@monsterId), .@monsterId, .@amount; makeitem(.@itemId, 1, .map$, rand2(.@lx, .@ux), rand2(.@ly, .@uy)); ++.st;
    specialeffect(54);

    // If we're done with waves
    if (.st >= 7) {
        getexp rand2(1, 100), rand2(1, 10);
        .lifetime=gettimetick(2)+330+rand2(0, 60);
        npctalk l("Disarmed with success for: @@", FuzzyTime(.lifetime, 2, 2));
        stopnpctimer; .st=0;
        specialeffect(27);
    }
    end;

OnInit:
    .sex = G_OTHER;
    .distance = 3;

    .casterId=0; // getcharid(0) → 3 is account number!!
    .lifetime=0;  // When will this gate expire (six minutes) (gettimetick(2) + (60*5))
    .st=0;        // Status after started

    end;
}
















soren,104,143,0	script	Soren's Lake	NPC_NO_SPRITE,{
    // Initial Checks
    if (.lifetime > gettimetick(2)) {
        npctalk l("This singularity will remain disarmed for @@ more!", FuzzyTime(.lifetime, 2, 2));
        end;
    }
    if (.st) {
        npctalk l("A disarm process is already running.");
        end;
    }

    // Main menu
    mesc l("Attempt to disarm the singularity?");
    if (askyesno() == ASK_YES) {
        .casterId=getcharid(3);
        .st=1;
        npctalk l("@@ started disarm process. Please stand by.", strcharinfo(0));
        initnpctimer;
        if (getvariableofnpc(.casterId, "Soren's Lake") == .casterId)
            @sorenp=10;
        else
            @sorenp=0;
    }
    close;

// Waves (total: 6 waves + 1 optional)
OnTimer4500:
OnTimer11300:
OnTimer17000:
OnTimer22000:
OnTimer26200:
OnTimer29100:
OnTimer30900:
    if (!attachrid(.casterId)) {
        npctalk "Disarm process aborted: Disarmer is gone.";
        stopnpctimer; .st=0;
        end;
    }
    if (!reachable(.x, .y, .distance)) {
        npctalk l("Disarm process aborted: Disarmer is out of reach.");
        stopnpctimer; .st=0;
        end;
    }
    if (Sp < MaxSp/100*15) {
        npctalk l("Disarm process aborted: Insufficient mana to proceed.");
        stopnpctimer; .st=0;
        end;
    }
    if (ispcdead()) {
        npctalk l("Disarm process aborted: Disarmer is dead.");
        stopnpctimer; .st=0;
        end;
    }

    // Penalty Handler.
    .@val=-2;
    if (getvariableofnpc(.casterId, "Soren's Fountain") == .casterId)
        .@val=.@val-10;
    if (getvariableofnpc(.casterId, "Soren's Gizmo") == .casterId)
        .@val=.@val-10;
    if (@sorenp)
        .@val-=@sorenp;

    percentheal (.@val/2), -13+.@val;

    // Monster Gen. Lake spawns less
    .@amount=rand2(.st/3+1, .st/2+1)+getareausers("soren", 12)-1;
    .@mid=rand2(1,3)+.st;
    switch (.@mid) {
        case 1:
        case 2:
                .@monsterId = CaveMaggot ; break;
        case 3:
        case 4:
                .@monsterId = RedSlime ; break;
        case 5:
        case 6:
                .@monsterId = LavaSlime ; break;
        case 7:
        case 8:
                .@monsterId = any(Snake, GrassSnake, OldSnake, MountainSnake) ; break;
        default: // case 9:
                .@monsterId = any(Yeti, Yeti, MountainSnake) ; break;
    }
    // Item Gen have a different mechanic here
    .@mid=rand(.st, .st*2+1);
    switch (.@mid) {
        case 1:
        case 2:
                .@itemId = Acorn ; break;
        case 3:
        case 4:
                .@itemId = any(BugLeg, ChocolateMouboo) ; break;
        case 5:
        case 6:
                .@itemId = OrangeCupcake ; break;
        case 7:
        case 8:
                .@itemId = CherryCake ; break;
        case 9:
        case 10:
                .@itemId = Chagashroom ; break;
        case 11:
                .@itemId = HastePotion ; break;
        case 12:
                .@itemId = rand2(Diamond, Amethyst) ; break;
        default: // case 13
                .@itemId = rand2(CopperOre, TitaniumOre) ; break;
    }
    // Defines for Lake are fixed on the same spot.
    .@lx=104; .@ux=104;
    .@ly=141; .@uy=141;

    // Core function
    areamonster .map$, .@lx, .@ly, .@ux, .@uy, strmobinfo(1, .@monsterId), .@monsterId, .@amount; makeitem(.@itemId, 1, .map$, rand2(.@lx, .@ux), rand2(.@ly, .@uy)); ++.st;

    // If we're done with waves
    if (.st >= 7) {
        .lifetime=gettimetick(2)+330+rand2(0, 60);
        npctalk l("Disarmed with success for: @@", FuzzyTime(.lifetime, 2, 2));
        stopnpctimer; .st=0;
    }
    end;

OnInit:
    .sex = G_OTHER;
    .distance = 2;

    .casterId=""; // getcharid(3) → Account number!!
    .lifetime=0;  // When will this gate expire (five~six minutes) (gettimetick(2) + (60*5))
    .st=0;        // Status after started

    end;
}


















soren,107,37,0	script	Soren's Gizmo	NPC_NO_SPRITE,{
    // Initial Checks
    if (.lifetime > gettimetick(2)) {
        npctalk l("This singularity will remain disarmed for @@ more!", FuzzyTime(.lifetime, 2, 2));
        end;
    }
    if (.st) {
        npctalk l("A disarm process is already running.");
        end;
    }

    // Main menu
    mesc l("Attempt to disarm the singularity?");
    if (askyesno() == ASK_YES) {
        .casterId=getcharid(3);
        .st=1;
        npctalk l("@@ started disarm process. Please stand by.", strcharinfo(0));
        initnpctimer;
        if (getvariableofnpc(.casterId, "Soren's Gizmo") == .casterId)
            @sorenp=10;
        else
            @sorenp=0;
    }
    close;

// Waves (total: 6 waves + 1 optional)
OnTimer6200:
OnTimer9300:
OnTimer13900:
OnTimer17200:
OnTimer24500:
OnTimer27400:
OnTimer31200:
    if (!attachrid(.casterId)) {
        npctalk "Disarm process aborted: Disarmer is gone.";
        stopnpctimer; .st=0;
        end;
    }
    if (!reachable(.x, .y, .distance)) {
        npctalk l("Disarm process aborted: Disarmer is out of reach.");
        stopnpctimer; .st=0;
        end;
    }
    if (Sp < MaxSp/100*15) {
        npctalk l("Disarm process aborted: Insufficient mana to proceed.");
        stopnpctimer; .st=0;
        end;
    }
    if (ispcdead()) {
        npctalk l("Disarm process aborted: Disarmer is dead.");
        stopnpctimer; .st=0;
        end;
    }

    // Penalty Handler.
    .@val=-2;
    if (getvariableofnpc(.casterId, "Soren's Lake") == .casterId)
        .@val=.@val-10;
    if (getvariableofnpc(.casterId, "Soren's Fountain") == .casterId)
        .@val=.@val-10;
    if (@sorenp)
        .@val-=@sorenp;

    percentheal (.@val/2), -13+.@val;

    // Monster Gen. Gizmo spawns more monsters because you can move more
    .@amount=rand2(.st/3+1, .st/2+1)+getareausers("soren", 12)+1;
    .@mid=rand2(1,3)+.st;
    switch (.@mid) {
        case 1:
        case 2:
                .@monsterId = CaveMaggot ; break;
        case 3:
        case 4:
                .@monsterId = RedSlime ; break;
        case 5:
        case 6:
                .@monsterId = LavaSlime ; break;
        case 7:
        case 8:
                .@monsterId = any(Snake, GrassSnake, OldSnake, MountainSnake) ; break;
        default: // case 9:
                .@monsterId = any(Yeti, Yeti, MountainSnake) ; break;
    }
    // Item Gen
    .@mid=rand(1,7)+.st;
    switch (.@mid) {
        case 1:
        case 2:
                .@itemId = Acorn ; break;
        case 3:
        case 4:
                .@itemId = any(BugLeg, ChocolateMouboo) ; break;
        case 5:
        case 6:
                .@itemId = OrangeCupcake ; break;
        case 7:
        case 8:
                .@itemId = CherryCake ; break;
        case 9:
        case 10:
                .@itemId = Chagashroom ; break;
        case 11:
                .@itemId = HastePotion ; break;
        case 12:
                .@itemId = rand2(Diamond, Amethyst) ; break;
        default: // case 13
                .@itemId = rand2(CopperOre, TitaniumOre) ; break;
    }
    // Defines
    .@lx=.x-.distance;
    .@ly=.y-.distance;
    .@ux=.x+.distance;
    .@uy=.y+.distance;

    // Core function
    areamonster .map$, .@lx, .@ly, .@ux, .@uy, strmobinfo(1, .@monsterId), .@monsterId, .@amount; makeitem(.@itemId, 1, .map$, rand2(.@lx, .@ux), rand2(.@ly, .@uy)); ++.st;

    // If we're done with waves
    if (.st >= 7) {
        .lifetime=gettimetick(2)+330+rand2(0, 60);
        npctalk l("Disarmed with success for: @@", FuzzyTime(.lifetime, 2, 2));
        stopnpctimer; .st=0;
    }
    end;


OnInit:
    .sex = G_OTHER;
    .distance = 4;

    .casterId=""; // getcharid(3) → Account number!!
    .lifetime=0;  // When will this gate expire (five~six minutes) (gettimetick(2) + (60*5))
    .st=0;        // Status after started

    end;
}

029-0,143,120,0	duplicate(Guild Storage)	Guild Storekeeper#FoS	NPC_TERRY