#include "upgrade_system"




///////index0 = allow in wave
///////index1 = index list squad enemies
///////index2 = spawn location type
///////index3 = count as midboss


array<string>@ mm_start_wave = {

"mm_wave1",
"mm_wave2",
"mm_wave3",
"mm_wave4",
"mm_wave5",
"mm_wave6",
"mm_wave7",
"mm_wave8"

};










///////index0 = ent name
///////index1 = model
///////index2 = body
///////index3 = skin
///////index4 = sound
///////index5 = display name
///////index6 = is ally
///////index7 = hp
///////index8 = score

array<array<string>>@ list_enemies = {


{"monster_zombie",  "models/hunger/hungerzombie.mdl", "0", "0", "../hunger/hungerzombie.txt", "Hunger Zombie", "0", "100", "1" },
{"monster_zombie",  "models/hunger/hungerzombie.mdl", "1", "0", "", "Hunger Zombie", "0", "100", "1" },
{"monster_zombie",  "models/hunger/hungerzombie.mdl", "2", "0", "../hunger/hungerzombie.txt", "Hunger Zombie", "0", "100", "1" },
{"monster_zombie",  "models/hunger/hungerzombie.mdl", "3", "0", "", "Hunger Zombie", "0", "100", "1" },
{"monster_zombie",  "models/hunger/hungerzombie.mdl", "4", "0", "../hunger/hungerzombie.txt", "Hunger Zombie", "0", "100", "1" },
{"monster_zombie",  "models/hunger/hungerzombie.mdl", "5", "0", "../hunger/hungerzombiefem.txt", "Hunger Zombie", "0", "100", "1" },
{"monster_zombie",  "models/hunger/hungerzombie.mdl", "6", "0", "../hunger/hungerzombie.txt", "Hunger Zombie", "0", "100", "1" },
{"monster_zombie",  "models/hunger/hungerzombie.mdl", "7", "0", "../hunger/hungerzombie.txt", "Hunger Zombie", "0", "100", "1" },
{"monster_zombie",  "models/hunger/hungerzombie.mdl", "8", "0", "../hunger/hungerzombie.txt", "Hunger Zombie", "0", "100", "1" },
{"monster_zombie",  "models/hunger/hungerzombie.mdl", "9", "0", "../hunger/hungerzombie.txt", "Hunger Zombie", "0", "100", "1" },
{"monster_zombie",  "models/hunger/hungerzombie.mdl", "10", "0", "../hunger/hungerzombie.txt", "Hunger Zombie", "0", "100", "1" },
{"monster_zombie",  "models/hunger/nursezombie.mdl", "0", "0", "../hunger/hungerzombiefem.txt", "Hunger Zombie", "0", "100", "1" },

{"monster_zombie_soldier",  "models/hunger/zombie2.mdl", "0", "0", "", "Hunger Zombie", "0", "100", "2" },
{"monster_zombie_soldier",  "models/hunger/zombie2.mdl", "1", "0", "../hunger/hungerzombie.txt", "Hunger Zombie", "0", "100", "2" },
{"monster_zombie_soldier",  "models/hunger/zombie2.mdl", "2", "0", "../hunger/hungerzombie.txt", "Hunger Zombie", "0", "100", "2" },
{"monster_zombie_soldier",  "models/hunger/zombie2.mdl", "3", "0", "../hunger/hungerzombie.txt", "Hunger Zombie", "0", "100", "2" },
{"monster_zombie_soldier",  "models/hunger/zombie2.mdl", "4", "0", "../hunger/hungerzombie.txt", "Hunger Zombie", "0", "100", "2" },
{"monster_zombie_soldier",  "models/hunger/zombie2.mdl", "5", "0", "", "Hunger Zombie", "0", "100", "2" },

{"monster_zombie_soldier",  "models/hunger/zombie3.mdl", "0", "0", "../hunger/hungerzombie.txt", "Hunger Zombie", "0", "100", "2" },
{"monster_zombie_soldier",  "models/hunger/zombie3.mdl", "1", "0", "../hunger/hungerzombiefem.txt", "Hunger Zombie", "0", "100", "2" },
{"monster_zombie_soldier",  "models/hunger/zombie3.mdl", "2", "0", "../hunger/hungerzombie.txt", "Hunger Zombie", "0", "100", "2" },
{"monster_zombie_soldier",  "models/hunger/zombie3.mdl", "3", "0", "../hunger/hungerzombie.txt", "Hunger Zombie", "0", "100", "2" },






{"monster_headcrab",  "models/hunger/hungercrab.mdl", "0", "0", "../hunger/hungercrab.txt", "Spider Head", "0", "20", "2" },
{"monster_headcrab",  "models/hunger/hungercrab.mdl", "1", "0", "../hunger/hungercrab.txt", "Spider Head", "0", "20", "2" },
{"monster_headcrab",  "models/hunger/hungercrab.mdl", "2", "0", "../hunger/hungercrab.txt", "Spider Head", "0", "20", "2" },
{"monster_headcrab",  "models/hunger/hungercrab.mdl", "3", "0", "../hunger/hungercrab.txt", "Spider Head", "0", "20", "2" },
{"monster_headcrab",  "models/hunger/hungercrab.mdl", "4", "0", "../hunger/hungercrab.txt", "Spider Head", "0", "20", "2" },
{"monster_headcrab",  "models/hunger/hungercrab.mdl", "5", "0", "../hunger/hungercrab.txt", "Spider Head", "0", "20", "2" },
{"monster_headcrab",  "models/hunger/hungercrab.mdl", "6", "0", "../hunger/hungercrab.txt", "Spider Head", "0", "20", "2" },


{"monster_headcrab",  "models/hunger/chicken.mdl", "0", "0", "../hunger/hungerchicken.txt", "Zombie Chicken", "0", "20", "1" }



};


array<array<string>>@ list_enemies_rare = {

{"monster_zombie_barney",  "models/hunger/zombie3.mdl", "4", "0", "../hunger/hungerzombie.txt", "Big Hunger Zombie", "0", "500", "15" },////0 <w1>
{"monster_zombie",  "models/hunger/hungerhound.mdl", "0", "0", "../hunger/hungerhound.txt", "Zombie Dog", "0", "100", "5" }, ////1 <w2>
{"monster_headcrab",  "models/hunger/thehand.mdl", "0", "0", "", "Living Hand", "0", "20", "10" }, ////2 <w3>
{"monster_bullchicken",  "models/hunger/bullsquid.mdl", "0", "0", "", "Zombie Lizard", "0", "200", "20" }, ////3 <w3>
{"monster_alien_grunt",  "models/hunger/zork.mdl", "0", "0", "../hunger/hungerzork.txt", "Zombie Brute", "0", "300", "50" }, ////4 <w4>
{"monster_gonome",  "models/hunger/hungergonome.mdl", "0", "0", "", "Zombie Berserker", "0", "200", "50" }, ////5 <w5>
{"monster_bullchicken",  "models/hunger/zombiebull.mdl", "0", "0", "../hunger/hungerbull.txt", "Zombie Bull", "0", "300", "75" }, ////6 <w6>
{"monster_alien_slave",  "models/hunger/hungerslave.mdl", "0", "0", "../hunger/hungerslave.txt", "Undead Skeleton", "0", "100", "25" }, ////7 <w6>
{"monster_barney",  "models/hunger/hungerbarney.mdl", "0", "1", "../hunger/hungerbarney.txt", "Zombie Police", "1", "50", "50" }, ////8 <w7>
{"monster_otis",  "models/hunger/hungerotis.mdl", "0", "0", "", "Zombie Officer", "1", "50", "100" }, ////9 <w8>
{"monster_human_grunt",  "models/hunger/zgrunt.mdl", "0", "0", "../hunger/hungerzombiesoldier.txt", "Zombie Military", "0", "200", "150" }   ////10 <w8>


};

array<int>@ max_roll_rare_enemies = {

0, 1, 3, 4, 5, 7, 8, 10

};




int CURRENT_WAVE = 0;
int MAX_WAVE = 8;
int REMAIN_ENEMY = 0;
////int COUNT_DEAD_ENEMIES = 0;

int MAX_ROLL_SQUAD = 4;
int MIDBOSS_COOLDOWN_COUNT = 0;
int MIDBOSS_COOLDOWN_COUNT_ASSIGN = 5;
int MAX_CHANCE_RARE_ENEMY = 10;
int MAX_RARE_ENEMY_ROLL = 1;

float CURRENT_HP_MULTIPIER = 0;
float BASE_HP_MULTIPIER = 0.8;
float HP_MULTIPIER_PER_PLAYERS = 0.2;


int BASE_MAX_ENEMIES_ACTIVE = 15;
int LIMITED_MAX_ENEMIES_ACTIVE = 150;
int CURRENT_MAX_ENEMIES_ACTIVE = 0;
int CURRENT_ENEMIES_ACTIVE = 0;
int ADD_MAX_ENEMIES_PER_PLAYER = 2;
float MULTIPIER_MAX_ENEMIES_PER_WAVE = 0.2;


float TOTAL_ENEMIES_PER_PLAYERS = 0.25;
int CURRENT_TOTAL_ENEMIES = 0;
int CURRENT_ENEMIES_QUOTA = 0;

int MAX_WAVE_TIME = 300;
int CURRENT_WAVE_TIME = 0;
int MAX_BREAK_TIME = 120;
int CURRENT_BREAK_TIME = 0;

float BASE_DMG_TAKEN = 0.2;
float DMG_TAKEN_INCREASE_PER_PLAYER = 0.05;
float MAX_DMG_TAKEN = 1.0;

float CURRENT_POINT_PER_PLAYER = 1;
float POINT_MULT_PER_PLAYER = 0.15;


int CURRENT_PLAYERS = 0;
int TEAM_RESPAWN_TIME = 60;
int MAX_TEAM_RES_TIME = 60;

bool ENABLE_BUYING_ROOM = true;
bool ALLOW_DISPLAY_TEATIME = false;
bool IS_BOSS_WAVE = false;
bool TIMER_Z_SPAWN = false;


HUDTextParams FORMAT_TEXT_INTERVAL;

HUDTextParams FORMAT_TEXT_TEATIME_INTERVAL;

void event_manual_wave(CBaseEntity@ activator, CBaseEntity@ pcaller, USE_TYPE usetype, float flValue)
{

            CBaseEntity@ mapcommand = null;
            @mapcommand = g_EntityFuncs.FindEntityByTargetname(mapcommand, "targ_map_command");

            CURRENT_WAVE_TIME = MAX_WAVE_TIME;

            string GET_NEXT_WAVE = mm_start_wave[CURRENT_WAVE];

            g_EntityFuncs.FireTargets(GET_NEXT_WAVE, mapcommand, mapcommand, USE_SET);


}









void event_spawn_wave_enemies()
{

   if(TIMER_Z_SPAWN)
     {

          if(CURRENT_ENEMIES_ACTIVE <= CURRENT_MAX_ENEMIES_ACTIVE)
            {


                   CBaseEntity@ spawn_enemy1;

                   CBaseEntity@ location_enemy1;

                   CBaseEntity@ map_command;



                  int zombie_random_location = Math.RandomLong( 1, 55 );
                  string ZOMBIE_SPAWN_LOCATION = "z_spawn_" + zombie_random_location;

                  

                  ////int RANDOM_ENEMY1 = Math.RandomLong( 0, list_enemy_human.length() - 1 );

                  ////MAX_ROLL_SQUAD = max_roll_squad_per_wave[CURRENT_WAVE -1];

                  ////int RANDOM_SQUAD = Math.RandomLong( 0, MAX_ROLL_SQUAD);

                  ////array<int>@ CHOSEN_SQUAD = list_squad_enemies[RANDOM_SQUAD];

                  ////int CHOSEN_ENEMY_MEMBER1 = CHOSEN_SQUAD[0];



                  int CHANCE_SPAWN_RARE = Math.RandomLong( 0, 100 );
                  int CURRENT_ROLL_ENEMY = Math.RandomLong( 0, list_enemies.length() - 1 );
                  array<array<string>> CHOSEN_ENEMY_TYPE = list_enemies;
                  if(CHANCE_SPAWN_RARE < MAX_CHANCE_RARE_ENEMY)
                    {
                         CHOSEN_ENEMY_TYPE = list_enemies_rare;
                         MAX_RARE_ENEMY_ROLL = max_roll_rare_enemies[CURRENT_WAVE - 1];
                         CURRENT_ROLL_ENEMY = Math.RandomLong ( 0 , MAX_RARE_ENEMY_ROLL);
                         
                         ////g_PlayerFuncs.ShowMessageAll(CURRENT_ROLL_ENEMY);

                    }



                  array<string>@ CHOSEN_ENEMY1 = CHOSEN_ENEMY_TYPE[CURRENT_ROLL_ENEMY];

                  string ENEMYCLASS1 = CHOSEN_ENEMY1[0];
                  string ENEMYNAME1 = CHOSEN_ENEMY1[5];
                  string ENEMYMODEL1 = CHOSEN_ENEMY1[1];
                  string ENEMYSOUND1 = CHOSEN_ENEMY1[4];
                  string ENEMYIFALLY1 = CHOSEN_ENEMY1[6];
                  string ENEMYHEALTH1 = CHOSEN_ENEMY1[7];
                  string ENEMYBODY1 = CHOSEN_ENEMY1[2];
                  string ENEMYSKIN1 = CHOSEN_ENEMY1[3];
                  string ENEMYSCORE1 = CHOSEN_ENEMY1[8];
                  float ENEMYHEALTH_TO_INT1 = atoi(ENEMYHEALTH1);
                  int ENEMYHEALTH_CALCULATED1 = (ENEMYHEALTH_TO_INT1 * CURRENT_HP_MULTIPIER);

                  float GET_POINT_MULT_ABS = (CURRENT_POINT_PER_PLAYER + 1);
                  float CONVERT_SCORE_TO_F = atoi(ENEMYSCORE1);
                  int ENEMYSCORE_CALCULATED1 = (CONVERT_SCORE_TO_F * GET_POINT_MULT_ABS);

                  int RANDOM_MONSTER_YAW1 = Math.RandomLong(0, 350);
        
                  @location_enemy1 = g_EntityFuncs.FindEntityByTargetname(location_enemy1, ZOMBIE_SPAWN_LOCATION);

                  dictionary keys1;
                  Vector origin1;
                  Vector angles1;
                  origin1 = location_enemy1.pev.origin;
                  angles1 = location_enemy1.pev.angles;

                  keys1["origin"] = "" + origin1.x + " " + origin1.y + " " + origin1.z;
                  keys1["angles"] = "" + angles1.x + " " + angles1.y + " " + angles1.z;
                  keys1["model"] = string(ENEMYMODEL1);
                  keys1["body"] = string(ENEMYBODY1);
                  keys1["skin"] = string(ENEMYSKIN1);
                  keys1["displayname"] = string(ENEMYNAME1);
                  keys1["is_player_ally"] =  string(ENEMYIFALLY1);
                  keys1["classify"]  =  string("5");
                  keys1["bloodcolor"] = string("1");
                  keys1["health"] = string(ENEMYHEALTH_CALCULATED1);
                  keys1["soundlist"] = string(ENEMYSOUND1);
                  keys1["TriggerCondition"] = string("4");
                  keys1["TriggerTarget"] = string("sc_cut_active_enemy");
                  keys1["renderamt"] = string(ENEMYSCORE_CALCULATED1);



                  @spawn_enemy1 = g_EntityFuncs.CreateEntity(ENEMYCLASS1, keys1, true);

                  CURRENT_ENEMIES_ACTIVE += 1;
                  CURRENT_ENEMIES_QUOTA -= 1;


                  string TEST_MSG = string(CURRENT_ENEMIES_ACTIVE);

                  ////g_PlayerFuncs.ShowMessageAll(TEST_MSG);

              }    








   }
}




void event_wave_apply(CBaseEntity@ activator, CBaseEntity@ pcaller, USE_TYPE usetype, float flValue)
{

         CURRENT_WAVE += 1;

        
          int GET_NUMBER_OF_PLAYER = g_PlayerFuncs.GetNumPlayers();
          ////int GET_NUMBER_OF_PLAYER = 32;

          

          float CALCULATED_PLAYER_FOR_HP_MULT = (GET_NUMBER_OF_PLAYER * HP_MULTIPIER_PER_PLAYERS);
          CURRENT_HP_MULTIPIER = BASE_HP_MULTIPIER + CALCULATED_PLAYER_FOR_HP_MULT;
        
          float GET_MAX_ACTIVE_PER_WAVE =  ((MULTIPIER_MAX_ENEMIES_PER_WAVE * CURRENT_WAVE) + 1);
          int GET_MAX_ACTIVE_WITH_PLAYER = (GET_NUMBER_OF_PLAYER * ADD_MAX_ENEMIES_PER_PLAYER);
       
          int CALCULATED_MAX_ACTIVE_WITH_PLAYER = (BASE_MAX_ENEMIES_ACTIVE + GET_MAX_ACTIVE_WITH_PLAYER);
          int CALCULATED_MAX_ACTIVE_WITH_WAVE = (GET_MAX_ACTIVE_PER_WAVE * CALCULATED_MAX_ACTIVE_WITH_PLAYER);
          CURRENT_MAX_ENEMIES_ACTIVE = CALCULATED_MAX_ACTIVE_WITH_WAVE; 
        
          if(CURRENT_MAX_ENEMIES_ACTIVE > LIMITED_MAX_ENEMIES_ACTIVE)
             {
                   CURRENT_MAX_ENEMIES_ACTIVE = LIMITED_MAX_ENEMIES_ACTIVE;
             }

          CURRENT_POINT_PER_PLAYER = (POINT_MULT_PER_PLAYER * GET_NUMBER_OF_PLAYER);



          ALLOW_DISPLAY_TEATIME = false;
          TIMER_Z_SPAWN = true;


          ////g_PlayerFuncs.ShowMessageAll(GET_MAX_ACTIVE_PER_WAVE);


}



void event_cut_active_enemy(CBaseEntity@ activator, CBaseEntity@ pcaller, USE_TYPE usetype, float flValue)
{

           CURRENT_ENEMIES_ACTIVE -= 1;
           CURRENT_TOTAL_ENEMIES  -= 1;
           
           ////CBaseEntity@ dead_zombie = g_PlayerFuncs.FindPlayerByName(activator.pev.netname, false);
           int SCORE_FROM_Z = activator.pev.renderamt;
           SCORE_POINT += SCORE_FROM_Z;

}


void event_break_time()
{

           CURRENT_BREAK_TIME = MAX_BREAK_TIME;
           ALLOW_DISPLAY_TEATIME = true;

        
           CBaseEntity@ mapcommand = null;
           @mapcommand = g_EntityFuncs.FindEntityByTargetname(mapcommand, "targ_map_command");


           TIMER_Z_SPAWN = false;

           if(CURRENT_WAVE >= 8)
           {
              g_EntityFuncs.FireTargets("mm_game_end", mapcommand, mapcommand, USE_SET);

           }

}

void tick_display_wave()
{

                  FORMAT_TEXT_INTERVAL.x = 0.025;
	          FORMAT_TEXT_INTERVAL.y = 0.05;
	          FORMAT_TEXT_INTERVAL.channel = 2;
	          FORMAT_TEXT_INTERVAL.fadeinTime = 0;
	          FORMAT_TEXT_INTERVAL.r1 = 255;
	          FORMAT_TEXT_INTERVAL.g1 = 255;
	          FORMAT_TEXT_INTERVAL.b1 = 255;
	          FORMAT_TEXT_INTERVAL.a1 = 200;
	          FORMAT_TEXT_INTERVAL.holdTime = 2;



                  FORMAT_TEXT_TEATIME_INTERVAL.x = -1;
	          FORMAT_TEXT_TEATIME_INTERVAL.y = 0.25;
	          FORMAT_TEXT_TEATIME_INTERVAL.channel = 3;
	         FORMAT_TEXT_TEATIME_INTERVAL.fadeinTime = 0;
	         FORMAT_TEXT_TEATIME_INTERVAL.r1 = 255;
	          FORMAT_TEXT_TEATIME_INTERVAL.g1 = 255;
	          FORMAT_TEXT_TEATIME_INTERVAL.b1 = 255;
	          FORMAT_TEXT_TEATIME_INTERVAL.a1 = 200;
	          FORMAT_TEXT_TEATIME_INTERVAL.holdTime = 2;



                  TEAM_RESPAWN_TIME -= 1;
                  if (TEAM_RESPAWN_TIME < 0)
                  {
                            TEAM_RESPAWN_TIME = MAX_TEAM_RES_TIME;
                            CBaseEntity@ mapcommand = null;
                            @mapcommand = g_EntityFuncs.FindEntityByTargetname(mapcommand, "targ_map_command");
                            g_EntityFuncs.FireTargets("res_team", mapcommand, mapcommand, USE_SET);
                            g_EntityFuncs.FireTargets("sp_grunt", mapcommand, mapcommand, USE_SET);

                  }

                  CURRENT_WAVE_TIME -=1;
                  if (CURRENT_WAVE_TIME < 0)
                  {

                     CURRENT_WAVE_TIME = 0;


                         if(CURRENT_WAVE > 0)
                           {
                                 if(!ALLOW_DISPLAY_TEATIME)
                                    {
                                       event_break_time();
                                    }
                           }
                  }




                  g_PlayerFuncs.HudMessageAll(FORMAT_TEXT_INTERVAL, "Wave: " + CURRENT_WAVE + "/" + MAX_WAVE + "\n" + "Wave Time: " + CURRENT_WAVE_TIME + "\n" + "Back Up: " + TEAM_RESPAWN_TIME + "\n" + "Point: " + SCORE_POINT);




                  


                if(ALLOW_DISPLAY_TEATIME)
                  {

                        CURRENT_BREAK_TIME -= 1;

                        if(CURRENT_WAVE < 8)
                         {
                               g_PlayerFuncs.HudMessageAll(FORMAT_TEXT_TEATIME_INTERVAL, "Next Wave Start In:" + "\n" + CURRENT_BREAK_TIME + "s");
                         }

                        if(CURRENT_BREAK_TIME <= 0)
                          {
                                 
                                 CBaseEntity@ mapcommand = null;
                                 @mapcommand = g_EntityFuncs.FindEntityByTargetname(mapcommand, "targ_map_command");
                           
                                 CURRENT_WAVE_TIME = MAX_WAVE_TIME;


                                 string GET_NEXT_WAVE = mm_start_wave[CURRENT_WAVE];

                                  g_EntityFuncs.FireTargets(GET_NEXT_WAVE, mapcommand, mapcommand, USE_SET);
                                  


                          }

                  }



}

