// TMW-2 Script
// Author:
// Jesusalva
// Description:
// GM Bot for the Monster King.
// VARIABLES
// $GAME_STORYLINE - Current Storyline status
// $@MK - Monster King Game ID
// $@MK_SCENE - Current event being handled by the Monster King
// $MK_TEMPVAR - Temporary Variable
// $@MK_THROTTLE - Event Throttler
//
// Storyline statuses:
// 0 - The Monster King is inactive (leading sieges to Hurnscald and Nivalis)
// 1 - The Monster King is known by players and is giving them a month break
// 2 - The Monster King is currently sieging towns at random
// 3 - The Monster King is preparing to perfom the Rite and Lightbringer seeks
// a wielder
// 4 - The Rite is in progress. Players must walk to MK evil lair and fight.
// 5 - The Monster King is dead. Or something. Depends on players.
//
// $MK_TEMPVAR meaning depends on GAME STORYLINE
// GS 0
// Ignored
// GS 1
// Tracks the day since 1970 when the town was cleared. A month break.
// GS 2
// Player score (1pt per Lieutenant, 10pts per Colonel)
// Affects the end of Game Story 2 and begin of Game Story 3
// Because we must wait players...
// GS 3
// Stage TBD
000-0,0,0,0 script Monster King NPC_HIDDEN,{
OnSlaveDie:
end;
OnBourneAgain:
if (playerattached()) {
channelmes("#world", strcharinfo(0)+" did an act worth of notice.");
dispbottom l("Oh well, this sucks, but that was only an illusion.");
dispbottom l("The real Monster King is probably on his fortress. It'll take more than that to take him down.");
getexp BaseLevel**3, 0;
Mobpt = Mobpt + 165;
$MOST_HEROIC$=strcharinfo(0);
}
// We need to start over
.bar=true;
OnInit:
$@MK=monster("boss", 45, 45, "The Monster King", MonsterKing, 1, "Monster King::OnBourneAgain");
if (!.bar) {
// Variables which other NPCs must take in account
$@MK_AGGRO=0;
$@MK_SCENE=0;
} else {
.bar=false;
}
// Variables only for this NPC
.users=getusers(1);
.nearby=getusers(8);
.mp$="boss";
.aid="200000";
.cid="150002";
// Constants
// We should jump straight to loop (it runs every 90 seconds)
OnTimer90000:
// Regenerate some data, and kill spurious mobs
.users=getusers(1);
if (mobcount(.mp$, "Monster King::OnSlaveDie")) {
announce ("Monster King: Noobs, you are all a bunch of noobs!"), bc_map|bc_npc;
killmonster(.mp$, "Monster King::OnSlaveDie");
}
// We are on an event, so skip this loop
if ($@MK_SCENE || $@GM_EVENT) {
initnpctimer;
end;
}
// The Monster King is online. This loop is not needed
if (isloggedin(.aid, .cid)) {
if (!$@MK_SCENE)
unitwarp($@MK, "boss", 45, 45);
else
rodex_sendmail(.cid, "MKBot", "Running Event", "An event is currently running by the MK Bot. Please logout and suppress it.");
initnpctimer;
}
// Raise aggro (1 pt per 2 users)
$@MK_AGGRO+=(.users/2);
// Mana Stone
if (.mp$ == "011-1")
enablenpc "Mana Stone";
// The Monster King will not move anymore because story
if ($GAME_STORYLINE == 0 ||
$GAME_STORYLINE == 4) {
if (.mp$ != "boss")
unitwarp($@MK, "boss", 45, 45);
initnpctimer;
end;
}
// Select a random map. Never shows up at Candor and cities, nor indoors. Not all maps either.
setarray .@m$, "boss", "boss", "001-1", "001-3", "001-4", "001-5", "001-6", "001-7", "001-10",
"003-1", "003-1-3", "004-1", "004-2", "007-1", "009-1", "010-1", "010-1-1", "010-2", "011-1",
"012-1", "014-1", "014-2", "014-3", "014-4", "014-5", "015-1", "015-2", "015-3", "015-5",
"018-1-1", "018-2", "018-3", "018-4", "018-4-1",
"019-1", "019-2", "019-4", "020-1", "021-1", "022-1", "023-1";
.mp$=any_of(.@m$);
// Try to warp randomly, up to 30 attempts
.@e=0; .@x=0; .@y=0;
do {
if (.@e >= 30) {
.mp$="boss";
.@x=45;
.@y=45;
break;
}
.@x = rand(20, 300);
.@y = rand(20, 300);
.@e+=1;
} while (!checknpccell(.mp$, .@x, .@y, cell_chkpass));
if (!checknpccell(.mp$, .@x, .@y, cell_chkpass)) {
Exception("gm.bot runtime error: GM_ERR_128 highlight @Jesusalva", RB_DEBUGMES|RB_IRCBROADCAST); .mp$="boss"; .@x=45; .@y=45;
}
unitwarp($@MK, .mp$, .@x, .@y);
sleep(50); // For some reason or other, adding sleep(norid) and sleep2(rid).
.nearby=getusers(8);
// Handle Mana Stone
if (.mp$ == "011-1")
disablenpc "Mana Stone";
// Debug markers
if ($@GM_OVERRIDE)
debugmes "Monster King (bot): "+.mp$+" ("+.@x+", "+.@y+")";
// If too few players are online, we don't need an event AT ALL!
if (.users < rand(2,4)) {
initnpctimer;
end;
}
// Siege events (req. 300 aggro, 3 users, and 70% chances to begin)
if ($@MK_AGGRO >= 300 && .users >= 3 && rand(0,100) < 70 &&
$GAME_STORYLINE == 2 && $@MK_THROTTLE < gettimetick(2)){
// Tulimshar
if (.mp$ ~= "003-*") {
announce ("Monster King: I smell humans! Humans must die!"), bc_map|bc_npc;
$@MK_THROTTLE=gettimetick(2)+12*60*60;
$@MK_SCENE=MK_SIEGE_TULIM;
donpcevent("Lieutenant Dausen::OnMKSiege");
}
// Halinarzo
else if (.mp$ ~= "009-*") {
announce ("Monster King: I smell humans! Humans must die!"), bc_map|bc_npc;
$@MK_THROTTLE=gettimetick(2)+12*60*60;
$@MK_SCENE=MK_SIEGE_HALIN;
donpcevent("Lieutenant Jacob::OnMKSiege");
}
// Hurnscald
else if (.mp$ ~= "012-*") {
announce ("Monster King: I smell humans! Humans must die!"), bc_map|bc_npc;
$@MK_THROTTLE=gettimetick(2)+12*60*60;
$@MK_SCENE=MK_SIEGE_HURNS;
donpcevent("#HurnscaldSiege::OnMKSiege");
}
// Nivalis
else if (.mp$ ~= "020-*") {
announce ("Monster King: I smell humans! Humans must die!"), bc_map|bc_npc;
$@MK_THROTTLE=gettimetick(2)+12*60*60;
$@MK_SCENE=MK_SIEGE_NIVAL;
donpcevent("Lieutenant Joshua::OnMKSiege");
}
}
// If a player is nearby while the Monster King prepares, event may happen
// Minimum 60 Aggro
if (.nearby > 1 && $@MK_AGGRO >= 80 &&
($GAME_STORYLINE == 1 || $GAME_STORYLINE == 3)){
// We should decide event kind, but that's NYI
announce ("Monster King: I smell humans! Humans must die!"), bc_map|bc_npc;
getmapxy(.@m$, .@x, .@y, UNITTYPE_MOB, $@MK);
// 50% more monsters at night time
if (is_night())
$@MK_AGGRO=$@MK_AGGRO*3/2;
// Spawn stuff
areamonster(.@m$, .@x-20, .@y-20, .@x+20, .@y+20, "Monster", ManaGhost, ($@MK_AGGRO/10)+.nearby, "Monster King::OnSlaveDie");
$@MK_AGGRO=$@MK_AGGRO/5;
}
// Maybe, just maybe, game storyline must be updated here
if ($GAME_STORYLINE == 1 && $MK_TEMPVAR &&
$MK_TEMPVAR <= gettimeparam(GETTIME_DAYOFMONTH)) {
// Game Story Change: Idle MK -> Active MK
kamibroadcast("I can't handle it anymore! NO MORE!", "Monster King");
sleep(2500);
kamibroadcast("Come, my minions! Lay siege to towns! LEAVE NO OPPOSITION TO ME!", "Monster King");
sleep(2500);
kamibroadcast("Burn, destroy, do whatever you need, until your last breath, my lieutenants and colonels!", "Monster King");
sleep(2500);
kamibroadcast("##4 .:: Game Story Instructions on #world ::.");
channelmes("#world", "##1 **GAME STORY CHANGE** - The Monster King minions will now attack cities and lay waste to them.");
channelmes("#world", "##1 Players must defeat the lieutenants and colonels in order to prevent sieges from continuing.");
// Apply the changes
$GAME_STORYLINE=2;
$MK_TEMPVAR=0;
}
// We're done, restart loop timer
initnpctimer;
end;
}