// TMW2 Scripts
// Author:
// Jesusalva
// Description:
// Celestia Yeti King's quest. This controls Soren's House Indoors. It will
// handle Lobby event, and is called by Soren's House script.
// It'll then spawn monsters and/or items, but with addtimer technology.
// Once all monsters are dead, and minimum time is over, a portal will show up.
// This later control is done by npctimer. The spawn logic continues, though.
// The addtimer will use compareandsetq, and the warp will use it too, so if
// you haven't spawned your quota, you won't be able to use the portal.
//
// 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.
//
// OnCheck:
// Everytime you kill a monster, this checks if all mobs are dead, and you
// have finished your share of spawns. Friends can really make your life
// harder.
// OnSanctum:
// This runs every once in a while, and may either spawn things, or drop
// items. ...Needless to say, if it spawn things, everyone on the room will
// get mad at you. Luck you, here's not PVP.
//
// One last thing. If you're way past your share, you'll get warnings about
// messing other players life. Simply use the warp, or leave the house and
// come back. If you don't, you'll be kicked from the game via @kick.
// Why? Because Jesusalva did this script.
soren-2,38,29,0 script #SorenSanctum NPC_NO_SPRITE,0,0,{
if (@sorensanctum == 0 && $@GM_OVERRIDE && is_admin())
doevent("#SorenSanctum::OnStart");
end;
OnTouch:
if (@sorensanctum >= 5 && !mobcount(.map$, "#SorenSanctum::OnCheck")) {
/*
dispbottom l("Error, contact Jesusalva! Missing warp. Healing & Reseting temporaly.");
percentheal 100, 100;*/
@sorensanctum=0;
compareandsetq HurnscaldQuest_Celestia, 4, 5;
warp "001-7", 30, 42;
}
end;
OnCheck:
// This doesn't works (or didn't used to), maybe because the way it's called
if (!mobcount("soren-2", "#SorenSanctum::OnCheck"))
setnpcdisplay "#SorenSanctum", NPC_SUMMONING_CIRC;
end;
OnSanctum:
++@sorensanctum;
if (ispcdead() || !isin("soren-2", 24, 27, 40, 36))
end;
// Decide if we'll spawn or add items. Previous failures are NOT considerated.
.@odds=rand(1, 10000);
.@amount=(rand2(0, 5)/2)+1;
.@lx=24; .@ly=27;
.@ux=40; .@uy=36;
// Core Logic, Part 1
// Decide rarity
// 1%: Super Rare drop
// 9%: Rare Drop
// 20%: Normal Drop
// 40%: Normal Spawn
// 10%: Rare Spawn
// 19%: Drop + Spawn
// 1%: Super Rare Spawn
if (.@odds <= 100 || .@odds >= 9900) {
.@bonus=2;
} else if (.@odds <= 1000 || (.@odds >= 7000 && .@odds < 8000)) {
.@bonus=1;
}
// Generate which monster/item would be dropped, depending on your (un)luck at ODDS
.@mid=rand(1,10)+.@bonus;
switch (.@mid) {
case 1:
.@monsterId = AngryRedScorpion ; break;
case 2:
.@monsterId = CaveMaggot ; break;
case 3:
.@monsterId = SeaSlime ; break;
case 4:
.@monsterId = AlphaMouboo ; break;
case 5:
.@monsterId = LavaSlime ; break;
case 6:
.@monsterId = BlackScorpion ; break;
case 7:
.@monsterId = Snake ; break;
case 8:
.@monsterId = FallenGuard2 ; break;
case 9:
.@monsterId = FallenGuard1 ; break;
case 10:
.@monsterId = Moonshroom ; break;
default:
.@monsterId = Yeti ; break;
}
// Item Gen
.@mid=rand(1,10)+.@bonus;
switch (.@mid) {
case 1:
.@itemId = Acorn ; break;
case 2:
.@itemId = Bread ; break;
case 3:
.@itemId = Aquada ; break;
case 4:
.@itemId = StrenghtPotion ; break;
case 5:
.@itemId = Plushroom ; break;
case 6:
.@itemId = Piberries ; break;
case 7:
.@itemId = Croconut ; break;
case 8:
.@itemId = Chagashroom ; break;
case 9:
.@itemId = Manana ; break;
case 10:
.@itemId = HastePotion ; break;
default:
.@itemId = rand(CopperOre, TitaniumOre) ; break;
}
// Rare drop
if (rand(1,6900) == 1337)
.@itemId=RaidTrousers;
// Core Logic, part 3
// Make Items or Monsters
if (.@odds <= 3333) {
makeitem(.@itemId, 1, .map$, rand(.@lx, .@ux), rand(.@ly, .@uy));
} else if (.@odds <= 7000 || .@odds > 9900) {
areamonster .map$, .@lx, .@ly, .@ux, .@uy, strmobinfo(1, .@monsterId), .@monsterId, .@amount;
} else {
areamonster .map$, .@lx, .@ly, .@ux, .@uy, strmobinfo(1, .@monsterId), .@monsterId, .@amount;
makeitem(.@itemId, 1, .map$, rand(.@lx, .@ux), rand(.@ly, .@uy));
}
// Revert sprite if needed
if (.@odds > 2000) {
setnpcdisplay .name$, NPC_NO_SPRITE;
} else if (!mobcount(.map$, "#SorenSanctum::OnCheck")) {
setnpcdisplay .name$, NPC_SUMMONING_CIRC;
}
// Handle maximum overtime you can do here: 10 cycles, or 3m20s ~ 6m40s
if (@sorensanctum == 8) {
specialeffect(28);
dispbottom col(l("WARNING: Do not spend unecessary time on Soren's House, you'll be disconnected!"), 1);
percentheal -5, -20;
}
if (@sorensanctum == 9) {
specialeffect(28);
dispbottom col(l("FINAL WARNING: Do not spend unecessary time on Soren's House, you'll be disconnected!!"), 1);
percentheal -20, -100;
}
if (@sorensanctum >= 10) {
atcommand "@kick "+strcharinfo(0);
npctalk l("The power of Soren's House kicks @@ like a game master.", strcharinfo(0));
}
// Random 20~40 seconds before next cycle. (Minimum 100~200 seconds, or 1m40s~3m20s)
// If you're past minimum, it'll be a little slower to don't affect other players too much.
// These values are for single player. If there are more users, the timer will tick for longer.
if (@sorensanctum < 5)
addtimer(rand(15000, 35000)+getusers(1)*5000, "#SorenSanctum::OnSanctum");
else
addtimer(rand(25000, 35000)+getusers(1)*5000, "#SorenSanctum::OnSanctum");
end;
OnStart:
// If you're not on stage 4, skip this. I could set here to stage 5, so this
// intro won't play again. But if it plays again, your progress is reset, and
// it is harder this way, so I'm not touching on quest state :>
if (getq(HurnscaldQuest_Celestia) != 4)
end;
addtimer(200, "#SorenSanctum::OnStep1"); // Allow client to update stuff
end;
OnStep1:
// When we reach here, we have both a player attached, and the player was already warped.
// I don't know if you walked in and out the house, though. If you do, this will loop...
// Which is actually bad for you, as that will reset your progress!!
npctalk3 l("Well well well, @@, good job in reaching Soren's House.", strcharinfo(0));
addtimer(3000, "#SorenSanctum::OnStep2");
end;
OnStep2:
//setnpcdisplay .name$, NPC_YETI_KING;
npctalk3 l("You done well in getting so far. I didn't thought you would make it.");
addtimer(3000, "#SorenSanctum::OnStep3");
end;
OnStep3:
npctalk3 l("The Cave Of Trials, and the Soren's Village... There's only one thing left.");
addtimer(3000, "#SorenSanctum::OnStep4");
end;
OnStep4:
npctalk3 l("...You still have not overcome his house.");
addtimer(3000, "#SorenSanctum::OnStep5");
end;
OnStep5:
//setnpcdisplay .name$, NPC_NO_SPRITE;
npctalk3 l("Defeat a few waves of Soren's House. Once you're done, this will become a warp. Hurry before it closes.");
@sorensanctum=0;
addtimer(5000, "#SorenSanctum::OnSanctum");
end;
OnInit:
end;
}