/*************************************************
 * Decompiled by Serious and Edited by SyndiShanX
 * Script: mp\killstreaks\_uav.gsc
*************************************************/

#using scripts\codescripts\struct;
#using scripts\mp\_util;
#using scripts\mp\gametypes\_globallogic_audio;
#using scripts\mp\killstreaks\_airsupport;
#using scripts\mp\killstreaks\_killstreak_bundles;
#using scripts\mp\killstreaks\_killstreak_detect;
#using scripts\mp\killstreaks\_killstreak_hacking;
#using scripts\mp\killstreaks\_killstreakrules;
#using scripts\mp\killstreaks\_killstreaks;
#using scripts\mp\teams\_teams;
#using scripts\shared\callbacks_shared;
#using scripts\shared\challenges_shared;
#using scripts\shared\clientfield_shared;
#using scripts\shared\damagefeedback_shared;
#using scripts\shared\killstreaks_shared;
#using scripts\shared\math_shared;
#using scripts\shared\scoreevents_shared;
#using scripts\shared\system_shared;
#using scripts\shared\tweakables_shared;
#using scripts\shared\util_shared;
#using scripts\shared\weapons\_heatseekingmissile;
#using scripts\shared\weapons\_weaponobjects;
#namespace uav;

function init() {
  if(level.teambased) {
    foreach(team in level.teams) {
      level.activeuavs[team] = 0;
    }
  } else {
    level.activeuavs = [];
  }
  level.activeplayeruavs = [];
  level.spawneduavs = [];
  if(tweakables::gettweakablevalue("killstreak", "allowradar")) {
    killstreaks::register("uav", "uav", "killstreak_uav", "uav_used", &activateuav);
    killstreaks::register_strings("uav", &"KILLSTREAK_EARNED_RADAR", &"KILLSTREAK_RADAR_NOT_AVAILABLE", &"KILLSTREAK_RADAR_INBOUND", undefined, &"KILLSTREAK_RADAR_HACKED");
    killstreaks::register_dialog("uav", "mpl_killstreak_radar", "uavDialogBundle", "uavPilotDialogBundle", "friendlyUav", "enemyUav", "enemyUavMultiple", "friendlyUavHacked", "enemyUavHacked", "requestUav", "threatUav");
  }
  level thread uavtracker();
  callback::on_connect(&onplayerconnect);
  callback::on_spawned(&onplayerspawned);
  callback::on_joined_team(&onplayerjoinedteam);
  setmatchflag("radar_allies", 0);
  setmatchflag("radar_axis", 0);
}

function hackedprefunction(hacker) {
  uav = self;
  uav resetactiveuav();
}

function configureteampost(owner, ishacked) {
  uav = self;
  uav thread teams::waituntilteamchangesingleton(owner, "UAV_watch_team_change", &onteamchange, owner.entnum, "delete", "death", "leaving");
  if(ishacked == 0) {
    uav teams::hidetosameteam();
  } else {
    uav setvisibletoall();
  }
  owner addactiveuav();
}

function activateuav() {
  assert(isDefined(level.players));
  if(self killstreakrules::iskillstreakallowed("uav", self.team) == 0) {
    return false;
  }
  killstreak_id = self killstreakrules::killstreakstart("uav", self.team);
  if(killstreak_id == -1) {
    return false;
  }
  rotator = level.airsupport_rotator;
  attach_angle = -90;
  uav = spawn("script_model", rotator gettagorigin("tag_origin"));
  if(!isDefined(level.spawneduavs)) {
    level.spawneduavs = [];
  } else if(!isarray(level.spawneduavs)) {
    level.spawneduavs = array(level.spawneduavs);
  }
  level.spawneduavs[level.spawneduavs.size] = uav;
  uav setModel("veh_t7_drone_uav_enemy_vista");
  uav.targetname = "uav";
  uav killstreaks::configure_team("uav", killstreak_id, self, undefined, undefined, &configureteampost);
  uav killstreak_hacking::enable_hacking("uav", &hackedprefunction, undefined);
  uav clientfield::set("enemyvehicle", 1);
  killstreak_detect::killstreaktargetset(uav);
  uav setdrawinfrared(1);
  uav.killstreak_id = killstreak_id;
  uav.leaving = 0;
  uav.health = 99999;
  uav.maxhealth = 700;
  uav.lowhealth = 700 * 0.5;
  uav setCanDamage(1);
  uav thread killstreaks::monitordamage("uav", uav.maxhealth, &destroyuav, uav.lowhealth, &onlowhealth, 0, undefined, 1);
  uav thread heatseekingmissile::missiletarget_proximitydetonateincomingmissile("crashing", undefined, 1);
  uav.rocketdamage = uav.maxhealth + 1;
  minflyheight = int(airsupport::getminimumflyheight());
  zoffset = minflyheight + (isDefined(level.uav_z_offset) ? level.uav_z_offset : 2500);
  angle = randomint(360);
  loc_00000E20:
    radiusoffset = (isDefined(level.uav_rotation_radius) ? level.uav_rotation_radius : 4000) + randomint((isDefined(level.uav_rotation_random_offset) ? level.uav_rotation_random_offset : 1000));
  xoffset = cos(angle) * radiusoffset;
  yoffset = sin(angle) * radiusoffset;
  anglevector = vectornormalize((xoffset, yoffset, zoffset));
  anglevector = anglevector * zoffset;
  uav linkto(rotator, "tag_origin", anglevector, (0, angle + attach_angle, 0));
  self addweaponstat(getweapon("uav"), "used", 1);
  uav thread killstreaks::waitfortimeout("uav", 25000, &ontimeout, "delete", "death", "crashing");
  uav thread killstreaks::waitfortimecheck(25000 / 2, &ontimecheck, "delete", "death", "crashing");
  uav thread startuavfx();
  self killstreaks::play_killstreak_start_dialog("uav", self.team, killstreak_id);
  uav killstreaks::play_pilot_dialog_on_owner("arrive", "uav", killstreak_id);
  uav thread killstreaks::player_killstreak_threat_tracking("uav");
  return true;
}

function onlowhealth(attacker, weapon) {
  self.is_damaged = 1;
  params = level.killstreakbundle["uav"];
  if(isDefined(params.fxlowhealth)) {
    playFXOnTag(params.fxlowhealth, self, "tag_origin");
  }
}

function onteamchange(entnum, event) {
  destroyuav(undefined, undefined);
}

function destroyuav(attacker, weapon) {
  attacker = self[[level.figure_out_attacker]](attacker);
  if(isDefined(attacker) && (!isDefined(self.owner) || self.owner util::isenemyplayer(attacker))) {
    challenges::destroyedaircraft(attacker, weapon, 0);
    scoreevents::processscoreevent("destroyed_uav", attacker, self.owner, weapon);
    luinotifyevent(&"player_callout", 2, &"KILLSTREAK_DESTROYED_UAV", attacker.entnum);
    attacker challenges::addflyswatterstat(weapon, self);
  }
  if(!self.leaving) {
    self removeactiveuav();
    self killstreaks::play_destroyed_dialog_on_owner("uav", self.killstreak_id);
  }
  self notify("crashing");
  self playSound("evt_helicopter_midair_exp");
  params = level.killstreakbundle["uav"];
  if(isDefined(params.ksexplosionfx)) {
    playFXOnTag(params.ksexplosionfx, self, "tag_origin");
  }
  self stoploopsound();
  self setModel("tag_origin");
  target_remove(self);
  self unlink();
  wait(0.5);
  arrayremovevalue(level.spawneduavs, self);
  self notify("delete");
  self delete();
}

function onplayerconnect() {
  self.entnum = self getentitynumber();
  if(!level.teambased) {
    level.activeuavs[self.entnum] = 0;
  }
  level.activeplayeruavs[self.entnum] = 0;
}

function onplayerspawned() {
  self endon("disconnect");
  if(level.teambased == 0 || level.multiteam == 1) {
    level notify("uav_update");
  }
}

function onplayerjoinedteam() {
  hidealluavstosameteam();
}

function ontimeout() {
  playafterburnerfx();
  if(isDefined(self.is_damaged) && self.is_damaged) {
    playFXOnTag("killstreaks/fx_uav_damage_trail", self, "tag_body");
  }
  self killstreaks::play_pilot_dialog_on_owner("timeout", "uav");
  self.leaving = 1;
  self removeactiveuav();
  airsupport::leave(10);
  wait(10);
  target_remove(self);
  arrayremovevalue(level.spawneduavs, self);
  self delete();
}

function ontimecheck() {
  self killstreaks::play_pilot_dialog_on_owner("timecheck", "uav", self.killstreak_id);
}

function startuavfx() {
  self endon("death");
  wait(0.1);
  if(isDefined(self)) {
    playFXOnTag("killstreaks/fx_uav_lights", self, "tag_origin");
    playFXOnTag("killstreaks/fx_uav_bunner", self, "tag_origin");
    self playLoopSound("veh_uav_engine_loop", 1);
  }
}

function playafterburnerfx() {
  self endon("death");
  wait(0.1);
  if(isDefined(self)) {
    playFXOnTag("killstreaks/fx_uav_bunner", self, "tag_origin");
    self stoploopsound();
    team = util::getotherteam(self.team);
    self playsoundtoteam("veh_kls_uav_afterburner", team);
  }
}

function hasuav(team_or_entnum) {
  return level.activeuavs[team_or_entnum] > 0;
}

function addactiveuav() {
  if(level.teambased) {
    assert(isDefined(self.team));
    level.activeuavs[self.team]++;
  } else {
    assert(isDefined(self.entnum));
    if(!isDefined(self.entnum)) {
      self.entnum = self getentitynumber();
    }
    level.activeuavs[self.entnum]++;
  }
  level.activeplayeruavs[self.entnum]++;
  level notify("uav_update");
}

function removeactiveuav() {
  uav = self;
  uav resetactiveuav();
  uav killstreakrules::killstreakstop("uav", self.originalteam, self.killstreak_id);
}

function resetactiveuav() {
  if(level.teambased) {
    level.activeuavs[self.team]--;
    assert(level.activeuavs[self.team] >= 0);
    if(level.activeuavs[self.team] < 0) {
      level.activeuavs[self.team] = 0;
    }
  } else if(isDefined(self.owner)) {
    assert(isDefined(self.owner.entnum));
    if(!isDefined(self.owner.entnum)) {
      self.owner.entnum = self.owner getentitynumber();
    }
    level.activeuavs[self.owner.entnum]--;
    assert(level.activeuavs[self.owner.entnum] >= 0);
    if(level.activeuavs[self.owner.entnum] < 0) {
      level.activeuavs[self.owner.entnum] = 0;
    }
  }
  if(isDefined(self.owner)) {
    level.activeplayeruavs[self.owner.entnum]--;
    assert(level.activeplayeruavs[self.owner.entnum] >= 0);
  }
  level notify("uav_update");
}

function uavtracker() {
  level endon("game_ended");
  while(true) {
    level waittill("uav_update");
    if(level.teambased) {
      foreach(team in level.teams) {
        activeuavs = level.activeuavs[team];
        activeuavsandsatellites = activeuavs + (isDefined(level.activesatellites) ? level.activesatellites[team] : 0);
        setteamspyplane(team, int(min(activeuavs, 2)));
        util::set_team_radar(team, activeuavsandsatellites > 0);
      }
    } else {
      for(i = 0; i < level.players.size; i++) {
        player = level.players[i];
        assert(isDefined(player.entnum));
        if(!isDefined(player.entnum)) {
          player.entnum = player getentitynumber();
        }
        activeuavs = level.activeuavs[player.entnum];
        activeuavsandsatellites = activeuavs + (isDefined(level.activesatellites) ? level.activesatellites[player.entnum] : 0);
        player setclientuivisibilityflag("radar_client", activeuavsandsatellites > 0);
        player.hasspyplane = int(min(activeuavs, 2));
      }
    }
  }
}

function hidealluavstosameteam() {
  foreach(uav in level.spawneduavs) {
    if(isDefined(uav)) {
      uav teams::hidetosameteam();
    }
  }
}