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/soren | |
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/soren')
-rw-r--r-- | npc/soren/_import.txt | 5 | ||||
-rw-r--r-- | npc/soren/_mobs.txt | 8 | ||||
-rw-r--r-- | npc/soren/main.txt | 531 | ||||
-rw-r--r-- | npc/soren/mapflags.txt | 1 |
4 files changed, 545 insertions, 0 deletions
diff --git a/npc/soren/_import.txt b/npc/soren/_import.txt new file mode 100644 index 0000000..7721a7c --- /dev/null +++ b/npc/soren/_import.txt @@ -0,0 +1,5 @@ +// Map soren: Soren's Village +// This file is generated automatically. All manually added changes will be removed when running the Converter. +"npc/soren/_mobs.txt", +"npc/soren/main.txt", +"npc/soren/mapflags.txt", diff --git a/npc/soren/_mobs.txt b/npc/soren/_mobs.txt new file mode 100644 index 0000000..79e4d5d --- /dev/null +++ b/npc/soren/_mobs.txt @@ -0,0 +1,8 @@ +// This file is generated automatically. All manually added changes will be removed when running the Converter. +// Map soren: Soren's Village mobs +soren,122,104,102,81 monster Moonshroom 1069,14,60000,60000 +soren,102,84,102,81 monster Forain 1061,5,60000,60000 +soren,103,91,64,40 monster 4144's Tortuga 1004,1,6600000,600000 +soren,105,87,30,23 monster Snake 1122,4,15000,15000 +soren,109,57,12,5 monster Guardians Of Soren 1130,4,5000,10000 +soren,110,97,103,81 monster Angry Red Scorpion 1130,18,5000,10000 diff --git a/npc/soren/main.txt b/npc/soren/main.txt new file mode 100644 index 0000000..845c662 --- /dev/null +++ b/npc/soren/main.txt @@ -0,0 +1,531 @@ +// TMW2 Scripts +// Author: +// Jesusalva +// Description: +// Celestia Yeti King's quest. This controls Soren's House and the three keysigns. +// Key #1 +// Perform the rite at the Fountain +// Key #2 +// Perform the rite at the south lake +// Key #3 +// Perform the rite at the Button Area +// +// If the same player performs the rite on different places, HE'LL BE PENALIZED. +// Performing the rite spawn monsters, so watch out. + +// Notes: +// I had two options: +// getvariableofnpc(<variable>, "<npc name>") +// This way, each summon point would have .caster and .lifetime +// getvariableofpc(<variable>, <account id>{, <default value>}) +// This way, I could use @cast_places to control stuff. +// +// Obviously NPC variables was more sane. +// +// The use of compareandsetq HurnscaldQuest_Celestia +// Ensures you're NOT capable of skipping to final stage in order to finish +// the quest. Nice attempt, but that won't work. The scripts will advance, +// but you'll stay at the same quest state, and when it's checked, you will +// be with bound hands. + +soren,105,57,0 script Soren's House NPC_NO_SPRITE,0,0,{ + end; + +OnTouch: + .@st1=getvariableofnpc(.lifetime, "Soren's Fountain")-gettimetick(2); + .@st2=getvariableofnpc(.lifetime, "Soren's Lake")-gettimetick(2); + .@st3=getvariableofnpc(.lifetime, "Soren's Gizmo")-gettimetick(2); + if (.@st1 > 0 && .@st2 > 0 && .@st3 > 0) { + @soren_penalty=0; + compareandsetq HurnscaldQuest_Celestia, 3, 4; + doevent("#SorenSanctum::OnStart"); + warp "soren-2", 32, 36; + end; + } else { + mesn l("Soren's House Tutorial"); + mesc l("There's a strong magic barrier. We need to disarm it in order to enter there."); + mesc l("There are three singularities on this island. If I disarm more than one, I'll have a penalty."); + mesc l("I should have full mana before attempting to disarm one."); + mesc l("Also, if I move away from the singularity during disarm process, it'll be lost."); + mesc l("The singularities keep arming themselves up again, so I have roughly five minutes between first disarm and entering here."); + mesc l("We should split our team, and have someone to protect our backs. Otherwise, we might not do it."); + // Protip: stock Elixir Of Life if you need to do this quest with less than 3 team members + close; + } + end; + +// Some cleanup might be needed to don't raise difficulty infinitely +// So every day, at 03:23 AM, if no one is trying the quest, it'll get rid +// of the non-permanent monsters on Soren Village & Soren House. +// FIXME: It also clears up Groata Grotto +OnClock0323: + if (getareausers("soren") == 0 && + getareausers("soren-2") == 0 && + getareausers("001-6") == 0 && + getareausers("001-7") == 0) { + killmonster("soren", "all"); + killmonster("soren-2", "all"); + } + if ($@GROTTO && + getareausers("006-0") == 0 && + getareausers("006-3") == 0 && + getareausers("006-5") == 0) { + killmonster("006-5", "all"); + $@GROATA = 0; + $@GROTTO = 0; + enablenpc "#006-5_49_54"; + } + end; +} + + + + + +soren,105,92,0 script Soren's Fountain NPC_NO_SPRITE,{ + // Initial Checks + if (.lifetime > gettimetick(2)) { + npctalk l("This singularity will remain disarmed for @@ more!", FuzzyTime(.lifetime, 2, 2)); + end; + } + if (.st) { + npctalk l("A disarm process is already running."); + end; + } + + // Main menu + mesc l("Attempt to disarm the singularity?"); + if (askyesno() == ASK_YES) { + .casterId=getcharid(3); + .st=1; + npctalk l("@@ started disarm process. Please stand by.", strcharinfo(0)); + initnpctimer; + if (getvariableofnpc(.casterId, "Soren's Fountain") == .casterId) + @sorenp=10; + else + @sorenp=0; + } + close; + +// Waves (total: 6 waves + 1 optional) +OnTimer5000: +OnTimer10300: +OnTimer14000: +OnTimer18000: +OnTimer25000: +OnTimer28000: +OnTimer31000: + if (!attachrid(.casterId)) { + npctalk "Disarm process aborted: Disarmer is gone."; + stopnpctimer; .st=0; + end; + } + if (!reachable(.x, .y, .distance)) { + npctalk l("Disarm process aborted: Disarmer is out of reach."); + stopnpctimer; .st=0; + end; + } + if (Sp < MaxSp/100*15) { + npctalk l("Disarm process aborted: Insufficient mana to proceed."); + stopnpctimer; .st=0; + end; + } + if (ispcdead()) { + npctalk l("Disarm process aborted: Disarmer is dead."); + stopnpctimer; .st=0; + end; + } + + // Penalty Handler. + .@val=-2; + if (getvariableofnpc(.casterId, "Soren's Lake") == .casterId) + .@val=.@val-10; + if (getvariableofnpc(.casterId, "Soren's Gizmo") == .casterId) + .@val=.@val-10; + if (@sorenp) + .@val-=@sorenp; + + percentheal (.@val/2), -13+.@val; + + // Monster Gen + .@amount=rand2(.st/3+1, .st/2+1)+getareausers("soren", 12); + .@mid=rand2(1,3)+.st; + switch (.@mid) { + case 1: + case 2: + .@monsterId = CaveMaggot ; break; + case 3: + case 4: + .@monsterId = RedSlime ; break; + case 5: + case 6: + .@monsterId = LavaSlime ; break; + case 7: + case 8: + .@monsterId = any(Snake, GrassSnake, OldSnake, MountainSnake) ; break; + default: // case 9: + .@monsterId = any(Yeti, Yeti, MountainSnake) ; break; + } + // Item Gen + .@mid=rand(1,7)+.st; + switch (.@mid) { + case 1: + case 2: + .@itemId = Acorn ; break; + case 3: + case 4: + .@itemId = any(BugLeg, ChocolateMouboo) ; break; + case 5: + case 6: + .@itemId = OrangeCupcake ; break; + case 7: + case 8: + .@itemId = CherryCake ; break; + case 9: + case 10: + .@itemId = Chagashroom ; break; + case 11: + .@itemId = GingerBreadMan ; break; + case 12: + .@itemId = rand2(Diamond, Amethyst) ; break; + default: // case 13 + .@itemId = rand2(CopperOre, TitaniumOre) ; break; + } + // Defines + .@lx=.x-.distance; + .@ly=.y-.distance; + .@ux=.x+.distance; + .@uy=.y+.distance; + + // Core function + areamonster .map$, .@lx, .@ly, .@ux, .@uy, strmobinfo(1, .@monsterId), .@monsterId, .@amount; makeitem(.@itemId, 1, .map$, rand2(.@lx, .@ux), rand2(.@ly, .@uy)); ++.st; + specialeffect(54); + + // If we're done with waves + if (.st >= 7) { + getexp rand2(1, 100), rand2(1, 10); + .lifetime=gettimetick(2)+330+rand2(0, 60); + npctalk l("Disarmed with success for: @@", FuzzyTime(.lifetime, 2, 2)); + stopnpctimer; .st=0; + specialeffect(27); + } + end; + +OnInit: + .sex = G_OTHER; + .distance = 3; + + .casterId=0; // getcharid(0) → 3 is account number!! + .lifetime=0; // When will this gate expire (six minutes) (gettimetick(2) + (60*5)) + .st=0; // Status after started + + end; +} + + + + + + + + + + + + + + + + +soren,104,143,0 script Soren's Lake NPC_NO_SPRITE,{ + // Initial Checks + if (.lifetime > gettimetick(2)) { + npctalk l("This singularity will remain disarmed for @@ more!", FuzzyTime(.lifetime, 2, 2)); + end; + } + if (.st) { + npctalk l("A disarm process is already running."); + end; + } + + // Main menu + mesc l("Attempt to disarm the singularity?"); + if (askyesno() == ASK_YES) { + .casterId=getcharid(3); + .st=1; + npctalk l("@@ started disarm process. Please stand by.", strcharinfo(0)); + initnpctimer; + if (getvariableofnpc(.casterId, "Soren's Lake") == .casterId) + @sorenp=10; + else + @sorenp=0; + } + close; + +// Waves (total: 6 waves + 1 optional) +OnTimer4500: +OnTimer11300: +OnTimer17000: +OnTimer22000: +OnTimer26200: +OnTimer29100: +OnTimer30900: + if (!attachrid(.casterId)) { + npctalk "Disarm process aborted: Disarmer is gone."; + stopnpctimer; .st=0; + end; + } + if (!reachable(.x, .y, .distance)) { + npctalk l("Disarm process aborted: Disarmer is out of reach."); + stopnpctimer; .st=0; + end; + } + if (Sp < MaxSp/100*15) { + npctalk l("Disarm process aborted: Insufficient mana to proceed."); + stopnpctimer; .st=0; + end; + } + if (ispcdead()) { + npctalk l("Disarm process aborted: Disarmer is dead."); + stopnpctimer; .st=0; + end; + } + + // Penalty Handler. + .@val=-2; + if (getvariableofnpc(.casterId, "Soren's Fountain") == .casterId) + .@val=.@val-10; + if (getvariableofnpc(.casterId, "Soren's Gizmo") == .casterId) + .@val=.@val-10; + if (@sorenp) + .@val-=@sorenp; + + percentheal (.@val/2), -13+.@val; + + // Monster Gen. Lake spawns less + .@amount=rand2(.st/3+1, .st/2+1)+getareausers("soren", 12)-1; + .@mid=rand2(1,3)+.st; + switch (.@mid) { + case 1: + case 2: + .@monsterId = CaveMaggot ; break; + case 3: + case 4: + .@monsterId = RedSlime ; break; + case 5: + case 6: + .@monsterId = LavaSlime ; break; + case 7: + case 8: + .@monsterId = any(Snake, GrassSnake, OldSnake, MountainSnake) ; break; + default: // case 9: + .@monsterId = any(Yeti, Yeti, MountainSnake) ; break; + } + // Item Gen have a different mechanic here + .@mid=rand(.st, .st*2+1); + switch (.@mid) { + case 1: + case 2: + .@itemId = Acorn ; break; + case 3: + case 4: + .@itemId = any(BugLeg, ChocolateMouboo) ; break; + case 5: + case 6: + .@itemId = OrangeCupcake ; break; + case 7: + case 8: + .@itemId = CherryCake ; break; + case 9: + case 10: + .@itemId = Chagashroom ; break; + case 11: + .@itemId = HastePotion ; break; + case 12: + .@itemId = rand2(Diamond, Amethyst) ; break; + default: // case 13 + .@itemId = rand2(CopperOre, TitaniumOre) ; break; + } + // Defines for Lake are fixed on the same spot. + .@lx=104; .@ux=104; + .@ly=141; .@uy=141; + + // Core function + areamonster .map$, .@lx, .@ly, .@ux, .@uy, strmobinfo(1, .@monsterId), .@monsterId, .@amount; makeitem(.@itemId, 1, .map$, rand2(.@lx, .@ux), rand2(.@ly, .@uy)); ++.st; + + // If we're done with waves + if (.st >= 7) { + .lifetime=gettimetick(2)+330+rand2(0, 60); + npctalk l("Disarmed with success for: @@", FuzzyTime(.lifetime, 2, 2)); + stopnpctimer; .st=0; + } + end; + +OnInit: + .sex = G_OTHER; + .distance = 2; + + .casterId=""; // getcharid(3) → Account number!! + .lifetime=0; // When will this gate expire (five~six minutes) (gettimetick(2) + (60*5)) + .st=0; // Status after started + + end; +} + + + + + + + + + + + + + + + + + + +soren,107,37,0 script Soren's Gizmo NPC_NO_SPRITE,{ + // Initial Checks + if (.lifetime > gettimetick(2)) { + npctalk l("This singularity will remain disarmed for @@ more!", FuzzyTime(.lifetime, 2, 2)); + end; + } + if (.st) { + npctalk l("A disarm process is already running."); + end; + } + + // Main menu + mesc l("Attempt to disarm the singularity?"); + if (askyesno() == ASK_YES) { + .casterId=getcharid(3); + .st=1; + npctalk l("@@ started disarm process. Please stand by.", strcharinfo(0)); + initnpctimer; + if (getvariableofnpc(.casterId, "Soren's Gizmo") == .casterId) + @sorenp=10; + else + @sorenp=0; + } + close; + +// Waves (total: 6 waves + 1 optional) +OnTimer6200: +OnTimer9300: +OnTimer13900: +OnTimer17200: +OnTimer24500: +OnTimer27400: +OnTimer31200: + if (!attachrid(.casterId)) { + npctalk "Disarm process aborted: Disarmer is gone."; + stopnpctimer; .st=0; + end; + } + if (!reachable(.x, .y, .distance)) { + npctalk l("Disarm process aborted: Disarmer is out of reach."); + stopnpctimer; .st=0; + end; + } + if (Sp < MaxSp/100*15) { + npctalk l("Disarm process aborted: Insufficient mana to proceed."); + stopnpctimer; .st=0; + end; + } + if (ispcdead()) { + npctalk l("Disarm process aborted: Disarmer is dead."); + stopnpctimer; .st=0; + end; + } + + // Penalty Handler. + .@val=-2; + if (getvariableofnpc(.casterId, "Soren's Lake") == .casterId) + .@val=.@val-10; + if (getvariableofnpc(.casterId, "Soren's Fountain") == .casterId) + .@val=.@val-10; + if (@sorenp) + .@val-=@sorenp; + + percentheal (.@val/2), -13+.@val; + + // Monster Gen. Gizmo spawns more monsters because you can move more + .@amount=rand2(.st/3+1, .st/2+1)+getareausers("soren", 12)+1; + .@mid=rand2(1,3)+.st; + switch (.@mid) { + case 1: + case 2: + .@monsterId = CaveMaggot ; break; + case 3: + case 4: + .@monsterId = RedSlime ; break; + case 5: + case 6: + .@monsterId = LavaSlime ; break; + case 7: + case 8: + .@monsterId = any(Snake, GrassSnake, OldSnake, MountainSnake) ; break; + default: // case 9: + .@monsterId = any(Yeti, Yeti, MountainSnake) ; break; + } + // Item Gen + .@mid=rand(1,7)+.st; + switch (.@mid) { + case 1: + case 2: + .@itemId = Acorn ; break; + case 3: + case 4: + .@itemId = any(BugLeg, ChocolateMouboo) ; break; + case 5: + case 6: + .@itemId = OrangeCupcake ; break; + case 7: + case 8: + .@itemId = CherryCake ; break; + case 9: + case 10: + .@itemId = Chagashroom ; break; + case 11: + .@itemId = HastePotion ; break; + case 12: + .@itemId = rand2(Diamond, Amethyst) ; break; + default: // case 13 + .@itemId = rand2(CopperOre, TitaniumOre) ; break; + } + // Defines + .@lx=.x-.distance; + .@ly=.y-.distance; + .@ux=.x+.distance; + .@uy=.y+.distance; + + // Core function + areamonster .map$, .@lx, .@ly, .@ux, .@uy, strmobinfo(1, .@monsterId), .@monsterId, .@amount; makeitem(.@itemId, 1, .map$, rand2(.@lx, .@ux), rand2(.@ly, .@uy)); ++.st; + + // If we're done with waves + if (.st >= 7) { + .lifetime=gettimetick(2)+330+rand2(0, 60); + npctalk l("Disarmed with success for: @@", FuzzyTime(.lifetime, 2, 2)); + stopnpctimer; .st=0; + } + end; + + +OnInit: + .sex = G_OTHER; + .distance = 4; + + .casterId=""; // getcharid(3) → Account number!! + .lifetime=0; // When will this gate expire (five~six minutes) (gettimetick(2) + (60*5)) + .st=0; // Status after started + + end; +} + +029-0,143,120,0 duplicate(Guild Storage) Guild Storekeeper#FoS NPC_TERRY + diff --git a/npc/soren/mapflags.txt b/npc/soren/mapflags.txt new file mode 100644 index 0000000..f38cb43 --- /dev/null +++ b/npc/soren/mapflags.txt @@ -0,0 +1 @@ +soren mapflag zone MMO |