summaryrefslogblamecommitdiff
path: root/npc/soren/main.txt
blob: d849a0a4fbe41e3f1f934fdef13f559d28e04783 (plain) (tree)






















                                                                                    
  
                                                                 



                                                                                




                                                           

                                                                         
                                                                      









                                                                                                                    
                                                                                                                                                
                                                                                                                      
                                                                                                  

              






        
                                                               












                                                                                                    
                                      
                                                      

                               
                                                                                 
                     
     
          
 
                                      




             

             









                                                                       





                                                                           

                       

                                                                 
                                                                  
                       

                                                                   

                           

                  
                                  











                                                    
                                   


                                           
                        




                                         
               
                                                   
               
               
                                                 

               
                                              
               
                



                                               
                                                           
                           


                                                                



                      


                                                                                                                                                                          
                      

                               
                   
                                         
                                                 

                                                                               
                          
     





                   
                                                          
                                                                                       
                                         






        











 
                                                       












                                                                                                    
                                      
                                                      







                                                                                 






             





















                                                                           

                                                                   

























































                                                                                                                                                                          






                                                      
                                                                                            
                                         







        


























                                                                                                    
                                      
                                                      







                                                                                 






             





















                                                                           

                                                                   



























































                                                                                                                                                                          

        
 




                                                      
                                                                                            
                                         



        
// 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) {
        compareandsetq HurnscaldQuest_Celestia, 3, 4;
        warp "soren-2", 32, 36;
        end;
    } else {
        mesn l("Soren's House Tutorial");
        mes col("There's a strong magic barrier. We need to disarm it in order to enter there.", 9);
        mes col("There are three singularities on this island. If I disarm more than one, I'll have a penalty.", 9);
        mes col("I should have full mana before attempting to disarm one.", 9);
        mes col("Also, if I move away from the singularity during disarm process, it'll be lost.", 9);
        mes col("The singularities keep arming themselves up again, so I have roughly five minutes between first disarm and entering here.", 9);
        mes col("We should split our team, and have someone to protect our backs. Otherwise, we might not do it.", 9);
        // Protip: stock Elixir Of Life if you need to do this quest with less than 3 team members
        close;
    }
    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
    mes col("Attempt to disarm the singularity?", 9);
    if (askyesno() == ASK_YES) {
        if (.casterId == getcharid(3))
            @soren_penalty=@soren_penalty+rand(8, 12);
        .casterId=getcharid(3);
        .st=1;
        npctalk l("@@ started disarm process. Please stand by.", strcharinfo(0));
        initnpctimer;
    }
    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;
    }

    // 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 (@soren_penalty > 0) // Weak protection against EXP farming.
        .@val=.@val-@soren_penalty;

    percentheal .@val, -15;

    // Monster Gen
    .@amount=rand(.st/2+1, .st+1);
    .@mid=rand(1,3)+.st;
    switch (.@mid) {
        case 1:
        case 2:
                .@monsterId = CaveMaggot ; break;
        case 3:
        case 4:
        case 5:
                .@monsterId = LavaSlime ; break;
        case 6:
        case 7:
                .@monsterId = MountainSnake ; break;
        default: // case 8: case 9:
                .@monsterId = Yeti ; break;
    }
    // Item Gen
    .@mid=rand(1,7)+.st;
    switch (.@mid) {
        case 1:
        case 2:
                .@itemId = Acorn ; break;
        case 3:
        case 4:
                .@itemId = 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 = rand(Diamond, Amethyst) ; break;
        default: // case 13
                .@itemId = rand(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$, rand(.@lx, .@ux), rand(.@ly, .@uy)); ++.st;
    specialeffect(54);

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

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

    .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
    mes col("Attempt to disarm the singularity?", 9);
    if (askyesno() == ASK_YES) {
        if (.casterId == getcharid(3))
            @soren_penalty=@soren_penalty+rand(8, 12);
        .casterId=getcharid(3);
        .st=1;
        npctalk l("@@ started disarm process. Please stand by.", strcharinfo(0));
        initnpctimer;
    }
    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;
    }

    // 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 (@soren_penalty > 0) // Weak protection against EXP farming.
        .@val=.@val-@soren_penalty;

    percentheal .@val, -15;

    // Monster Gen. Lake spawns less
    .@amount=rand(.st/3+1, .st/2+1);
    .@mid=rand(1,3)+.st;
    switch (.@mid) {
        case 1:
        case 2:
                .@monsterId = CaveMaggot ; break;
        case 3:
        case 4:
        case 5:
                .@monsterId = LavaSlime ; break;
        case 6:
        case 7:
                .@monsterId = MountainSnake ; break;
        default: // case 8: case 9:
                .@monsterId = Yeti ; 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 = 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 = rand(Diamond, Amethyst) ; break;
        default: // case 13
                .@itemId = rand(CopperOre, TitaniumOre) ; break;
    }
    // Defines for Lake are fixed
    .@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$, rand(.@lx, .@ux), rand(.@ly, .@uy)); ++.st;

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

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

    .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
    mes col("Attempt to disarm the singularity?", 9);
    if (askyesno() == ASK_YES) {
        if (.casterId == getcharid(3))
            @soren_penalty=@soren_penalty+rand(8, 12);
        .casterId=getcharid(3);
        .st=1;
        npctalk l("@@ started disarm process. Please stand by.", strcharinfo(0));
        initnpctimer;
    }
    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;
    }

    // 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 (@soren_penalty > 0) // Weak protection against EXP farming.
        .@val=.@val-@soren_penalty;

    percentheal .@val, -15;

    // Monster Gen. Gizmo spawns more monsters because you can move more
    .@amount=rand(.st/2+2, .st+2);
    .@mid=rand(1,3)+.st;
    switch (.@mid) {
        case 1:
        case 2:
                .@monsterId = CaveMaggot ; break;
        case 3:
        case 4:
        case 5:
                .@monsterId = LavaSlime ; break;
        case 6:
        case 7:
                .@monsterId = MountainSnake ; break;
        default: // case 8: case 9:
                .@monsterId = Yeti ; break;
    }
    // Item Gen
    .@mid=rand(1,7)+.st;
    switch (.@mid) {
        case 1:
        case 2:
                .@itemId = Acorn ; break;
        case 3:
        case 4:
                .@itemId = 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 = rand(Diamond, Amethyst) ; break;
        default: // case 13
                .@itemId = rand(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$, rand(.@lx, .@ux), rand(.@ly, .@uy)); ++.st;

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


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

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