// 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(, "") // This way, each summon point would have .caster and .lifetime // getvariableofpc(, {, }) // 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 Dizmo")-gettimetick(2); if (.@st1 > 0 && .@st2 > 0 && .@st3 > 0) { compareandsetq HurnscaldQuest_Celestia, 3, 4; warp "soren-2", 32, 36; end; } else { mesn l("Soren's House Tutorial"); mes col("There's a strong magic barrier. We need to disarm it in order to enter there.", 9); mes col("There are three singularities on this island. If I disarm more than one, I'll have a penalty.", 9); mes col("I should have full mana before attempting to disarm one.", 9); mes col("Also, if I move away from the singularity during disarm process, it'll be lost.", 9); mes col("The singularities keep arming themselves up again, so I have roughly five minutes between first disarm and entering here.", 9); mes col("We should split our team, and have someone to protect our backs. Otherwise, we might not do it.", 9); close; } 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 mes col("Attempt to disarm the singularity?", 9); if (askyesno() == ASK_YES) { .casterId=getcharid(3); .st=1; npctalk l("@@ started disarm process. Please stand by."); initnpctimer; close; } end; // Waves (total: 6 waves) OnTimer5000: OnTimer10300: OnTimer14000: OnTimer18000: OnTimer25000: OnTimer29000: 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; } // Penalty Handler. .@val=-2; if (getvariableofnpc(.casterId, "Soren's Lake") == .casterId) .@val=.@val-10; if (getvariableofnpc(.casterId, "Soren's Dizmo") == .casterId) .@val=.@val-10; percentheal .@val, -15; // Monster Gen .@amount=rand(.st/2+1, .st+1); .@mid=rand(1,3)+.st; switch (.@mid) { case 1: case 2: .@monsterId = CaveMaggot ; break; case 3: case 4: case 5: .@monsterId = LavaSlime ; break; case 6: case 7: .@monsterId = MountainSnake ; break; default: .@monsterId = Yeti ; break; } // Item Gen .@mid=rand(1,5)+.st; switch (.@mid) { case 1: case 2: .@itemId = Acorn ; break; case 3: .@itemId = ChocolateMouboo ; break; case 4: case 5: .@itemId = OrangeCupcake ; break; case 6: .@itemId = CherryCake ; break; case 7: case 8: .@itemId = Chagashroom ; break; case 9: .@itemId = HastePotion ; break; case 10: .@itemId = rand(Diamond, Amethyst) ; break; default: // case 11 .@itemId = rand(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$, rand(.@lx, .@ux), rand(.@ly, .@uy)); ++.st; // If we're done with waves if (.st >= 6) { .lifetime=gettimetick(2)+300+rand(0, 60); npctalk l("Disarmed with success for: @@", FuzzyTime(.lifetime, 2, 2)); stopnpctimer; .st=0; } end; OnInit: .sex = G_OTHER; .distance = 2; .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,{ end; OnInit: .sex = G_OTHER; .distance = 1; .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 Dizmo NPC_NO_SPRITE,{ end; OnInit: .sex = G_OTHER; .distance = 3; .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; }