// TMW2 scripts. // Authors: // Jesusalva // Description: // Town Siege utilities // Siege Spawn // Can be used anywhere to spawn on the whole map, margins respected. // siege_spawn( map, mobID, Amount, eventID ) function script siege_spawn { .@mp$=getarg(0); .@mid=getarg(1); .@qnt=getarg(2); .@ev$=getarg(3); areamonster(.@mp$, 20, 20, getmapinfo(MAPINFO_SIZE_X, .@mp$)-20, getmapinfo(MAPINFO_SIZE_Y, .@mp$)-20, strmobinfo(1, .@mid), .@mid, .@qnt, .@ev$); return; } // Calculate player average level // if highest is set, it will return highest player level, with minimum the value // passed. (A level "0" is clearly not valid, of course) // siege_calcdiff ( map{, highest_lvl} ) function script siege_calcdiff { .@bsum=0; .@highest=getarg(1, false); .@c = getunits(BL_PC, .@players, false, getarg(0)); // Fallback: No players on map, always return 0 if (.@c == 0) return 0; // There is at least one player, do things properly for (.@i = 0; .@i < .@c; .@i++) { .@b=readparam(BaseLevel, .@players[.@i]); .@bsum+=.@b; if (.@b > .@highest) .@highest=.@b; } //debugmes "calcdiff: Total %d Average %d Highest %d", .@bsum, (.@bsum/.@c), .@highest; if (getarg(1,false)) return .@highest; else return (.@bsum/.@c); } // push to $@SIEGE_TMPMOBS the if their level is within a 15 levels range // above or below // siege_push ( mobID, level ) function script siege_push { .@mi=getarg(0); .@lv=getarg(1,0); if ( is_between(.@lv-15, .@lv+15, strmobinfo(3, .@mi)) ) { //debugmes "Monster %s (%d) level %d ~= %d", strmobinfo(1, .@mi), .@mi, strmobinfo(3, .@mi), .@lv; array_push($@SIEGE_TMPMOBS, .@mi); } return; } // Selects a monster based on player average strength and base difficulty // It'll select monsters from 20 levels below to 20 levels above // tp_mask is the same as TP_* constants and changes mobs present. Only TP_TULIM, // TP_HURNS and TP_NIVAL are supported. You can use them with the "|" operand, eg., // TP_TULIM | TP_HURNS. // // It currently only creates $@SIEGE_TMPMOBS, you need to use any_of() manually. // siege_selectmob ( blvl, difficulty{, tp_mask} ) function script siege_selectmob { .@blv=getarg(0); .@dif=getarg(1, 0); .@tp=getarg(2, 0); // We don't need .@dif, so we convert difficulty to levels .@blv+=.@dif; deletearray $@SIEGE_TMPMOBS; setarray $@SIEGE_TMPMOBS, ManaGhost, CandiedSlime, Bif, SlimeBlast; // Now we must select mobs, using array_push() to $@SIEGE_TMPMOBS // First, mobs on all envs siege_push(BlackScorpion, .@blv); siege_push(GreenSlime, .@blv); siege_push(CaveMaggot, .@blv); siege_push(MagicGoblin, .@blv); siege_push(AngryBat, .@blv); siege_push(BlackSlime, .@blv); siege_push(BlackScorpion, .@blv); siege_push(Forain, .@blv); siege_push(GreenDragon, .@blv); siege_push(Terranite, .@blv); siege_push(JackO, .@blv); siege_push(BlackMamba, .@blv); siege_push(TerraniteProtector, .@blv); siege_push(Reaper, .@blv); // What if we are trying to select a boss and they're... overleveled? // We need a level 105, 120 and a level 135 monsters siege_push(FallenKing2, .@blv); siege_push(TerraniteKing, .@blv); // Now, mobs on only certain envs if (.@tp & TP_TULIM) { siege_push(AngryScorpion, .@blv); siege_push(AngryRedScorpion, .@blv); siege_push(DesertBandit, .@blv); siege_push(LavaSlime, .@blv); siege_push(OldSnake, .@blv); siege_push(Snake, .@blv); } if (.@tp & TP_HURNS) { siege_push(RedSlime, .@blv); siege_push(Bandit, .@blv); siege_push(RedMushroom, .@blv); siege_push(RobinBandit, .@blv); siege_push(AngryYellowSlime, .@blv); siege_push(GrassSnake, .@blv); siege_push(WickedMushroom, .@blv); } if (.@tp & TP_NIVAL) { siege_push(Bluepar, .@blv); siege_push(Wolvern, .@blv); siege_push(Yeti, .@blv); siege_push(Moggun, .@blv); // PS. Not aggressive } // Removed //siege_push(DarkLizard, .@blv); //siege_push(Crafty, .@blv); return; } ///////////////////////////////////////////////////////////// // Prepare a siege with optional announce // siege_setup ( map{, announce} ) function script siege_setup { .@m$=getarg(0); .@msg$=getarg(1, ""); addmapmask .@m$, MASK_MATTACK; changemusic .@m$, any("mythica.ogg", "eric_matyas_ghouls.ogg", "misuse.ogg", "Arabesque.ogg"); disablenpc("Mana Stone"); pvpon(.@m$); setmapflag(.@m$,mf_bexp,rand(140,160)); // 40~60% EXP UP on siege maps if (.@msg$ != "") kamibroadcast(col(.@msg$,1)); return; } // Revert what siege_setup did // siege_revert ( map ) function script siege_revert { .@m$=getarg(0); removemapmask .@m$, MASK_MATTACK; changemusic .@m$, "caketown.ogg"; // :> enablenpc("Mana Stone"); pvpoff(.@m$); removemapflag(.@m$,mf_bexp); killmonsterall(.@m$); return; } // Spawn some monsters // siege_cast ( map, NPCName, {, difficulty{, tpflag}} ) function script siege_cast { // mz - map ; n - name ; d - difficulty ; tp - teleport // a - ammount ; e - mobId .@mz$=getarg(0); .@n$=getarg(1); .@d=getarg(2,0); .@tp=getarg(3,0); siege_selectmob(siege_calcdiff(.@mz$), .@d, .@tp); // How many monsters? .@a=(.@d/3)+1; .@e=any_of($@SIEGE_TMPMOBS); array_remove($@SIEGE_TMPMOBS, .@e); siege_spawn(.@mz$, .@e, .@a, .@n$+"::OnRespawn"); .@e=any_of($@SIEGE_TMPMOBS); array_remove($@SIEGE_TMPMOBS, .@e); siege_spawn(.@mz$, .@e, .@a, .@n$+"::OnRespawn"); .@e=any_of($@SIEGE_TMPMOBS); array_remove($@SIEGE_TMPMOBS, .@e); siege_spawn(.@mz$, .@e, .@a, .@n$+"::OnRespawn"); return; } // Utility NPC - script #SiegeCtrl NPC_HIDDEN,{ end; // Boss Death Labels OnLieutenantDeath: getitem StrangeCoin, 1; mapannounce(getmap(), l("##2The Monster Lieutenant was defeated by @@!", strcharinfo(0)), bc_map); $MK_TEMPVAR+=1; end; OnColonelDeath: getitem StrangeCoin, 5; $MOST_HEROIC$=strcharinfo(0); mapannounce(getmap(), l("##2The Monster Colonel was defeated by @@!", strcharinfo(0)), bc_map); $MK_TEMPVAR+=10; end; }