/*************************************************
 * Decompiled by Serious and Edited by SyndiShanX
 * Script: mp\killstreaks\_qrdrone.csc
*************************************************/

#using scripts\codescripts\struct;
#using scripts\mp\_util;
#using scripts\mp\_vehicle;
#using scripts\shared\clientfield_shared;
#using scripts\shared\system_shared;
#using scripts\shared\util_shared;
#using scripts\shared\vehicle_shared;
#namespace qrdrone;

function autoexec __init__sytem__() {
  system::register("qrdrone", &__init__, undefined, undefined);
}

function __init__() {
  type = "qrdrone_mp";
  clientfield::register("helicopter", "qrdrone_state", 1, 3, "int", &statechange, 0, 0);
  clientfield::register("vehicle", "qrdrone_state", 1, 3, "int", &statechange, 0, 0);
  level._effect["qrdrone_enemy_light"] = "killstreaks/fx_drgnfire_light_red_3p";
  level._effect["qrdrone_friendly_light"] = "killstreaks/fx_drgnfire_light_green_3p";
  level._effect["qrdrone_viewmodel_light"] = "killstreaks/fx_drgnfire_light_green_1p";
  clientfield::register("helicopter", "qrdrone_countdown", 1, 1, "int", &start_blink, 0, 0);
  clientfield::register("helicopter", "qrdrone_timeout", 1, 1, "int", &final_blink, 0, 0);
  clientfield::register("vehicle", "qrdrone_countdown", 1, 1, "int", &start_blink, 0, 0);
  clientfield::register("vehicle", "qrdrone_timeout", 1, 1, "int", &final_blink, 0, 0);
  clientfield::register("vehicle", "qrdrone_out_of_range", 1, 1, "int", &out_of_range_update, 0, 0);
  vehicle::add_vehicletype_callback("qrdrone_mp", &spawned);
}

function spawned(localclientnum) {
  self util::waittill_dobj(localclientnum);
  self thread restartfx(localclientnum, 0);
  self thread collisionhandler(localclientnum);
  self thread enginestutterhandler(localclientnum);
  self thread qrdrone_watch_distance();
}

function statechange(localclientnum, oldval, newval, bnewent, binitialsnap, fieldname, bwastimejump) {
  self endon("entityshutdown");
  self util::waittill_dobj(localclientnum);
  self restartfx(localclientnum, newval);
}

function restartfx(localclientnum, blinkstage) {
  self notify("restart_fx");
  println("" + blinkstage);
  switch (blinkstage) {
    case 0: {
      self spawn_solid_fx(localclientnum);
      break;
    }
    case 1: {
      self.fx_interval = 1;
      self spawn_blinking_fx(localclientnum);
      break;
    }
    case 2: {
      self.fx_interval = 0.133;
      self spawn_blinking_fx(localclientnum);
      break;
    }
    case 3: {
      self notify("stopfx");
      self notify("fx_death");
      return;
    }
  }
  self thread watchrestartfx(localclientnum);
}

function watchrestartfx(localclientnum) {
  self endon("entityshutdown");
  level util::waittill_any("demo_jump", "player_switch", "killcam_begin", "killcam_end");
  self restartfx(localclientnum, clientfield::get("qrdrone_state"));
}

function spawn_solid_fx(localclientnum) {
  if(self islocalclientdriver(localclientnum)) {
    fx_handle = playFXOnTag(localclientnum, level._effect["qrdrone_viewmodel_light"], self, "tag_body");
  } else {
    if(self util::friend_not_foe(localclientnum)) {
      fx_handle = playFXOnTag(localclientnum, level._effect["qrdrone_friendly_light"], self, "tag_body");
    } else {
      fx_handle = playFXOnTag(localclientnum, level._effect["qrdrone_enemy_light"], self, "tag_body");
    }
  }
  self thread cleanupfx(localclientnum, fx_handle);
}

function spawn_blinking_fx(localclientnum) {
  self thread blink_fx_and_sound(localclientnum, "wpn_qr_alert");
}

function blink_fx_and_sound(localclientnum, soundalias) {
  self endon("entityshutdown");
  self endon("restart_fx");
  self endon("fx_death");
  if(!isDefined(self.interval)) {
    self.interval = 1;
  }
  while(true) {
    self playSound(localclientnum, soundalias);
    self spawn_solid_fx(localclientnum);
    util::server_wait(localclientnum, self.interval / 2);
    self notify("stopfx");
    util::server_wait(localclientnum, self.interval / 2);
    self.interval = self.interval / 1.17;
    if(self.interval < 0.1) {
      self.interval = 0.1;
    }
  }
}

function cleanupfx(localclientnum, handle) {
  self util::waittill_any("entityshutdown", "blink", "stopfx", "restart_fx");
  stopfx(localclientnum, handle);
}

function start_blink(localclientnum, oldval, newval, bnewent, binitialsnap, fieldname, bwastimejump) {
  if(!newval) {
    return;
  }
  self notify("blink");
}

function final_blink(localclientnum, oldval, newval, bnewent, binitialsnap, fieldname, bwastimejump) {
  if(!newval) {
    return;
  }
  self.interval = 0.133;
}

function out_of_range_update(localclientnum, oldval, newval, bnewent, binitialsnap, fieldname, bwastimejump) {
  model = getuimodel(getuimodelforcontroller(localclientnum), "vehicle.outOfRange");
  if(isDefined(model)) {
    setuimodelvalue(model, newval);
  }
}

function loop_local_sound(localclientnum, alias, interval, fx) {
  self endon("entityshutdown");
  self endon("stopfx");
  level endon("demo_jump");
  level endon("player_switch");
  if(!isDefined(self.interval)) {
    self.interval = interval;
  }
  while(true) {
    self playSound(localclientnum, alias);
    self spawn_solid_fx(localclientnum);
    util::server_wait(localclientnum, self.interval / 2);
    self notify("stopfx");
    util::server_wait(localclientnum, self.interval / 2);
    self.interval = self.interval / 1.17;
    if(self.interval < 0.1) {
      self.interval = 0.1;
    }
  }
}

function check_for_player_switch_or_time_jump(localclientnum) {
  self endon("entityshutdown");
  level util::waittill_any("demo_jump", "player_switch", "killcam_begin");
  self notify("stopfx");
  waittillframeend();
  self thread blink_light(localclientnum);
  if(isDefined(self.blinkstarttime) && self.blinkstarttime <= level.servertime) {
    self.interval = 1;
    self thread start_blink(localclientnum, 1);
  } else {
    self spawn_solid_fx(localclientnum);
  }
  self thread check_for_player_switch_or_time_jump(localclientnum);
}

function blink_light(localclientnum) {
  self endon("entityshutdown");
  level endon("demo_jump");
  level endon("player_switch");
  level endon("killcam_begin");
  self waittill("blink");
  if(!isDefined(self.blinkstarttime)) {
    self.blinkstarttime = level.servertime;
  }
  if(self islocalclientdriver(localclientnum)) {
    self thread loop_local_sound(localclientnum, "wpn_qr_alert", 1, level._effect["qrdrone_viewmodel_light"]);
  } else {
    if(self util::friend_not_foe(localclientnum)) {
      self thread loop_local_sound(localclientnum, "wpn_qr_alert", 1, level._effect["qrdrone_friendly_light"]);
    } else {
      self thread loop_local_sound(localclientnum, "wpn_qr_alert", 1, level._effect["qrdrone_enemy_light"]);
    }
  }
}

function collisionhandler(localclientnum) {
  self endon("entityshutdown");
  while(true) {
    self waittill("veh_collision", hip, hitn, hit_intensity);
    driver_local_client = self getlocalclientdriver();
    if(isDefined(driver_local_client)) {
      player = getlocalplayer(driver_local_client);
      if(isDefined(player)) {
        if(hit_intensity > 15) {
          player playrumbleonentity(driver_local_client, "damage_heavy");
        } else {
          player playrumbleonentity(driver_local_client, "damage_light");
        }
      }
    }
  }
}

function enginestutterhandler(localclientnum) {
  self endon("entityshutdown");
  while(true) {
    self waittill("veh_engine_stutter");
    if(self islocalclientdriver(localclientnum)) {
      player = getlocalplayer(localclientnum);
      if(isDefined(player)) {
        player playrumbleonentity(localclientnum, "rcbomb_engine_stutter");
      }
    }
  }
}

function getminimumflyheight() {
  if(!isDefined(level.airsupportheightscale)) {
    level.airsupportheightscale = 1;
  }
  airsupport_height = struct::get("air_support_height", "targetname");
  if(isDefined(airsupport_height)) {
    planeflyheight = airsupport_height.origin[2];
  } else {
    println("");
    planeflyheight = 850;
    if(isDefined(level.airsupportheightscale)) {
      level.airsupportheightscale = getdvarint("scr_airsupportHeightScale", level.airsupportheightscale);
      planeflyheight = planeflyheight * getdvarint("scr_airsupportHeightScale", level.airsupportheightscale);
    }
    if(isDefined(level.forceairsupportmapheight)) {
      planeflyheight = planeflyheight + level.forceairsupportmapheight;
    }
  }
  return planeflyheight;
}

function qrdrone_watch_distance() {
  self endon("entityshutdown");
  qrdrone_height = struct::get("qrdrone_height", "targetname");
  if(isDefined(qrdrone_height)) {
    self.maxheight = qrdrone_height.origin[2];
  } else {
    self.maxheight = int(getminimumflyheight());
  }
  self.maxdistance = 12800;
  level.mapcenter = getmapcenter();
  self.minheight = level.mapcenter[2] - 800;
  inrangepos = self.origin;
  soundent = spawn(0, self.origin, "script_origin");
  soundent linkto(self);
  self thread qrdrone_staticstopondeath(soundent);
  while(true) {
    if(!self qrdrone_in_range()) {
      staticalpha = 0;
      while(!self qrdrone_in_range()) {
        if(isDefined(self.heliinproximity)) {
          dist = distance(self.origin, self.heliinproximity.origin);
          staticalpha = 1 - ((dist - 150) / 150);
        } else {
          dist = distance(self.origin, inrangepos);
          staticalpha = min(1, dist / 200);
        }
        sid = soundent playLoopSound("veh_qrdrone_static_lp", 0.2);
        self vehicle::set_static_amount(staticalpha * 2);
        wait(0.05);
      }
      self thread qrdrone_staticfade(staticalpha, soundent, sid);
    }
    inrangepos = self.origin;
    wait(0.05);
  }
}

function qrdrone_in_range() {
  if(self.origin[2] < self.maxheight && self.origin[2] > self.minheight) {
    if(self isinsideheightlock()) {
      return true;
    }
  }
  return false;
}

function qrdrone_staticfade(staticalpha, sndent, sid) {
  self endon("entityshutdown");
  while(self qrdrone_in_range()) {
    staticalpha = staticalpha - 0.05;
    if(staticalpha <= 0) {
      sndent stopallloopsounds(0.5);
      self vehicle::set_static_amount(0);
      break;
    }
    setsoundvolumerate(sid, 0.6);
    setsoundvolume(sid, staticalpha);
    self vehicle::set_static_amount(staticalpha * 2);
    wait(0.05);
  }
}

function qrdrone_staticstopondeath(sndent) {
  self waittill("entityshutdown");
  sndent stopallloopsounds(0.1);
  sndent delete();
}