summaryrefslogblamecommitdiff
path: root/npc/001-14/ctrl.txt
blob: c64d20dc69011595a4ab32b4963b97d11a3d0eac (plain) (tree)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15














                                                                                                    
                                                                                 









                                                         
                                                                                 
                                                         
                                         
                         











                                                                                                                                                                    
                    





































                                                                                                
                              

                                                                                                  


                                      

                                    



                                           


        
                              

                                         





                                                                       





                                                         
                            

                                                                                                       
                                     





                                                                  
                              

                                                        


                                                          
                    



                
                 


        
                                                                                 
                                                         





                                                                                                                       





                
                                                                                 









                                                         
                                                                                 
                                    
                                                                 




                                                                               





                
                                                                                 
                                                              


















                                                                                            





                
                                                                                 
                                                         
                         













































                                                                                                                                                         
                            
































                                                                                                       

                                                            



                                                          



                

             


        
                                                                                 
                                                         




                                                                                                                                                                   





                
                                                                                 
                                                         









                                                                                                                                                                                                         
                                                                  








                                                                       
                                                                    


























































































































































































































































                                                                                                                                        
                      






                                                                       

                                                        
                                                                    



                                                        


                                                                  

        













                                                                                       




                
                                                                                 
                                                         
                         





























































































































                                                                                                                                                                             
                        














                                                                                                                     

                                                          



                                                          



                

                 


        
                                                                                 
                                                         


























                                                                                                                                                                    

                                                                  








                                                                                                    

                                                          




                                                                                   
                                                                      

























                                                                                                       






                
                                                                                 
                                                         





                                                                                             






                
 
// TMW2 script
// Author:
//   Jesusalva
// Description:
//    Magic Olympics

001-14,91,90,0	script	#MOLY_Sign00	NPC_NO_SPRITE,{
    dispbottom l("Welcome to Porthos - The Town of Portals (Kaizei's æther / Moubootaur Legends)");
    end;

OnInit:
    .distance=2;
    end;
}

/////////////////////////////////////////////////////////////////////////////////
// FIXME
001-14,88,27,0	script	Hocus#MOLY1200	NPC_BLACKWIZARD,{
    npctalk l("Icicle Challenge");
    end;

OnInit:
    .distance=7;
    end;
}

/////////////////////////////////////////////////////////////////////////////////
001-14,111,42,0	script	Hocus#MOLY0100	NPC_BLACKWIZARD,{
    if (gettimetick(2) < @moly_tick) end;
    if (@moly_chall) end;
    mes ".:: " + l("Energy Ball Challenge") + ":: .";
    mes l("The goal is simple - I'll spawn an energy ball and you must kill it quickly. You'll be disqualified if you equip a non-magical weapon at any time.");
    dnext;
    mes l("You'll have 60 seconds to kill as many balls as you can!");
    mesc l("NOTE: Beside wands and staves, %s, %s, and the %s count as magic weapons.", getitemlink(Judgement), getitemlink(DarkPulsar), getitemlink(Lightbringer));
    mes "";
    mesc l("Your progress thus far: %s sparks", fnum(FYMOLY_ENBALL)), 3;
    next;
    mesc l("Begin campaign?"), 1;
    if (askyesno() == ASK_NO) close;
    @moly_tick = gettimetick(2) + 60;
    @moly_score = 0;
    @moly_chall = 1;
    .m$=getmap();
    @map$=getmap();
    .@m=areamonster(.m$, 108, 43, 118, 48, "Target", YellowSpark, 1, "Hocus#MOLY0100::OnClick");
    setunitdata(.@m, UDT_HP, 1);
    setunitdata(.@m, UDT_MAXHP, 1);
    setunitdata(.@m, UDT_LEVEL, 1);
    setunitdata(.@m, UDT_SPEED, 60);
    npctalk3 l("Countdown: 1 minute");
    addtimer 2000, instance_npcname("Hocus#MOLY0100")+"::OnCheck";
    initnpctimer;
    closeclientdialog;
    close;

OnTimer15000:
    npctalk "45 seconds";
    end;

OnTimer30000:
    npctalk "30 seconds";
    end;

OnTimer45000:
    npctalk "15 seconds";
    end;

OnTimer55000:
    npctalk col("5 seconds", 1);
    end;

OnTimer60000:
    killmonsterall(.m$);
    maptimer2(.m$, 10, "Hocus#MOLY0100::OnEnd");
    npctalk col("Time out!", 1);
    stopnpctimer;
    end;

OnClick:
    if (gettimetick(2) > @moly_tick) end;
    if (@moly_chall != 1) end;
    @moly_score+=1;
    .@m=areamonster(@map$, 108, 43, 118, 48, "Target", YellowSpark, 1, "Hocus#MOLY0100::OnClick");
    .@hp=rand2(50, 100);
    setunitdata(.@m, UDT_MAXHP, .@hp);
    setunitdata(.@m, UDT_HP, .@hp);
    setunitdata(.@m, UDT_LEVEL, 1);
    setunitdata(.@m, UDT_SPEED, 60);
    setunitdata(.@m, UDT_MODE, MD_CANMOVE);
    setunitdata(.@m, UDT_DEF, 32760);
    setunitdata(.@m, UDT_MDEF, 0);
    setunitdata(.@m, UDT_LUK, 32760);
    end;

OnCheck:
    if (@moly_chall != 1) end;
    if (gettimetick(2) > @moly_tick) end;
    .@wp = getequipid(EQI_HAND_R);
    // Disarmed
    if (.@wp < 1) {
        addtimer(2000, instance_npcname("Hocus#MOLY0100")+"::OnCheck");
        end;
    }
    // Illegal weapon
    if (.@wp != Judgement &&
        .@wp != DarkPulsar &&
        .@wp != Lightbringer &&
        getiteminfo(.@wp, ITEMINFO_SUBTYPE) != W_STAFF) {
            @moly_score = -1;
            @moly_tick = 0;
            @moly_chall = 0;
            dispbottom col(l("You have been disqualified - illegal weapon: %s", getitemname(.@wp)), 1);
            stopnpctimer;
            killmonsterall(getmap());
            end;
    }
    addtimer 2000, instance_npcname("Hocus#MOLY0100")+"::OnCheck";
    end;

OnEnd:
    if (@moly_chall != 1) end;
    .@pts=getq2(Q_AuroraEvent);
    setq2 Q_AuroraEvent, .@pts+rand2(1, 1+@moly_scr/10);
    dispbottom l("End! Score this time: %d", @moly_score);
    FYMOLY_ENBALL = max(FYMOLY_ENBALL, @moly_score);
    @moly_score = 0;
    @moly_chall = 0;
    end;

OnInit:
    .distance=7;
    .m$="001-14";
    end;
}

/////////////////////////////////////////////////////////////////////////////////
001-14,135,61,0	script	Hocus#MOLY0200	NPC_BLACKWIZARD,{
    mes ".:: " + l("Intensive Mage Challenge") + ":: .";
    mes l("Description: Use a lot of magic spells, regardless of type or raw strength. Points earned by skill level.");
    mesc l("Note: Passives and some skills (e.g. Resync) doesn't count."), 1;
    mes "";
    mesc l("Your progress thus far: %s skills casted", fnum(FYMOLY_SPAMMY)), 3;
    close;

OnInit:
    .distance=7;
    end;
}

/////////////////////////////////////////////////////////////////////////////////
// FIXME
001-14,139,85,0	script	Hocus#MOLY0300	NPC_BLACKWIZARD,{
    npctalk l("Fluffy Hunter Challenge");
    end;

OnInit:
    .distance=7;
    end;
}

/////////////////////////////////////////////////////////////////////////////////
// Note: Do player knows any chants?
001-14,135,117,0	script	Hocus#MOLY0400	NPC_BLACKWIZARD,{
    mes ".:: " + l("Chanting Challenge") + ":: .";
    mes l("Description: Use chant-based magic. All chants score equally.");
    mes "";
    mesc l("Your progress thus far: %s chants casted", fnum(FYMOLY_CHANTI)), 3;
    close;

OnInit:
    .distance=7;
    end;
}

/////////////////////////////////////////////////////////////////////////////////
001-14,119,135,0	script	Hocus#MOLY0500	NPC_NICHOLAS,{
    mes ".:: " + l("Alchemy Master Challenge") + ":: .";
    mes l("Description: Whoever crafts more potions, regardless of type, wins this event.");
    mes "";
    mesc l("Your progress thus far: %s potions baked", fnum(FYMOLY_ALCHMY)), 3;
    next;
    // FREE brewing during event
    do {
        mesc l("What will you brew today?");
        mes "";

        if (AlchemySystem(CRAFT_PLAYER)) {
            mesc l("Success!"), 3;
        } else {
            mesc l("That didn't work!"), 1;
        }
        next;
        mesc l("Try again?");
    } while (askyesno() == ASK_YES);
    close;

OnInit:
    .distance=7;
    end;
}

/////////////////////////////////////////////////////////////////////////////////
001-14,88,139,0	script	Hocus#MOLY0600	NPC_BLACKWIZARD,{
    if (@moly_chall) end;
    mes ".:: " + l("Magic Raw Power Challenge") + ":: .";
    mes l("Description: For starters, I'll blow away all your summons and summon an ent. You must do the most damage to it within 10 seconds.");
    mes l("Using potions and support magic is fine. It has high defense, so magic attacks work better.");
    mesc l("Only magic weapons are allowed, but legendary ones - %s and %s - won't be tolerated.", getitemlink(Runestaff), getitemlink(Lightbringer)), 1;
    mes "";
    mesc l("Your progress thus far: %s damage inflicted", fnum(FYMOLY_MPWLVL)), 3;
    next;
    mesc l("Begin campaign?"), 1;
    if (askyesno() == ASK_NO) close;
    killmonsterall(getmap());
    .@m=areamonster(getmap(), 87, 140, 93, 145, strmobinfo(1, EntAbomination), EntAbomination, 1);
    setunitdata(.@m, UDT_MAXHP, 1000000);
    setunitdata(.@m, UDT_HP, 1000000);
    setunitdata(.@m, UDT_LEVEL, 1);
    setunitdata(.@m, UDT_SPEED, 60);
    setunitdata(.@m, UDT_MODE, MD_CANMOVE|MD_CANATTACK|MD_BOSS);
    setunitdata(.@m, UDT_DEF, 999);
    setunitdata(.@m, UDT_MDEF, 0);
    setunitdata(.@m, UDT_LUK, 32760);
    .mob = .@m;
    .pid = getcharid(3);
    @moly_tick = gettimetick(2) + 60;
    @moly_score = 0;
    @moly_chall = 6;
    npctalk "10";
    addtimer 550, instance_npcname("Hocus#MOLY0600")+"::OnCheck";
    initnpctimer;
    closeclientdialog;
    close;

OnCheck:
    if (@moly_chall != 6) end;
    if (gettimetick(2) > @moly_tick) end;
    .@wp = getequipid(EQI_HAND_R);
    // Disarmed
    if (.@wp < 1) {
        addtimer(550, instance_npcname("Hocus#MOLY0600")+"::OnCheck");
        end;
    }
    // Illegal weapon
    if ((.@wp == Lightbringer || .@wp == Runestaff) ||
        (.@wp != Judgement &&
        .@wp != DarkPulsar &&
        getiteminfo(.@wp, ITEMINFO_SUBTYPE) != W_STAFF)) {
            @moly_score = -1;
            @moly_tick = 0;
            @moly_chall = 0;
            dispbottom col(l("You have been disqualified - illegal weapon: %s", getitemname(.@wp)), 1);
            stopnpctimer;
            killmonsterall(getmap());
            end;
    }
    addtimer 550, instance_npcname("Hocus#MOLY0600")+"::OnCheck";
    end;

OnTimer1000:
    npctalk "9"; end;
OnTimer2000:
    npctalk "8"; end;
OnTimer3000:
    npctalk "7"; end;
OnTimer4000:
    npctalk "6"; end;
OnTimer5000:
    npctalk "5"; end;
OnTimer6000:
    npctalk "4"; end;
OnTimer7000:
    npctalk col("3", 1); end;
OnTimer8000:
    npctalk col("2", 1); end;
OnTimer9000:
    npctalk col("1", 1); end;
OnTimer10000:
    npctalk col("Time out!", 1);
    stopnpctimer;
    attachrid(.pid);
    if (@moly_chall != 6) end;
    @moly_score = (getunitdata(.mob, UDT_HP) - getunitdata(.mob, UDT_MAXHP)) * -1;
    killmonsterall(getmap());
    .@pts=getq2(Q_AuroraEvent);
    setq2 Q_AuroraEvent, .@pts+rand2(1, 1+@moly_score/1500);
    dispbottom l("End! Score this time: %d", @moly_score);
    FYMOLY_MPWLVL = max(FYMOLY_MPWLVL, @moly_score);
    @moly_score = 0;
    @moly_chall = 0;
    end;

OnInit:
    .distance=7;
    .mob = 0;
    .pid = 0;
    end;
}

/////////////////////////////////////////////////////////////////////////////////
001-14,54,133,0	script	Hocus#MOLY0700	NPC_BLACKWIZARD,{
    mes ".:: " + l("Mana Experience Challenge") + ":: .";
    mes l("Description: Similar to Intensive Mage, but measures mana experience - meaning even less skills will count, and swapping skills give a better effect.");
    mes "";
    mesc l("Your progress thus far: %s exp earned", fnum(FYMOLY_MANAXP)), 3;
    close;

OnInit:
    .distance=7;
    end;
}

/////////////////////////////////////////////////////////////////////////////////
001-14,39,114,0	script	Hocus#MOLY0800	NPC_BLACKWIZARD,{
    if (@moly_chall) end;
    mes ".:: " + l("Maze Race Challenge") + ":: .";
    mes l("Description: Reach the other side of the maze and defeat the %s as quick as possible.", getmonsterlink(EntAbomination));
    mes l("There'll be monsters, the maze is randomly generated, and the initial position for you and the Ent is not fixed. Therefore, you may begin handicapped in some cases depending on luck only.");
    mesc l("NOTE: No equipment restriction. Less time is better.");
    mes "";
    mesc l("Your progress thus far: %s taken.", FuzzyTime(gettimetick(2) + FYMOLY_RACERS)), 3;
    next;
    mesc l("Begin campaign?"), 1;
    if (askyesno() == ASK_NO) close;
    addtimer 2500, instance_npcname("Hocus#MOLY0800")+"::OnCheck";
    @map$ = getmap();
    @moly_tick = gettimetick(2); // Will be used to determine score
    @moly_score = 0;             // Actually unused
    @moly_chall = 8;

    CreateMaze(IOT_CHAR);
    .@mx=getmapinfo(MAPINFO_SIZE_X, MAZE_MAP$)-20;
    .@my=getmapinfo(MAPINFO_SIZE_Y, MAZE_MAP$)-20;
    .@tl=(20-.@mx)*(20-.@my) * 3 / 10; // Total tiles + collision guess
    .@tl=.@tl / rand2(12,16) + 1; // Monster density is a bit random

    /* *** Copied from 006-5/groata.txt & 018-2-2/main.txt! *** */
    /* ********** Spawn monsters based on your level ********** */
    .@lv = max(6, BaseLevel) - 5;
    .@mb[0] = MagicGoblin;
    .@mb[1] = CaveMaggot;

    // Artillery
    if (.@lv > 40)
        array_push(.@mb, RobinBandit);
    if (.@lv > 50)
        array_push(.@mb, DustGatling);
    if (.@lv > 60)
        array_push(.@mb, DustRifle);
    if (.@lv > 70)
        array_push(.@mb, DustRevolver);
    if (.@lv > 80)
        array_push(.@mb, DustBoss);
    if (.@lv > 90)
        array_push(.@mb, GreatMoubooSlime);
    if (.@lv > 100)
        array_push(.@mb, Jhon);

    // Monsters
    if (is_between2(0, .@lv, 40)) {
        array_push(.@mb, Piou);
        array_push(.@mb, Piousse);
        array_push(.@mb, Squirrel);
        array_push(.@mb, ManaPiou);
        array_push(.@mb, ForestPiou);
        array_push(.@mb, RedButterfly);
        array_push(.@mb, Maggot);
        array_push(.@mb, CandorScorpion);
        array_push(.@mb, HouseMaggot);
        array_push(.@mb, LittleYellowSlime);
        array_push(.@mb, Ratto);
        array_push(.@mb, RudolphSlime);
        array_push(.@mb, MoubooSlime);
        array_push(.@mb, Croc);
        array_push(.@mb, Scorpion);
        array_push(.@mb, SmallFrog);
    }
    if (is_between2(10, .@lv, 50)) {
        array_push(.@mb, BigFrog);
        array_push(.@mb, Lavern);
        array_push(.@mb, LittleRedSlime);
        array_push(.@mb, ChocolateSlime);
        array_push(.@mb, Blub);
        array_push(.@mb, Duck);
        array_push(.@mb, Bat);
        array_push(.@mb, CaveMaggot);
        array_push(.@mb, ManaGhost);
        array_push(.@mb, ManaBug);
        array_push(.@mb, Fluffy);
        array_push(.@mb, FireGoblin);
        array_push(.@mb, ViciousSquirrel);
        array_push(.@mb, RedScorpion);
        array_push(.@mb, WhiteSlime);
        array_push(.@mb, AzulSlime);
        array_push(.@mb, DesertLogHead);
    }
    if (is_between2(20, .@lv, 50)) {
        array_push(.@mb, RedSlime);
        array_push(.@mb, PoisonSpikyMushroom);
        array_push(.@mb, DesertBandit);
        array_push(.@mb, OceanCroc);
        array_push(.@mb, ToppyBlub);
        array_push(.@mb, Sarracenus);
        array_push(.@mb, IceMaggot);
        array_push(.@mb, VampireBat);
        array_push(.@mb, Bandit);
        array_push(.@mb, Pinkie);
        array_push(.@mb, LivingPotato);
        array_push(.@mb, Assassin);
        array_push(.@mb, Skeleton);
    }
    if (is_between2(30, .@lv, 60)) {
        array_push(.@mb, CaveSnake);
        array_push(.@mb, GreenSlime);
        array_push(.@mb, CopperSlime);
        array_push(.@mb, YellowSlime);
        array_push(.@mb, SantaSlime);
        array_push(.@mb, LavaSlime);
        array_push(.@mb, Bluepar);
        array_push(.@mb, DeathCat);
        array_push(.@mb, Moggun);
        array_push(.@mb, SeaSlime);
        array_push(.@mb, RedMushroom);
        array_push(.@mb, Mouboo);
        array_push(.@mb, LogHead);
        array_push(.@mb, CandiedSlime);
        array_push(.@mb, OldSnake);
        array_push(.@mb, GrassSnake);
    }
    if (is_between2(40, .@lv, 70)) {
        array_push(.@mb, GiantMaggot);
        array_push(.@mb, IcedFluffy);
        array_push(.@mb, Snake);
        array_push(.@mb, BlackSlime);
        array_push(.@mb, Tipiou);
        array_push(.@mb, AlphaMouboo);
        array_push(.@mb, Pollet);
        array_push(.@mb, PiouKnight);
        array_push(.@mb, Shrewboo);
    }
    if (is_between2(40, .@lv, 80)) {
        array_push(.@mb, Wolvern);
        array_push(.@mb, FireSkull);
        array_push(.@mb, DarkLizard);
    }
    if (is_between2(50, .@lv, 90)) {
        array_push(.@mb, ArmoredSkeleton);
        array_push(.@mb, BlackScorpion);
        array_push(.@mb, ElectroWorm);
        array_push(.@mb, EarthFairy);
        array_push(.@mb, FireFairy);
        array_push(.@mb, WaterFairy);
        array_push(.@mb, WindFairy);
        array_push(.@mb, PoisonFairy);
        array_push(.@mb, MountainSnake);
        array_push(.@mb, HoodedNinja);
        array_push(.@mb, ForestMushroom);
        array_push(.@mb, GoldenScorpion);
    }
    if (is_between2(60, .@lv, 100)) {
        array_push(.@mb, Yeti);
        array_push(.@mb, FallenGuard1);
        array_push(.@mb, GreenSlimeMother);
        array_push(.@mb, SnowFlower);
        array_push(.@mb, BlueSlimeMother);
        array_push(.@mb, WickedMushroom);
        array_push(.@mb, CopperSlimeMother);
        array_push(.@mb, YellowSlimeMother);
        array_push(.@mb, RedSlimeMother);
        array_push(.@mb, ChocolateSlimeMother);
        array_push(.@mb, WhiteSlimeMother);
        array_push(.@mb, Archant);
        array_push(.@mb, Scar);
    }
    if (is_between2(70, .@lv, 110)) {
        array_push(.@mb, AzulSlimeMother);
        array_push(.@mb, SeaSlimeMother);
        array_push(.@mb, LavaSlimeMother);
        array_push(.@mb, BlackSlimeMother);
        array_push(.@mb, Crafty);
        array_push(.@mb, Forain);
        array_push(.@mb, GreenDragon);
        array_push(.@mb, Michel);
        array_push(.@mb, Troll);
    }
    if (is_between2(80, .@lv, 120)) {
        array_push(.@mb, EliteDuck);
        array_push(.@mb, AzulSkullSlime);
        array_push(.@mb, Moonshroom);
        array_push(.@mb, RedSkullSlime);
        array_push(.@mb, Terranite);
        array_push(.@mb, JackO);
        array_push(.@mb, BlackMamba);
        array_push(.@mb, GreenSkullSlime);
        array_push(.@mb, BloodyMouboo);
        array_push(.@mb, Centaur);
        array_push(.@mb, GoboBear);
    }
    if (is_between2(90, .@lv, 130)) {
        array_push(.@mb, CopperSkullSlime);
        array_push(.@mb, LavaSkullSlime);
        array_push(.@mb, BlackSkullSlime);
        array_push(.@mb, GiantCaveMaggot);
        array_push(.@mb, TerraniteProtector);
        array_push(.@mb, VanityPixie);
        array_push(.@mb, HolyPixie);
    }
    if (is_between2(100, .@lv, 140)) {
        array_push(.@mb, ShadowPixie);
        array_push(.@mb, NulityPixie);
        array_push(.@mb, Reaper);
        array_push(.@mb, NightmareDragon);
        array_push(.@mb, Snail);
        array_push(.@mb, WhirlyBird);
    }
    if (is_between2(110, .@lv, 150)) {
        array_push(.@mb, PinkieSuseran);
        array_push(.@mb, Mandragora);
        array_push(.@mb, PinkieMaximus);
    }
    if (.@lv > 120) {
        array_push(.@mb, Junglefowl);
        array_push(.@mb, Tengu);
        array_push(.@mb, Moubi);
    }
    if (.@lv > 130) {
        array_push(.@mb, SuperiorShroom);
        array_push(.@mb, Nutcracker);
        array_push(.@mb, Golem);
    }
    if (.@lv > 140) {
        array_push(.@mb, SiegeTower);
        array_push(.@mb, GreenhornAbomination);
        array_push(.@mb, ShadowTortuga);
        array_push(.@mb, FireElement);
        array_push(.@mb, WaterElement);
        array_push(.@mb, EarthElement);
        array_push(.@mb, WindElement);
    }
    if (.@lv > 150) {
        array_push(.@mb, SacredWisp);
        array_push(.@mb, EvilWisp);
        array_push(.@mb, PanthomWisp);
        array_push(.@mb, EpiphanyWisp);
    }
    if (.@lv > 175)
        array_push(.@mb, Tortuga);

    // Initialize instance but without InitMaze and short lived
	instance_set_timeout(900, 900, MAZE_INST);
	instance_init(MAZE_INST);

    /* Spawn them and make hostile */
    freeloop(true);
    for (.@i = 0; .@i < 1+(.@tl); .@i++) {
        .@mid = any_of(.@mb);
        .@m=areamonster(MAZE_MAP$, 20, 20, .@mx, .@my, strmobinfo(1, .@mid), .@mid, 1);
        set_aggro(.@m);
    }
    freeloop(false);

    // Create the target boss
    .@mx=getmapinfo(MAPINFO_SIZE_X, MAZE_MAP$)-20;
    .@my=getmapinfo(MAPINFO_SIZE_Y, MAZE_MAP$)-20;
    .@m=areamonster(MAZE_MAP$, .@mx-20, .@my-20, .@mx, .@my, strmobinfo(1, EntAbomination), EntAbomination, 1, "Hocus#MOLY0800::OnWin");
    setunitdata(.@m, UDT_MAXHP, 100);
    setunitdata(.@m, UDT_HP, 100);
    setunitdata(.@m, UDT_LEVEL, 1);
    setunitdata(.@m, UDT_MODE, MD_BOSS);
    setunitdata(.@m, UDT_LUK, 32760);

    // Find random, warpable coordinates from the nearby zone
    .@e=0; .@x=0; .@y=0;
    .@mx=40;
    .@my=40;
    do {
        .@x = rand2(20, .@mx);
        .@y = rand2(20, .@my);
        .@e += 1;
        if (.@e > 30) {
            consolebug("Olympics - Too many failures at Maze \"%s\"! Trying anyway!", MAZE_MAP$);
            break;
        }
    } while (!checknpccell(MAZE_MAP$, .@x, .@y, cell_chkpass));

    warp MAZE_MAP$, .@x, .@y;
    closeclientdialog;
    end;

OnWin:
    warp @map$, 39, 117;
    if (@moly_tick < gettimetick(2) / 2) end; // Ticks were Corrupted
    @moly_score = gettimetick(2) - @moly_tick;
    if (@moly_score < 8) end; // This is impossible*, don't even bother
    .@pts=getq2(Q_AuroraEvent);
    setq2 Q_AuroraEvent, .@pts+rand2(1, 1+BaseLevel/20);
    dispbottom l("End! Score this time: %s", FuzzyTime(@moly_tick));
    if (FYMOLY_RACERS >= 8)
        FYMOLY_RACERS = min(FYMOLY_RACERS, @moly_score);
    else
        FYMOLY_RACERS = @moly_score;
    @moly_score = 0;
    @moly_chall = 0;
    // *: Distance is always at least ~50 tiles in a straight line
    end;

OnCheck:
    if (@moly_chall != 8) end;
    // Game Over
    if (ispcdead() ||
        getmap() != MAZE_MAP$) { // NOT a typo - starting square is OK
            // Game Over!
            dispbottom col(l("You have been disqualified - died or left the maze"), 1);
            @moly_score = 0;
            @moly_chall = 0;
            end;
    }
    addtimer 2500, instance_npcname("Hocus#MOLY0800")+"::OnCheck";
    end;

OnInit:
    .distance=7;
    end;
}

/////////////////////////////////////////////////////////////////////////////////
001-14,37,84,0	script	Hocus#MOLY0900	NPC_BLACKWIZARD,{
    if (@moly_chall) end;
    mes ".:: " + l("Hocus Said So Challenge") + ":: .";
    mes l("Description: There'll be differently colored sparks and you must kill ONLY those of the color I say so! Failure to do so will cause immediate disqualification!");
    mesc l("PS. No equipment restriction");
    mes "";
    mesc l("Your progress thus far: %s sparks killed", fnum(FYMOLY_HOCUSM)), 3;
    next;
    mesc l("Begin campaign?"), 1;
    if (askyesno() == ASK_NO) close;
    @moly_tick = gettimetick(2) + 60;
    @moly_score = 0;
    @moly_chall = 9;
    .m$=getmap();
    @map$=getmap();
    .@m=areamonster(.m$, 38, 85, 40, 90, strmobinfo(1, YellowSpark), YellowSpark, 1, "Hocus#MOLY0900::OnClY");
    setunitdata(.@m, UDT_HP, 1);
    setunitdata(.@m, UDT_MAXHP, 1);
    setunitdata(.@m, UDT_LEVEL, 1);
    setunitdata(.@m, UDT_SPEED, 60);
    .@m=areamonster(.m$, 38, 85, 40, 90, strmobinfo(1, MagentaSpark), MagentaSpark, 1, "Hocus#MOLY0900::OnClM");
    setunitdata(.@m, UDT_HP, 1);
    setunitdata(.@m, UDT_MAXHP, 1);
    setunitdata(.@m, UDT_LEVEL, 1);
    setunitdata(.@m, UDT_SPEED, 60);
    .@m=areamonster(.m$, 38, 85, 40, 90, strmobinfo(1, YellowSpark), YellowSpark, 1, "Hocus#MOLY0900::OnClY");
    setunitdata(.@m, UDT_HP, 1);
    setunitdata(.@m, UDT_MAXHP, 1);
    setunitdata(.@m, UDT_LEVEL, 1);
    setunitdata(.@m, UDT_SPEED, 60);
    .@m=areamonster(.m$, 38, 85, 40, 90, strmobinfo(1, MagentaSpark), MagentaSpark, 1, "Hocus#MOLY0900::OnClM");
    setunitdata(.@m, UDT_HP, 1);
    setunitdata(.@m, UDT_MAXHP, 1);
    setunitdata(.@m, UDT_LEVEL, 1);
    setunitdata(.@m, UDT_SPEED, 60);
    @cl=any(YellowSpark, MagentaSpark);
    npctalk3 l("Countdown: 1 minute - Kill %s!", strmobinfo(1, @cl));
    initnpctimer;
    closeclientdialog;
    close;

OnTimer9000:
    npctalk "Hocus commands...";
    end;

OnTimer10000:
    maptimer2(.m$, 10, "Hocus#MOLY0900::OnSeed");
    npctalk sprintf("Time left = 50 seconds");
    end;

OnTimer19000:
    npctalk "Hocus commands...";
    end;

OnTimer20000:
    maptimer2(.m$, 10, "Hocus#MOLY0900::OnSeed");
    npctalk sprintf("Time left = 40 seconds");
    end;

OnTimer29000:
    npctalk "Hocus commands...";
    end;

OnTimer30000:
    maptimer2(.m$, 10, "Hocus#MOLY0900::OnSeed");
    npctalk sprintf("Time left = 30 seconds");
    end;

OnTimer39000:
    npctalk "Hocus commands...";
    end;

OnTimer40000:
    maptimer2(.m$, 10, "Hocus#MOLY0900::OnSeed");
    npctalk sprintf("Time left = 20 seconds");
    end;

OnTimer49000:
    npctalk "Hocus commands...";
    end;

OnTimer50000:
    maptimer2(.m$, 10, "Hocus#MOLY0900::OnSeed");
    npctalk sprintf("Time left = 10 seconds");
    end;

OnTimer55000:
    npctalk col("5 seconds", 1);
    end;

OnTimer60000:
    killmonsterall(.m$);
    maptimer2(.m$, 10, "Hocus#MOLY0900::OnEnd");
    npctalk col("Time out!", 1);
    stopnpctimer;
    end;

OnSeed:
    @cl=any(YellowSpark, MagentaSpark);
    dispbottom l("Kill %s!", strmobinfo(1, @cl));
    end;

OnClY:
    if (gettimetick(2) > @moly_tick) end;
    if (@moly_chall != 9) end;
    if (@cl != YellowSpark) {
        @moly_score = -1;
        @moly_tick = 0;
        @moly_chall = 0;
        dispbottom col(l("You have been disqualified - target was: %s", strmobinfo(1, @cl)), 1);
        killmonsterall(getmap());
        // FIXME: Stop npc timer
        end;
    }
    @moly_score+=1;
    .@m=areamonster(getmap(), 38, 85, 40, 90, strmobinfo(1, YellowSpark), YellowSpark, 1, "Hocus#MOLY0900::OnClY");
    setunitdata(.@m, UDT_HP, 1);
    setunitdata(.@m, UDT_MAXHP, 1);
    setunitdata(.@m, UDT_LEVEL, 1);
    setunitdata(.@m, UDT_SPEED, 60);
    end;

OnClM:
    if (gettimetick(2) > @moly_tick) end;
    if (@moly_chall != 9) end;
    if (@cl != MagentaSpark) {
        @moly_score = -1;
        @moly_tick = 0;
        @moly_chall = 0;
        dispbottom col(l("You have been disqualified - target was: %s", strmobinfo(1, @cl)), 1);
        killmonsterall(getmap());
        // FIXME: Stop npc timer
        end;
    }
    @moly_score+=1;
    .@m=areamonster(getmap(), 38, 85, 40, 90, strmobinfo(1, MagentaSpark), MagentaSpark, 1, "Hocus#MOLY0900::OnClM");
    setunitdata(.@m, UDT_HP, 1);
    setunitdata(.@m, UDT_MAXHP, 1);
    setunitdata(.@m, UDT_LEVEL, 1);
    setunitdata(.@m, UDT_SPEED, 60);
    end;

OnEnd:
    if (@moly_chall != 9) end;
    .@pts=getq2(Q_AuroraEvent);
    setq2 Q_AuroraEvent, .@pts+rand2(1, 1+@moly_score/10);
    dispbottom l("End! Score this time: %d", @moly_score);
    FYMOLY_HOCUSM = max(FYMOLY_HOCUSM, @moly_score);
    @moly_score = 0;
    @moly_chall = 0;
    end;

OnInit:
    .distance=7;
    .m$="001-14";
    .cl=Dummy;
    end;
}

/////////////////////////////////////////////////////////////////////////////////
001-14,41,46,0	script	Hocus#MOLY1000	NPC_BLACKWIZARD,{
    if (@moly_chall) end;
    mes ".:: " + l("Survival Challenge") + ":: .";
    mes l("Description: Survive for the longest you can without leaving the designed region.");
    mes l("Using potions and support magic is fine, as well as summons; but using a non-magical weapon will disqualify you.");
    mesc l("NOTE: Beside wands and staves, %s, %s, and the %s count as magic weapons.", getitemlink(Judgement), getitemlink(DarkPulsar), getitemlink(Lightbringer));
    mes "";
    mesc l("Your progress thus far: %s survived.", FuzzyTime(gettimetick(2) + FYMOLY_SURVIV)), 3;
    next;
    mesc l("Begin campaign?"), 1;
    if (askyesno() == ASK_NO) close;
    killmonsterall(getmap());
    @moly_score = 0;
    @moly_chall = 10;
    @map$ = getmap();
    addtimer 500, instance_npcname("Hocus#MOLY1000")+"::OnCheck";
    closeclientdialog;
    close;

OnCheck:
    if (@moly_chall != 10) end;
    @moly_score += 1;
    // Game Over
    if (ispcdead() ||
        !isin(@map$, 37, 47, 49, 58)) { // NOT a typo - starting square is OK
            // Game Over!
            killmonsterall(getmap());
            @moly_score = @moly_score / 2;
            .@pts=getq2(Q_AuroraEvent);
            setq2 Q_AuroraEvent, .@pts+rand2(1, 1+@moly_score/20);
            dispbottom l("End! Score this time: %s", FuzzyTime(gettimetick(2)+@moly_score));
            FYMOLY_SURVIV = max(FYMOLY_SURVIV, @moly_score);
            @moly_score = 0;
            @moly_chall = 0;
            end;
    }
    /* Spawn */
    if (!(@moly_score % 2)) {
        .@m=areamonster(getmap(), 37, 47, 49, 57, strmobinfo(1, EntAbomination), EntAbomination, 1);
        setunitdata(.@m, UDT_MAXHP, 50 + @moly_score * 6);
        setunitdata(.@m, UDT_HP, 50 + @moly_score * 6);
        setunitdata(.@m, UDT_LEVEL, 1 + (@moly_score / 2));
        setunitdata(.@m, UDT_SPEED, max(50, 900-(@moly_score * 10)));
        setunitdata(.@m, UDT_MODE, MD_CANMOVE|MD_CANATTACK|MD_AGGRESSIVE|MD_ANGRY);
        setunitdata(.@m, UDT_DEF, min(32760, 20+@moly_score));
        setunitdata(.@m, UDT_MDEF, min(32760, @moly_score));
        setunitdata(.@m, UDT_LUK, min(32760, rand2(@moly_score) * 7));
        setunitdata(.@m, UDT_HIT, 32760);
        setunitdata(.@m, UDT_FLEE, 0);
        setunitdata(.@m, UDT_ATKMIN, @moly_score);
        setunitdata(.@m, UDT_ATKMAX, @moly_score+20);
        setunitdata(.@m, UDT_ADELAY, max(672, 1872-(@moly_score * 4)));
    }
    /* Weapon Check */
    .@wp = getequipid(EQI_HAND_R);
    // Disarmed
    if (.@wp < 1) {
        addtimer 500, instance_npcname("Hocus#MOLY1000")+"::OnCheck";
        end;
    }
    // Illegal weapon
    if (.@wp != Judgement &&
        .@wp != DarkPulsar &&
        .@wp != Lightbringer &&
        getiteminfo(.@wp, ITEMINFO_SUBTYPE) != W_STAFF) {
            @moly_score = -1;
            @moly_tick = 0;
            @moly_chall = 0;
            dispbottom col(l("You have been disqualified - illegal weapon: %s", getitemname(.@wp)), 1);
            killmonsterall(getmap());
            end;
    }
    addtimer 500, instance_npcname("Hocus#MOLY1000")+"::OnCheck";
    end;

OnInit:
    .distance=7;
    end;
}

/////////////////////////////////////////////////////////////////////////////////
001-14,62,37,0	script	Hocus#MOLY1100	NPC_BLACKWIZARD,{
    mes ".:: " + l("Friendship's Strength Challenge") + ":: .";
    mes l("Description: Use support skills and win the event with the power of FRIENDSHIP!");
    mesc l("Note: Support skills used on self does not count."), 1;
    mes "";
    mesc l("Your progress thus far: %s friends supported", fnum(FYMOLY_FRIEND)), 3;
    close;

OnInit:
    .distance=7;
    end;
}