summaryrefslogblamecommitdiff
path: root/npc/006-7/ctrl.txt
blob: 17243b5610a2301b4279876a835cfbd75197596c (plain) (tree)
1
2
3
4
5
6



               

                           






                                                        




                                                                                             
                                 
                                                  
        

 
                                                     
                                




                                                                                                     


                                                                                             
                                                         
                                        
                                                         
         








                                                         



                      
 
                     
                                                 

                                                                   
 
                       

                                                                       

                                                      





















                                            
                                                                   









                                                                        
 
                              




                      
                                          



                                                                          
             
             

                                                                     
            
                                 

                                                   
                                                                                        

                                
                                      
                                                                             
                   
                  
                                   


                     
 

















                                                                            
                           
                                                                           

                                                   
                             


                                     

                                                           
                             
                                                       

         
                
 






                                           
                                                                 

                                                                   
                                              


            
                                                                                           
                                                                              
                    

                                                                                            
                          





            

                                        
                       
                                             
                                                                                                                   
                                       
                              
                                                
                                                                                                                              


                                                
                                                                                                                            

                                     
                                                 


                                    
                                                                                                

                                                








                                                           
                                                                                                              

                                                                          
                                                                                                               



                                                                                
                       








                                                                                       






                                                        
                                













                                                                       
                                






                                                                                             
                                




                                                                                                 
                                                        
                                                       
                                

                                                           




                            





















                                                                                                          






                                                          
                                     

                                                         
                                     
                                        
                       
                                                        
                                   

                                                                                             
                              
                                                       
                                  


                                                                                             
                                  


                                       
                                                                                                              

                                       
                                                                                                              


                                        
                                                                                                             

                                                                                                                                                       

     






                            
              
              


        
// TMW2 Script
// Author:
//    Jesusalva

006-7	mapflag	zone	MMO

006-7,44,50,0	script	#OutOf0067	NPC_HIDDEN,0,0,{
    end;

OnTouch:
    if (!$@ICICLE_CHALLENGE)
        warp "006-6", 40, 36;
    end;

OnRw:
    getexp 1000000, 0;
    Mobpt += 10000;
    dispbottom l("Der Schneemann has been defeated: %s Monster Points gained.", fnum(10000));
    RegEasterEgg(EE_SNOWMAN, 25);
    specialeffect(FX_FANFARE, SELF, getcharid(3));
    end;
}

006-7,44,35,0	script	Ice Lord	NPC_YETIFLY,{
    if ($@ICICLE_CHALLENGE) end;
    if (.ticks > gettimetick(2)) {
        mesn;
        mesq l("This challenge will be available in %s. Please wait until then.", FuzzyTime(.ticks));
        close;
    }
    mesn;
    mesq l("With Magic and Blades, The Icicle shall break. Do you undertake the challenge?");
    mesc l("Advised: 6+ players"), 1;
    mesc l("Advised: 1+ mage, 1+ tanker, 2+ healers"), 1;
    mesc l("Time Limit: 90 minutes"), 1;
    mesc l("Enter/Leave after start: %s", b(l("NO"))), 1;
    next;
    select
        l("Not yet."),
        l("Bring it on!"),
        rif(REBIRTH, l("Bring me, my worst nightmare."));
    mes "";
    if (@menu == 1) {
        closeclientdialog;
        close;
    }
    if (@menu == 2)
        .hard = false;
    else
        .hard = true;

    // Der Schneemann
    .ticks = gettimetick(2) + 5400; // 90 minutes
    .BOSS = monster("006-7", 44, 36, "The Icicle", SnowmanBoss, 1);
    .@mlt = (.hard ? 15 : 10);

    // Basic attributes
    setunitdata(.BOSS, UDT_MAXHP, 750000 * .@mlt / 10); // 750k ~ 1250k
    setunitdata(.BOSS, UDT_HP,    750000 * .@mlt / 10);
    setunitdata(.BOSS, UDT_ATKRANGE, (.hard ? 7 : 6));

    // Reconfigure the AI
    .@opt=getunitdata(.BOSS, UDT_MODE);
    // Disable looting
    if (.@opt & MD_LOOTER)
        .@opt=.@opt^MD_LOOTER;
    // Add knockback immunity
    .@opt=.@opt|MD_NOKNOCKBACK;
    // Mark as boss
    .@opt=.@opt|MD_BOSS;
    // Mark as aggressive
    .@opt=.@opt|MD_AGGRESSIVE;
    .@opt=.@opt|MD_ANGRY;
    // Make it more op
    .@opt=.@opt|MD_DETECTOR;
    .@opt=.@opt|MD_CASTSENSOR_CHASE;
    .@opt=.@opt|MD_CASTSENSOR_IDLE;
    .@opt=.@opt|MD_CHANGECHASE;
    .@opt=.@opt|MD_CHANGETARGET_MELEE;
    .@opt=.@opt|MD_CHANGETARGET_CHASE;
    setunitdata(.BOSS, UDT_MODE, .@opt);

    // Nerf the damage, but never miss a hit
    setunitdata(.BOSS, UDT_ATKMIN,   60 * .@mlt / 10); // 60~90 dmg
    setunitdata(.BOSS, UDT_ATKMAX,   60 * .@mlt / 10);
    setunitdata(.BOSS, UDT_ADELAY, 2220 / .@mlt * 10); // 2220 or 1480ms
    setunitdata(.BOSS, UDT_HIT,      2400);

    // Boosting the defense is not necessary
    // It nerfs weapons to 40% (bows to 20%)
    // Then it resists 50% of Neutral element.
    // Note it is strong against Water (25% dmg)
    // And weak against Fire (snow) and Wind (100% dmg)
    // Otherwise, behave as Ghost element

    $@ICICLE_CHALLENGE = true;
    disablenpc .name$;
    initnpctimer;
    closeclientdialog;
    close;

// Fail-safe Mechanism (will never happen)
OnTimer60000:
    consolebug("Warning! final fail-safe mechanism triggered to Icicle.");
    initnpctimer;
    end;
OnTimer25000:
OnTimer15000:
    consolewarn("Warning, fail-safe mechanism triggered to Icicle.");
// This is the boss' core
OnTimer5000:
    /* Maybe the fight is over */
    if (!mobcount("006-7", "all"))
        maptimer2("006-7", 10, "#OutOf0067::OnRw");
    if (.ticks < gettimetick(2) || !mobcount("006-7", "all") || !getmapusers("006-7")) {
        killmonsterall("006-7");
        enablenpc .name$;
        npctalk "The battle is over!";
        .ticks = min(.ticks, gettimetick(2) + 1800); // Min. Cooldown: 30 min
        .beats = 0;
        .warn = 0;
        $@ICICLE_CHALLENGE = false;
        stopnpctimer;
        end;
    }

    /* Warn players when time is about to end */
    if (.ticks - 1800 < gettimetick(2) && .warn < 1) {
        mapannounce("006-7", "Warning : ##1##BTime left: 30 minutes##b", 0);
        .warn = 1;
    }
    else if (.ticks - 900 < gettimetick(2) && .warn < 2) {
        mapannounce("006-7", "Warning : ##1##BTime left: 15 minutes##b", 0);
        .warn = 2;
    }
    else if (.ticks - 600 < gettimetick(2) && .warn < 3) {
        mapannounce("006-7", "Warning : ##1##BTime left: 10 minutes##b", 0);
        .warn = 3;
    }
    else if (.ticks - 300 < gettimetick(2) && .warn < 4) {
        mapannounce("006-7", "Warning : ##1##BTime left: 5 minutes##b", 0);
        .warn = 4;
    }

    /* Prepare some data */
    .@hp = getunitdata(.BOSS, UDT_HP) * 10 / getunitdata(.BOSS, UDT_MAXHP);
    getmapxy(.@m$, .@x, .@y, UNITTYPE_MOB, .BOSS);
    .@c=getunits(BL_PC, .@pcs, MAX_CYCLE_PC, .@m$);
    .@mvp=0;.@rnd=0;.@def=-1;
    for (.@i = 0; .@i < .@c; .@i++) {
        if (!.@rnd || !rand2(.@c))
            .@rnd=.@pcs[.@i];
        if (readbattleparam(.@pcs[.@i], UDT_DEF) > .@def) {
            if (readparam(Hp, .@pcs[.@i]) < 1) continue;
            .@mvp=.@pcs[.@i];
            .@def=readbattleparam(.@pcs[.@i], UDT_DEF);
        }
    }
    .beats += 1;

    /* Everyone is dead, get rid of them */
    if (!.@mvp || !.@rnd) {
        mapwarp("006-7", "006-6", 40, 36);
        initnpctimer;
        end;
    }

    //debugmes "----------- Skill Loop, beat is %d", .beats % 18;
    /* Decide the skill to use based on ~5s beats over 3 minutes */
    switch (.beats % 18) {
    // (1/6) Summon Reinforcements (every 60s)
    case 0:
    case 6:
    case 12:
        unittalk(.BOSS, "Come forth, ##Bsnow army##b, for the Icicle shall live forever!");
        specialeffect(65, AREA, .BOSS); // Actually 64, but won't do well here
        sleep(1000);
        monster("006-7", 44, 22, strmobinfo(1, Snowman), Snowman, max(1, (11 - .@hp) / 10));
        break;
    // (2/6) Tanker (~30s)
    case 1:
    case 4:
    case 7:
    case 10:
    case 13:
    case 16:
        specialeffect(702, AREA, .BOSS);
        sleep(1000);
        if (.@hp < 3) {
            // Third Attack Pattern: Judgment
            unittalk(.BOSS, sprintf("%s cannot stop me! ##BJudgment##b!", strcharinfo(0, "cursed player", .@mvp)));
            .@PW=240; .@SPW=60; .@RG=3;
        } else if (.@hp < 7) {
            // Second Attack Pattern: Holy Light
            unittalk(.BOSS, sprintf("%s, I'll show you no mercy! ##BHoly Light##b!", strcharinfo(0, "cursed player", .@mvp)));
            .@PW=125; .@SPW=25; .@RG=1;
        } else {
            // First Attack Pattern: Napalm Beat
            unittalk(.BOSS, sprintf("This battle is over, %s! ##BNapalm Beat##b!", strcharinfo(0, "cursed player", .@mvp)));
            .@PW=35; .@SPW=5; .@RG=2;
        }
        .@mtk = calcdmg(.BOSS, .@mvp, HARM_MAGI);
        .@dmg = .@mtk * .@PW / 100;
        .@dsb = .@mtk * .@SPW / 100;
        sleep(1000);
        areaharm(.@mvp, .@RG, .@dsb, HARM_MAGI, Ele_Holy, "filter_always", BL_PC|BL_MER|BL_HOM);
        harm(.@mvp, .@dmg, HARM_MAGI, Ele_Holy);
        break;
    // (3/6) Random Target (~60s)
    case 2:
    case 8:
    case 14:
        specialeffect(50, AREA, .BOSS);
        sleep(1000);
        .@time=rand2(18000, 36000) + 10000 - (.@hp * 1000);
        // Switch between curse and disable
        if (any(true,false)) {
            unittalk(.BOSS, sprintf("I hereby ##Bcurse##b you, %s!", strcharinfo(0, "cursed player", .@rnd)));
            sc_start(SC_CURSE, .@time, 1, 10000, SCFLAG_FIXEDRATE, .@rnd);
        } else {
            unittalk(.BOSS, sprintf("I shall ##Bdisable##b you, %s!", strcharinfo(0, "cursed player", .@rnd)));
            sc_start(SC_BLIND, .@time / 2, 1, 10000, SCFLAG_FIXEDRATE, .@rnd);
            sc_start(SC_SILENCE, .@time / 2, 1, 10000, SCFLAG_FIXEDRATE, .@rnd);
        }
        // Second pattern: Bleeding ON
        if (.@hp < 7) {
            sc_start(SC_BLOODING, 10000, 1, 9000-(.@hp*1000), SCFLAG_FIXEDRATE, .@rnd);
        }
        break;
    // (4/6) Traps (~60s)
    case 3:
    case 9:
    case 15:
        .@x1=rand2(31, 58); .@x2=rand2(31, 58); .@x3=rand2(31, 58);
        .@y1=rand2(23, 49); .@y2=rand2(23, 49); .@y3=rand2(23, 49);
        .@t1=monster("006-7", .@x1, .@y1, "", Dummy, 1);
        .@t2=monster("006-7", .@x2, .@y2, "", Dummy, 1);
        .@t3=monster("006-7", .@x3, .@y3, "", Dummy, 1);
        specialeffect(67, AREA, .@t1);
        specialeffect(67, AREA, .@t2);
        specialeffect(67, AREA, .@t3);
        immortal(.@t1); immortal(.@t2); immortal(.@t3);
        if (.@hp < 5 || .hard) {
            .@x4=rand2(31, 58); .@x5=rand2(31, 58); .@x6=rand2(31, 58);
            .@y4=rand2(23, 49); .@y5=rand2(23, 49); .@y6=rand2(23, 49);
            .@t4=monster("006-7", .@x1, .@y1, "", Dummy, 1);
            .@t5=monster("006-7", .@x2, .@y2, "", Dummy, 1);
            .@t6=monster("006-7", .@x3, .@y3, "", Dummy, 1);
            specialeffect(67, AREA, .@t4);
            specialeffect(67, AREA, .@t5);
            specialeffect(67, AREA, .@t6);
            immortal(.@t4); immortal(.@t5); immortal(.@t6);
        }
        sleep(2000);
        specialeffect(11, AREA, .@t1);
        specialeffect(11, AREA, .@t2);
        specialeffect(11, AREA, .@t3);
        if (.@hp < 5 || .hard) {
            specialeffect(11, AREA, .@t4);
            specialeffect(11, AREA, .@t5);
            specialeffect(11, AREA, .@t6);
        }
        areaharm(.@t1, 2, 450, HARM_MISC, Ele_Neutral, "filter_always", BL_PC|BL_MER|BL_HOM);
        areaharm(.@t2, 2, 450, HARM_MISC, Ele_Neutral, "filter_always", BL_PC|BL_MER|BL_HOM);
        areaharm(.@t3, 2, 450, HARM_MISC, Ele_Neutral, "filter_always", BL_PC|BL_MER|BL_HOM);
        if (.@hp < 5 || .hard) {
            areaharm(.@t4, 2, 450, HARM_MISC, Ele_Neutral, "filter_always", BL_PC|BL_MER|BL_HOM);
            areaharm(.@t5, 2, 450, HARM_MISC, Ele_Neutral, "filter_always", BL_PC|BL_MER|BL_HOM);
            areaharm(.@t6, 2, 450, HARM_MISC, Ele_Neutral, "filter_always", BL_PC|BL_MER|BL_HOM);
        }
        sleep(1000);
        // FIXME: M+ fails to remove them, need @refresh
        unitkill(.@t1); unitkill(.@t2); unitkill(.@t3);
        if (.@hp < 5 || .hard) {
            unitkill(.@t4); unitkill(.@t5); unitkill(.@t6);
        }
        break;
    // (5/6) Weak AOE (~60s)
    case 5:
    case 11:
    case 17:
        specialeffect(60, AREA, .BOSS);
        sleep(500);
        switch (rand2(3)) {
        case 1:
            unittalk(.BOSS, "I shall ##Bpoison##b you all!");
            .@sc = (.@hp < 1 ? SC_DPOISON : SC_POISON);
            break;
        case 2:
            unittalk(.BOSS, "I shall ##Bhurt##b you all!");
            .@sc = SC_BLOODING;
            break;
        case 3:
            unittalk(.BOSS, "I shall ##Bsilence##b you all!");
            .@sc = SC_SILENCE;
            break;
        default:
            unittalk(.BOSS, "I shall ##Bcripple##b you all!");
            .@sc = SC_BLIND;
            break;
        }
        areasc((.hard ? 7 : 6), 45000, .@sc, BL_PC|BL_HOM|BL_MER, 1, "filter_always", .BOSS, 95000);
        areaharm(.BOSS, (.hard ? 7 : 6), 100, HARM_MAGI, Ele_Water, "filter_always", BL_PC|BL_MER|BL_HOM);
        break;
    }
    // Strong AOE: Every 3 minutes (case = 0)
    // Stalls all other skills for a while
    if (.beats % 18 == 0) {
        specialeffect(66, AREA, .BOSS);
        unittalk(.BOSS, "I am the Icicle, the immortal.");
        sleep((.hard ? 1000 : 1500));
        specialeffect(700, AREA, .BOSS);
        unittalk(.BOSS, "You're no match for me, so...");
        sleep((.hard ? 1000 : 1500));
        specialeffect(700, AREA, .BOSS);
        if (.@hp < 3) {
            unittalk(.BOSS, "Perish! ##BSnowstorm##b!");
            .@dmg=rand2(900, 1100);
            areasc(3, 5000, SC_FREEZE, BL_PC|BL_HOM|BL_MER, 1, "filter_always", .BOSS, 2000);
            areasc(6, 10000, SC_BLIND, BL_PC|BL_HOM|BL_MER, 1, "filter_always", .BOSS, 2000);
        } else if (.@hp < 7) {
            unittalk(.BOSS, "Perish! ##BBlizzard##b!");
            .@dmg=rand2(650, 900);
            areasc(3, 5000, SC_FREEZE, BL_PC|BL_HOM|BL_MER, 1, "filter_always", .BOSS, 1500);
        } else {
            unittalk(.BOSS, "Perish! ##BShattering Winds##b!");
            .@dmg=rand2(400, 650);
        }
        /* Three blocks */
        specialeffect(66, AREA, .BOSS);
        areaharm(.BOSS, (.hard ? 7 : 6), .@dmg, HARM_MAGI, Ele_Neutral, "filter_always", BL_PC|BL_MER|BL_HOM);
        sleep(500);
        specialeffect(66, AREA, .BOSS);
        areaharm(.BOSS, (.hard ? 18 : 12), .@dmg, HARM_MAGI, Ele_Water, "filter_always", BL_PC|BL_MER|BL_HOM);
        sleep(500);
        specialeffect(66, AREA, .BOSS);
        specialeffect(312, AREA, .BOSS);
        areaharm(.BOSS, (.hard ? 24 : 18), .@dmg, HARM_MAGI, Ele_Holy, "filter_always", BL_PC|BL_MER|BL_HOM);
        areasc((.hard ? 24 : 18), .@dmg*rand2(50, 100), SC_FROSTMISTY, BL_PC|BL_HOM|BL_MER, 1, "filter_always", .BOSS, 10001 - (.@hp * 1000)); // FIXME
        // SC_COLD freezes you, so trying SC_FROSTMISTY
    }

    initnpctimer;
    end;

OnInit:
    .distance = 4;
    .ticks = gettimetick(2);
    .beats = 0;
    .hard = 0;
    .warn = 0;
    end;
}