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

#using scripts\codescripts\struct;
#using scripts\mp\_challenges;
#using scripts\mp\_util;
#using scripts\mp\gametypes\_globallogic_audio;
#using scripts\mp\gametypes\_spawning;
#using scripts\mp\killstreaks\_airsupport;
#using scripts\mp\killstreaks\_killstreak_bundles;
#using scripts\mp\killstreaks\_killstreak_hacking;
#using scripts\mp\killstreaks\_killstreakrules;
#using scripts\mp\killstreaks\_killstreaks;
#using scripts\mp\killstreaks\_planemortar;
#using scripts\mp\killstreaks\_satellite;
#using scripts\shared\challenges_shared;
#using scripts\shared\clientfield_shared;
#using scripts\shared\scoreevents_shared;
#using scripts\shared\util_shared;
#using scripts\shared\weapons\_hacker_tool;
#namespace drone_strike;

function init() {
  killstreaks::register("drone_strike", "drone_strike", "killstreak_drone_strike", "drone_strike_used", &activatedronestrike, 1);
  killstreaks::register_strings("drone_strike", &"KILLSTREAK_DRONE_STRIKE_EARNED", &"KILLSTREAK_DRONE_STRIKE_NOT_AVAILABLE", &"KILLSTREAK_DRONE_STRIKE_INBOUND", &"KILLSTREAK_DRONE_STRIKE_INBOUND_NEAR_PLAYER", &"KILLSTREAK_DRONE_STRIKE_HACKED");
  killstreaks::register_dialog("drone_strike", "mpl_killstreak_drone_strike", "droneStrikeDialogBundle", undefined, "friendlyDroneStrike", "enemyDroneStrike", "enemyDroneStrikeMultiple", "friendlyDroneStrikeHacked", "enemyDroneStrikeHacked", "requestDroneStrike", "threatDroneStrike");
  killstreaks::set_team_kill_penalty_scale("drone_strike", level.teamkillreducedpenalty);
}

function activatedronestrike() {
  if(self killstreakrules::iskillstreakallowed("drone_strike", self.team) == 0) {
    return false;
  }
  result = self selectdronestrikepath();
  if(!isDefined(result) || !result) {
    return false;
  }
  return true;
}

function selectdronestrikepath() {
  self beginlocationnapalmselection("map_directional_selector");
  self.selectinglocation = 1;
  self thread airsupport::endselectionthink();
  locations = [];
  if(!isDefined(self.pers["drone_strike_radar_used"]) || !self.pers["drone_strike_radar_used"]) {
    self thread planemortar::singleradarsweep();
  }
  location = self waitforlocationselection();
  if(!isDefined(self)) {
    return 0;
  }
  if(!isDefined(location.origin)) {
    self.pers["drone_strike_radar_used"] = 1;
    self notify("cancel_selection");
    return 0;
  }
  if(self killstreakrules::iskillstreakallowed("drone_strike", self.team) == 0) {
    self.pers["drone_strike_radar_used"] = 1;
    self notify("cancel_selection");
    return 0;
  }
  self.pers["drone_strike_radar_used"] = 0;
  return self airsupport::finishhardpointlocationusage(location, &dronestrikelocationselected);
}

function waitforlocationselection() {
  self endon("emp_jammed");
  self endon("emp_grenaded");
  self waittill("confirm_location", location, yaw);
  locationinfo = spawnStruct();
  locationinfo.origin = location;
  locationinfo.yaw = yaw;
  return locationinfo;
}

function dronestrikelocationselected(location) {
  team = self.team;
  killstreak_id = self killstreakrules::killstreakstart("drone_strike", team, 0, 1);
  if(killstreak_id == -1) {
    return false;
  }
  self killstreaks::play_killstreak_start_dialog("drone_strike", team, killstreak_id);
  self addweaponstat(getweapon("drone_strike"), "used", 1);
  spawn_influencer = level spawning::create_enemy_influencer("artillery", location.origin, team);
  self thread watchforkillstreakend(team, spawn_influencer, killstreak_id);
  self thread startdronestrike(location.origin, location.yaw, team, killstreak_id);
  return true;
}

function watchforkillstreakend(team, influencer, killstreak_id) {
  self util::waittill_any("disconnect", "joined_team", "joined_spectators", "drone_strike_complete", "emp_jammed");
  killstreakrules::killstreakstop("drone_strike", team, killstreak_id);
}

function startdronestrike(position, yaw, team, killstreak_id) {
  self endon("emp_jammed");
  self endon("joined_team");
  self endon("joined_spectators");
  self endon("disconnect");
  angles = (0, yaw, 0);
  direction = anglesToForward(angles);
  height = airsupport::getminimumflyheight() + 3000;
  selectedposition = (position[0], position[1], height);
  startpoint = selectedposition + (vectorscale(direction, -14000));
  endpoint = selectedposition + (vectorscale(direction, -6000));
  tracestartpos = (position[0], position[1], height);
  traceendpos = (position[0], position[1], height * -1);
  trace = bulletTrace(tracestartpos, traceendpos, 0, undefined);
  targetpoint = (trace["fraction"] < 1 ? trace["position"] : (position[0], position[1], 0));
  initialoffset = (vectorscale(direction, ((12 * 0.5) - 1) * 500)) * -1;
  for(i = 0; i < 12; i++) {
    right = anglestoright(angles);
    rightoffset = vectorscale(right, 300);
    leftoffset = vectorscale(right, 900);
    forwardoffset = (endpoint + initialoffset) + (vectorscale(direction, i * 500));
    self thread spawndrone(startpoint + rightoffset, forwardoffset + rightoffset, targetpoint, angles, self.team, killstreak_id);
    self thread spawndrone(startpoint - rightoffset, forwardoffset - rightoffset, targetpoint, angles, self.team, killstreak_id);
    self thread spawndrone(startpoint + leftoffset, forwardoffset + leftoffset, targetpoint, angles, self.team, killstreak_id);
    wait(1);
    self playSound("mpl_thunder_flyover_wash");
  }
  wait(3);
  self notify("drone_strike_complete");
}

function spawndrone(startpoint, endpoint, targetpoint, angles, team, killstreak_id) {
  drone = spawnplane(self, "script_model", startpoint);
  drone.team = team;
  drone.targetname = "drone_strike";
  drone setowner(self);
  drone.owner = self;
  drone.owner thread watchownerevents(drone);
  drone killstreaks::configure_team("drone_strike", killstreak_id, self);
  drone killstreak_hacking::enable_hacking("drone_strike");
  target_set(drone);
  drone endon("delete");
  drone endon("death");
  drone.angles = angles;
  drone setModel("veh_t7_drone_rolling_thunder");
  drone setenemymodel("veh_t7_drone_rolling_thunder");
  drone notsolid();
  playFXOnTag("killstreaks/fx_rolling_thunder_thruster_trails", drone, "tag_fx");
  drone clientfield::set("enemyvehicle", 1);
  drone setupdamagehandling();
  drone thread watchforemp(self);
  drone moveto(endpoint, 1.8, 0, 0);
  wait(1.8);
  weapon = getweapon("drone_strike");
  velocity = drone getvelocity();
  halfgravity = 386;
  dxy = abs(-6000);
  dz = endpoint[2] - targetpoint[2];
  dvxy = dxy * (sqrt(halfgravity / dz));
  nvel = vectornormalize(velocity);
  launchvel = nvel * dvxy;
  bomb = self launchbomb(weapon, drone.origin, launchvel);
  target_set(bomb);
  bomb killstreaks::configure_team("drone_strike", killstreak_id, self);
  bomb killstreak_hacking::enable_hacking("drone_strike");
  drone notify("hackertool_update_ent", bomb);
  bomb clientfield::set("enemyvehicle", 1);
  bomb.targetname = "drone_strike";
  bomb setowner(self);
  bomb.owner = self;
  bomb.team = team;
  bomb playSound("mpl_thunder_incoming_start");
  bomb setupdamagehandling();
  bomb thread watchforemp(self);
  bomb.owner thread watchownerevents(bomb);
  wait(0.05);
  drone hide();
  wait(0.05);
  drone delete();
}

function setupdamagehandling() {
  drone = self;
  drone setCanDamage(1);
  drone.maxhealth = killstreak_bundles::get_max_health("drone_strike");
  drone.lowhealth = killstreak_bundles::get_low_health("drone_strike");
  drone.health = drone.maxhealth;
  drone thread killstreaks::monitordamage("drone_strike", drone.maxhealth, &destroydroneplane, drone.lowhealth, undefined, 0, &empdamagedrone, 1);
}

function destroydroneplane(attacker, weapon) {
  self endon("death");
  attacker = self[[level.figure_out_attacker]](attacker);
  if(isDefined(attacker) && (!isDefined(self.owner) || self.owner util::isenemyplayer(attacker))) {
    challenges::destroyedaircraft(attacker, weapon, 0);
    attacker challenges::addflyswatterstat(weapon, self);
    scoreevents::processscoreevent("destroyed_rolling_thunder_drone", attacker, self.owner, weapon);
    luinotifyevent(&"player_callout", 2, &"KILLSTREAK_DESTROYED_ROLLING_THUNDER_DRONE", attacker.entnum);
  }
  params = level.killstreakbundle["drone_strike"];
  if(isDefined(params.ksexplosionfx)) {
    playFXOnTag(params.ksexplosionfx, self, "tag_origin");
  }
  self setModel("tag_origin");
  wait(0.5);
  self delete();
}

function watchownerevents(bomb) {
  player = self;
  bomb endon("death");
  player util::waittill_any("disconnect", "joined_team", "joined_spectators");
  if(isDefined(isalive(bomb))) {
    bomb delete();
  }
}

function watchforemp(owner) {
  self endon("delete");
  self endon("death");
  self waittill("emp_deployed", attacker);
  thread dronestrikeawardempscoreevent(attacker, self);
  self blowupdronestrike();
}

function empdamagedrone(attacker) {
  thread dronestrikeawardempscoreevent(attacker, self);
  self blowupdronestrike();
}

function dronestrikeawardempscoreevent(attacker, victim) {
  owner = self.owner;
  attacker endon("disconnect");
  attacker notify("dronestrikeawardscoreevent_singleton");
  attacker endon("dronestrikeawardscoreevent_singleton");
  waittillframeend();
  attacker = self[[level.figure_out_attacker]](attacker);
  scoreevents::processscoreevent("destroyed_rolling_thunder_all_drones", attacker, victim, getweapon("emp"));
  challenges::destroyedaircraft(attacker, getweapon("emp"), 0);
  attacker challenges::addflyswatterstat(getweapon("emp"), self);
  luinotifyevent(&"player_callout", 2, &"KILLSTREAK_DESTROYED_ROLLING_THUNDER_ALL_DRONES", attacker.entnum);
  owner globallogic_audio::play_taacom_dialog("destroyed", "drone_strike");
}

function blowupdronestrike() {
  params = level.killstreakbundle["drone_strike"];
  if(isDefined(self) && isDefined(params.ksexplosionfx)) {
    playFX(params.ksexplosionfx, self.origin);
  }
  self delete();
}