diff options
author | Jesusaves <cpntb1@ymail.com> | 2022-10-23 21:44:22 -0300 |
---|---|---|
committer | Jesusaves <cpntb1@ymail.com> | 2022-10-23 21:44:22 -0300 |
commit | a7c45a192268da2601cef47a4cdba987ae2327ca (patch) | |
tree | c5fb5b97db109fe7106496dd96498c475881046b /npc/034-4 | |
download | serverdata-a7c45a192268da2601cef47a4cdba987ae2327ca.tar.gz serverdata-a7c45a192268da2601cef47a4cdba987ae2327ca.tar.bz2 serverdata-a7c45a192268da2601cef47a4cdba987ae2327ca.tar.xz serverdata-a7c45a192268da2601cef47a4cdba987ae2327ca.zip |
Initial commit (Moubootaur Legends fork)
Diffstat (limited to 'npc/034-4')
-rw-r--r-- | npc/034-4/_import.txt | 6 | ||||
-rw-r--r-- | npc/034-4/exit.txt | 276 | ||||
-rw-r--r-- | npc/034-4/intro.txt | 211 | ||||
-rw-r--r-- | npc/034-4/lobby.txt | 263 | ||||
-rw-r--r-- | npc/034-4/storage.txt | 186 |
5 files changed, 942 insertions, 0 deletions
diff --git a/npc/034-4/_import.txt b/npc/034-4/_import.txt new file mode 100644 index 0000000..4e1f47c --- /dev/null +++ b/npc/034-4/_import.txt @@ -0,0 +1,6 @@ +// Map 034-4: Forsaken Inn +// This file is generated automatically. All manually added changes will be removed when running the Converter. +"npc/034-4/exit.txt", +"npc/034-4/intro.txt", +"npc/034-4/lobby.txt", +"npc/034-4/storage.txt", diff --git a/npc/034-4/exit.txt b/npc/034-4/exit.txt new file mode 100644 index 0000000..07d96ea --- /dev/null +++ b/npc/034-4/exit.txt @@ -0,0 +1,276 @@ +// TMW2 scripts. +// Authors: +// Jesusalva +// Description: +// Gemini Sisters Quest - Part D: Final Chamber + +034-4,144,82,0 script #GeminiFExit NPC_HIDDEN,0,0,{ + +OnWumpus: + GeminiCheck(15); + .@q = getq2(HurnscaldQuest_Gemini); + // TODO: Maybe exchange an Wumpus Egg for a Sunny Crystal or Mylarin Dust? + // Have a NPC do so only once, for the Savior set. + if (.@q == 0 || .@q == 2 || (.@q > 5 && !(.@q % 3))) + getitem WumpusEgg, 1; + else + getitem LightGreenDiamond, 1; + getexp 0, rand2(7500, 9999); + setq2 HurnscaldQuest_Gemini, .@q + 1; + @forced_sick$ = ""; + end; + +OnRw: + getitem StrangeCoin, 1; + if (!GEMINI_WINNER) + GEMINI_WINNER = gettimetick(2); + end; + +OnExit: + .@p=getcharid(1); + partytimer(MAZE_MAP$, 10, "#GeminiFExit::OnRw", getcharid(1)); + if ($GEMINI_WINNER$ == "") { + $GEMINI_WINNER$=strcharinfo(0); + channelmes("#world", $GEMINI_WINNER$+" is the first player to finish Gemini Sisters Quest!! GG, dude! %%N"); + announce "All hail ##B"+$GEMINI_WINNER$+"##b, first to complete the ##3Gemini Sisters Quest!", bc_all|bc_npc; + getitem PrismGift, 1; + mesc l("CONGRATULATIONS! You are the first player to finish Gemini Sisters quest!!"), 2; + mesc l("You just gained a Prism Gift for your bravery!"), 2; + next; + } + sleep2(400); + warp "014-2-2", 35, 20; + warpparty("014-2-2", 35, 20, getcharid(1), MAZE_MAP$, true); + end; + +OnTouch: + if (instance_id() < 0 || getcharid(1) < 1) end; + GeminiCheck(15); + // Only the party leader go ahead + if (strcharinfo(0) != getpartyleader(getcharid(1))) { + mes l("Only %s has the key.", getpartyleader(getcharid(1))); + close; + } + + mesc l("Are you sure you want to leave?"), 1; + mesc l("You, and everyone on the party, won't be able to return."), 1; + if (askyesno() == ASK_NO) close; + closeclientdialog; + + // Create maze and populate (From 45x45 to 60x60) + CreateMaze(IOT_CHAR, MAZE_SIZE_M | MAZE_SIZE_G); + .@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 / 10) + 1; // Monster density is a bit random + + /* *** Copied from 006-5/groata.txt & 018-2-2/main.txt! *** */ + .@mb[0] = MagicGoblin; + .@mb[1] = CaveMaggot; + array_push(.@mb, BronzeChest); + array_push(.@mb, SmallMagicBif); + array_push(.@mb, Bif); + array_push(.@mb, RobinBandit); + array_push(.@mb, SilverChest); + array_push(.@mb, DustGatling); + array_push(.@mb, MagicBif); + array_push(.@mb, DustRifle); + array_push(.@mb, DustRevolver); + array_push(.@mb, GoldenChest); + array_push(.@mb, GreatMoubooSlime); + array_push(.@mb, Piousse); + array_push(.@mb, ManaPiou); + array_push(.@mb, ForestPiou); + array_push(.@mb, HouseMaggot); + array_push(.@mb, LittleYellowSlime); + array_push(.@mb, MoubooSlime); + array_push(.@mb, SmallFrog); + array_push(.@mb, BigFrog); + array_push(.@mb, Lavern); + array_push(.@mb, LittleRedSlime); + array_push(.@mb, ChocolateSlime); + array_push(.@mb, Duck); + array_push(.@mb, Bat); + array_push(.@mb, CaveMaggot); + array_push(.@mb, ManaGhost); + array_push(.@mb, ManaBug); + array_push(.@mb, FireGoblin); + array_push(.@mb, ViciousSquirrel); + array_push(.@mb, RedScorpion); + array_push(.@mb, WhiteSlime); + array_push(.@mb, AzulSlime); + array_push(.@mb, DesertLogHead); + array_push(.@mb, RedSlime); + array_push(.@mb, DesertBandit); + array_push(.@mb, Sarracenus); + array_push(.@mb, IceMaggot); + array_push(.@mb, VampireBat); + array_push(.@mb, Bandit); + array_push(.@mb, Assassin); + array_push(.@mb, Skeleton); + 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, RedMushroom); + array_push(.@mb, CandiedSlime); + array_push(.@mb, OldSnake); + array_push(.@mb, GrassSnake); + array_push(.@mb, Snake); + array_push(.@mb, BlackSlime); + array_push(.@mb, Pollet); + array_push(.@mb, PiouKnight); + array_push(.@mb, Shrewboo); + array_push(.@mb, Wolvern); + array_push(.@mb, FireSkull); + array_push(.@mb, DarkLizard); + 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); + array_push(.@mb, FallenGuard2); + array_push(.@mb, WickedMushroom); + array_push(.@mb, Archant); + array_push(.@mb, Scar); + array_push(.@mb, Crafty); + array_push(.@mb, Forain); + array_push(.@mb, GreenDragon); + array_push(.@mb, Michel); + array_push(.@mb, Troll); + 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, GoboBear); + array_push(.@mb, TerraniteProtector); + array_push(.@mb, WhirlyBird); + + /* 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); + + // Spawn & Configure the boss monster + // Defeating the boss yields a bonus + .@mob=areamonster(MAZE_MAP$, 60, 60, .@mx-40, .@my-40, "Wumpus?", PanthomLord, 1, "#GeminiFExit::OnWumpus"); + setunitdata(.@mob, UDT_MAXHP, 250000); + setunitdata(.@mob, UDT_HP, 250000); + setunitdata(.@mob, UDT_SPEED, 275); + setunitdata(.@mob, UDT_HIT, 3500); + setunitdata(.@mob, UDT_DMOTION, 50); + + // NOTE: Once you exit, put the quest in cooldown for 4 hours as well. + .@mx = getmapinfo(MAPINFO_SIZE_X, MAZE_MAP$); .@my = getmapinfo(MAPINFO_SIZE_Y, MAZE_MAP$); + .@mob=monster(MAZE_MAP$, .@mx-25, .@my-25, "Exit", FortressGate, 1, "#GeminiFExit::OnExit"); + setunitdata(.@mob, UDT_MAXHP, 50000); + setunitdata(.@mob, UDT_HP, 50000); + + // Miscellaneous data + .@old$=getmap(); + .@p=getcharid(1); + InitMaze(7200, false); + $@VALIA_STATUS[.@p]=16; + sleep2(500); + changeplayermusic "Arabesque.ogg"; + dispbottom l("It was a trap! We must escape!"); + $@VALIA_MAP$[.@p]=getmap(); + partytimer(.@old$, 2000, "#GeminiFExit::OnSick", .@p); + sleep2(2000); + @forced_sick$ = getmap(); + doevent "#DungeonCore::OnSick"; + end; + +OnSick: + .@p=getcharid(1); + MAZE_MAP$ = $@VALIA_MAP$[.@p]; + // Find random, warpable coordinates + .@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("Too many failures at Maze \"%s\"! Trying anyway!", MAZE_MAP$); + break; + } + } while (!checknpccell(MAZE_MAP$, .@x, .@y, cell_chkpass)); + + warp MAZE_MAP$, .@x, .@y; + sleep2(500); + changeplayermusic "Arabesque.ogg"; + dispbottom l("It was a trap! We must escape!"); + sleep2(2000); + @forced_sick$ = getmap(); + doevent "#DungeonCore::OnSick"; + end; +} + +034-4,146,83,0 script Chest#gemini NPC_CHEST,{ + if (instance_id() < 0 || getcharid(1) < 1) end; + GeminiCheck(15); + // Already taken + if (@mystatus > 20) { + dispbottom l("I already took my share from this chest."); + end; + } + // One prize per person + inventoryplace Iten, 1; + @mystatus = 99; + // Non party leaders receive "less" + if (strcharinfo(0) != getpartyleader(getcharid(1))) { + Mobpt+=7500; + getexp 96000, 900; + dispbottom l("I found %s and %s!", "7,500 "+l("monster points"), "96,000 "+l("experience points")); + end; + } + // Party leaders receive "more" + .@q = getq(HurnscaldQuest_Gemini); + setq HurnscaldQuest_Gemini, .@q + 1; + //getitem RentCart, 1; // Not rented + switch (.@q) { + case 1: + getitem SarabArmlet, 1; + dispbottom l("I found %s!", l("a(n) ")+getitemlink(SarabArmlet)); + break; + case 2: + getitem StrangeCoin, 150; + getitem MysteriousFruit, 1; + dispbottom l("I found %s and %s!", "150 "+getitemlink(StrangeCoin), ("a(n) ")+getitemlink(MysteriousFruit)); + break; + default: + Mobpt+=7500; + getexp 96000, 900; + dispbottom l("I found %s and %s!", "7,500 "+l("monster points"), "96,000 "+l("experience points")); + end; + } + end; + +OnInit: + .distance=2; + end; +} + + diff --git a/npc/034-4/intro.txt b/npc/034-4/intro.txt new file mode 100644 index 0000000..43692a3 --- /dev/null +++ b/npc/034-4/intro.txt @@ -0,0 +1,211 @@ +// TMW2 scripts. +// Authors: +// Jesusalva +// Description: +// Gemini Sisters Quest - Part A: Party Room + +034-4,43,52,0 script #GeminiNoBack NPC_HIDDEN,0,0,{ + end; +OnTouch: + if (instance_id() < 0 || getcharid(1) < 1) end; + GeminiCheck(8); + npctalkonce l("Oh noes ─ the door is sealed! We can only press forward and failure is final!"); + end; +} + +034-4,43,51,0 script #GeminiIntro NPC_HIDDEN,2,2,{ + end; +OnTouch: + if (instance_id() < 0 || getcharid(1) < 1) end; + GeminiCheck(8); + .@p=getcharid(1); + if (strcharinfo(0) != getpartyleader(.@p)) end; + + if (!.state) { + .mp$ = getmap(); + .pn$ = getpartyname(getcharid(1)); + .pid = getcharid(1); + .state = true; + initnpctimer; + killmonsterall(.mp$); // Cancel everything done thus far, incl. showdown + } + end; + +OnTimer1000: + .luvia = monster(.mp$, 48, 45, "Luvia Gemini", Luvia, 1); + immortal(.luvia); + setunitdata(.luvia, UDT_MODE, MD_BOSS|MD_PLANT|MD_NOKNOCKBACK); + end; + +OnTimer2500: + unittalk(.luvia, "Well, well, well, look at what we have here!"); + end; + +OnTimer6000: + unittalk(.luvia, sprintf("If it isn't the so-called \"%s\"!", .pn$)); + end; + +OnTimer9500: + unittalk(.luvia, "I'm sure it was a long journey to reach here, and well, this IS an Inn."); + end; + + +OnTimer13000: + unittalk(.luvia, "Where are my manners, of course I'll offer you room to sleep..."); + end; + + +OnTimer16500: + unittalk(.luvia, "...Yes, I'll put all of you to sleep... PERMANENTLY! Hahahaha!"); + .@pi = getmapusers(.mp$) + 2; + areamonster(.mp$, 45, 40, 54, 45, strmobinfo(1, Scar), Scar, .@pi / 2); + setunitdata(.luvia, UDT_MODE, MD_BOSS|MD_PLANT|MD_NOKNOCKBACK|MD_CANMOVE); + unitwalk(.luvia, 51, 45); + end; + +OnTimer18000: + unitwalk(.luvia, 51, 38); + end; + +OnTimer20000: + .@pi = getmapusers(.mp$) + 1; + areamonster(.mp$, 45, 40, 54, 45, strmobinfo(1, Scar), Scar, .@pi); + unittalk(.luvia, "HAHAHahahaha!"); + unitwalk(.luvia, 50, 34); + end; + +OnTimer24000: + .@pi = getmapusers(.mp$) + 1; + monster(.mp$, 37, 33, strmobinfo(1, Scar), Scar, .@pi); + monster(.mp$, 43, 52, strmobinfo(1, Scar), Scar, .@pi); + unitwalk(.luvia, 50, 29); + end; + +OnTimer28000: + .@pi = getmapusers(.mp$) + 1; + monster(.mp$, 50, 29, strmobinfo(1, Scar), Scar, .@pi); + unitwarp(.luvia, "034-4", 45, 45); + end; + +OnTimer25000: + unitkill(.luvia); + end; + +OnTimer50000: + .@pi = getmapusers(.mp$) + 1; + monster(.mp$, 50, 29, strmobinfo(1, Scar), Scar, .@pi); + monster(.mp$, 43, 52, strmobinfo(1, Scar), Scar, .@pi); + monster(.mp$, 37, 33, strmobinfo(1, Scar), Scar, .@pi * 3 / 2); + end; + +// 1 minute + +OnTimer110000: + monster(.mp$, 50, 29, strmobinfo(1, Scar), Scar, 1); + monster(.mp$, 43, 52, strmobinfo(1, Scar), Scar, 1); + monster(.mp$, 37, 33, strmobinfo(1, Scar), Scar, 1); + end; + +// 40 seconds + +OnTimer150000: + .@pi = getmapusers(.mp$) + 1; + monster(.mp$, 50, 29, strmobinfo(1, Scar), Scar, .@pi * 3 / 2); + monster(.mp$, 43, 52, strmobinfo(1, Scar), Scar, .@pi); + monster(.mp$, 37, 33, strmobinfo(1, Scar), Scar, .@pi); + monster(.mp$, 43, 52, strmobinfo(1, BlackMamba), BlackMamba, 1); + end; + +// 1 minute + +OnTimer210000: + monster(.mp$, 50, 29, strmobinfo(1, Scar), Scar, 1); + monster(.mp$, 43, 52, strmobinfo(1, Scar), Scar, 1); + monster(.mp$, 37, 33, strmobinfo(1, Scar), Scar, 1); + end; + +// 1 minute + +OnTimer270000: + .@pi = getmapusers(.mp$) + 1; + monster(.mp$, 50, 29, strmobinfo(1, Scar), Scar, .@pi * 3 / 2); + monster(.mp$, 43, 52, strmobinfo(1, Scar), Scar, .@pi); + monster(.mp$, 37, 33, strmobinfo(1, Scar), Scar, .@pi); + monster(.mp$, 43, 52, strmobinfo(1, Terranite), Terranite, 1+(.@pi/2)); + end; + +// 1.5 minutes + +OnTimer360000: + .@pi = getmapusers(.mp$) + 1; + monster(.mp$, 50, 29, strmobinfo(1, Scar), Scar, 1+(.@pi/2)); + monster(.mp$, 43, 52, strmobinfo(1, Scar), Scar, 1+(.@pi/2)); + monster(.mp$, 37, 33, strmobinfo(1, Scar), Scar, 1+(.@pi/2)); + monster(.mp$, 50, 29, strmobinfo(1, Terranite), Terranite, .@pi); + monster(.mp$, 43, 52, strmobinfo(1, Forain), Forain, .@pi); + monster(.mp$, 37, 33, strmobinfo(1, AzulSkullSlime), AzulSkullSlime, 1+(.@pi/2)); + end; + +// 1 minute + +OnTimer420000: + monster(.mp$, 50, 29, strmobinfo(1, Scar), Scar, 1); + monster(.mp$, 43, 52, strmobinfo(1, Scar), Scar, 1); + monster(.mp$, 37, 33, strmobinfo(1, Scar), Scar, 1); + end; + +// 1 minute + +OnTimer480000: + .@pi = getmapusers(.mp$) + 1; + monster(.mp$, 50, 29, strmobinfo(1, Terranite), Terranite, .@pi); + monster(.mp$, 43, 52, strmobinfo(1, BlackSlimeMother), BlackSlimeMother, 1); + monster(.mp$, 37, 33, strmobinfo(1, BlackMamba), BlackMamba, .@pi + 4); + end; + +// +1 minute + +// Bypass, or it'll take... a while +OnTimer40000: + if (!$@GM_OVERRIDE) end; +OnTimer540000: + .@pi = getmapusers(.mp$) + 1; + monster(.mp$, 50, 29, strmobinfo(1, GoboBear), GoboBear, 1+(.@pi/2)); + $@VALIA_STATUS[.pid] = 10; + stopnpctimer; + end; + +OnInit: +OnInstanceInit: + .state = false; + .mp$ = ""; + .pn$ = ""; + .pid = 0; + .luvia = 0; + end; +} + + +034-4,50,29,0 script #GeminiPartB NPC_HIDDEN,0,0,{ + end; +OnTouch: + if (instance_id() < 0 || getcharid(1) < 1) end; + GeminiCheck(8); + .@p=getcharid(1); + if ($@VALIA_STATUS[.@p] < 10) { + dispbottom l("Uh? I can't pass. I wonder why, maybe I need to wait?"); + end; + } + if (mobcount(getmap(), "all") > 0) { + dispbottom l("I should defeat all mobs before passing."); + end; + } + if (mobcount(getmap(), "all") <= 0 && $@VALIA_STATUS[.@p] == 10) { + $@VALIA_STATUS[.@p]=11; + } + if ($@VALIA_STATUS[.@p] >= 11) { + slide 33, 81; + } + end; +} + diff --git a/npc/034-4/lobby.txt b/npc/034-4/lobby.txt new file mode 100644 index 0000000..dd9a267 --- /dev/null +++ b/npc/034-4/lobby.txt @@ -0,0 +1,263 @@ +// TMW2 scripts. +// Authors: +// Jesusalva +// Description: +// Gemini Sisters Quest - Part C: Showdown + +034-4,98,22,0 script #GeminiPartD NPC_HIDDEN,0,0,{ + end; +OnTouch: + if (instance_id() < 0 || getcharid(1) < 1) end; + GeminiCheck(13); + .@p=getcharid(1); + if ($@VALIA_STATUS[.@p] < 14 || mobcount(getmap(), "#GeminiShowdown::OnABC")) { + dispbottom l("Luvia is too dangerous to be left alone."); + end; + } + if (mobcount(getmap(), "all") > 0) { + dispbottom l("I cannot leave until Luvia and her allies are dead."); + end; + } + if (mobcount(getmap(), "all") <= 0 && $@VALIA_STATUS[.@p] == 14) { + $@VALIA_STATUS[.@p]=15; + } + if ($@VALIA_STATUS[.@p] >= 15) { + if (!@v_fanfare) + specialeffect(FX_FANFARE, SELF, getcharid(3)); + slide 143, 96; + } + end; +} + +// 98 36 with radius 12? +034-4,98,28,0 script #GeminiShowdown NPC_HIDDEN,2,1,{ + end; +OnTouch: + if (instance_id() < 0 || getcharid(1) < 1) end; + GeminiCheck(13); + .@p=getcharid(1); + if (strcharinfo(0) != getpartyleader(.@p)) end; + + if (!.state) { + .mp$ = getmap(); + .beats = 0; + .pid = getcharid(1); + .state = true; + initnpctimer; + killmonsterall(.mp$); // Cancel everything done thus far, incl. showdown + } + end; + +OnABC: + // Extra drop chance (20% chance) + getmapxy(.@m$, .@x, .@y, 0); + if (!rand2(5)) + makeitem BronzeBossGift, 1, .@m$, .@x, .@y; + end; + +OnTimer1000: + .luvia = monster(.mp$, 98, 32, "Luvia Gemini", Luvia, 1); + immortal(.luvia); + setunitdata(.luvia, UDT_MODE, MD_BOSS|MD_PLANT|MD_NOKNOCKBACK); + end; + +OnTimer2500: + unittalk(.luvia, "Ara! Look at who is trying to sneak past me!"); + end; + +OnTimer6000: + unittalk(.luvia, "How silly. I prepared this party for ya, you know."); + end; + +OnTimer9500: + unittalk(.luvia, "Isbamuth wants all of you dead ─ And I'll carry out his orders."); + end; + +OnTimer13000: + unittalk(.luvia, "Long live Isbamuth... And death to traitors! Now begone!!"); + end; + +OnTimer15000: + // Create a new Luvia Gemini + unitwarp(.luvia, "034-4", 98, 32); + unitkill(.luvia); + .luvia = monster(.mp$, 98, 38, "Luvia Gemini", Luvia, 1, "#GeminiShowdown::OnABC"); + + // Grant her more HP if more players came to attack her + .@hp = getunitdata(.luvia, UDT_MAXHP) + (getmapusers(.mp$) * 12000); + setunitdata(.luvia, UDT_MAXHP, .@hp); + setunitdata(.luvia, UDT_HP, .@hp); + + // Reconfigure the AI + .@opt=getunitdata(.luvia, UDT_MODE); + // Add knockback immunity + .@opt=.@opt|MD_NOKNOCKBACK; + // 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(.luvia, UDT_MODE, .@opt); + + + // Prepare the party, lalala! + .@pi = getmapusers(.mp$) * 2 + 1; + monster(.mp$, 117, 51, strmobinfo(1, Scar), Scar, .@pi); + monster(.mp$, 83, 58, strmobinfo(1, Scar), Scar, .@pi); + monster(.mp$, 83, 51, strmobinfo(1, Scar), Scar, .@pi); + monster(.mp$, 114, 29, strmobinfo(1, Scar), Scar, .@pi); + monster(.mp$, 98, 22, strmobinfo(1, Scar), Scar, .@pi); + $@VALIA_STATUS[.pid] = 14; + end; + +// The fight loops from 20k (the restart point) +// So this cycle happens every 10 seconds +OnTimer60000: +OnTimer45000: + consolewarn("Warning, fail-safe mechanism triggered to Luvia."); +OnTimer30000: + if (mobcount(.mp$, "#GeminiShowdown::OnABC") < 1) { + stopnpctimer; + end; + } + .beats+=1; + + /* Prepare some data */ + .@hp = getunitdata(.luvia, UDT_HP) * 10 / getunitdata(.luvia, UDT_MAXHP); + .@pi = getmapusers(.mp$); + getmapxy(.@m$, .@x, .@y, UNITTYPE_MOB, .luvia); + .@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); + } + }*/ + + // Luvia's spell casting + // She casts every ~30 seconds + switch (.beats % 18) { + case 0: + case 6: + case 12: + unittalk(.luvia, "Hahahah, die, die!"); + specialeffect(64, AREA, .luvia); + sleep(1000); + monster(.mp$, .@x, .@y, strmobinfo(1, Scar), Scar, .@pi + max(1, (11 - .@hp) / 10)); + monster(.mp$, .@x, .@y, strmobinfo(1, MagicGoblin), MagicGoblin, .@pi + max(1, (11 - .@hp) / 10)); + // Doors reinforcements + // As time passes, they get stronger + // But after 7 minutes, it resets + switch ((.beats / 6) % 14) { + case 0: + .@mob = Skeleton; break; // Shouldn't trigger + case 1: + .@mob = LavaSlime; break; + case 2: + .@mob = ArmoredSkeleton; break; + case 3: + .@mob = DustRifle; break; + case 4: + .@mob = DarkLizard; break; + case 5: + .@mob = HoodedNinja; break; + case 6: + .@mob = Archant; break; + case 7: + .@mob = Scar; break; + case 8: + .@mob = Terranite; break; + case 9: + .@mob = EliteDuck; break; + case 10: + .@mob = Troll; break; + case 11: + .@mob = YellowSkullSlime; break; + case 12: + .@mob = Michel; break; + case 13: + .@mob = JackO; break; + } + + monster(.mp$, 114, 29, strmobinfo(1, .@mob), .@mob, 1); + // If you can't deal enough damage, less support comes + if (.@hp <= 7) // Up to 79% HP + monster(.mp$, 117, 51, strmobinfo(1, .@mob), .@mob, 1); + if (.@hp <= 6) // Up to 69% HP + monster(.mp$, 98, 22, strmobinfo(1, .@mob), .@mob, 1); + if (.@hp <= 4) // Up to 39% HP + monster(.mp$, 83, 58, strmobinfo(1, .@mob), .@mob, 1); + if (.@hp <= 3) // Up to 29% HP + monster(.mp$, 83, 51, strmobinfo(1, .@mob), .@mob, 1); + break; + case 3: + case 9: + case 15: + specialeffect(60, AREA, .luvia); + sleep(500); + .@r = (10-.@hp) / 5 + rand2(4); // From 0 to 5 + // Blind has extra chance until her HP falls below 60% + // Curse won't happen if her HP is equal or above 60% + // Once her HP falls below 10%, she no longer silences + // And her poison is strengthened. + switch (.@r) { + case 1: + unittalk(.luvia, "The dead are ##Bsilent##b, just like you!"); + .@sc = SC_SILENCE; + break; + case 2: + unittalk(.luvia, "I am your doom, and ##Bpoison##b is my tool!"); + .@sc = (.@hp < 1 ? SC_DPOISON : SC_POISON); + break; + case 3: + unittalk(.luvia, "You shall ##Bbleed##b, and cease!"); + .@sc = SC_BLOODING; + break; + case 4: + unittalk(.luvia, "You dare to underestimate me?! ##BCurse##b you!"); + .@sc = SC_CURSE; + break; + default: + unittalk(.luvia, "You won't see what killed you when ##Bblind##b!"); + .@sc = SC_BLIND; + break; + } + areasc(9, 45000, .@sc, BL_PC|BL_HOM|BL_MER, 1, "filter_always", .luvia, 95000); + .@dmg=100 + (max(1, (11 - .@hp) / 10) * 40); + areaharm(.luvia, 9, .@dmg, HARM_MAGI, any(Ele_Water,Ele_Fire,Ele_Wind,Ele_Earth), "filter_always", BL_PC|BL_MER|BL_HOM); + break; + default: + specialeffect(60, AREA, .luvia); + unittalk(.luvia, any("I am getting tired of you!", + "That's all you can muster?", + "Long live Isbamuth!", + "Hahahahah!", + "Incompetent! Simply incompetent!", + "You shall not resist!", + "I'm not afraid of you!")); + sleep(500); + .@dmg=40 + (max(1, (11 - .@hp) / 10) * 20); + areaharm(.luvia, 9, .@dmg, HARM_MAGI, any(Ele_Water,Ele_Fire,Ele_Wind,Ele_Earth), "filter_always", BL_PC|BL_MER|BL_HOM); + break; + } + + // And we're done! Wait 10 seconds before next casting + setnpctimer 20000; + end; + +OnInit: +OnInstanceInit: + .state = false; + .mp$ = ""; + .pid = 0; + .luvia = 0; + .beats = 0; + end; +} + diff --git a/npc/034-4/storage.txt b/npc/034-4/storage.txt new file mode 100644 index 0000000..893971f --- /dev/null +++ b/npc/034-4/storage.txt @@ -0,0 +1,186 @@ +// TMW2 scripts. +// Authors: +// Jesusalva +// Description: +// Gemini Sisters Quest - Part B: Storage Room + +034-4,45,78,0 script #GeminiPartC NPC_HIDDEN,0,0,{ + end; +OnTouch: + if (instance_id() < 0 || getcharid(1) < 1) end; + GeminiCheck(11); + .@p=getcharid(1); + if ($@VALIA_STATUS[.@p] < 12) { + dispbottom l("Uh? I can't pass. I wonder why, maybe I need to wait?"); + end; + } + if (mobcount(getmap(), "all") > 0) { + dispbottom l("I should defeat all mobs before passing."); + end; + } + if (mobcount(getmap(), "all") <= 0 && $@VALIA_STATUS[.@p] == 12) { + $@VALIA_STATUS[.@p]=13; + } + if ($@VALIA_STATUS[.@p] >= 13) { + slide 83, 58; + } + end; +} + +034-4,33,77,0 script #GeminiStorei NPC_HIDDEN,2,2,{ +function storageutil; + end; +OnTouch: + if (instance_id() < 0 || getcharid(1) < 1) end; + GeminiCheck(11); + .@p=getcharid(1); + if (strcharinfo(0) != getpartyleader(.@p)) end; + + if (!.state) { + .mp$ = getmap(); + .pn$ = getpartyname(getcharid(1)); + .pid = getcharid(1); + .state = true; + /* We now must calculate amount of waves */ + /* It is a hack for now, though */ + .mto = 5 + (BaseLevel / 30) + getmapusers(.mp$); + initnpctimer; + killmonsterall(.mp$); // Cancel everything done thus far, incl. showdown + } + end; + +OnTimer1000: + .luvia = monster(.mp$, 37, 76, "Luvia Gemini", Luvia, 1); + immortal(.luvia); + setunitdata(.luvia, UDT_MODE, MD_BOSS|MD_PLANT|MD_NOKNOCKBACK); + end; + +OnTimer2500: + unittalk(.luvia, "So you aren't made of sugar!"); + end; + +OnTimer6000: + unittalk(.luvia, "I was worried you would all have melted on the lobby!"); + end; + +OnTimer9500: + unittalk(.luvia, "Hahaha, but this is just the beginning of your journey..."); + end; + + +OnTimer13000: + unittalk(.luvia, "I am Luvia Gemini, and this is my trial for you!"); + end; + + +OnTimer16500: + unittalk(.luvia, sprintf("Show me of what you are made of, %s!", .pn$)); + .@pi = getmapusers(.mp$) + 2; + monster(.mp$, 44, 78, strmobinfo(1, Scar), Scar, .@pi); + end; + +OnTimer19000: + unittalk(.luvia, "HAHAHahahaha!"); + end; + +OnTimer20000: + unitwarp(.luvia, "034-4", 45, 45); + end; + +OnTimer21000: + unitkill(.luvia); + end; + +OnTimer30000: + storageutil(); + .sto += 1; + end; + +OnTimer45000: + if (.sto < .mto) + setnpctimer 22000; + monster(.mp$, 44, 78, strmobinfo(1, BlackMamba), BlackMamba, 1); + end; + +OnTimer60000: + .@pi = getmapusers(.mp$) + 1; + monster(.mp$, 44, 78, strmobinfo(1, GoboBear), GoboBear, .@pi); + $@VALIA_STATUS[.pid] = 12; + stopnpctimer; + end; + + +function storageutil { + // Decide if we'll spawn or add items. Previous failures are NOT considerated. + .@r=rand2(10000)+(.sto * 100); + + // Super rare drop?! (~1.5%) + if (.@r < 120 || .@r > 10000) { + makeitem(any(DeathPotion, PoisonAmmoBox, AncientBlueprint, ThornAmmoBox, MercBoxD, ScholarshipBadge, DarkDesertMushroom), 1, .mp$, rand2(30, 35), rand2(83, 86)); + } + + // Super strong monster?! (4%) + if ((.@r > 6000 && .@r < 6400) || .sto == 15 || .sto == 17 || .sto >= 20) { + .@mob=any(WanderingShadow, SeaSlimeMother, NightDragon, GiantMutatedBat, Reaper, Mandragora); + monster(.mp$, 44, 78, strmobinfo(1, .@mob), .@mob, 1); + // Warn players? + } + + // Compulsory monster spawn + switch (.sto) { + case 0: + .@mob = ArmoredSkeleton; break; + case 1: + .@mob = DustRifle; break; + case 2: + .@mob = HoodedNinja; break; + case 3: + .@mob = WickedMushroom; break; + case 4: + .@mob = any(Archant, Scar); break; + case 5: + .@mob = Scar; break; + case 6: + .@mob = AzulSkullSlime; break; + case 7: + .@mob = Forain; break; + case 8: + .@mob = GreenDragon; break; + case 9: + .@mob = Michel; break; + case 10: + .@mob = EliteDuck; break; + case 11: + .@mob = Terranite; break; + case 12: + .@mob = JackO; break; + case 13: + .@mob = BloodyMouboo; break; + default: + .@mob = GoboBear; + } + monster(.mp$, 44, 78, strmobinfo(1, .@mob), .@mob, 1+getmapusers(.mp$)); + + // Compulsory item drop + // If it falls on a collision, the item won't be created at all + freeloop(true); + for (.@i=0; .@i <= ((.sto/2)+getmapusers(.mp$)); .@i++) { + makeitem(any(Wurtzite, ShadowHerb, AlizarinHerb, DiamondPowder, RubyPowder, EmeraldPowder, SapphirePowder, TopazPowder, AmethystPowder, CopperOre, IronOre, Coal, LeadOre, Lifestone, ScorpionClaw, WhiteFur, SquirrelPelt, TinOre, PileOfAsh, EmptyBottle, FluoPowder, TerraniteOre, SulfurPowder, LeatherPatch, LazuriteShard, Root, ReedBundle, GambogeHerb, MauveHerb, CobaltHerb, MaggotSlime, BugLeg, RawLog, BanditHood, BatWing, IronPowder, ArtichokeHerb, LeftCraftyWing, RightCraftyWing, Coral, BlueCoral, Pearl, Moss, RattoTail, RattoTeeth, Knife, SharpKnife, StrangeCoin, PurificationPotion, IcedBottle, Grenade, SmokeGrenade, TreasureMap, AgiPotionA, VitPotionA, IntPotionA, DexPotionA, LukPotionA, EmptyBox, HastePotion, StrengthPotion, Croconut, ChocolateBar, ChocolateBiscuit, PinkieLeg, Potatoz, Coffee, SnakeEgg, Plushroom, Chagashroom, Honey, MoubooSteak, Milk, Orange, CherryCake, Piberries, Aquada, Cheese, Bread, Acorn, Manana), 1, .mp$, rand2(30, 71), rand2(44, 87)); + } + freeloop(false); + return; +} + +OnInit: +OnInstanceInit: + .state = false; + .mp$ = ""; + .pn$ = ""; + .pid = 0; + .luvia = 0; + .sto = 0; + .mto = 0; + end; +} + + |