// TMW2 Script // Author: // TMW Org. (original code) // Jesusalva // Description: // Crazyfefe will wake up when he smells battle // Variables: // $@FEFE_CAVE_LEVEL // Tracks selected difficulty level. // 0 - Not started // 1 - Easy // 2 - Normal // 3 - Hard // 4 - Out of Mind (Exclusive for top 3) // 5 - Cronqvist Mode (Exclusive for Candor Battle Season) // $@FEFE_DELAY // Tracks the delay between challenges. Also used to start the combat. Set it to zero so you can start fight at once. // $@FEFE_CAVE_HERO$ // Whoever started a fight. Also used to know if a fight is about to begin. // $@FEFE_CAVE_PLAYER_COUNT // How many players are there. // $@FEFE_WAVE // Current wave // $@GM_OVERRIDE // Only possible with @set command, overrides the co-op requeriment. Affects other scripts. 006-1,47,22,0 script Crazyfefe NPC_STATUE_EVILMAN,{ function pleaseWait; function Scoreboard; function Challenge; function aboutCandor; function StartFight; function CleanUp; function CaveLogic; function NextRound; // Battle already begun if ($@FEFE_WAVE) { npctalk3 l("Pay attention to the fight, @@!", strcharinfo(0)); dispbottom l("Round @@", $@FEFE_WAVE); end; } if ($@FEFE_CAVE_HERO$ != "") { pleaseWait(); close; } // Main Loop mesn; mesq l("Who dares to disturb my slumber?"); next; do { select l("Sorry, sorry! Please rest, great Crazyfefe!"), l("I do. I want to challenge the Candor Cave!"), l("What are current leaderboard?"), l("What is this place anyway?"); mes ""; switch (@menu) { case 1: close; break; case 2: Challenge(); break; case 3: Scoreboard(); break; case 4: aboutCandor(); break; } } while (true); close; /// Functions function pleaseWait { // Battle in delay (either to begin or to allow new challenges) if ($@FEFE_DELAY > gettimetick(2)) { .@time$=FuzzyTime($@FEFE_DELAY,2,2); // Less than 30 seconds left, do not open a message window. if ($@FEFE_DELAY-gettimetick(2) <= 30) { npctalk3 l("@@!", .@time$); end; } mesn; mesq l("Be Patient... You still need to wait @@.", .@time$); close; } return; } // Are you a Candor Top 3? // ISCANDORTOP3( - ) function ISCANDORTOP3 { return (strcharinfo(0) == $@cfefe_name$[0] || strcharinfo(0) == $@cfefe_name$[1] || strcharinfo(0) == $@cfefe_name$[2]); } function Scoreboard { mesc l("All leaderboards are refreshed hourly."), 1; mesc l("Your current score: @@", CRAZYPOINTS), 3; HallOfCandor(); next; return; } function aboutCandor { mesn; mesq l("I am @@, guardian of Candor Cave. Below this cave, lies the legendary Fefe, arch-wizard from the Great War.", .name$); next; mesn; mesq l("During the war, the Monster King cursed the place where he died, but he fought back, and cursed the curse."); next; mesn; mesq l("For short, they had a fight with curses, and now there's a talking statue over his grave which can spawn monsters here."); next; mesn; mesq l("If you pay the fee, I'll spawn them, for no longer than 20 minutes. You should not fight alone, instead, you need a group of at least three, because, you know, the curse. Or something."); next; return; } function Challenge { pleaseWait(); if ($EVENT$ != "Candor") { mesn; mesq l("Very well, but for a fee of @@ GP. There's no free lunch, after all!", .price); //mesc l("A minimum of %d players at the time of start is required!", 2), 1; mesc l("If at any moment in the fight there's less than %d players in the room, a severe penalty will be applied, so watch out!", 3), 1; // Not enough money? We end here. if (Zeny < .price) close; next; } else { mesn; mesq l("Very well, let's see what you are made of!"); mesc l("A minimum of %d players at the time of start is required!", 2), 1; next; } // Difficulty Selection mesc l("Select difficulty."), 1; mesc l("Out of Mind mode is only available for Top 3."); mesc l("Cronqvist mode is only available during Candor Battle."); mesc l("Only Cronqvist Mode yields more points per wave!"); menuint l("Easy"), 1, l("Hard"), 3, rif(ISCANDORTOP3() || is_master(), l("Out of Mind")), 5, rif($EVENT$ == "Candor" || is_master(), l("Cronqvist Mode")), 12, rif($EVENT$ == "Candor" && ISCANDORTOP3() || is_master(), l("Crazyfefe Mode")), 25, rif($EVENT$ == "Candor" && $GAME_STORYLINE >= 4 || is_master(), l("Monster King Mode")), 100, rif($EVENT$ == "Candor" && ISCANDORTOP3() && $GAME_STORYLINE >= 4 || is_master(), l("Mooubootaur Mode")), 250; .@cdif=@menuret; next; // Already started? if ($@FEFE_WAVE || $@FEFE_CAVE_HERO$ != "") { mesn; mesq l("Sorry, @@ already started the fight.", $@FEFE_CAVE_HERO$); close; } menuint l("Sorry, I misclicked the first button. Have a nice nap, great Crazyfefe!"), -1, rif(is_gm() || $EVENT$ == "Candor", l("WHAT ARE WE WAITING FOR?! START ALREADY!")), 0, l("Yeah, I have the money. Give me FIVE minutes, and Bring it on!"), 5, l("Yeah, I have the money. Give me TEN minutes, and Bring it on!"), 10, l("Yeah, I have the money. Give me FIFTEEN minutes, and Bring it on!"), 15, rif(is_gm(), l("I'm GM and got the money. Gimme HALF HOUR to invite everybody!")), 30; // Cancel? if (@menuret < 0) close; // Already started? if ($@FEFE_WAVE || $@FEFE_CAVE_HERO$ != "") { mesn; mesq l("Sorry, @@ already started the fight.", $@FEFE_CAVE_HERO$); close; } // Use the money if ($EVENT$ != "Candor") Zeny -= .price; // Time delay $@FEFE_DELAY = gettimetick(2)+60*@menuret; $@FEFE_CAVE_HERO$ = strcharinfo(0); .DIFFICULTY = .@cdif; // We must begin at once, so ignore normal procedure if (!@menuret) { logmes "candor fight - start without announce", LOGMES_ATCOMMAND; closeclientdialog; StartFight(); } // Give you a bonus for starting the fight, and announce the fight. @crazypoints=1; initnpctimer; .@msg$=$@FEFE_CAVE_HERO$+" invites everyone to a challenge against Candor Cave. It'll start in "+FuzzyTime($@FEFE_DELAY,2,2)+". Prepare yourselves!"; kamibroadcast(.@msg$); mesn; mesq l("Please wait, the fight will start in @@, as requested.", FuzzyTime($@FEFE_DELAY,2,2)); close; return; } function StartFight { if (getmapusers("006-1") < 1 && !$@GM_OVERRIDE) { mapannounce("006-1", "Oh noes! There's not enough players. Fight aborted, no refunds!", bc_map); CleanUp(); } $@FEFE_CAVE_LEVEL = .DIFFICULTY; .DIFFICULTY = 0; $@FEFE_WAVE = 0; $@FEFE_DELAY = gettimetick(2)+.delay; $@FEFE_CAVE_PLAYER_COUNT = getmapusers("006-1"); mapannounce("006-1", "The battle is about to begin!", bc_map); killmonsterall("006-1"); // Saulc likes to spawn stuff to heat stuff up // Recalculate difficulty $@FEFE_DIFFICULTY=0; areatimer "006-1", 20, 20, 70, 60, 10, "Crazyfefe::OnSumLevel"; initnpctimer; end; } // Recalc difficulty OnSumLevel: if (ispcdead()) end; $@FEFE_DIFFICULTY+=BaseLevel; end; // Check if we're ready for next wave. Otherwise, do this check again after 5 seconds. function CaveLogic { .wtime+=5; // This is looped every 5 s $@FEFE_CAVE_PLAYER_COUNT = getmapusers("006-1"); // Victory conditions: Too few players are alive OR twenty minutes went on. // WARNING, dead players still in cave are counted, we might never finish the fight. // And a GM might be called to ban everyone inside. if ($@FEFE_CAVE_PLAYER_COUNT < 1 && !$@GM_OVERRIDE || gettimetick(2) >= $@FEFE_DELAY - 300) { CleanUp(); } // Recalculate difficulty $@FEFE_DIFFICULTY=0; areatimer "006-1", 20, 20, 70, 60, 10, "Crazyfefe::OnSumLevel"; sleep(15); // Penalty for being below the player count thresholds // It merely assumes you *are* within the threshold if ($@FEFE_CAVE_PLAYER_COUNT < 2) $@FEFE_DIFFICULTY *= 3; else if ($@FEFE_CAVE_PLAYER_COUNT < 3) $@FEFE_DIFFICULTY *= 2; // New wave condition: All mobs dead, or 90 seconds have passed if (mobcount("006-1", "Crazyfefe::OnPetDeath") <= 0 || .wtime >= 90) NextRound(); // reset timer initnpctimer; end; } function NextRound { .wtime=0; $@FEFE_WAVE = $@FEFE_WAVE + 1; // Prepare next round, and reward survivors $@FEFE_DIFFICULTY+=$@FEFE_CAVE_PLAYER_COUNT+$@FEFE_WAVE*8; $@FEFE_DIFFICULTY+=(($@FEFE_WAVE/5)*10); .@mult=10+(3*$@FEFE_CAVE_LEVEL); // +30% per difficulty setting $@FEFE_DIFFICULTY=$@FEFE_DIFFICULTY*.@mult/10; areatimer "006-1", 20, 20, 70, 60, 10, "Crazyfefe::OnReward"; mapannounce "006-1", "The wave nÂș "+$@FEFE_WAVE+" is starting with " + $@FEFE_CAVE_PLAYER_COUNT + " player(s) left alive." , 0; .@amount=$@FEFE_WAVE+$@FEFE_CAVE_PLAYER_COUNT+rand2(1,2); freeloop(true); for (.@i = 0; .@i < .@amount; ++.@i) { .@monsterId=Piou; .@lv=max(1, $@FEFE_DIFFICULTY/10); // Luck shall interfer with .@lv (up to +20 random levels) // This prevents from excess of House Maggots, for example .@lv+=any(0, 0, 0, 1, 1, 2); //debugmes("[Candor] Difficulty is %d, pool is %d", .@lv, $@FEFE_DIFFICULTY); .@lv=rand(0, .@lv); switch (.@lv) { case 0: case 1: case 2: //.@monsterId = any(HouseMaggot, HouseMaggot, SlimeBlast, HouseMaggot) ; break; case 3: .@monsterId = any(AngryScorpion, CaveMaggot, MagicGoblin, ViciousSquirrel, AngryBat, HouseMaggot, SlimeBlast) ; break; case 4: case 5: case 6: .@monsterId = any(AngryBat, RedSlime, AngryRedScorpion, DesertBandit, Bandit, Sarracenus, VampireBat, Skeleton, GreenSlime) ; break; case 7: case 8: .@monsterId = any(GreenSlime, LavaSlime, Bluepar, RedMushroom, CandiedSlime, RobinBandit, AngryYellowSlime, OldSnake, GrassSnake, BlueSlime) ; break; case 9: case 10: .@monsterId = any(BlueSlime, SaxsoGhost, Snake, BlackSlime, Wolvern, FireSkull, DarkLizard, BlackScorpion) ; break; case 11: case 12: .@monsterId = any(BlackScorpion, DustRifle, DustGatling, DustRevolver, ArmoredSkeleton, Grenadier) ; break; case 13: case 14: .@monsterId = any(DustRifle, DustGatling, DustRevolver, MountainSnake, Yeti, HoodedNinja, FallenGuard1, FallenGuard2) ; break; case 15: case 16: .@monsterId = any(FallenGuard1, FallenGuard2, BanditLord, Yeti, WickedMushroom, Thug, Grenadier) ; break; case 17: case 18: .@monsterId = any(Forain, WickedMushroom, BlackMamba, Michel, Terranite) ; break; case 19: case 20: case 21: .@monsterId = any(Forain, Archant, BlackMamba, JackO, TerraniteProtector, EliteDuck) ; break; default: .@monsterId = any(GoboBear, GiantMutatedBat, TerraniteProtector, Reaper) ; break; } .@m=areamonster("006-1", 20, 20, 70, 60, strmobinfo(1, .@monsterId), .@monsterId, 1, "Crazyfefe::OnPetDeath"); set_aggro(.@m); // We must lower difficulty according to summoned monster. Only 60% is lowered. // If total level exceeds 250, it will cap at that to prevent excessive "slooping" .@lower=(limit(1, .@lv, 25)*6); .@lower=.@lower*7/10; // 70% $@FEFE_DIFFICULTY=$@FEFE_DIFFICULTY-.@lower; } freeloop(false); return; } function CleanUp { mapannounce "006-1", "Game over! Who will be the next to fall on Crazyfefe's Cave?", 0; areatimer "006-1", 20, 20, 70, 60, 10, "Crazyfefe::OnReward2"; $@FEFE_OLD = $@FEFE_CAVE_LEVEL; $@FEFE_CAVE_LEVEL = 0; $@FEFE_WAVE = 0; $@FEFE_CAVE_HERO$ = ""; $@FEFE_DELAY=gettimetick(2)+180; .wtime=0; killmonster "006-1", "Crazyfefe::OnPetDeath"; stopnpctimer; initnpctimer; stopnpctimer; end; } // Special case for survivors. OnReward2: if (@crazypoints > CRAZYPOINTS) { CRAZYPOINTS=@crazypoints; dispbottom l("Crazyfefe Cave: New Highscore: @@ points", CRAZYPOINTS); @crazypoints=0; } if (!ispcdead() && $@FEFE_OLD >= .BONUS_LVL) getitem StrangeCoin, limit(1, @crazypoints/25, 5); // Rewards surviving players between rounds, according to performance, and get rid of dead PCs. OnReward: if (ispcdead()) { recovery(getcharid(3)); warp "Save", 0, 0; // If your current points is more than your top, update if (@crazypoints > CRAZYPOINTS) { CRAZYPOINTS=@crazypoints; dispbottom l("Crazyfefe Cave: New Highscore: @@ points", CRAZYPOINTS); @crazypoints=0; } end; } // Player reward is a random number based on current wave .@prize=rand($@FEFE_WAVE/2,$@FEFE_WAVE)*2; // $@FEFE_DIFFICULTY might not be available anymore if ($@FEFE_WAVE % 5 == 0) Zeny+=.@prize; getexp .@prize, rand(1,3); @crazypoints+=($@FEFE_CAVE_LEVEL >= .BONUS_LVL && $EVENT$ == "Candor" ? 2 : 1); end; // Every 5 seconds, handle cave, if fighting. Does nothing when waiting. OnTimer5000: if ($@FEFE_CAVE_LEVEL) CaveLogic(); end; // Announces and attempts to start the fight once time run out (assuming there are enough players) OnTimer300000: if ($@FEFE_CAVE_LEVEL > 0) end; if ($@FEFE_DELAY <= gettimetick(2)) StartFight(); .@msg$=$@FEFE_CAVE_HERO$+" invites everyone to a challenge against Candor Cave. It'll start in "+FuzzyTime($@FEFE_DELAY)+". Prepare yourselves!"; announce .@msg$, bc_all|bc_npc; //channelmes("#world", .@msg$); //kamibroadcast(.@msg$); initnpctimer; end; OnPetDeath: end; OnInit: .sex=G_OTHER; .distance=5; .price=400; .delay=(60*25); .wtime=0; .DIFFICULTY=0; .BONUS_LVL=5; end; }