/*************************************************
 * Decompiled by Serious and Edited by SyndiShanX
 * Script: cp\doa\_doa_enemy_boss.gsc
*************************************************/

#using scripts\codescripts\struct;
#using scripts\cp\cp_doa_bo3_enemy;
#using scripts\cp\doa\_doa_arena;
#using scripts\cp\doa\_doa_dev;
#using scripts\cp\doa\_doa_enemy;
#using scripts\cp\doa\_doa_fx;
#using scripts\cp\doa\_doa_hazard;
#using scripts\cp\doa\_doa_pickups;
#using scripts\cp\doa\_doa_player_utility;
#using scripts\cp\doa\_doa_round;
#using scripts\cp\doa\_doa_score;
#using scripts\cp\doa\_doa_sfx;
#using scripts\cp\doa\_doa_utility;
#using scripts\shared\clientfield_shared;
#using scripts\shared\flag_shared;
#using scripts\shared\flagsys_shared;
#using scripts\shared\util_shared;
#using_animtree("generic");
#namespace namespace_4973e019;

function init() {
  level.doa.var_55dddb3a = getent("doa_silverback_spawner", "targetname");
  if(isDefined(level.doa.var_55dddb3a)) {
    level thread function_d95d34bd(level.doa.var_55dddb3a);
  }
}

function private function_d95d34bd(spawner) {
  level notify("hash_d95d34bd");
  level endon("hash_d95d34bd");
  while(true) {
    level waittill("hash_31b5dd0d");
    if(!getdvarint("scr_boss_force_spawn", 0)) {
      if(level.doa.round_number < level.doa.rules.var_cd6c242e) {
        continue;
      }
      if(randomint(100) > level.doa.var_4714c375) {
        level.doa.var_4714c375 = level.doa.var_4714c375 + 5;
        continue;
      }
      level.doa.var_4714c375 = level.doa.rules.var_ca8dc008;
      if(isDefined(level.doa.var_c03fe5f1)) {
        if(!namespace_3ca3c537::function_85c94f67(level.doa.var_c03fe5f1)) {
          continue;
        }
      }
    }
    spawn_set = level.doa.arenas[level.doa.current_arena].name + "_enemy_spawn";
    if(level.doa.spawners[spawn_set]["boss"].size == 0) {
      continue;
    }
    loc = level.doa.spawners[spawn_set]["boss"][randomint(level.doa.spawners[spawn_set]["boss"].size)];
    level.doa.boss = namespace_51bd792::function_36aa8b6c(loc);
    if(getdvarint("scr_boss_debug", 0) && isDefined(spawner)) {
      level thread namespace_2f63e553::function_5e6b8376(spawner.origin, 20, 500, (0, 0, 1));
    }
    if(isDefined(level.doa.boss)) {
      level.doa.boss.takedamage = 0;
      level.doa.boss.ignoreall = 1;
      level.doa.boss.ignoreme = 1;
      level.doa.boss.goalradius = 64;
      level.doa.boss.goalheight = 256;
      level.doa.boss thread namespace_eaa992c::function_285a2999("red_shield");
      level.doa.boss thread function_ce73145c();
      level.doa.boss thread function_5bd24aae();
      level.doa.boss thread function_e5e28b1b();
      level.doa.boss thread function_555608c7();
      level.doa.boss.var_f1eeb152 = getclosestpointonnavmesh(level.doa.boss.origin, 512);
      waittillframeend();
      level.doa.boss function_a2756e92();
      if(!isDefined(level.doa.boss)) {
        continue;
      }
      level.doa.boss thread function_2ca4656();
      level.doa.boss thread function_66efd1eb();
    }
    level waittill("exit_taken");
  }
}

function private function_555608c7() {
  self endon("death");
  self.takedamage = 1;
  while(true) {
    self waittill("damage", amount, attacker);
    if(isDefined(attacker) && isPlayer(attacker)) {
      break;
    }
  }
  self thread namespace_1a381543::function_90118d8c("zmb_simianaut_roar");
  self.health = 999999;
  self.takedamage = 0;
  waittillframeend();
  self clearforcedgoal();
  self clearpath();
  self setgoal(self.origin, 1);
  self.var_88168473 = 1;
  if(isDefined(attacker) && isPlayer(attacker)) {
    self.ignoreall = 0;
    self.favoriteenemy = attacker;
    self setentitytarget(attacker);
    self orientmode("face enemy");
  }
  self.anchor = spawn("script_origin", self.origin);
  self.anchor thread doa_utility::function_981c685d(self);
  self.anchor.angles = self.angles;
  self linkto(self.anchor);
  anim_ang = vectortoangles(attacker.origin - self.origin);
  self.anchor rotateto((0, anim_ang[1], 0), 0.5);
  self.anchor waittill("rotatedone");
  self thread namespace_1a381543::function_90118d8c("zmb_simianaut_roar");
  self forceteleport(self.origin, (0, anim_ang[1], 0));
  self unlink();
  self orientmode("face enemy");
  self animscripted("pissedoff", self.origin, self.angles, "ai_zombie_doa_simianaut_ground_pound");
  self waittillmatch("pissedoff");
  playFX(level._effect["ground_pound"], self.origin);
  self waittillmatch("pissedoff");
  self.anchor delete();
  self.var_faa677d7 = gettime() + 10000;
  self thread namespace_1a381543::function_90118d8c("zmb_simianaut_roar");
  self.zombie_move_speed = "run";
  if(isDefined(attacker) && isPlayer(attacker)) {
    self setgoal(attacker.origin, 1);
    self.ignoreall = 0;
    self.favoriteenemy = attacker;
    self waittill("goal");
  }
  self.var_88168473 = undefined;
}

function private function_4e81959(waittime) {
  self endon("death");
  wait(waittime);
  self.zombie_move_speed = "sprint";
}

function private function_a2756e92() {
  self endon("death");
  self notify("hash_d96c599c");
  self thread namespace_1a381543::function_90118d8c("zmb_simianaut_roar");
  self.var_88168473 = 1;
  self.zombie_move_speed = "walk";
  self.var_f4a5c4fe = doa_pickups::function_ac410a13().origin;
  if(isDefined(self.var_f4a5c4fe)) {
    self setgoal(self.var_f4a5c4fe, 1);
  }
  if(getdvarint("scr_boss_debug", 0)) {
    level thread namespace_2f63e553::function_5e6b8376(self.var_f4a5c4fe, 128, 0.5, (1, 0, 0));
  }
  self util::waittill_any_timeout(14, "goal", "damage", "death");
  self.var_88168473 = undefined;
  self.zombie_move_speed = "run";
  self thread function_4e81959(20);
}

function function_ce73145c() {
  trigger = spawn("trigger_radius", self.origin, 2, 32, 50);
  trigger.targetname = "_doaBossDamageShield";
  trigger enablelinkto();
  trigger linkto(self, "tag_origin");
  trigger endon("death");
  trigger thread doa_utility::function_783519c1("exit_taken", 1);
  trigger thread doa_utility::function_981c685d(self);
  trigger.silverback = 1;
  while(isDefined(self)) {
    trigger waittill("trigger", guy);
    if(!isDefined(guy)) {
      continue;
    }
    if(isDefined(level.var_a7749866)) {
      continue;
    }
    if(isDefined(self)) {
      if(!isPlayer(guy)) {
        self animscripted("pissedoff", self.origin, self.angles, "ai_zombie_doa_simianaut_attack_v1");
        self waittillmatch("pissedoff");
        if(isDefined(guy)) {
          playFX(level._effect["ground_pound"], guy.origin);
          if(isDefined(guy)) {
            guy dodamage(guy.health + 107, self.origin, undefined, undefined, "MOD_EXPLOSIVE");
          }
        }
        continue;
      }
      if(!isDefined(guy.doa)) {
        continue;
      }
      if(isDefined(guy.doa.var_1db1e638) && gettime() < guy.doa.var_1db1e638) {
        continue;
      }
      guy dodamage(666, guy.origin, self, self);
      if(isDefined(guy.doa)) {
        guy.doa.var_1db1e638 = gettime() + 10000;
        self animscripted("pissedoff", self.origin, self.angles, "ai_zombie_doa_simianaut_chestbeat");
        self waittillmatch("pissedoff");
      }
    }
  }
}

function private function_66efd1eb() {
  self endon("death");
  self endon("hash_19503b17");
  while(isDefined(self)) {
    wait(0.05);
    if(isDefined(self.var_faa677d7)) {
      if(gettime() < self.var_faa677d7) {
        continue;
      }
    }
    self.ignoreall = 1;
    self.favoriteenemy = undefined;
    self clearentitytarget();
    if(isDefined(level.hostmigrationtimer) && level.hostmigrationtimer) {
      continue;
    }
    allies = arraycombine(getaiteamarray("allies"), namespace_831a4a7c::function_5eb6e4d1(), 0, 0);
    for(i = 0; i < allies.size; i++) {
      player = allies[i];
      if(!isDefined(player) || !isalive(player)) {
        continue;
      }
      if(isPlayer(player) && isDefined(player.doa.var_1db1e638) && gettime() < player.doa.var_1db1e638) {
        continue;
      }
      if(isPlayer(player) && (isDefined(player.doa.respawning) && player.doa.respawning)) {
        continue;
      }
      if(isDefined(player.vehicle)) {
        continue;
      }
      distsq = distancesquared(self.origin, player.origin);
      if(distsq <= (128 * 128)) {
        self.ignoreall = 0;
        if(getdvarint("scr_boss_debug", 0)) {
          level thread namespace_2f63e553::function_5e6b8376(self.origin, 100, 0.5, (1, 0, 0));
        }
        wait(0.5);
        break;
      }
    }
    if(getdvarint("scr_boss_debug", 0)) {
      level thread namespace_2f63e553::function_5e6b8376(self.origin, 128, 500, (1, 0.8, 0.8));
      level thread namespace_2f63e553::function_5e6b8376(self.origin, 32, 0.05, (0, 1, 0));
    }
  }
}

function private function_5bd24aae() {
  self endon("death");
  level waittill("exit_taken");
  level notify("hash_48b870e4");
  level.doa.boss = undefined;
  level doa_utility::function_d0e32ad0(1);
  self delete();
}

function private function_2ca4656() {
  self endon("death");
  wait(0.1);
  timeout = gettime() + 10000;
  while(isDefined(self.var_88168473) && self.var_88168473 && gettime() < timeout) {
    wait(0.05);
  }
  tries = 5;
  failed = 0;
  while(tries) {
    wait(0.05);
    if(self.ignoreall == 0) {
      wait(1);
      tries--;
      continue;
    }
    if(failed) {
      tries--;
    }
    items = getEntArray("a_pickup_item", "script_noteworthy");
    pickupsitems = [];
    foreach(item in items) {
      if(!isDefined(item)) {
        continue;
      }
      if(isDefined(item.unreachable) && item.unreachable) {
        continue;
      }
      pickupsitems[pickupsitems.size] = item;
    }
    if(failed && pickupsitems.size > 0) {
      target = pickupsitems[randomint(pickupsitems.size)];
    } else {
      target = self doa_utility::getclosesttome(pickupsitems);
    }
    failed = 0;
    if(isDefined(target)) {
      spot = getclosestpointonnavmesh(target.origin, 512, 36);
      if(isDefined(spot) && self findpath(self.origin, spot, 1, 0)) {
        self.var_f4a5c4fe = spot;
        self setgoal(self.var_f4a5c4fe, 1);
        if(getdvarint("scr_boss_debug", 0)) {
          level thread namespace_2f63e553::function_5e6b8376(target.origin, 32, 500, (1, 1, 0));
        }
        self util::waittill_any_timeout(10, "goal", "death");
        self.var_f4a5c4fe = undefined;
        if(isDefined(target)) {
          target.unreachable = 1;
        }
      } else {
        failed = 1;
      }
    } else {
      failed = 1;
    }
  }
  self notify("hash_19503b17");
  self.var_88168473 = 1;
  self.zombie_move_speed = "sprint";
  self.ignoreall = 1;
  self.favoriteenemy = undefined;
  self clearentitytarget();
  self.var_f4a5c4fe = self.var_f1eeb152;
  tries = 0;
  while(isDefined(self.var_f4a5c4fe) && self findpath(self.origin, self.var_f4a5c4fe, 1, 0)) {
    distsq = distancesquared(self.origin, self.var_f1eeb152);
    if(distsq > 64 || tries > 9) {
      self setgoal(self.var_f4a5c4fe, 1);
      self waittill("goal");
      self.var_f4a5c4fe = self.var_f1eeb152;
      tries++;
    } else {
      break;
    }
  }
  if(isDefined(self.var_f1eeb152)) {
    distsq = distancesquared(self.origin, self.var_f1eeb152);
  }
  if(!isDefined(distsq) || distsq > 64) {
    org = spawn("script_model", self.origin);
    org thread doa_utility::function_981c685d(self);
    org.targetname = "_doaBossCollectPickups";
    org setModel("tag_origin");
    self linkto(org, "tag_origin");
    org thread namespace_eaa992c::function_285a2999("boss_takeoff");
    spot = self.origin + vectorscale((0, 0, 1), 2000);
    org thread doa_utility::function_a98c85b2(spot, 0.8);
    self util::waittill_any_timeout(2, "movedone", "death");
    org delete();
  }
  if(isDefined(level.doa.var_2836c8ee) && level.doa.var_2836c8ee) {
    self thread namespace_eaa992c::function_285a2999("spawnZombie");
    wait(1);
  }
  self delete();
}

function private function_e5e28b1b() {
  self endon("death");
  while(true) {
    pickupsitems = getEntArray("a_pickup_item", "script_noteworthy");
    for(i = 0; i < pickupsitems.size; i++) {
      pickup = pickupsitems[i];
      if(isDefined(pickup)) {
        distsq = distancesquared(self.origin, pickup.origin);
        if(distsq < (72 * 72)) {
          pickup thread doa_pickups::function_6b4a5f81();
        }
      }
    }
    wait(0.1);
  }
}

function function_76b30cc1() {
  self endon("death");
  amount = int(self.health * 0.15);
  while(self.health > 0) {
    wait(3);
    self notify("damage", amount);
  }
}