diff options
Diffstat (limited to 'npc/functions/mkbot.txt')
-rw-r--r-- | npc/functions/mkbot.txt | 235 |
1 files changed, 235 insertions, 0 deletions
diff --git a/npc/functions/mkbot.txt b/npc/functions/mkbot.txt new file mode 100644 index 000000000..f71334435 --- /dev/null +++ b/npc/functions/mkbot.txt @@ -0,0 +1,235 @@ +// 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 = rand2(20, 300); + .@y = rand2(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 < rand2(2,4)) { + initnpctimer; + end; + } + + // Siege events (req. 300 aggro, 3 users, and 70% chances to begin) + if ($@MK_AGGRO >= ($GAME_STORYLINE == 2 ? 300 : 500) && .users >= 3 && rand2(0,100) < 70 && + is_between(1, 3, $GAME_STORYLINE) && $@MK_THROTTLE < gettimetick(2)){ + // Delta handles the compulsory wait time between waves. + // 6 hours normally, 12 hours if the army is in disarray. + .@delta=6; + if ($GAME_STORYLINE == 3) + .@delta=12; + // Tulimshar + if (compare(.mp$, "003-")) { + announce ("Monster King: I smell humans! Humans must die!"), bc_map|bc_npc; + $@MK_THROTTLE=gettimetick(2)+.@delta*60*60; + $@MK_SCENE=MK_SIEGE_TULIM; + donpcevent("Lieutenant Dausen::OnMKSiege"); + } + // Halinarzo + else if (compare(.mp$, "009-")) { + announce ("Monster King: I smell humans! Humans must die!"), bc_map|bc_npc; + $@MK_THROTTLE=gettimetick(2)+.@delta*60*60; + $@MK_SCENE=MK_SIEGE_HALIN; + donpcevent("Lieutenant Jacob::OnMKSiege"); + } + // Hurnscald + else if (compare(.mp$, "012-")) { + announce ("Monster King: I smell humans! Humans must die!"), bc_map|bc_npc; + $@MK_THROTTLE=gettimetick(2)+.@delta*60*60; + $@MK_SCENE=MK_SIEGE_HURNS; + donpcevent("#HurnscaldSiege::OnMKSiege"); + } + // Nivalis + else if (compare(.mp$, "020-")) { + announce ("Monster King: I smell humans! Humans must die!"), bc_map|bc_npc; + $@MK_THROTTLE=gettimetick(2)+.@delta*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 && $@MK_THROTTLE >= gettimetick(2)) )){ + // 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); + + // 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*$GAME_STORYLINE)/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; + } + if ($GAME_STORYLINE == 2 && + $MK_TEMPVAR >= 500) { + kamibroadcast("##1##BThe Monster King army is in total disarray and disorder!", "Saulc"); + sleep(2500); + kamibroadcast("##1##BIt's our chance to strike back!", "Saulc"); + sleep(2500); + + // Apply the changes + $GAME_STORYLINE=3; + $MK_TEMPVAR=0; // In past, we forced 1 month wait. Now we have KW mechs... + } + + // We're done, restart loop timer + initnpctimer; + end; +} + |