
   /*********************************************************
   *          Bugblatter Monster Extension - V3.5          *
   *********************************************************
   *                                                       *
   * Monster Plugin converted for AMX Mod                  *
   *                                                       *
   * Requires                                              *
   *  - Monster DLL (Bugblatter)                           *
   *  - AMX >= 0.9.4                                       *
   *                                                       *
   *                                                       *
   *********************************************************/
   #include <amxmod>
   #include <amxmisc>
   #define ACCESS_LEVEL ADMIN_LEVEL_A
   #define MAX_PLAYERS 33
   #define DEFAULT_ENABLED 1
   #define MIN_ENABLED 0
   #define MAX_ENABLED 1
   #define DEFAULT_REPORT 1
   #define MIN_REPORT 0
   #define MAX_REPORT 1
   #define DEFAULT_MAX_MONSTERS 4
   #define MIN_MAX_MONSTERS 1
   #define MAX_MAX_MONSTERS 18
   #define DEFAULT_TIMEOUT 30.0
   #define MIN_TIMEOUT 10
   #define MAX_TIMEOUT 120
   #define DEFAULT_SCORE 0
   #define MIN_SCORE 0
   #define MAX_SCORE 10
   #define DEFAULT_MANIA 0
   #define MIN_MANIA 0
   #define MAX_MANIA 1
   #define DEFAULT_MANIASCORE 1
   #define MIN_MANIASCORE 0
   #define MAX_MANIASCORE 10
   /* Don't change this - its a limit from the monster_mm.dll */
   #define MAX_MONSTER_COUNT 20
   #define  MANIA_TIMER 101                                    /* Monster
   Mania spawn timer */
   #define  TIMEOUT_TIMER 102                                /* Timer for
   timeouts */
   /* Configuration variables */
   new  g_Enabled = DEFAULT_ENABLED                            /* Is this
   plugin enabled */
   new     g_Report     =    DEFAULT_REPORT                            /*
   Automatically show report after command? */
   new  g_Monsters[MAX_MAX_MONSTERS][32]                    /*  Names  of
   available monsters */
   new g_MonstersSize = 0                                    /* Length of
   monsters names list */
   new  g_MaxMonsters  =  DEFAULT_MAX_MONSTERS                /*  Maximum
   number of monsters player can spawn in each time period */
   new  Float:g_Timeout = DEFAULT_TIMEOUT                    /* Length of
   time period */
   new  g_Score  = DEFAULT_SCORE                                /* Points
   per mosnter frag */
   new  g_Mania = DEFAULT_MANIA                                /* Monster
   Mania on/off */
   new  g_ManiaScore  =  DEFAULT_MANIASCORE                    /* Monster
   Mania score */
   new  g_ManiaProtected  =  0                                /* Is Mania
   protected */
   /* Status vrariables */
   new  g_Spawns[MAX_PLAYERS]                                /* Number of
   monsters each player has spawned */
   new  g_MonsterCount  =  0                                    /* Tracks
   number of monsters in the game */
   new   g_NextMonsterID   =  0                                    /*  ID
   numbers for mosnters */
   public plugin_init()
   {
       register_plugin("Bugblatter's Monster
   plugin","3.5","SniperBeamer")
       register_srvcmd("admin_command","server_commands")
       register_logevent("monsters_slay",2,"0=World
   triggered","1=Round_End")
       register_logevent("monsters_respawn",2,"0=World
   triggered","1=Round_Start")
       register_concmd("bbmonster_enabled","admin_enabled",ACCESS_LEVEL,"
   ^"on^" | ^"off^": Enables / disables monster plugin")
       register_concmd("bbmonster_spawn","admin_spawn",ACCESS_LEVEL,"<mon
   ster> [<player>]: Spawns a monster on a player")
       register_concmd("bbmonster_timeout","admin_timeout",ACCESS_LEVEL,"
   <seconds>: Sets timeout for reseting spawn limit")
       register_concmd("bbmonster_maxmonsters","admin_maxmonsters",ACCESS
   _LEVEL,"<seconds>: Sets maximum number of monsters in each period")
       register_concmd("bbmonster_score","admin_score",ACCESS_LEVEL,"<poi
   nts>: Sets frags score for killing a monster")
       register_concmd("bbmonster_mania","admin_mania",ACCESS_LEVEL,"^"on
   ^" | ^"off^" | <points>: Enable monster mania mode, and sets score for
   a mania kill")
       register_concmd("bbmonster_report","admin_report",ACCESS_LEVEL,"[
   ^"on^"  |  ^"off^"  ]:  Shows  report  and  enables/disables automatic
   report")
       register_concmd("bbmonster_reset","admin_reset",ACCESS_LEVEL,":
   sets all monster settings to defaults")
       g_Report =
   GetVault("bbmonster_report",MIN_REPORT,MAX_REPORT,DEFAULT_REPORT)
       g_Enabled =
   GetVault("bbmonster_enabled",MIN_ENABLED,MAX_ENABLED,DEFAULT_ENABLED)
       g_MaxMonsters =
   GetVault("bbmonster_maxmonsters",MIN_MAX_MONSTERS,MAX_MAX_MONSTERS,DEF
   AULT_MAX_MONSTERS)
       g_Timeout = float(
   GetVault("bbmonster_timeout",MIN_TIMEOUT,MAX_TIMEOUT,floatround(DEFAUL
   T_TIMEOUT)) )
       g_Score =
   GetVault("bbmonster_score",MIN_SCORE,MAX_SCORE,DEFAULT_SCORE)
       g_Mania =
   GetVault("bbmonster_mania",MIN_MANIA,MAX_MANIA,DEFAULT_MANIA)
       g_ManiaScore =
   GetVault("bbmonster_maniascore",MIN_MANIASCORE,MAX_MANIASCORE,DEFAULT_
   MANIASCORE)
       ReadMonsterList()
       CheckMania()
       set_task(g_Timeout,"ResetSpawnCounts",TIMEOUT_TIMER,"",0,"b")
   }
   /*********************************************************/
   /* Monster DLL callback handlers                         */
   /*********************************************************/
   public server_commands()
   {
       new arg1[32],arg2[32],arg3[32],num1,num2
       read_argv(1,arg1,31)
       read_argv(2,arg2,31)
       read_argv(3,arg3,31)
       num1 = str_to_num(arg2)
       num2 = str_to_num(arg3)
       if ( equal(arg1,"bbmonstercb_spawned") )
           monster_spawned()
       else if ( equal(arg1,"bbmonstercb_kill") )
           monster_kill(num1,num2)
       else if ( equal(arg1,"bbmonstercb_killed") )
           monster_killed(num1,num2)
       else if ( equal(arg1,"bbmonstercb_dead") )
           monster_dead()
       else
           return PLUGIN_CONTINUE
       return PLUGIN_HANDLED
   }
   monster_spawned()
   {
       g_MonsterCount++
   }
   monster_kill(Player,Monster)
   {
       new pName[32]
       get_user_name(Player,pName,31)
       log_to_file("monster.log","Monster       %d       has       killed
   %s",Monster,pName)
       client_print(0,print_chat,"Monster       %d       has       killed
   %s",Monster,pName)
   }
   monster_killed(Player,Monster)
   {
       new pName[32]
       get_user_name(Player,pName,31)
       log_to_file("monster.log","%s       has       killed       monster
   %d",pName,Monster)
       client_print(0,print_chat,"%s       has       killed       monster
   %d",pName,Monster)
   }
   monster_dead()
   {
       g_MonsterCount--
   }
   /*********************************************************/
   /* Event command handlers                                */
   /*********************************************************/
   public monsters_slay()
   {
       server_cmd("slaymonsters")
       set_task(3.0,"ForceUnload")
       g_ManiaProtected = 1
       new Float:tl = get_cvar_float("mp_timelimit")+15
       if ( tl<20 )
           tl = 20.0
       set_task(tl,"ManiaProtectEnd")
       return PLUGIN_CONTINUE
   }
   public monsters_respawn()
   {
       server_cmd("respawnmonsters")
       return PLUGIN_CONTINUE
   }
   public ForceUnload()
   {
       server_cmd("slaymonsters force")
       g_MonsterCount = 0
   }
   public ManiaProtectEnd()
   {
       if ( g_ManiaProtected==2 )
           set_task(float(random(20)),"ManiaTimer",MANIA_TIMER)
       g_ManiaProtected = 0
   }
   /*********************************************************/
   /* Command handlers for admin commands                   */
   /*********************************************************/
   public admin_enabled(id,level,cid)
   {
       if (!cmd_access(id,level,cid,2))
           return PLUGIN_HANDLED
       new arg[32],num,temp[2]
       read_argv(1,arg,31)
       num = str_to_num(arg)
       if ( equal(arg,"on") )
           g_Enabled = 1
       else if ( equal(arg,"off") )
           g_Enabled = 0
       else if ( CheckValue(num,MIN_ENABLED,MAX_ENABLED) )
           g_Enabled = num
       else
       {
           ShowConfig(id,0)
           return PLUGIN_HANDLED
       }
       num_to_str(g_Enabled,temp,1)
       set_vaultdata("bbmonster_maxmonsters",temp)
       CheckMania()
       if ( g_Enabled==0 )
       {
           server_cmd("slaymonsters force")
           g_MonsterCount=0
       }
       ShowConfig(id,0)
       return PLUGIN_HANDLED
   }
   public admin_spawn(id,level,cid)
   {
       if ( g_Enabled==0 || !cmd_access(id,level,cid,3) )
           return PLUGIN_HANDLED
       new arg1[32],arg2[32],arg3[32],arg4[32],uName[32]
       read_argv(1,arg1,31)
       read_argv(2,arg2,31)
       read_argv(3,arg3,31)
       read_argv(4,arg4,31)
       if ( equal(arg1,"") || !CheckMonster(arg1) )
       {
           ListMonsters(id)
           return PLUGIN_HANDLED
       }
       if ( g_Spawns[id]>=g_MaxMonsters )
       {
           client_print(id,print_chat,"You   must  wait  a  while  before
   spawning any more monsters")
           return PLUGIN_HANDLED
       }
       if ( g_MonsterCount>=MAX_MONSTER_COUNT )
       {
           client_print(id,print_chat,"There   are  already  the  maximum
   number of monsters in the game")
           return PLUGIN_HANDLED
       }
       if ( arg2[0]=='@' )
       {
           replace(arg2,31,"@","")
           new co1 = str_to_num(arg2)
           new co2 = str_to_num(arg3)
           new co3 = str_to_num(arg4)
           if ( co1>0 && co2>0 && co3>0 )
           {
               get_user_name(id,uName,31)
               show_activity(id,uName,"spawning    a    %s   at   %d   %d
   %d",arg1,co1,co2,co3)
               log_to_file("monster.log","Player  %s  is spawning a %s at
   %d %d %d",uName,arg1,co1,co2,co3)
               server_cmd("monster  model %s tag %d score %d origin %d %d
   %d",arg1,g_NextMonsterID++,g_Score,co1,co2,co3)
           }
       }
       else
       {
           new player,pName[32]
           player = cmd_target(id,arg2,7)
           if ( !player ) return PLUGIN_HANDLED
           get_user_name(player,pName,31)
           get_user_name(id,uName,31)
           show_activity(id,uName,"spawning     a     %s     on    player
   %s",arg1,pName)
           log_to_file("monster.log","Player  %s  is  spawning  a  %s  on
   player %s",uName,arg1,pName)
           server_cmd("monster   model   %s   tag   %d  score  %d  player
   %s",arg1,g_NextMonsterID++,g_Score,pName)
       }
       return PLUGIN_HANDLED
   }
   public admin_timeout(id,level,cid)
   {
       if (!cmd_access(id,level,cid,2))
           return PLUGIN_HANDLED
       new arg[32],num,temp[4]
       read_argv(1,arg,31)
       num = str_to_num(arg)
       if ( CheckValue(num,MIN_TIMEOUT,MAX_TIMEOUT) )
       {
           g_Timeout = float(num)
           remove_task(TIMEOUT_TIMER)
           set_task(g_Timeout,"ResetSpawnCounts",TIMEOUT_TIMER,"",0,"b")
           num_to_str(num,temp,3)
           set_vaultdata("bbmonster_maxmonsters",temp)
       }
       ShowConfig(0,id)
       return PLUGIN_HANDLED
   }
   public admin_maxmonsters(id,level,cid)
   {
       if (!cmd_access(id,level,cid,2))
           return PLUGIN_HANDLED
       new arg[32],num,temp[3]
       read_argv(1,arg,31)
       num = str_to_num(arg)
       if ( CheckValue(num,MIN_MAX_MONSTERS,MAX_MAX_MONSTERS) )
       {
           g_MaxMonsters = num
           num_to_str(num,temp,2)
           set_vaultdata("bbmonster_maxmonsters",temp)
       }
       ShowConfig(0,id)
       return PLUGIN_HANDLED
   }
   public admin_score(id,level,cid)
   {
       if (!cmd_access(id,level,cid,2))
           return PLUGIN_HANDLED
       new arg[32],num,temp[3]
       read_argv(1,arg,31)
       num = str_to_num(arg)
       if ( CheckValue(num,MIN_SCORE,MAX_SCORE) )
       {
           g_Score = num
           num_to_str(num,temp,2)
           set_vaultdata("bbmonster_score",temp)
       }
       ShowConfig(0,id)
       return PLUGIN_HANDLED
   }
   public admin_mania(id,level,cid)
   {
       if (!cmd_access(id,level,cid,2))
           return PLUGIN_HANDLED
       new arg[32],mania,num,temp[2]
       read_argv(1,arg,31)
       num = str_to_num(arg)

       if ( equal(arg,"on") )
           mania = 1
       else if ( equal(arg,"off") )
           mania = 0
       else if ( CheckValue(num,-1,MAX_MANIASCORE) )
           mania = num
       else
       {
           ShowConfig(id,0)
           return PLUGIN_HANDLED
       }
       if ( mania==-1 )
       {
           g_Mania = 1
           g_ManiaScore = 1
       }
       else if ( mania==0 )
       {
           g_Mania = 0
           g_ManiaScore = 0
       }
       else
       {
           g_Mania = 1
           g_ManiaScore = mania
       }
       num_to_str(num,temp,1)
       set_vaultdata("bbmonster_mania",temp)
       num_to_str(mania,temp,1)
       set_vaultdata("bbmonster_maniascore",temp)
       CheckMania()
       ShowConfig(id,0)
       return PLUGIN_HANDLED
   }
   public admin_report(id,level,cid)
   {
       if (!cmd_access(id,level,cid,2))
           return PLUGIN_HANDLED
       new arg[32],num,temp[2]
       read_argv(1,arg,31)
       num = str_to_num(arg)
       if ( equal(arg,"on") )
           g_Report = 1
       else if ( equal(arg,"off") )
           g_Report = 0
       else if ( CheckValue(num,MIN_REPORT,MAX_REPORT) )
           g_Report = num
       else
       {
           ShowConfig(id,1)
           return PLUGIN_HANDLED
       }
       num_to_str(g_Enabled,temp,1)
       set_vaultdata("bbmonster_report",temp)
       ShowConfig(id,0)
       return PLUGIN_HANDLED
   }
   public admin_reset(id,level,cid)
   {
       new temp[4]
       g_Enabled = DEFAULT_ENABLED
       g_MaxMonsters = DEFAULT_MAX_MONSTERS
       g_Timeout = DEFAULT_TIMEOUT
       g_Score = DEFAULT_SCORE
       g_Mania = DEFAULT_MANIA
       g_ManiaScore = DEFAULT_MANIASCORE
       num_to_str(g_MaxMonsters,temp,3)
       set_vaultdata("bbmonster_maxmonsters",temp)
       format(temp,3,"%d",floatround(g_Timeout))
       set_vaultdata("bbmonster_timeout",temp)
       num_to_str(g_Enabled,temp,3)
       set_vaultdata("bbmonster_enabled",temp)
       num_to_str(g_Score,temp,3)
       set_vaultdata("bbmonster_score",temp)
       num_to_str(g_Mania,temp,3)
       set_vaultdata("bbmonster_mania",temp)
       num_to_str(g_ManiaScore,temp,3)
       set_vaultdata("bbmonster_maniascore",temp)
       CheckMania()
       ShowConfig(id,0)
       return PLUGIN_HANDLED
   }
   ShowConfig(id,Force)
   {
       if ( Force==0 && g_Report==0 )
           return PLUGIN_HANDLED
       console_print(id,"Bugblatter Monster configuration:")
       console_print(id,"    -   Monster   spawning   is   currently   %s
   (bbmonster_enabled)",(g_Enabled)?"enabled":"disabled")
       console_print(id,"  -  Each  player  can  spawn  a  maximum  of %d
   monsters (bbmonster_maxmonsters)",g_MaxMonsters)
       console_print(id,"   -  Monster  limit  resets  after  %d  seconds
   (bbmonster_timeout)",floatround(g_Timeout))
       console_print(id,"  - Players score %d frags for killing a monster
   (bbmonster_score)",g_Score)
       if ( g_Mania ) console_print(id," - Monster mania is enabled, with
   %d frags for killing a monster(bbmonster_mania)",g_ManiaScore)
       else    console_print(id,"    -    Monster   mania   is   disabled
   (bbmonster_mania)")
       return PLUGIN_HANDLED
   }
   ReadMonsterList()
   {
       g_MonstersSize = 0
       new len,pos = 0
       new File[64]
       get_cvar_string("monster_precache",File,63)

       if ( !file_exists(File) ) return
       while ( read_file(File,pos++,g_Monsters[g_MonstersSize],31,len) )
       {
           if   (  len  &&  !equal(g_Monsters[g_MonstersSize],"//",2)  &&
   g_MonstersSize<MAX_MAX_MONSTERS )
               ++g_MonstersSize
       }
   }
   public ResetSpawnCounts()
   {
       new i=0
       for(i=0;i<MAX_PLAYERS;i++)
           g_Spawns[i] = 0
   }
   ListMonsters(id)
   {
       new i=0
       console_print(id,"Monsters:")
       for(i=0;i<g_MonstersSize;i++)
           console_print(id,g_Monsters[i])
   }
   bool:CheckMonster(name[])
   {
       new i=0
       for (i=0;i<g_MonstersSize;i++)
       {
           if ( equali(g_Monsters[i],name) )
               return true
       }
       return false
   }
   PickMonster()
   {
       new i
       new tries = 100
       while (tries>0)
       {
           i = random(g_MonstersSize)
           if ( !equali(g_Monsters[i],"apache") )
               return i
           tries--
       }
       return -1
   }
   CheckMania()
   {
       if ( g_Enabled && g_Mania )
       {
           if ( !task_exists(MANIA_TIMER) )
               set_task(50.0+random(20),"ManiaTimer",MANIA_TIMER)
       }
       else if ( task_exists(MANIA_TIMER) )
       {
           remove_task(MANIA_TIMER)
       }
   }
   public ManiaTimer()
   {
       if ( g_ManiaProtected==1 )
       {
           /* If this happens near the start of a round,
           * flag that we tried to spawn, so that when
           * the protectin period ends, the spawn will
           * take place */
           g_ManiaProtected = 2
       }
       else
       {
           ManiaSpawn()
       }
   }
   ManiaSpawn()
   {
       new players[32],chPl[2],num,pName[32]
       get_players(players,num,"ae","CT")
       chPl[0] = players[random(num)]
       get_players(players,num,"ae","TERRORIST")
       chPl[1] = players[random(num)]
       new mon = PickMonster()
       if ( mon==-1 )
       {
           set_task(50.0+random(20),"ManiaTimer",MANIA_TIMER)
           return PLUGIN_HANDLED
       }
       for (new i=0; i<2; i++)
       {
           if ( g_MonsterCount>=MAX_MONSTER_COUNT )
           {
               set_task(50.0+random(20),"ManiaTimer",MANIA_TIMER)
               return PLUGIN_HANDLED
           }
           client_print(0,print_center,"It's   Monster  Mania!  Kill  the
   monsters for %d bonus points",g_ManiaScore)
           get_user_name(chPl[i],pName,31)
           log_to_file("monster.log","Monster  Mania  is spawning a %s on
   player %s",g_Monsters[mon],pName)
           for (new j=0; j<2; j++)
               server_cmd("monster  model  %s  tag  %d  score  %d  player
   %s",g_Monsters[mon],g_NextMonsterID++,g_ManiaScore,pName)
       }
       set_task(50.0+random(20),"ManiaTimer",MANIA_TIMER)
       return PLUGIN_HANDLED
   }
   CheckValue(Value,Min,Max)
   {
       if ( Value<Min || Value>Max)
           return false
       return true
   }
   GetVault(Vault[],Min,Max,Def)
   {
       new temp
       if ( vaultdata_exists(Vault) )
       {
           temp = get_vaultdata(Vault)
           if ( CheckValue(temp,Min,Max) )
               return temp
       }
       return Def
   }
