// 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 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,0,0,{
// 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;
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,0,0,{
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,0,0,{
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;
}