/*************************************************
 * Decompiled by Serious and Edited by SyndiShanX
 * Script: shared\duplicaterenderbundle.csc
*************************************************/

#using scripts\codescripts\struct;
#using scripts\shared\callbacks_shared;
#using scripts\shared\filter_shared;
#using scripts\shared\gfx_shared;
#using scripts\shared\math_shared;
#using scripts\shared\system_shared;
#using scripts\shared\util_shared;
#namespace duplicate_render_bundle;

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

function __init__() {
  callback::on_localplayer_spawned(&localplayer_duplicate_render_bundle_init);
}

function localplayer_duplicate_render_bundle_init(localclientnum) {
  init_duplicate_render_bundles();
}

function init_duplicate_render_bundles() {
  if(isDefined(self.duprenderbundelsinited)) {
    return;
  }
  self.duprenderbundelsinited = 1;
  self.playingduprenderbundle = "";
  self.forcestopduprenderbundle = 0;
  self.exitduprenderbundle = 0;
  self thread duprenderbundledebuglisten();
}

function duprenderbundledebuglisten() {
  self endon("entityshutdown");
  setDvar("", "");
  setDvar("", "");
  setDvar("", "");
  while(true) {
    playbundlename = getdvarstring("");
    if(playbundlename != "") {
      self thread playduprenderbundle(playbundlename);
      setDvar("", "");
    }
    stopbundlename = getdvarstring("");
    if(stopbundlename != "") {
      self thread stopduprenderbundle();
      setDvar("", "");
    }
    stopbundlename = getdvarstring("");
    if(stopbundlename != "") {
      self thread exitduprenderbundle();
      setDvar("", "");
    }
    wait(0.5);
  }
}

function playduprenderbundle(playbundlename) {
  self endon("entityshutdown");
  init_duplicate_render_bundles();
  stopplayingduprenderbundle();
  bundle = struct::get_script_bundle("duprenderbundle", playbundlename);
  if(!isDefined(bundle)) {
    println(("" + playbundlename) + "");
    return;
  }
  totalaccumtime = 0;
  filter::init_filter_indices();
  self.playingduprenderbundle = playbundlename;
  localclientnum = self.localclientnum;
  looping = 0;
  enterstage = 0;
  exitstage = 0;
  finishlooponexit = 0;
  if(isDefined(bundle.looping)) {
    looping = bundle.looping;
  }
  if(isDefined(bundle.enterstage)) {
    enterstage = bundle.enterstage;
  }
  if(isDefined(bundle.exitstage)) {
    exitstage = bundle.exitstage;
  }
  if(isDefined(bundle.finishlooponexit)) {
    finishlooponexit = bundle.finishlooponexit;
  }
  if(looping) {
    num_stages = 1;
    if(enterstage) {
      num_stages++;
    }
    if(exitstage) {
      num_stages++;
    }
  } else {
    num_stages = bundle.num_stages;
  }
  for(stageidx = 0; stageidx < num_stages && !self.forcestopduprenderbundle; stageidx++) {
    stageprefix = "s";
    if(stageidx < 10) {
      stageprefix = stageprefix + "0";
    }
    stageprefix = stageprefix + (stageidx + "_");
    stagelength = getstructfield(bundle, stageprefix + "length");
    if(!isDefined(stagelength)) {
      finishplayingduprenderbundle(localclientnum, stageprefix + " length not defined");
      return;
    }
    stagelength = stagelength * 1000;
    adddupmaterial(localclientnum, bundle, stageprefix + "fb_", 0);
    adddupmaterial(localclientnum, bundle, stageprefix + "dupfb_", 1);
    adddupmaterial(localclientnum, bundle, stageprefix + "sonar_", 2);
    loopingstage = looping && (!enterstage && stageidx == 0 || (enterstage && stageidx == 1));
    accumtime = 0;
    prevtime = self getclienttime();
    while(loopingstage || accumtime < stagelength && !self.forcestopduprenderbundle) {
      gfx::setstage(localclientnum, bundle, undefined, stageprefix, stagelength, accumtime, totalaccumtime, &setshaderconstants);
      wait(0.016);
      currtime = self getclienttime();
      deltatime = currtime - prevtime;
      accumtime = accumtime + deltatime;
      totalaccumtime = totalaccumtime + deltatime;
      prevtime = currtime;
      if(loopingstage) {
        while(accumtime >= stagelength) {
          accumtime = accumtime - stagelength;
        }
        if(self.exitduprenderbundle) {
          loopingstage = 0;
          if(!finishlooponexit) {
            break;
          }
        }
      }
    }
    self disableduplicaterendering();
  }
  finishplayingduprenderbundle(localclientnum, "Finished " + playbundlename);
}

function adddupmaterial(localclientnum, bundle, prefix, type) {
  method = 0;
  methodstr = getstructfield(bundle, prefix + "method");
  if(isDefined(methodstr)) {
    switch (methodstr) {
      case "off": {
        method = 0;
        break;
      }
      case "default material": {
        method = 1;
        break;
      }
      case "custom material": {
        method = 3;
        break;
      }
      case "force custom material": {
        method = 3;
        break;
      }
      case "thermal": {
        method = 2;
        break;
      }
      case "enemy material": {
        method = 4;
        break;
      }
    }
  }
  materialname = getstructfield(bundle, prefix + "mc_material");
  materialid = -1;
  if(isDefined(materialname) && materialname != "") {
    materialname = ("mc/") + materialname;
    materialid = filter::mapped_material_id(materialname);
    if(!isDefined(materialid)) {
      filter::map_material_helper_by_localclientnum(localclientnum, materialname);
      materialid = filter::mapped_material_id();
      if(!isDefined(materialid)) {
        materialid = -1;
      }
    }
  }
  self addduplicaterenderoption(type, method, materialid);
}

function setshaderconstants(localclientnum, shaderconstantname, filterid, values) {
  self mapshaderconstant(localclientnum, 0, shaderconstantname, values[0], values[1], values[2], values[3]);
}

function finishplayingduprenderbundle(localclientnum, msg) {
  if(isDefined(msg)) {
    println(msg);
  }
  self.forcestopduprenderbundle = 0;
  self.exitduprenderbundle = 0;
  self.playingduprenderbundle = "";
}

function stopplayingduprenderbundle() {
  if(self.playingduprenderbundle != "") {
    stopduprenderbundle();
  }
}

function stopduprenderbundle() {
  if(!(isDefined(self.forcestopduprenderbundle) && self.forcestopduprenderbundle) && isDefined(self.playingduprenderbundle) && self.playingduprenderbundle != "") {
    self.forcestopduprenderbundle = 1;
    while(self.playingduprenderbundle != "") {
      wait(0.016);
      if(!isDefined(self)) {
        return;
      }
    }
  }
}

function exitduprenderbundle() {
  if(!(isDefined(self.exitduprenderbundle) && self.exitduprenderbundle) && isDefined(self.playingduprenderbundle) && self.playingduprenderbundle != "") {
    self.exitduprenderbundle = 1;
  }
}