Merge branch 'master' into Mario/turrets
authorTimePath <andrew.hardaker1995@gmail.com>
Sun, 23 Aug 2015 08:07:27 +0000 (18:07 +1000)
committerTimePath <andrew.hardaker1995@gmail.com>
Sun, 23 Aug 2015 08:08:06 +0000 (18:08 +1000)
# Conflicts:
# qcsrc/client/main.qc
# qcsrc/client/progs.src
# qcsrc/client/tturrets.qc
# qcsrc/client/tturrets.qh
# qcsrc/common/command/generic.qc
# qcsrc/common/monsters/sv_monsters.qc
# qcsrc/common/nades.qc
# qcsrc/common/triggers/teleporters.qc
# qcsrc/server/autocvars.qh
# qcsrc/server/g_damage.qc
# qcsrc/server/g_damage.qh
# qcsrc/server/g_world.qc
# qcsrc/server/miscfunctions.qc
# qcsrc/server/mutators/mutators_include.qc
# qcsrc/server/progs.src
# qcsrc/server/tturrets/include/turrets_early.qh
# qcsrc/server/tturrets/system/system_damage.qc
# qcsrc/server/tturrets/system/system_main.qc
# qcsrc/server/tturrets/system/system_misc.qc
# qcsrc/server/tturrets/units/unit_ewheel.qc
# qcsrc/server/tturrets/units/unit_flac.qc
# qcsrc/server/tturrets/units/unit_machinegun.qc
# qcsrc/server/tturrets/units/unit_phaser.qc
# qcsrc/server/tturrets/units/unit_plasma.qc
# qcsrc/server/tturrets/units/unit_tessla.qc
# qcsrc/server/tturrets/units/unit_walker.qc
# qcsrc/server/vehicles/bumblebee.qc
# qcsrc/server/vehicles/racer.qc
# qcsrc/server/vehicles/vehicles.qc
# qcsrc/server/vehicles/vehicles_def.qh

37 files changed:
1  2 
qcsrc/client/damage.qc
qcsrc/client/main.qc
qcsrc/client/progs.src
qcsrc/common/command/generic.qc
qcsrc/common/deathtypes.qh
qcsrc/common/monsters/sv_monsters.qc
qcsrc/common/nades.qc
qcsrc/common/notifications.qh
qcsrc/common/triggers/teleporters.qc
qcsrc/common/turrets/cl_turrets.qc
qcsrc/common/turrets/sv_turrets.qc
qcsrc/common/turrets/sv_turrets.qh
qcsrc/common/turrets/turrets.qc
qcsrc/common/turrets/unit/ewheel.qc
qcsrc/common/turrets/unit/flac.qc
qcsrc/common/turrets/unit/fusionreactor.qc
qcsrc/common/turrets/unit/hellion.qc
qcsrc/common/turrets/unit/hk.qc
qcsrc/common/turrets/unit/machinegun.qc
qcsrc/common/turrets/unit/mlrs.qc
qcsrc/common/turrets/unit/phaser.qc
qcsrc/common/turrets/unit/plasma.qc
qcsrc/common/turrets/unit/plasma_dual.qc
qcsrc/common/turrets/unit/tesla.qc
qcsrc/common/turrets/unit/walker.qc
qcsrc/common/turrets/util.qc
qcsrc/common/vehicles/sv_vehicles.qh
qcsrc/server/autocvars.qh
qcsrc/server/g_damage.qc
qcsrc/server/g_damage.qh
qcsrc/server/g_world.qc
qcsrc/server/miscfunctions.qc
qcsrc/server/miscfunctions.qh
qcsrc/server/mutators/gamemode_assault.qc
qcsrc/server/mutators/gamemode_onslaught.qc
qcsrc/server/mutators/mutators_include.qc
qcsrc/server/progs.src

Simple merge
  #include "mapvoting.qh"
  #include "modeleffects.qh"
  #include "particles.qh"
+ #include "prandom.qh"
  #include "scoreboard.qh"
  #include "shownames.qh"
- #include "target_music.qh"
+ #include "sortlist.qh"
 -#include "tturrets.qh"
  #include "tuba.qh"
+ #include "t_items.qh"
  #include "wall.qh"
  #include "waypointsprites.qh"
  
- #include "vehicles/vehicles.qh"
+ #include "../common/vehicles/unit/bumblebee.qh"
+ #include "../common/vehicles/cl_vehicles.qh"
+ #include "../common/vehicles/vehicles.qh"
  
- #include "../server/vehicles/bumblebee.qh"
+ #include "weapons/projectile.qh"
  
+ #include "../common/buffs.qh"
+ #include "../common/deathtypes.qh"
+ #include "../common/effects.qh"
+ #include "../common/mapinfo.qh"
+ #include "../common/monsters/all.qh"
+ #include "../common/nades.qh"
  #include "../common/net_notice.qh"
+ #include "../common/notifications.qh"
+ #include "../common/stats.qh"
+ #include "../common/teams.qh"
  
- #include "../common/monsters/monsters.qh"
+ #include "../common/items/all.qh"
+ #include "../common/mutators/base.qh"
+ #include "../common/weapons/all.qh"
+ #include "../csqcmodellib/cl_model.qh"
+ #include "../csqcmodellib/interpolate.qh"
+ #include "../common/triggers/include.qh"
  
 +#include "../common/turrets/cl_turrets.qh"
 +#include "../common/turrets/turrets.qh"
 +
  #include "../warpzonelib/client.qh"
  
  // --------------------------------------------------------------------------
@@@ -109,10 -144,7 +146,8 @@@ void CSQC_Init(void
        GetTeam(NUM_SPECTATOR, true); // add specs first
  
        // needs to be done so early because of the constants they create
-       CALL_ACCUMULATED_FUNCTION(RegisterWeapons);
+       static_init();
 +      CALL_ACCUMULATED_FUNCTION(RegisterTurrets);
-       CALL_ACCUMULATED_FUNCTION(RegisterMonsters);
-       CALL_ACCUMULATED_FUNCTION(RegisterGametypes);
        CALL_ACCUMULATED_FUNCTION(RegisterNotifications);
        CALL_ACCUMULATED_FUNCTION(RegisterDeathtypes);
        CALL_ACCUMULATED_FUNCTION(RegisterHUD_Panels);
        Hook_Precache();
        GibSplash_Precache();
        Casings_Precache();
-       Vehicles_Precache();
 -      turrets_precache();
        Tuba_Precache();
        CSQCPlayer_Precache();
  
@@@ -27,10 -27,10 +27,9 @@@ rubble.q
  scoreboard.qc
  shownames.qc
  sortlist.qc
- target_music.qc
  teamradar.qc
 -tturrets.qc
  tuba.qc
vehicles/vehicles.qc
t_items.qc
  view.qc
  wall.qc
  waypointsprites.qc
@@@ -50,16 -54,15 +53,20 @@@ weapons/projectile.qc // TOD
  ../common/urllib.qc
  ../common/util.qc
  
- ../common/command/generic.qc
- ../common/command/markup.qc
- ../common/command/rpn.qc
+ ../common/viewloc.qc
  
- ../common/monsters/monsters.qc
++../common/weapons/all.qc // TODO
 +
+ ../common/items/all.qc
+ ../common/monsters/all.qc
 +../common/turrets/cl_turrets.qc
 +../common/turrets/turrets.qc
 +
- ../common/weapons/weapons.qc // TODO
+ ../common/weapons/all.qc // TODO
+ ../common/triggers/include.qc
  
  ../csqcmodellib/cl_model.qc
  ../csqcmodellib/cl_player.qc
@@@ -71,6 -74,8 +78,9 @@@
  
  ../warpzonelib/anglestransform.qc
  ../warpzonelib/client.qc
 +
  ../warpzonelib/common.qc
  ../warpzonelib/mathlib.qc
+ ../warpzonelib/util_server.qc
+ ../../mod/client/progs.inc
@@@ -1,6 -1,28 +1,28 @@@
+ #include "command.qh"
  #include "generic.qh"
- #include "shared_defs.qh"
- #include "../turrets/config.qh"
+ #include "markup.qh"
+ #include "rpn.qh"
+ #include "../mapinfo.qh"
+ #include "../test.qh"
+ #ifndef MENUQC
+       #include "../notifications.qh"
+ #endif
+ #ifdef CSQC
+       #include "../../client/command/cl_cmd.qh"
+ #endif
+ #ifdef SVQC
+       #include "../../server/command/banning.qh"
+       #include "../../server/command/cmd.qh"
+       #include "../../server/command/common.qh"
+       #include "../../server/command/sv_cmd.qh"
 -
++      #include "../../common/turrets/config.qh"
+       #include "../../common/weapons/config.qh"
+ #endif
  
  // =========================================================
  //  Generic program common command code, written by Samual
@@@ -682,8 -670,8 +723,9 @@@ void GenericCommand_(float request
  #define GENERIC_COMMANDS(request,arguments,command) \
        GENERIC_COMMAND("addtolist", GenericCommand_addtolist(request, arguments), "Add a string to a cvar") \
        GENERIC_COMMAND("dumpcommands", GenericCommand_dumpcommands(request), "Dump all commands on the program to *_cmd_dump.txt") \
+       GENERIC_COMMAND("dumpitems", GenericCommand_dumpitems(request), "Dump all items to the console") \
        GENERIC_COMMAND("dumpnotifs", GenericCommand_dumpnotifs(request), "Dump all notifications into notifications_dump.txt") \
 +      GENERIC_COMMAND("dumpturrets", GenericCommand_dumpturrets(request), "Dump all turrets into turrets_dump.txt") \
        GENERIC_COMMAND("dumpweapons", GenericCommand_dumpweapons(request), "Dump all weapons into weapons_dump.txt") \
        GENERIC_COMMAND("maplist", GenericCommand_maplist(request, arguments), "Automatic control of maplist") \
        GENERIC_COMMAND("nextframe", GenericCommand_nextframe(request, arguments, command), "Execute the given command next frame of this VM") \
Simple merge
      #include "../../server/defs.qh"
      #include "../deathtypes.qh"
      #include "../../server/mutators/mutators_include.qh"
-     #include "../../server/vehicles/vehicles_def.qh"
 -    #include "../../server/tturrets/include/turrets_early.qh"
++    #include "../../server/steerlib.qh"
++    #include "../turrets/sv_turrets.qh"
++    #include "../turrets/util.qh"
+     #include "../vehicles/sv_vehicles.qh"
      #include "../../server/campaign.qh"
      #include "../../server/command/common.qh"
      #include "../../server/command/cmd.qh"
+       #include "../triggers/triggers.qh"
      #include "../../csqcmodellib/sv_model.qh"
      #include "../../server/round_handler.qh"
 -    #include "../../server/tturrets/include/turrets.qh"
  #endif
  
  // =========================
@@@ -3,7 -3,8 +3,7 @@@
        #include "../client/defs.qh"
        #include "nades.qh"
        #include "buffs.qh"
-       #include "../client/movetypes.qh"
+       #include "../common/movetypes/movetypes.qh"
 -      #include "../server/tturrets/include/turrets_early.qh"
        #include "../client/main.qh"
        #include "../csqcmodellib/cl_model.qh"
  #elif defined(MENUQC)
@@@ -11,6 -12,6 +11,7 @@@
        #include "../dpdefs/progsdefs.qh"
      #include "constants.qh"
      #include "../server/constants.qh"
++      #include "../common/turrets/sv_turrets.qh"
  #endif
  
  
Simple merge
index 0000000,a583716..5cd0981
mode 000000,100644..100644
--- /dev/null
@@@ -1,0 -1,253 +1,253 @@@
 -    #include "../../server/tturrets/include/turrets_early.qh"
+ #include "teleporters.qh"
+ #if defined(CSQC)
+ #elif defined(MENUQC)
+ #elif defined(SVQC)
+       #include "../../server/_all.qh"
+     #include "../../warpzonelib/common.qh"
+     #include "../../warpzonelib/util_server.qh"
+     #include "../../warpzonelib/server.qh"
+     #include "../constants.qh"
+       #include "../triggers/subs.qh"
+     #include "../util.qh"
+     #include "../../server/weapons/csqcprojectile.qh"
+     #include "../../server/autocvars.qh"
+     #include "../../server/constants.qh"
+     #include "../../server/defs.qh"
+     #include "../deathtypes.qh"
++    #include "../turrets/sv_turrets.qh"
+     #include "../vehicles/sv_vehicles.qh"
+     #include "../mapinfo.qh"
+     #include "../../server/anticheat.qh"
+ #endif
+ #ifdef SVQC
+ float check_tdeath(entity player, vector org, vector telefragmin, vector telefragmax)
+ {
+       if (IS_PLAYER(player) && player.health >= 1)
+       {
+               TDEATHLOOP(org)
+               {
+                       if (!(teamplay && autocvar_g_telefrags_teamplay && head.team == player.team))
+                               if(IS_PLAYER(head))
+                                       if(head.health >= 1)
+                                               return 1;
+               }
+       }
+       return 0;
+ }
+ void tdeath(entity player, entity teleporter, entity telefragger, vector telefragmin, vector telefragmax)
+ {
+       TDEATHLOOP(player.origin)
+       {
+               if (IS_PLAYER(player) && player.health >= 1)
+               {
+                       if (!(teamplay && autocvar_g_telefrags_teamplay && head.team == player.team))
+                       {
+                               if(IS_PLAYER(head))
+                                       if(head.health >= 1)
+                                               ++tdeath_hit;
+                               Damage (head, teleporter, telefragger, 10000, DEATH_TELEFRAG, head.origin, '0 0 0');
+                       }
+               }
+               else // dead bodies and monsters gib themselves instead of telefragging
+                       Damage (telefragger, teleporter, telefragger, 10000, DEATH_TELEFRAG, telefragger.origin, '0 0 0');
+       }
+ }
+ void spawn_tdeath(vector v0, entity e, vector v)
+ {
+       tdeath(e, e, e, '0 0 0', '0 0 0');
+ }
+ void TeleportPlayer(entity teleporter, entity player, vector to, vector to_angles, vector to_velocity, vector telefragmin, vector telefragmax, float tflags)
+ {
+       entity telefragger;
+       vector from;
+       if(teleporter.owner)
+               telefragger = teleporter.owner;
+       else
+               telefragger = player;
+       makevectors (to_angles);
+       if(player.teleportable == TELEPORT_NORMAL) // don't play sounds or show particles for anything that isn't a player, maybe change later to block only observers
+       {
+               if(self.pushltime < time) // only show one teleport effect per teleporter per 0.2 seconds, for better fps
+               {
+                       if(tflags & TELEPORT_FLAG_SOUND)
+                               sound (player, CH_TRIGGER, "misc/teleport.wav", VOL_BASE, ATTEN_NORM);
+                       if(tflags & TELEPORT_FLAG_PARTICLES)
+                       {
+                               Send_Effect("teleport", player.origin, '0 0 0', 1);
+                               Send_Effect("teleport", to + v_forward * 32, '0 0 0', 1);
+                       }
+                       self.pushltime = time + 0.2;
+               }
+       }
+       // Relocate the player
+       // assuming to allows PL_MIN to PL_MAX box and some more
+       from = player.origin;
+       setorigin (player, to);
+       player.oldorigin = to; // don't undo the teleport by unsticking
+       player.angles = to_angles;
+       player.fixangle = true;
+       player.velocity = to_velocity;
+       BITXOR_ASSIGN(player.effects, EF_TELEPORT_BIT);
+       makevectors(player.angles);
+       Reset_ArcBeam(player, v_forward);
+       UpdateCSQCProjectileAfterTeleport(player);
+       if(IS_PLAYER(player))
+       {
+               if(tflags & TELEPORT_FLAG_TDEATH)
+                       if(player.takedamage && player.deadflag == DEAD_NO && !g_race && !g_cts && (autocvar_g_telefrags || (tflags & TELEPORT_FLAG_FORCE_TDEATH)))
+                               tdeath(player, teleporter, telefragger, telefragmin, telefragmax);
+               // player no longer is on ground
+               player.flags &= ~FL_ONGROUND;
+               // reset tracking of oldvelocity for impact damage (sudden velocity changes)
+               player.oldvelocity = player.velocity;
+               // reset tracking of who pushed you into a hazard (for kill credit)
+               if(teleporter.owner)
+               {
+                       player.pusher = teleporter.owner;
+                       player.pushltime = time + autocvar_g_maxpushtime;
+                       player.istypefrag = player.BUTTON_CHAT;
+               }
+               else
+               {
+                       player.pushltime = 0;
+                       player.istypefrag = 0;
+               }
+               player.lastteleporttime = time;
+       }
+ }
+ entity Simple_TeleportPlayer(entity teleporter, entity player)
+ {
+       vector locout;
+       entity e;
+       float p;
+       // Find the output teleporter
+       if(teleporter.enemy)
+       {
+               e = teleporter.enemy;
+       }
+       else
+       {
+               RandomSelection_Init();
+               for(e = world; (e = find(e, targetname, teleporter.target)); )
+               {
+                       p = 1;
+                       if(autocvar_g_telefrags_avoid)
+                       {
+                               locout = e.origin + '0 0 1' * (1 - player.mins.z - 24);
+                               if(check_tdeath(player, locout, '0 0 0', '0 0 0'))
+                                       p = 0;
+                       }
+                       RandomSelection_Add(e, 0, string_null, (e.cnt ? e.cnt : 1), p);
+               }
+               e = RandomSelection_chosen_ent;
+       }
+       if(!e) { sprint(player, "Teleport destination vanished. Sorry... please complain to the mapper.\n"); }
+       makevectors(e.mangle);
+       if(e.speed)
+               if(vlen(player.velocity) > e.speed)
+                       player.velocity = normalize(player.velocity) * max(0, e.speed);
+       if(autocvar_g_teleport_maxspeed)
+               if(vlen(player.velocity) > autocvar_g_teleport_maxspeed)
+                       player.velocity = normalize(player.velocity) * max(0, autocvar_g_teleport_maxspeed);
+       locout = e.origin + '0 0 1' * (1 - player.mins.z - 24);
+       TeleportPlayer(teleporter, player, locout, e.mangle, v_forward * vlen(player.velocity), '0 0 0', '0 0 0', TELEPORT_FLAGS_TELEPORTER);
+       return e;
+ }
+ void teleport_findtarget (void)
+ {
+       entity e;
+       float n;
+       n = 0;
+       for(e = world; (e = find(e, targetname, self.target)); )
+       {
+               ++n;
+               if(e.movetype == MOVETYPE_NONE)
+                       waypoint_spawnforteleporter(self, e.origin, 0);
+               if(e.classname != "info_teleport_destination")
+                       print("^3MAPPER ERROR: teleporter does target an invalid teleport destination entity. Angles will not work.\n");
+       }
+       if(n == 0)
+       {
+               // no dest!
+               objerror ("Teleporter with nonexistant target");
+               return;
+       }
+       else if(n == 1)
+       {
+               // exactly one dest - bots love that
+               self.enemy = find(e, targetname, self.target);
+       }
+       else
+       {
+               // have to use random selection every single time
+               self.enemy = world;
+       }
+       // now enable touch
+       self.touch = Teleport_Touch;
+ }
+ entity Teleport_Find(vector mi, vector ma)
+ {
+       entity e;
+       for(e = world; (e = find(e, classname, "trigger_teleport")); )
+               if(WarpZoneLib_BoxTouchesBrush(mi, ma, e, world))
+                       return e;
+       return world;
+ }
+ void WarpZone_PostTeleportPlayer_Callback(entity pl)
+ {
+       makevectors(pl.angles);
+       Reset_ArcBeam(pl, v_forward);
+       UpdateCSQCProjectileAfterTeleport(pl);
+       {
+               entity oldself = self;
+               self = pl;
+               anticheat_fixangle();
+               self = oldself;
+       }
+       // "disown" projectiles after teleport
+       if(pl.owner)
+       if(pl.owner == pl.realowner)
+       {
+               if(!(pl.flags & FL_PROJECTILE))
+                       print("A non-projectile got through a warpzone and its owner cleared. It's a ", pl.classname, ".\n");
+               pl.owner = world;
+       }
+       if(IS_PLAYER(pl))
+       {
+               // reset tracking of oldvelocity for impact damage (sudden velocity changes)
+               pl.oldvelocity = pl.velocity;
+               // reset teleport time tracking too (or multijump can cause insane speeds)
+               pl.lastteleporttime = time;
+       }
+ }
+ #endif
index 2f8e77d,0000000..c39b938
mode 100644,000000..100644
--- /dev/null
@@@ -1,445 -1,0 +1,445 @@@
-                               txt = "gfx/vehicles/vth-mover.tga";
 +void turret_remove()
 +{
 +      remove(self.tur_head);
 +      //remove(self.enemy);
 +      self.tur_head = world;
 +}
 +
 +.vector glowmod;
 +void turret_changeteam()
 +{
 +      self.glowmod = Team_ColorRGB(self.team - 1) * 2;
 +      self.teamradar_color = Team_ColorRGB(self.team - 1);
 +
 +      if(self.team)
 +              self.colormap = 1024 + (self.team - 1) * 17;
 +
 +      self.tur_head.colormap = self.colormap;
 +      self.tur_head.glowmod = self.glowmod;
 +
 +}
 +
 +void turret_head_draw()
 +{
 +      self.drawmask = MASK_NORMAL;
 +}
 +
 +void turret_draw()
 +{
 +      float dt;
 +
 +      dt = time - self.move_time;
 +      self.move_time = time;
 +      if(dt <= 0)
 +              return;
 +
 +      self.tur_head.angles += dt * self.tur_head.move_avelocity;
 +
 +      if (self.health < 127)
 +      {
 +              dt = random();
 +
 +              if(dt < 0.03)
 +                      te_spark(self.origin + '0 0 40', randomvec() * 256 + '0 0 256', 16);
 +      }
 +
 +      if(self.health < 85)
 +      if(dt < 0.01)
 +              pointparticles(particleeffectnum("smoke_large"), (self.origin + (randomvec() * 80)), '0 0 0', 1);
 +
 +      if(self.health < 32)
 +      if(dt < 0.015)
 +              pointparticles(particleeffectnum("smoke_small"), (self.origin + (randomvec() * 80)), '0 0 0', 1);
 +
 +}
 +
 +void turret_draw2d()
 +{
 +      if(self.netname == "")
 +              return;
 +
 +      if(!autocvar_g_waypointsprite_turrets)
 +              return;
 +
 +      if(autocvar_cl_hidewaypoints)
 +              return;
 +
 +      float dist = vlen(self.origin - view_origin);
 +      float t = (GetPlayerColor(player_localnum) + 1);
 +
 +      vector o;
 +      string txt;
 +
 +      if(autocvar_cl_vehicles_hud_tactical)
 +      if(dist < 10240 && t != self.team)
 +      {
 +              // TODO: Vehicle tactical hud
 +              o = project_3d_to_2d(self.origin + '0 0 32');
 +              if(o_z < 0
 +              || o_x < (vid_conwidth * waypointsprite_edgeoffset_left)
 +              || o_y < (vid_conheight * waypointsprite_edgeoffset_top)
 +              || o_x > (vid_conwidth - (vid_conwidth * waypointsprite_edgeoffset_right))
 +              || o_y > (vid_conheight - (vid_conheight * waypointsprite_edgeoffset_bottom)))
 +                      return; // Dont draw wp's for turrets out of view
 +              o_z = 0;
 +              if(hud != HUD_NORMAL)
 +              {
 +                      if((get_turretinfo(self.turretid)).spawnflags & TUR_FLAG_MOVE)
-                               txt = "gfx/vehicles/vth-stationary.tga";
++                              txt = "gfx/vehicles/turret_moving.tga";
 +                      else
-                       vector pz = drawgetimagesize(txt) * 0.25;
-                       drawpic(o - pz * 0.5, txt, pz , '1 1 1', 0.75, DRAWFLAG_NORMAL);
++                              txt = "gfx/vehicles/turret_stationary.tga";
 +
++                      vector pz = drawgetimagesize(txt) * autocvar_cl_vehicles_crosshair_size;
++                      drawpic(o - pz * 0.5, txt, pz , '1 1 1', 0.7, DRAWFLAG_NORMAL);
 +              }
 +      }
 +
 +      if(dist > self.maxdistance)
 +              return;
 +
 +      string spriteimage = self.netname;
 +      float a = self.alpha * autocvar_hud_panel_fg_alpha;
 +      vector rgb = spritelookupcolor(spriteimage, self.teamradar_color);
 +
 +
 +      if(self.maxdistance > waypointsprite_normdistance)
 +              a *= pow(bound(0, (self.maxdistance - dist) / (self.maxdistance - waypointsprite_normdistance), 1), waypointsprite_distancealphaexponent);
 +      else if(self.maxdistance > 0)
 +              a *= pow(bound(0, (waypointsprite_fadedistance - dist) / (waypointsprite_fadedistance - waypointsprite_normdistance), 1), waypointsprite_distancealphaexponent) * (1 - waypointsprite_minalpha) + waypointsprite_minalpha;
 +
 +      if(rgb == '0 0 0')
 +      {
 +              self.teamradar_color = '1 0 1';
 +              printf("WARNING: sprite of name %s has no color, using pink so you notice it\n", spriteimage);
 +      }
 +
 +      txt = self.netname;
 +      if(autocvar_g_waypointsprite_spam && waypointsprite_count >= autocvar_g_waypointsprite_spam)
 +              txt = _("Spam");
 +      else
 +              txt = spritelookuptext(spriteimage);
 +
 +      if(time - floor(time) > 0.5 && t == self.team)
 +      {
 +              if(self.helpme && time < self.helpme)
 +              {
 +                      a *= SPRITE_HELPME_BLINK;
 +                      txt = sprintf(_("%s under attack!"), txt);
 +              }
 +              else
 +                      a *= spritelookupblinkvalue(spriteimage);
 +      }
 +
 +      if(autocvar_g_waypointsprite_uppercase)
 +              txt = strtoupper(txt);
 +
 +      if(a > 1)
 +      {
 +              rgb *= a;
 +              a = 1;
 +      }
 +
 +      if(a <= 0)
 +              return;
 +
 +      rgb = fixrgbexcess(rgb);
 +
 +      o = project_3d_to_2d(self.origin + '0 0 64');
 +      if(o_z < 0
 +      || o_x < (vid_conwidth * waypointsprite_edgeoffset_left)
 +      || o_y < (vid_conheight * waypointsprite_edgeoffset_top)
 +      || o_x > (vid_conwidth - (vid_conwidth * waypointsprite_edgeoffset_right))
 +      || o_y > (vid_conheight - (vid_conheight * waypointsprite_edgeoffset_bottom)))
 +              return; // Dont draw wp's for turrets out of view
 +
 +      o_z = 0;
 +
 +      float edgedistance_min, crosshairdistance;
 +              edgedistance_min = min((o_y - (vid_conheight * waypointsprite_edgeoffset_top)),
 +      (o_x - (vid_conwidth * waypointsprite_edgeoffset_left)),
 +      (vid_conwidth - (vid_conwidth * waypointsprite_edgeoffset_right)) - o_x,
 +      (vid_conheight - (vid_conheight * waypointsprite_edgeoffset_bottom)) - o_y);
 +
 +      float vidscale = max(vid_conwidth / vid_width, vid_conheight / vid_height);
 +
 +      crosshairdistance = sqrt( pow(o_x - vid_conwidth/2, 2) + pow(o_y - vid_conheight/2, 2) );
 +
 +      t = waypointsprite_scale * vidscale;
 +      a *= waypointsprite_alpha;
 +
 +      {
 +              a = a * (1 - (1 - waypointsprite_distancefadealpha) * (bound(0, dist/waypointsprite_distancefadedistance, 1)));
 +              t = t * (1 - (1 - waypointsprite_distancefadescale) * (bound(0, dist/waypointsprite_distancefadedistance, 1)));
 +      }
 +      if (edgedistance_min < waypointsprite_edgefadedistance) {
 +              a = a * (1 - (1 - waypointsprite_edgefadealpha) * (1 - bound(0, edgedistance_min/waypointsprite_edgefadedistance, 1)));
 +              t = t * (1 - (1 - waypointsprite_edgefadescale) * (1 - bound(0, edgedistance_min/waypointsprite_edgefadedistance, 1)));
 +      }
 +      if(crosshairdistance < waypointsprite_crosshairfadedistance) {
 +              a = a * (1 - (1 - waypointsprite_crosshairfadealpha) * (1 - bound(0, crosshairdistance/waypointsprite_crosshairfadedistance, 1)));
 +              t = t * (1 - (1 - waypointsprite_crosshairfadescale) * (1 - bound(0, crosshairdistance/waypointsprite_crosshairfadedistance, 1)));
 +      }
 +
 +      o = drawspritearrow(o, M_PI, rgb, a, SPRITE_ARROW_SCALE * t);
 +      o = drawspritetext(o, M_PI, (SPRITE_HEALTHBAR_WIDTH + 2 * SPRITE_HEALTHBAR_BORDER) * t, rgb, a, waypointsprite_fontsize * '1 1 0', txt);
 +      drawhealthbar(
 +                      o,
 +                      0,
 +                      self.health / 255,
 +                      '0 0 0',
 +                      '0 0 0',
 +                      0.5 * SPRITE_HEALTHBAR_WIDTH * t,
 +                      0.5 * SPRITE_HEALTHBAR_HEIGHT * t,
 +                      SPRITE_HEALTHBAR_MARGIN * t + 0.5 * waypointsprite_fontsize,
 +                      SPRITE_HEALTHBAR_BORDER * t,
 +                      0,
 +                      rgb,
 +                      a * SPRITE_HEALTHBAR_BORDERALPHA,
 +                      rgb,
 +                      a * SPRITE_HEALTHBAR_HEALTHALPHA,
 +                      DRAWFLAG_NORMAL
 +                      );
 +}
 +
 +void turret_construct()
 +{
 +      entity tur = get_turretinfo(self.turretid);
 +
 +      if(self.tur_head == world)
 +              self.tur_head = spawn();
 +
 +      self.netname = TUR_NAME(self.turretid);
 +
 +      setorigin(self, self.origin);
 +      setmodel(self, tur.model);
 +      setmodel(self.tur_head, tur.head_model);
 +      setsize(self, tur.mins, tur.maxs);
 +      setsize(self.tur_head, '0 0 0', '0 0 0');
 +
 +      if(self.turretid == TUR_EWHEEL)
 +              setattachment(self.tur_head, self, "");
 +      else
 +              setattachment(self.tur_head, self, "tag_head");
 +
 +      self.tur_head.classname                 = "turret_head";
 +      self.tur_head.owner                             = self;
 +      self.tur_head.move_movetype             = MOVETYPE_NOCLIP;
 +      self.move_movetype                              = MOVETYPE_NOCLIP;
 +      self.tur_head.angles                    = self.angles;
 +      self.health                                             = 255;
 +      self.solid                                              = SOLID_BBOX;
 +      self.tur_head.solid                             = SOLID_NOT;
 +      self.movetype                                   = MOVETYPE_NOCLIP;
 +      self.tur_head.movetype                  = MOVETYPE_NOCLIP;
 +      self.draw                                               = turret_draw;
 +      self.entremove                                  = turret_remove;
 +      self.drawmask                                   = MASK_NORMAL;
 +      self.tur_head.drawmask                  = MASK_NORMAL;
 +      self.anim_start_time                    = 0;
 +      self.draw2d = turret_draw2d;
 +      self.maxdistance = autocvar_g_waypointsprite_turrets_maxdist;
 +      self.teamradar_color = '1 0 0';
 +      self.alpha = 1;
 +      
 +      TUR_ACTION(self.turretid, TR_SETUP);
 +}
 +
 +entity turret_gibtoss(string _model, vector _from, vector _to, vector _cmod, float _explode);
 +void turret_gibboom();
 +void turret_gib_draw()
 +{
 +      Movetype_Physics_MatchTicrate(autocvar_cl_gibs_ticrate, autocvar_cl_gibs_sloppy);
 +
 +      self.drawmask = MASK_NORMAL;
 +
 +      if(self.cnt)
 +      {
 +              if(time >= self.nextthink)
 +              {
 +                      turret_gibboom();
 +                      remove(self);
 +              }
 +      }
 +      else
 +      {
 +              self.alpha = bound(0, self.nextthink - time, 1);
 +              if(self.alpha < ALPHA_MIN_VISIBLE)
 +                      remove(self);
 +      }
 +}
 +
 +void turret_gibboom()
 +{
 +      float i;
 +
 +      sound (self, CH_SHOTS, "weapons/rocket_impact.wav", VOL_BASE, ATTEN_NORM);
 +      pointparticles(particleeffectnum("rocket_explode"), self.origin, '0 0 0', 1);
 +
 +      for (i = 1; i < 5; i = i + 1)
 +              turret_gibtoss(strcat("models/turrets/head-gib", ftos(i), ".md3"), self.origin + '0 0 2', self.velocity + randomvec() * 700, '0 0 0', false);
 +}
 +
 +entity turret_gibtoss(string _model, vector _from, vector _to, vector _cmod, float _explode)
 +{
 +      entity gib;
 +
 +      traceline(_from, _to, MOVE_NOMONSTERS, world);
 +      if(trace_startsolid)
 +              return world;
 +
 +      gib = spawn();
 +      setorigin(gib, _from);
 +      setmodel(gib, _model);
 +      gib.colormod    = _cmod;
 +      gib.solid          = SOLID_CORPSE;
 +      gib.draw                = turret_gib_draw;
 +      gib.cnt          = _explode;
 +      setsize(gib, '-1 -1 -1', '1 1 1');
 +      if(_explode)
 +      {
 +              gib.nextthink = time + 0.2 * (autocvar_cl_gibs_lifetime * (1 + prandom() * 0.15));
 +              gib.effects = EF_FLAME;
 +      }
 +      else
 +              gib.nextthink = time + autocvar_cl_gibs_lifetime * (1 + prandom() * 0.15);
 +
 +      gib.gravity              = 1;
 +      gib.move_movetype   = MOVETYPE_BOUNCE;
 +      gib.move_origin  = _from;
 +      setorigin(gib,          _from);
 +      gib.move_velocity   = _to;
 +      gib.move_avelocity  = prandomvec() * 32;
 +      gib.move_time      = time;
 +      gib.damageforcescale = 1;
 +      gib.classname = "turret_gib";
 +
 +      return gib;
 +}
 +
 +void turret_die()
 +{
 +      sound (self, CH_SHOTS, "weapons/rocket_impact.wav", VOL_BASE, ATTEN_NORM);
 +      pointparticles(particleeffectnum("rocket_explode"), self.origin, '0 0 0', 1);
 +      if (!autocvar_cl_nogibs)
 +      {
 +              // Base
 +              if(self.turretid == TUR_EWHEEL)
 +                      turret_gibtoss((get_turretinfo(self.turretid)).model, self.origin + '0 0 18', self.velocity + '0 0 400' + '0.1 0.1 1' * (random() * 400), '-1 -1 -1', true);
 +              else if (self.turretid == TUR_WALKER)
 +                      turret_gibtoss((get_turretinfo(self.turretid)).model, self.origin + '0 0 18', self.velocity + '0 0 300' + '0.1 0.1 1' * (random() * 200), '-1 -1 -1', true);
 +              else if (self.turretid == TUR_TESLA)
 +                      turret_gibtoss((get_turretinfo(self.turretid)).model, self.origin + '0 0 18', '0 0 200', '-1 -1 -1', false);
 +              else
 +              {
 +                      if (random() > 0.5)
 +                      {
 +                              turret_gibtoss("models/turrets/base-gib2.md3", self.origin + '0 0 8', '0 0 50' + randomvec() * 150, '0 0 0', false);
 +                              turret_gibtoss("models/turrets/base-gib3.md3", self.origin + '0 0 8', '0 0 50' + randomvec() * 150, '0 0 0', false);
 +                              turret_gibtoss("models/turrets/base-gib4.md3", self.origin + '0 0 8', '0 0 50' + randomvec() * 150, '0 0 0', false);
 +                      }
 +                      else
 +                              turret_gibtoss("models/turrets/base-gib1.md3", self.origin + '0 0 8', '0 0 0', '0 0 0', true);
 +
 +                      entity headgib = turret_gibtoss((get_turretinfo(self.turretid)).head_model, self.origin + '0 0 32', '0 0 200' + randomvec() * 200, '-1 -1 -1', true);
 +                      if(headgib)
 +                      {
 +                              headgib.angles = headgib.move_angles = self.tur_head.angles;
 +                              headgib.avelocity = headgib.move_avelocity = self.tur_head.move_avelocity + randomvec() * 45;
 +                              headgib.avelocity_y = headgib.move_avelocity_y = headgib.move_avelocity_y * 5;
 +                              headgib.gravity = 0.5;
 +                      }
 +              }
 +      }
 +
 +      setmodel(self, "null");
 +      setmodel(self.tur_head, "null");
 +}
 +
 +void ent_turret()
 +{
 +      float sf;
 +      sf = ReadByte();
 +
 +      if(sf & TNSF_SETUP)
 +      {
 +              self.turretid = ReadByte();
 +
 +              self.origin_x = ReadCoord();
 +              self.origin_y = ReadCoord();
 +              self.origin_z = ReadCoord();
 +              setorigin(self, self.origin);
 +
 +              self.angles_x = ReadAngle();
 +              self.angles_y = ReadAngle();
 +              
 +              turret_construct();
 +              self.colormap = 1024;
 +              self.glowmod = '0 1 1';
 +              self.tur_head.colormap = self.colormap;
 +              self.tur_head.glowmod = self.glowmod;
 +      }
 +
 +      if(sf & TNSF_ANG)
 +      {
 +              if(self.tur_head == world) // aparenly this can happpen before TNSF_SETUP. great.
 +                      self.tur_head = spawn();
 +
 +              self.tur_head.move_angles_x = ReadShort();
 +              self.tur_head.move_angles_y = ReadShort();
 +              //self.tur_head.angles = self.angles + self.tur_head.move_angles;
 +              self.tur_head.angles = self.tur_head.move_angles;
 +      }
 +
 +      if(sf & TNSF_AVEL)
 +      {
 +              if(self.tur_head == world) // aparenly this can happpen before TNSF_SETUP. great.
 +                      self.tur_head = spawn();
 +
 +              self.tur_head.move_avelocity_x = ReadShort();
 +              self.tur_head.move_avelocity_y = ReadShort();
 +      }
 +
 +      if(sf & TNSF_MOVE)
 +      {
 +              self.origin_x = ReadShort();
 +              self.origin_y = ReadShort();
 +              self.origin_z = ReadShort();
 +              setorigin(self, self.origin);
 +
 +              self.velocity_x = ReadShort();
 +              self.velocity_y = ReadShort();
 +              self.velocity_z = ReadShort();
 +
 +              self.move_angles_y = ReadShort();
 +
 +              self.move_time   = time;
 +              self.move_velocity = self.velocity;
 +              self.move_origin   = self.origin;
 +      }
 +
 +      if(sf & TNSF_ANIM)
 +      {
 +              self.frame1time = ReadCoord();
 +              self.frame        = ReadByte();
 +      }
 +
 +      if(sf & TNSF_STATUS)
 +      {
 +              float _tmp;
 +              _tmp = ReadByte();
 +              if(_tmp != self.team)
 +              {
 +                      self.team = _tmp;
 +                      turret_changeteam();
 +              }
 +
 +              _tmp = ReadByte();
 +              if(_tmp == 0 && self.health != 0)
 +                      turret_die();
 +              else if(self.health && self.health != _tmp)
 +                      self.helpme = servertime + 10;
 +
 +              self.health = _tmp;
 +      }
 +      //self.enemy.health = self.health / 255;
 +}
index 91d427f,0000000..4c309b2
mode 100644,000000..100644
--- /dev/null
@@@ -1,1394 -1,0 +1,1394 @@@
- void turret_damage (entity inflictor, entity attacker, float damage, float deathtype, vector hitloc, vector vforce)
 +#ifdef SVQC
 +#include "../../server/autocvars.qh"
 +
 +// Generic aiming
 +vector turret_aim_generic()
 +{
 +
 +      vector pre_pos, prep;
 +      float distance, impact_time = 0, i, mintime;
 +
 +      turret_tag_fire_update();
 +
 +      if(self.aim_flags & TFL_AIM_SIMPLE)
 +              return real_origin(self.enemy);
 +
 +      mintime = max(self.attack_finished_single - time,0) + sys_frametime;
 +
 +      // Baseline
 +      pre_pos = real_origin(self.enemy);
 +
 +      // Lead?
 +      if (self.aim_flags & TFL_AIM_LEAD)
 +      {
 +              if (self.aim_flags & TFL_AIM_SHOTTIMECOMPENSATE)           // Need to conpensate for shot traveltime
 +              {
 +                      prep = pre_pos;
 +                      
 +                      distance = vlen(prep - self.tur_shotorg);
 +                      impact_time = distance / self.shot_speed;
 +
 +                      prep = pre_pos + (self.enemy.velocity * (impact_time + mintime));
 +
 +                      if(self.aim_flags & TFL_AIM_ZPREDICT)
 +                      if(!(self.enemy.flags & FL_ONGROUND))
 +                      if(self.enemy.movetype == MOVETYPE_WALK || self.enemy.movetype == MOVETYPE_TOSS || self.enemy.movetype == MOVETYPE_BOUNCE)
 +                      {
 +                              float vz;
 +                              prep_z = pre_pos_z;
 +                              vz = self.enemy.velocity_z;
 +                              for(i = 0; i < impact_time; i += sys_frametime)
 +                              {
 +                                      vz = vz - (autocvar_sv_gravity * sys_frametime);
 +                                      prep_z = prep_z + vz * sys_frametime;
 +                              }
 +                      }
 +                      pre_pos = prep;
 +              }
 +              else
 +                      pre_pos = pre_pos + self.enemy.velocity * mintime;
 +      }
 +
 +      if(self.aim_flags & TFL_AIM_SPLASH)
 +      {
 +              //tracebox(pre_pos + '0 0 32',self.enemy.mins,self.enemy.maxs,pre_pos -'0 0 64',MOVE_WORLDONLY,self.enemy);
 +              traceline(pre_pos + '0 0 32',pre_pos -'0 0 64',MOVE_WORLDONLY,self.enemy);
 +              if(trace_fraction != 1.0)
 +                      pre_pos = trace_endpos;
 +      }
 +
 +      return pre_pos;
 +}
 +
 +float turret_targetscore_support(entity _turret,entity _target)
 +{
 +      float score;            // Total score
 +      float s_score = 0, d_score;
 +
 +      if (_turret.enemy == _target) s_score = 1;
 +
 +      d_score = min(_turret.target_range_optimal,tvt_dist) / max(_turret.target_range_optimal,tvt_dist);
 +
 +      score = (d_score * _turret.target_select_rangebias) +
 +                      (s_score * _turret.target_select_samebias);
 +
 +      return score;
 +}
 +
 +/*
 +* Generic bias aware score system.
 +*/
 +float turret_targetscore_generic(entity _turret, entity _target)
 +{
 +      float d_dist;      // Defendmode Distance
 +      float score;            // Total score
 +      float d_score;    // Distance score
 +      float a_score;    // Angular score
 +      float m_score = 0;  // missile score
 +      float p_score = 0;  // player score
 +      float ikr;                // ideal kill range
 +
 +      if (_turret.tur_defend)
 +      {
 +              d_dist = vlen(real_origin(_target) - _turret.tur_defend.origin);
 +              ikr = vlen(_turret.origin - _turret.tur_defend.origin);
 +              d_score = 1 - d_dist / _turret.target_range;
 +      }
 +      else
 +      {
 +              // Make a normlized value base on the targets distance from our optimal killzone
 +              ikr = _turret.target_range_optimal;
 +              d_score = min(ikr, tvt_dist) / max(ikr, tvt_dist);
 +      }
 +
 +      a_score = 1 - tvt_thadf / _turret.aim_maxrotate;
 +
 +      if ((_turret.target_select_missilebias > 0) && (_target.flags & FL_PROJECTILE))
 +              m_score = 1;
 +
 +      if ((_turret.target_select_playerbias > 0) && IS_CLIENT(_target))
 +              p_score = 1;
 +
 +      d_score = max(d_score, 0);
 +      a_score = max(a_score, 0);
 +      m_score = max(m_score, 0);
 +      p_score = max(p_score, 0);
 +
 +      score = (d_score * _turret.target_select_rangebias) +
 +                      (a_score * _turret.target_select_anglebias) +
 +                      (m_score * _turret.target_select_missilebias) +
 +                      (p_score * _turret.target_select_playerbias);
 +
 +      if(_turret.target_range < vlen(_turret.tur_shotorg - real_origin(_target)))
 +      {
 +              //dprint("Wtf?\n");
 +              score *= 0.001;
 +      }
 +
 +#ifdef TURRET_DEBUG
 +      string sd,sa,sm,sp,ss;
 +      string sdt,sat,smt,spt;
 +
 +      sd = ftos(d_score);
 +      d_score *= _turret.target_select_rangebias;
 +      sdt = ftos(d_score);
 +
 +      //sv = ftos(v_score);
 +      //v_score *= _turret.target_select_samebias;
 +      //svt = ftos(v_score);
 +
 +      sa = ftos(a_score);
 +      a_score *= _turret.target_select_anglebias;
 +      sat = ftos(a_score);
 +
 +      sm = ftos(m_score);
 +      m_score *= _turret.target_select_missilebias;
 +      smt = ftos(m_score);
 +
 +      sp = ftos(p_score);
 +      p_score *= _turret.target_select_playerbias;
 +      spt = ftos(p_score);
 +
 +
 +      ss = ftos(score);
 +      bprint("^3Target scores^7 \[  ",_turret.netname, "  \] ^3for^7 \[  ", _target.netname,"  \]\n");
 +      bprint("^5Range:\[  ",sd,  "  \]^2+bias:\[  ",sdt,"  \]\n");
 +      bprint("^5Angle:\[  ",sa,  "  \]^2+bias:\[  ",sat,"  \]\n");
 +      bprint("^5Missile:\[  ",sm,"  \]^2+bias:\[  ",smt,"  \]\n");
 +      bprint("^5Player:\[  ",sp, "  \]^2+bias:\[  ",spt,"  \]\n");
 +      bprint("^3Total (w/bias):\[^1",ss,"\]\n");
 +
 +#endif
 +
 +      return score;
 +}
 +
 +// Generic damage handling
 +void turret_hide()
 +{
 +      self.effects   |= EF_NODRAW;
 +      self.nextthink = time + self.respawntime - 0.2;
 +      self.think       = turret_respawn;
 +}
 +
 +void turret_die()
 +{
 +      self.deadflag             = DEAD_DEAD;
 +      self.tur_head.deadflag = self.deadflag;
 +
 +// Unsolidify and hide real parts
 +      self.solid                       = SOLID_NOT;
 +      self.tur_head.solid      = self.solid;
 +
 +      self.event_damage                 = func_null;
 +      self.takedamage                  = DAMAGE_NO;
 +
 +      self.health                      = 0;
 +
 +// Go boom
 +      //RadiusDamage (self,self, min(self.ammo,50),min(self.ammo,50) * 0.25,250,world,min(self.ammo,50)*5,DEATH_TURRET,world);
 +
 +      if(self.damage_flags & TFL_DMG_DEATH_NORESPAWN)
 +      {
 +              TUR_ACTION(self.turretid, TR_DEATH);
 +
 +              remove(self.tur_head);
 +              remove(self);
 +      }
 +      else
 +      {
 +              // Setup respawn
 +              self.SendFlags    |= TNSF_STATUS;
 +              self.nextthink   = time + 0.2;
 +              self.think               = turret_hide;
 +
 +              TUR_ACTION(self.turretid, TR_DEATH);
 +      }
 +}
 +
- void turret_projectile_damage(entity inflictor, entity attacker, float damage, float deathtype, vector hitloc, vector vforce)
++void turret_damage (entity inflictor, entity attacker, float damage, int deathtype, vector hitloc, vector vforce)
 +{
 +      // Enough already!
 +      if(self.deadflag == DEAD_DEAD)
 +              return;
 +
 +      // Inactive turrets take no damage. (hm..)
 +      if(!self.active)
 +              return;
 +
 +      if(SAME_TEAM(self, attacker))
 +      {
 +              if(autocvar_g_friendlyfire)
 +                      damage = damage * autocvar_g_friendlyfire;
 +              else
 +                      return;
 +      }
 +
 +      self.health -= damage;
 +
 +      // thorw head slightly off aim when hit?
 +      if (self.damage_flags & TFL_DMG_HEADSHAKE)
 +      {
 +              self.tur_head.angles_x = self.tur_head.angles_x + (-0.5 + random()) * damage;
 +              self.tur_head.angles_y = self.tur_head.angles_y + (-0.5 + random()) * damage;
 +
 +              self.SendFlags  |= TNSF_ANG;
 +      }
 +
 +      if (self.turret_flags & TUR_FLAG_MOVE)
 +              self.velocity = self.velocity + vforce;
 +
 +      if (self.health <= 0)
 +      {
 +              self.event_damage                 = func_null;
 +              self.tur_head.event_damage = func_null;
 +              self.takedamage                  = DAMAGE_NO;
 +              self.nextthink = time;
 +              self.think = turret_die;
 +      }
 +
 +      self.SendFlags  |= TNSF_STATUS;
 +}
 +
 +void() turret_think;
 +void turret_respawn()
 +{
 +      // Make sure all parts belong to the same team since
 +      // this function doubles as "teamchange" function.
 +      self.tur_head.team      = self.team;
 +      self.effects                       &= ~EF_NODRAW;
 +      self.deadflag                           = DEAD_NO;
 +      self.effects                            = EF_LOWPRECISION;
 +      self.solid                                      = SOLID_BBOX;
 +      self.takedamage                         = DAMAGE_AIM;
 +      self.event_damage                       = turret_damage;
 +      self.avelocity                          = '0 0 0';
 +      self.tur_head.avelocity         = self.avelocity;
 +      self.tur_head.angles            = self.idle_aim;
 +      self.health                                     = self.max_health;
 +      self.enemy                                      = world;
 +      self.volly_counter                      = self.shot_volly;
 +      self.ammo                                       = self.ammo_max;
 +
 +      self.nextthink = time + self.ticrate;
 +      self.think       = turret_think;
 +
 +      self.SendFlags = TNSF_FULL_UPDATE;
 +      
 +      TUR_ACTION(self.turretid, TR_SETUP);
 +}
 +
 +
 +// Main functions
 +#define cvar_base "g_turrets_unit_"
 +.float clientframe;
 +void turrets_setframe(float _frame, float client_only)
 +{
 +      if((client_only ? self.clientframe : self.frame ) != _frame)
 +      {
 +              self.SendFlags |= TNSF_ANIM;
 +              self.anim_start_time = time;
 +      }
 +
 +       if(client_only)
 +              self.clientframe = _frame;
 +      else
 +              self.frame = _frame;
 +
 +}
 +
 +float turret_send(entity to, float sf)
 +{
 +
 +      WriteByte(MSG_ENTITY, ENT_CLIENT_TURRET);
 +      WriteByte(MSG_ENTITY, sf);
 +      if(sf & TNSF_SETUP)
 +      {
 +              WriteByte(MSG_ENTITY, self.turretid);
 +
 +              WriteCoord(MSG_ENTITY, self.origin_x);
 +              WriteCoord(MSG_ENTITY, self.origin_y);
 +              WriteCoord(MSG_ENTITY, self.origin_z);
 +
 +              WriteAngle(MSG_ENTITY, self.angles_x);
 +              WriteAngle(MSG_ENTITY, self.angles_y);
 +      }
 +
 +      if(sf & TNSF_ANG)
 +      {
 +              WriteShort(MSG_ENTITY, rint(self.tur_head.angles_x));
 +              WriteShort(MSG_ENTITY, rint(self.tur_head.angles_y));
 +      }
 +
 +      if(sf & TNSF_AVEL)
 +      {
 +              WriteShort(MSG_ENTITY, rint(self.tur_head.avelocity_x));
 +              WriteShort(MSG_ENTITY, rint(self.tur_head.avelocity_y));
 +      }
 +
 +      if(sf & TNSF_MOVE)
 +      {
 +              WriteShort(MSG_ENTITY, rint(self.origin_x));
 +              WriteShort(MSG_ENTITY, rint(self.origin_y));
 +              WriteShort(MSG_ENTITY, rint(self.origin_z));
 +
 +              WriteShort(MSG_ENTITY, rint(self.velocity_x));
 +              WriteShort(MSG_ENTITY, rint(self.velocity_y));
 +              WriteShort(MSG_ENTITY, rint(self.velocity_z));
 +
 +              WriteShort(MSG_ENTITY, rint(self.angles_y));
 +      }
 +
 +      if(sf & TNSF_ANIM)
 +      {
 +              WriteCoord(MSG_ENTITY, self.anim_start_time);
 +              WriteByte(MSG_ENTITY, self.frame);
 +      }
 +
 +      if(sf & TNSF_STATUS)
 +      {
 +              WriteByte(MSG_ENTITY, self.team);
 +
 +              if(self.health <= 0)
 +                      WriteByte(MSG_ENTITY, 0);
 +              else
 +                      WriteByte(MSG_ENTITY, ceil((self.health / self.max_health) * 255));
 +      }
 +
 +      return true;
 +}
 +
 +void load_unit_settings(entity ent, string unitname, float is_reload)
 +{
 +      string sbase;
 +
 +      if (ent == world)
 +              return;
 +
 +      if(!ent.turret_scale_damage)    ent.turret_scale_damage = 1;
 +      if(!ent.turret_scale_range)             ent.turret_scale_range  = 1;
 +      if(!ent.turret_scale_refire)    ent.turret_scale_refire = 1;
 +      if(!ent.turret_scale_ammo)              ent.turret_scale_ammo   = 1;
 +      if(!ent.turret_scale_aim)               ent.turret_scale_aim     = 1;
 +      if(!ent.turret_scale_health)    ent.turret_scale_health = 1;
 +      if(!ent.turret_scale_respawn)   ent.turret_scale_respawn = 1;
 +
 +      sbase = strcat(cvar_base,unitname);
 +      if (is_reload)
 +      {
 +              ent.enemy = world;
 +              ent.tur_head.avelocity = '0 0 0';
 +
 +              ent.tur_head.angles = '0 0 0';
 +      }
 +
 +      ent.health       = cvar(strcat(sbase,"_health")) * ent.turret_scale_health;
 +      ent.respawntime = cvar(strcat(sbase,"_respawntime")) * ent.turret_scale_respawn;
 +
 +      ent.shot_dmg             = cvar(strcat(sbase,"_shot_dmg")) * ent.turret_scale_damage;
 +      ent.shot_refire   = cvar(strcat(sbase,"_shot_refire")) * ent.turret_scale_refire;
 +      ent.shot_radius   = cvar(strcat(sbase,"_shot_radius")) * ent.turret_scale_damage;
 +      ent.shot_speed          = cvar(strcat(sbase,"_shot_speed"));
 +      ent.shot_spread   = cvar(strcat(sbase,"_shot_spread"));
 +      ent.shot_force          = cvar(strcat(sbase,"_shot_force")) * ent.turret_scale_damage;
 +      ent.shot_volly          = cvar(strcat(sbase,"_shot_volly"));
 +      ent.shot_volly_refire = cvar(strcat(sbase,"_shot_volly_refire")) * ent.turret_scale_refire;
 +
 +      ent.target_range                 = cvar(strcat(sbase,"_target_range")) * ent.turret_scale_range;
 +      ent.target_range_min     = cvar(strcat(sbase,"_target_range_min")) * ent.turret_scale_range;
 +      ent.target_range_optimal = cvar(strcat(sbase,"_target_range_optimal")) * ent.turret_scale_range;
 +      //ent.target_range_fire = cvar(strcat(sbase,"_target_range_fire")) * ent.turret_scale_range;
 +
 +      ent.target_select_rangebias = cvar(strcat(sbase,"_target_select_rangebias"));
 +      ent.target_select_samebias  = cvar(strcat(sbase,"_target_select_samebias"));
 +      ent.target_select_anglebias = cvar(strcat(sbase,"_target_select_anglebias"));
 +      ent.target_select_playerbias = cvar(strcat(sbase,"_target_select_playerbias"));
 +      //ent.target_select_fov = cvar(cvar_gets(sbase,"_target_select_fov"));
 +
 +      ent.ammo_max     = cvar(strcat(sbase,"_ammo_max")) * ent.turret_scale_ammo;
 +      ent.ammo_recharge = cvar(strcat(sbase,"_ammo_recharge")) * ent.turret_scale_ammo;
 +
 +      ent.aim_firetolerance_dist = cvar(strcat(sbase,"_aim_firetolerance_dist"));
 +      ent.aim_speed   = cvar(strcat(sbase,"_aim_speed")) * ent.turret_scale_aim;
 +      ent.aim_maxrotate  = cvar(strcat(sbase,"_aim_maxrot"));
 +      ent.aim_maxpitch = cvar(strcat(sbase,"_aim_maxpitch"));
 +
 +      ent.track_type          = cvar(strcat(sbase,"_track_type"));
 +      ent.track_accel_pitch = cvar(strcat(sbase,"_track_accel_pitch"));
 +      ent.track_accel_rotate  = cvar(strcat(sbase,"_track_accel_rot"));
 +      ent.track_blendrate  = cvar(strcat(sbase,"_track_blendrate"));
 +
 +      if(is_reload)
 +              TUR_ACTION(self.turretid, TR_SETUP);
 +}
 +
 +void turret_projectile_explode()
 +{
 +
 +      self.takedamage = DAMAGE_NO;
 +      self.event_damage = func_null;
 +#ifdef TURRET_DEBUG
 +      float d;
 +      d = RadiusDamage (self, self.owner, self.owner.shot_dmg, 0, self.owner.shot_radius, self, world, self.owner.shot_force, self.totalfrags, world);
 +      self.owner.tur_debug_dmg_t_h = self.owner.tur_debug_dmg_t_h + d;
 +      self.owner.tur_debug_dmg_t_f = self.owner.tur_debug_dmg_t_f + self.owner.shot_dmg;
 +#else
 +      RadiusDamage (self, self.realowner, self.owner.shot_dmg, 0, self.owner.shot_radius, self, world, self.owner.shot_force, self.totalfrags, world);
 +#endif
 +      remove(self);
 +}
 +
 +void turret_projectile_touch()
 +{
 +      PROJECTILE_TOUCH;
 +      turret_projectile_explode();
 +}
 +
-       if(e_target.vehicle_flags & VHF_ISVEHICLE)
++void turret_projectile_damage(entity inflictor, entity attacker, float damage, int deathtype, vector hitloc, vector vforce)
 +{
 +      self.velocity  += vforce;
 +      self.health     -= damage;
 +      //self.realowner = attacker; // Dont change realowner, it does not make much sense for turrets
 +      if(self.health <= 0)
 +              W_PrepareExplosionByDamage(self.owner, turret_projectile_explode);
 +}
 +
 +entity turret_projectile(string _snd, float _size, float _health, float _death, float _proj_type, float _cull, float _cli_anim)
 +{
 +      entity proj;
 +
 +      sound (self, CH_WEAPON_A, _snd, VOL_BASE, ATTEN_NORM);
 +      proj                             = spawn ();
 +      setorigin(proj, self.tur_shotorg);
 +      setsize(proj, '-0.5 -0.5 -0.5' * _size, '0.5 0.5 0.5' * _size);
 +      proj.owner                = self;
 +      proj.realowner    = self;
 +      proj.bot_dodge    = true;
 +      proj.bot_dodgerating = self.shot_dmg;
 +      proj.think                = turret_projectile_explode;
 +      proj.touch                = turret_projectile_touch;
 +      proj.nextthink    = time + 9;
 +      proj.movetype           = MOVETYPE_FLYMISSILE;
 +      proj.velocity           = normalize(self.tur_shotdir_updated + randomvec() * self.shot_spread) * self.shot_speed;
 +      proj.flags                = FL_PROJECTILE;
 +      proj.enemy                = self.enemy;
 +      proj.totalfrags  = _death;
 +      PROJECTILE_MAKETRIGGER(proj);
 +      if(_health)
 +      {
 +              proj.health              = _health;
 +              proj.takedamage  = DAMAGE_YES;
 +              proj.event_damage  = turret_projectile_damage;
 +      }
 +      else
 +              proj.flags |= FL_NOTARGET;
 +
 +      CSQCProjectile(proj, _cli_anim, _proj_type, _cull);
 +
 +      return proj;
 +}
 +
 +/**
 +** updates enemy distances, predicted impact point/time
 +** and updated aim<->predict impact distance.
 +**/
 +void turret_do_updates(entity t_turret)
 +{
 +      vector enemy_pos;
 +      entity oldself;
 +
 +      oldself = self;
 +      self = t_turret;
 +
 +      enemy_pos = real_origin(self.enemy);
 +
 +      turret_tag_fire_update();
 +
 +      self.tur_shotdir_updated = v_forward;
 +      self.tur_dist_enemy = vlen(self.tur_shotorg - enemy_pos);
 +      self.tur_dist_aimpos = vlen(self.tur_shotorg - self.tur_aimpos);
 +
 +      /*if((self.firecheck_flags & TFL_FIRECHECK_VERIFIED) && (self.enemy))
 +      {
 +              oldpos = self.enemy.origin;
 +              setorigin(self.enemy, self.tur_aimpos);
 +              tracebox(self.tur_shotorg, '-1 -1 -1', '1 1 1', self.tur_shotorg + (self.tur_shotdir_updated * self.tur_dist_aimpos), MOVE_NORMAL,self);
 +              setorigin(self.enemy, oldpos);
 +
 +              if(trace_ent == self.enemy)
 +                      self.tur_dist_impact_to_aimpos = 0;
 +              else
 +                      self.tur_dist_impact_to_aimpos = vlen(trace_endpos - self.tur_aimpos);
 +      }
 +      else*/
 +              tracebox(self.tur_shotorg, '-1 -1 -1','1 1 1', self.tur_shotorg + (self.tur_shotdir_updated * self.tur_dist_aimpos), MOVE_NORMAL,self);
 +
 +      self.tur_dist_impact_to_aimpos = vlen(trace_endpos - self.tur_aimpos) - (vlen(self.enemy.maxs - self.enemy.mins) * 0.5);
 +      self.tur_impactent                       = trace_ent;
 +      self.tur_impacttime                     = vlen(self.tur_shotorg - trace_endpos) / self.shot_speed;
 +
 +      self = oldself;
 +}
 +
 +/**
 +** Handles head rotation according to
 +** the units .track_type and .track_flags
 +**/
 +.float turret_framecounter;
 +void turret_track()
 +{
 +      vector target_angle; // This is where we want to aim
 +      vector move_angle;   // This is where we can aim
 +      float f_tmp;
 +      vector v1, v2;
 +      v1 = self.tur_head.angles;
 +      v2 = self.tur_head.avelocity;
 +
 +      if (self.track_flags == TFL_TRACK_NO)
 +              return;
 +
 +      if(!self.active)
 +              target_angle = self.idle_aim - ('1 0 0' * self.aim_maxpitch);
 +      else if (self.enemy == world)
 +      {
 +              if(time > self.lip)
 +                      target_angle = self.idle_aim + self.angles;
 +              else
 +                      target_angle = vectoangles(normalize(self.tur_aimpos - self.tur_shotorg));
 +      }
 +      else
 +      {
 +              target_angle = vectoangles(normalize(self.tur_aimpos - self.tur_shotorg));
 +      }
 +
 +      self.tur_head.angles_x = anglemods(self.tur_head.angles_x);
 +      self.tur_head.angles_y = anglemods(self.tur_head.angles_y);
 +
 +      // Find the diffrence between where we currently aim and where we want to aim
 +      //move_angle = target_angle - (self.angles + self.tur_head.angles);
 +      //move_angle = shortangle_vxy(move_angle,(self.angles + self.tur_head.angles));
 +
 +      move_angle = AnglesTransform_ToAngles(AnglesTransform_LeftDivide(AnglesTransform_FromAngles(self.angles), AnglesTransform_FromAngles(target_angle))) - self.tur_head.angles;
 +      move_angle = shortangle_vxy(move_angle, self.tur_head.angles);
 +
 +      switch(self.track_type)
 +      {
 +              case TFL_TRACKTYPE_STEPMOTOR:
 +                      f_tmp = self.aim_speed * self.ticrate; // dgr/sec -> dgr/tic
 +                      if (self.track_flags & TFL_TRACK_PITCH)
 +                      {
 +                              self.tur_head.angles_x += bound(-f_tmp,move_angle_x, f_tmp);
 +                              if(self.tur_head.angles_x > self.aim_maxpitch)
 +                                      self.tur_head.angles_x = self.aim_maxpitch;
 +
 +                              if(self.tur_head.angles_x  < -self.aim_maxpitch)
 +                                      self.tur_head.angles_x = self.aim_maxpitch;
 +                      }
 +
 +                      if (self.track_flags & TFL_TRACK_ROTATE)
 +                      {
 +                              self.tur_head.angles_y += bound(-f_tmp, move_angle_y, f_tmp);
 +                              if(self.tur_head.angles_y > self.aim_maxrotate)
 +                                      self.tur_head.angles_y = self.aim_maxrotate;
 +
 +                              if(self.tur_head.angles_y  < -self.aim_maxrotate)
 +                                      self.tur_head.angles_y = self.aim_maxrotate;
 +                      }
 +
 +                      // CSQC
 +                      self.SendFlags  |= TNSF_ANG;
 +
 +                      return;
 +
 +              case TFL_TRACKTYPE_FLUIDINERTIA:
 +                      f_tmp = self.aim_speed * self.ticrate; // dgr/sec -> dgr/tic
 +                      move_angle_x = bound(-self.aim_speed, move_angle_x * self.track_accel_pitch * f_tmp, self.aim_speed);
 +                      move_angle_y = bound(-self.aim_speed, move_angle_y * self.track_accel_rotate * f_tmp, self.aim_speed);
 +                      move_angle = (self.tur_head.avelocity * self.track_blendrate) + (move_angle * (1 - self.track_blendrate));
 +                      break;
 +
 +              case TFL_TRACKTYPE_FLUIDPRECISE:
 +
 +                      move_angle_y = bound(-self.aim_speed, move_angle_y, self.aim_speed);
 +                      move_angle_x = bound(-self.aim_speed, move_angle_x, self.aim_speed);
 +
 +                      break;
 +      }
 +
 +      //  pitch
 +      if (self.track_flags & TFL_TRACK_PITCH)
 +      {
 +              self.tur_head.avelocity_x = move_angle_x;
 +              if((self.tur_head.angles_x + self.tur_head.avelocity_x * self.ticrate) > self.aim_maxpitch)
 +              {
 +                      self.tur_head.avelocity_x = 0;
 +                      self.tur_head.angles_x = self.aim_maxpitch;
 +
 +                      self.SendFlags  |= TNSF_ANG;
 +              }
 +
 +              if((self.tur_head.angles_x + self.tur_head.avelocity_x * self.ticrate) < -self.aim_maxpitch)
 +              {
 +                      self.tur_head.avelocity_x = 0;
 +                      self.tur_head.angles_x = -self.aim_maxpitch;
 +
 +                      self.SendFlags  |= TNSF_ANG;
 +              }
 +      }
 +
 +      //  rot
 +      if (self.track_flags & TFL_TRACK_ROTATE)
 +      {
 +              self.tur_head.avelocity_y = move_angle_y;
 +
 +              if((self.tur_head.angles_y + self.tur_head.avelocity_y * self.ticrate) > self.aim_maxrotate)
 +              {
 +                      self.tur_head.avelocity_y = 0;
 +                      self.tur_head.angles_y = self.aim_maxrotate;
 +
 +                      self.SendFlags  |= TNSF_ANG;
 +              }
 +
 +              if((self.tur_head.angles_y + self.tur_head.avelocity_y * self.ticrate) < -self.aim_maxrotate)
 +              {
 +                      self.tur_head.avelocity_y = 0;
 +                      self.tur_head.angles_y = -self.aim_maxrotate;
 +
 +                      self.SendFlags  |= TNSF_ANG;
 +              }
 +      }
 +
 +      self.SendFlags  |= TNSF_AVEL;
 +
 +      // Force a angle update every 10'th frame
 +      self.turret_framecounter += 1;
 +      if(self.turret_framecounter >= 10)
 +      {
 +              self.SendFlags |= TNSF_ANG;
 +              self.turret_framecounter = 0;
 +      }
 +}
 +
 +/*
 + + TFL_TARGETSELECT_NO
 + + TFL_TARGETSELECT_LOS
 + + TFL_TARGETSELECT_PLAYERS
 + + TFL_TARGETSELECT_MISSILES
 + - TFL_TARGETSELECT_TRIGGERTARGET
 + + TFL_TARGETSELECT_ANGLELIMITS
 + + TFL_TARGETSELECT_RANGELIMITS
 + + TFL_TARGETSELECT_TEAMCHECK
 + - TFL_TARGETSELECT_NOBUILTIN
 + + TFL_TARGETSELECT_OWNTEAM
 +*/
 +
 +/**
 +** Evaluate a entity for target valitity based on validate_flags
 +** NOTE: the caller must check takedamage before calling this, to inline this check.
 +**/
 +float turret_validate_target(entity e_turret, entity e_target, float validate_flags)
 +{
 +      vector v_tmp;
 +
 +      //if(!validate_flags & TFL_TARGETSELECT_NOBUILTIN)
 +      //      return -0.5;
 +
 +      if(!e_target)
 +              return -2;
 +
 +      if(e_target.owner == e_turret)
 +              return -0.5;
 +
 +      if(!checkpvs(e_target.origin, e_turret))
 +              return -1;
 +
 +      if(e_target.alpha <= 0.3)
 +              return -1;
 +
 +      if(g_onslaught)
 +              if (substring(e_target.classname, 0, 10) == "onslaught_") // don't attack onslaught targets, that's the player's job!
 +                      return - 3;
 +
 +      if (validate_flags & TFL_TARGETSELECT_NO)
 +              return -4;
 +
 +      // If only this was used more..
 +      if (e_target.flags & FL_NOTARGET)
 +              return -5;
 +
 +      // Cant touch this
-                       if (e.turret_flags & TUR_FLAG_ISTURRET)
++      if(IS_VEHICLE(e_target))
 +      {
 +              if (e_target.vehicle_health <= 0)
 +                      return -6;
 +      }
 +      else if (e_target.health <= 0)
 +              return -6;
 +      else if(e_target.frozen > 0)
 +              return -6;
 +
 +      // player
 +      if (IS_CLIENT(e_target))
 +      {
 +              if(!(validate_flags & TFL_TARGETSELECT_PLAYERS))
 +                      return -7;
 +
 +              if (e_target.deadflag != DEAD_NO)
 +                      return -8;
 +      }
 +
 +      // enemy turrets
 +      if(validate_flags & TFL_TARGETSELECT_NOTURRETS)
 +      if(e_target.owner.tur_head == e_target)
 +      if(e_target.team != e_turret.team) // Dont break support units.
 +              return -9;
 +
 +      // Missile
 +      if (e_target.flags & FL_PROJECTILE)
 +      if(!(validate_flags & TFL_TARGETSELECT_MISSILES))
 +              return -10;
 +
 +      if (validate_flags & TFL_TARGETSELECT_MISSILESONLY)
 +      if(!(e_target.flags & FL_PROJECTILE))
 +              return -10.5;
 +
 +      // Team check
 +      if (validate_flags & TFL_TARGETSELECT_TEAMCHECK)
 +      {
 +              if (validate_flags & TFL_TARGETSELECT_OWNTEAM)
 +              {
 +                      if (e_target.team != e_turret.team)
 +                              return -11;
 +
 +                      if (e_turret.team != e_target.owner.team)
 +                              return -12;
 +              }
 +              else
 +              {
 +                      if (e_target.team == e_turret.team)
 +                              return -13;
 +
 +                      if (e_turret.team == e_target.owner.team)
 +                              return -14;
 +              }
 +      }
 +
 +      // Range limits?
 +      tvt_dist = vlen(e_turret.origin - real_origin(e_target));
 +      if (validate_flags & TFL_TARGETSELECT_RANGELIMITS)
 +      {
 +              if (tvt_dist < e_turret.target_range_min)
 +                      return -15;
 +
 +              if (tvt_dist > e_turret.target_range)
 +                      return -16;
 +      }
 +
 +      // Can we even aim this thing?
 +      tvt_thadv = angleofs3(e_turret.tur_head.origin, e_turret.angles + e_turret.tur_head.angles, e_target);
 +      tvt_tadv = shortangle_vxy(angleofs(e_turret, e_target), e_turret.angles);
 +      tvt_thadf = vlen(tvt_thadv);
 +      tvt_tadf = vlen(tvt_tadv);
 +
 +      /*
 +      if(validate_flags & TFL_TARGETSELECT_FOV)
 +      {
 +              if(e_turret.target_select_fov < tvt_thadf)
 +                      return -21;
 +      }
 +      */
 +
 +      if (validate_flags & TFL_TARGETSELECT_ANGLELIMITS)
 +      {
 +              if (fabs(tvt_tadv_x) > e_turret.aim_maxpitch)
 +                      return -17;
 +
 +              if (fabs(tvt_tadv_y) > e_turret.aim_maxrotate)
 +                      return -18;
 +      }
 +
 +      // Line of sight?
 +      if (validate_flags & TFL_TARGETSELECT_LOS)
 +      {
 +              v_tmp = real_origin(e_target) + ((e_target.mins + e_target.maxs) * 0.5);
 +
 +              traceline(e_turret.origin + '0 0 16', v_tmp, 0, e_turret);
 +
 +              if (e_turret.aim_firetolerance_dist < vlen(v_tmp - trace_endpos))
 +                      return -19;
 +      }
 +
 +      if (e_target.classname == "grapplinghook")
 +              return -20;
 +
 +      /*
 +      if (e_target.classname == "func_button")
 +              return -21;
 +      */
 +
 +#ifdef TURRET_DEBUG_TARGETSELECT
 +      dprint("Target:",e_target.netname," is a valid target for ",e_turret.netname,"\n");
 +#endif
 +
 +      return 1;
 +}
 +
 +entity turret_select_target()
 +{
 +      entity e;               // target looper entity
 +      float  score;   // target looper entity score
 +      entity e_enemy;  // currently best scoreing target
 +      float  m_score;  // currently best scoreing target's score
 +
 +      m_score = 0;
 +      if(self.enemy && self.enemy.takedamage && turret_validate_target(self,self.enemy,self.target_validate_flags) > 0)
 +      {
 +              e_enemy = self.enemy;
 +              m_score = self.turret_score_target(self,e_enemy) * self.target_select_samebias;
 +      }
 +      else
 +              e_enemy = self.enemy = world;
 +
 +      e = findradius(self.origin, self.target_range);
 +
 +      // Nothing to aim at?
 +      if (!e)
 +              return world;
 +
 +      while (e)
 +      {
 +              if(e.takedamage)
 +              {
 +                      float f = turret_validate_target(self, e, self.target_select_flags);
 +                      //dprint("F is: ", ftos(f), "\n");
 +                      if ( f > 0)
 +                      {
 +                              score = self.turret_score_target(self,e);
 +                              if ((score > m_score) && (score > 0))
 +                              {
 +                                      e_enemy = e;
 +                                      m_score = score;
 +                              }
 +                      }
 +              }
 +              e = e.chain;
 +      }
 +
 +      return e_enemy;
 +}
 +
 +
 +/*
 + + = implemented
 + - = not implemented
 +
 + + TFL_FIRECHECK_NO
 + + TFL_FIRECHECK_WORLD
 + + TFL_FIRECHECK_DEAD
 + + TFL_FIRECHECK_DISTANCES
 + - TFL_FIRECHECK_LOS
 + + TFL_FIRECHECK_AIMDIST
 + + TFL_FIRECHECK_REALDIST
 + - TFL_FIRECHECK_ANGLEDIST
 + - TFL_FIRECHECK_TEAMCECK
 + + TFL_FIRECHECK_AFF
 + + TFL_FIRECHECK_AMMO_OWN
 + + TFL_FIRECHECK_AMMO_OTHER
 + + TFL_FIRECHECK_REFIRE
 +*/
 +
 +/**
 +** Preforms pre-fire checks based on the uints firecheck_flags
 +**/
 +float turret_firecheck()
 +{
 +      // This one just dont care =)
 +      if (self.firecheck_flags & TFL_FIRECHECK_NO)
 +              return 1;
 +
 +      if (self.enemy == world)
 +              return 0;
 +
 +      // Ready?
 +      if (self.firecheck_flags & TFL_FIRECHECK_REFIRE)
 +              if (self.attack_finished_single > time) return 0;
 +
 +      // Special case: volly fire turret that has to fire a full volly if a shot was fired.
 +      if (self.shoot_flags & TFL_SHOOT_VOLLYALWAYS)
 +              if (self.volly_counter != self.shot_volly)
 +                      if(self.ammo >= self.shot_dmg)
 +                              return 1;
 +
 +      // Lack of zombies makes shooting dead things unnecessary :P
 +      if (self.firecheck_flags & TFL_FIRECHECK_DEAD)
 +              if (self.enemy.deadflag != DEAD_NO)
 +                      return 0;
 +
 +      // Own ammo?
 +      if (self.firecheck_flags & TFL_FIRECHECK_AMMO_OWN)
 +              if (self.ammo < self.shot_dmg)
 +                      return 0;
 +
 +      // Other's ammo? (support-supply units)
 +      if (self.firecheck_flags & TFL_FIRECHECK_AMMO_OTHER)
 +              if (self.enemy.ammo >= self.enemy.ammo_max)
 +                      return 0;
 +
 +      // Target of opertunity?
 +      if(turret_validate_target(self, self.tur_impactent, self.target_validate_flags) > 0)
 +      {
 +              self.enemy = self.tur_impactent;
 +              return 1;
 +      }
 +
 +      if (self.firecheck_flags & TFL_FIRECHECK_DISTANCES)
 +      {
 +              // To close?
 +              if (self.tur_dist_aimpos < self.target_range_min)
 +                      if(turret_validate_target(self, self.tur_impactent, self.target_validate_flags) > 0)
 +                              return 1; // Target of opertunity?
 +                      else
 +                              return 0;
 +      }
 +
 +      // Try to avoid FF?
 +      if (self.firecheck_flags & TFL_FIRECHECK_AFF)
 +              if (self.tur_impactent.team == self.team)
 +                      return 0;
 +
 +      // aim<->predicted impact
 +      if (self.firecheck_flags & TFL_FIRECHECK_AIMDIST)
 +              if (self.tur_dist_impact_to_aimpos > self.aim_firetolerance_dist)
 +                      return 0;
 +
 +      // Volly status
 +      if (self.shot_volly > 1)
 +              if (self.volly_counter == self.shot_volly)
 +                      if (self.ammo < (self.shot_dmg * self.shot_volly))
 +                              return 0;
 +
 +      /*if(self.firecheck_flags & TFL_FIRECHECK_VERIFIED)
 +              if(self.tur_impactent != self.enemy)
 +                      return 0;*/
 +
 +      return 1;
 +}
 +
 +void turret_fire()
 +{
 +      if (autocvar_g_turrets_nofire != 0)
 +              return;
 +              
 +      TUR_ACTION(self.turretid, TR_ATTACK);
 +
 +      self.attack_finished_single = time + self.shot_refire;
 +      self.ammo -= self.shot_dmg;
 +      self.volly_counter = self.volly_counter - 1;
 +
 +      if (self.volly_counter <= 0)
 +      {
 +              self.volly_counter = self.shot_volly;
 +
 +              if (self.shoot_flags & TFL_SHOOT_CLEARTARGET)
 +                      self.enemy = world;
 +
 +              if (self.shot_volly > 1)
 +                      self.attack_finished_single = time + self.shot_volly_refire;
 +      }
 +
 +#ifdef TURRET_DEBUG
 +      if (self.enemy) paint_target3(self.tur_aimpos, 64, self.tur_debug_rvec, self.tur_impacttime + 0.25);
 +#endif
 +}
 +
 +void turret_think()
 +{
 +      entity e;
 +
 +      self.nextthink = time + self.ticrate;
 +
 +      // ONS uses somewhat backwards linking.
 +      if (teamplay)
 +      {
 +              if (g_onslaught)
 +                      if (self.target)
 +                      {
 +                              e = find(world, targetname,self.target);
 +                              if (e != world)
 +                                      self.team = e.team;
 +                      }
 +
 +              if (self.team != self.tur_head.team)
 +                      turret_respawn();
 +      }
 +
 +#ifdef TURRET_DEBUG
 +      if (self.tur_debug_tmr1 < time)
 +      {
 +              if (self.enemy) paint_target (self.enemy,128,self.tur_debug_rvec,0.9);
 +              paint_target(self,256,self.tur_debug_rvec,0.9);
 +              self.tur_debug_tmr1 = time + 1;
 +      }
 +#endif
 +
 +      // Handle ammo
 +      if (!(self.spawnflags & TSF_NO_AMMO_REGEN))
 +      if (self.ammo < self.ammo_max)
 +              self.ammo = min(self.ammo + self.ammo_recharge, self.ammo_max);
 +
 +      // Inactive turrets needs to run the think loop,
 +      // So they can handle animation and wake up if need be.
 +      if(!self.active)
 +      {
 +              turret_track();
 +              return;
 +      }
 +
 +      // This is typicaly used for zaping every target in range
 +      // turret_fusionreactor uses this to recharge friendlys.
 +      if (self.shoot_flags & TFL_SHOOT_HITALLVALID)
 +      {
 +              // Do a self.turret_fire for every valid target.
 +              e = findradius(self.origin,self.target_range);
 +              while (e)
 +              {
 +                      if(e.takedamage)
 +                      {
 +                              if (turret_validate_target(self,e,self.target_validate_flags))
 +                              {
 +                                      self.enemy = e;
 +
 +                                      turret_do_updates(self);
 +
 +                                      if (self.turret_firecheckfunc())
 +                                              turret_fire();
 +                              }
 +                      }
 +
 +                      e = e.chain;
 +              }
 +              self.enemy = world;
 +      }
 +      else if(self.shoot_flags & TFL_SHOOT_CUSTOM)
 +      {
 +              // This one is doing something.. oddball. assume its handles what needs to be handled.
 +
 +              // Predict?
 +              if(!(self.aim_flags & TFL_AIM_NO))
 +                      self.tur_aimpos = turret_aim_generic();
 +
 +              // Turn & pitch?
 +              if(!(self.track_flags & TFL_TRACK_NO))
 +                      turret_track();
 +
 +              turret_do_updates(self);
 +
 +              // Fire?
 +              if (self.turret_firecheckfunc())
 +                      turret_fire();
 +      }
 +      else
 +      {
 +              // Special case for volly always. if it fired once it must compleate the volly.
 +              if(self.shoot_flags & TFL_SHOOT_VOLLYALWAYS)
 +                      if(self.volly_counter != self.shot_volly)
 +                      {
 +                              // Predict or whatnot
 +                              if(!(self.aim_flags & TFL_AIM_NO))
 +                                      self.tur_aimpos = turret_aim_generic();
 +
 +                              // Turn & pitch
 +                              if(!(self.track_flags & TFL_TRACK_NO))
 +                                      turret_track();
 +
 +                              turret_do_updates(self);
 +
 +                              // Fire!
 +                              if (self.turret_firecheckfunc() != 0)
 +                                      turret_fire();
 +                                      
 +                              TUR_ACTION(self.turretid, TR_THINK);
 +
 +                              return;
 +                      }
 +
 +              // Check if we have a vailid enemy, and try to find one if we dont.
 +
 +              // g_turrets_targetscan_maxdelay forces a target re-scan at least this often
 +              float do_target_scan = 0;
 +              if((self.target_select_time + autocvar_g_turrets_targetscan_maxdelay) < time)
 +                      do_target_scan = 1;
 +
 +              // Old target (if any) invalid?
 +              if(self.target_validate_time < time)
 +              if (turret_validate_target(self, self.enemy, self.target_validate_flags) <= 0)
 +              {
 +                      self.enemy = world;
 +                      self.target_validate_time = time + 0.5;
 +                      do_target_scan = 1;
 +              }
 +
 +              // But never more often then g_turrets_targetscan_mindelay!
 +              if (self.target_select_time + autocvar_g_turrets_targetscan_mindelay > time)
 +                      do_target_scan = 0;
 +
 +              if(do_target_scan)
 +              {
 +                      self.enemy = turret_select_target();
 +                      self.target_select_time = time;
 +              }
 +
 +              // No target, just go to idle, do any custom stuff and bail.
 +              if (self.enemy == world)
 +              {
 +                      // Turn & pitch
 +                      if(!(self.track_flags & TFL_TRACK_NO))
 +                              turret_track();
 +                              
 +                      TUR_ACTION(self.turretid, TR_THINK);
 +
 +                      // And bail.
 +                      return;
 +              }
 +              else
 +                      self.lip = time + autocvar_g_turrets_aimidle_delay; // Keep track of the last time we had a target.
 +
 +              // Predict?
 +              if(!(self.aim_flags & TFL_AIM_NO))
 +                      self.tur_aimpos = turret_aim_generic();
 +
 +              // Turn & pitch?
 +              if(!(self.track_flags & TFL_TRACK_NO))
 +                      turret_track();
 +
 +              turret_do_updates(self);
 +
 +              // Fire?
 +              if (self.turret_firecheckfunc())
 +                      turret_fire();
 +      }
 +
 +      TUR_ACTION(self.turretid, TR_THINK);
 +}
 +
 +/*
 +      When .used a turret switch team to activator.team.
 +      If activator is world, the turret go inactive.
 +*/
 +void turret_use()
 +{
 +      dprint("Turret ",self.netname, " used by ", activator.classname, "\n");
 +
 +      self.team = activator.team;
 +
 +      if(self.team == 0)
 +              self.active = ACTIVE_NOT;
 +      else
 +              self.active = ACTIVE_ACTIVE;
 +
 +}
 +
 +void turret_link()
 +{
 +      Net_LinkEntity(self, true, 0, turret_send);
 +      self.think       = turret_think;
 +      self.nextthink = time;
 +      self.tur_head.effects = EF_NODRAW;
 +}
 +
 +void turrets_manager_think()
 +{
 +      self.nextthink = time + 1;
 +
 +      entity e;
 +      if (autocvar_g_turrets_reloadcvars == 1)
 +      {
 +              e = nextent(world);
 +              while (e)
 +              {
-       if(MUTATOR_CALLHOOK(TurretSpawn))
++                      if (IS_TURRET(e))
 +                      {
 +                              load_unit_settings(e,e.cvar_basename,1);
 +                              TUR_ACTION(self.turretid, TR_THINK);
 +                      }
 +
 +                      e = nextent(e);
 +              }
 +              cvar_set("g_turrets_reloadcvars","0");
 +      }
 +}
 +
 +float turret_initialize(float tur_id)
 +{
 +      if(!autocvar_g_turrets)
 +              return false;
 +
 +      entity e;
 +      entity tur = get_turretinfo(tur_id);
 +      if(tur.turretid == 0)
 +              return false; // invalid turret
 +
 +      if(!self.tur_head) { TUR_ACTION(tur_id, TR_PRECACHE); } // if tur_head exists, we can assume this turret re-spawned
 +
 +      e = find(world, classname, "turret_manager");
 +      if(!e)
 +      {
 +              e = spawn();
 +              e.classname = "turret_manager";
 +              e.think = turrets_manager_think;
 +              e.nextthink = time + 2;
 +      }
 +
 +      if(!(self.spawnflags & TSF_SUSPENDED))
 +              builtin_droptofloor();
 +
 +      self.cvar_basename = tur.cvar_basename;
 +      load_unit_settings(self, self.cvar_basename, 0);
 +      
 +      if(!self.team || !teamplay)             { self.team = MAX_SHOT_DISTANCE; }
 +      if(!self.ticrate)                               { self.ticrate = ((self.turret_flags & TUR_FLAG_SUPPORT) ? 0.2 : 0.1); }
 +      if(!self.health)                                { self.health = 1000; }
 +      if(!self.shot_refire)                   { self.shot_refire = 1; }
 +      if(!self.tur_shotorg)                   { self.tur_shotorg = '50 0 50'; }
 +      if(!self.turret_flags)                  { self.turret_flags = TUR_FLAG_SPLASH | TUR_FLAG_MEDPROJ | TUR_FLAG_PLAYER; }
 +      if(!self.damage_flags)                  { self.damage_flags = TFL_DMG_YES | TFL_DMG_RETALIATE | TFL_DMG_AIMSHAKE; }
 +      if(!self.aim_flags)                             { self.aim_flags = TFL_AIM_LEAD | TFL_AIM_SHOTTIMECOMPENSATE; }
 +      if(!self.track_type)                    { self.track_type = TFL_TRACKTYPE_STEPMOTOR; }
 +      if(!self.track_flags)                   { self.track_flags = TFL_TRACK_PITCH | TFL_TRACK_ROTATE; }
 +      if(!self.ammo_flags)                    { self.ammo_flags = TFL_AMMO_ENERGY | TFL_AMMO_RECHARGE; }
 +      if(!self.target_select_flags)   { self.target_select_flags = TFL_TARGETSELECT_LOS | TFL_TARGETSELECT_TEAMCHECK | TFL_TARGETSELECT_RANGELIMITS | TFL_TARGETSELECT_ANGLELIMITS; }
 +      if(!self.firecheck_flags)               { self.firecheck_flags = TFL_FIRECHECK_DEAD | TFL_FIRECHECK_DISTANCES | TFL_FIRECHECK_LOS
 +                                                                                                                 | TFL_FIRECHECK_AIMDIST | TFL_FIRECHECK_TEAMCHECK | TFL_FIRECHECK_AMMO_OWN | TFL_FIRECHECK_REFIRE; }
 +                                                                                                                 
 +      if(self.track_type != TFL_TRACKTYPE_STEPMOTOR)
 +      {
 +              // Fluid / Ineria mode. Looks mutch nicer.
 +              // Can reduce aim preformance alot, needs a bit diffrent aimspeed
 +              
 +              self.aim_speed = bound(0.1, ((!self.aim_speed) ? 180 : self.aim_speed), 1000);
 +              
 +              if(!self.track_accel_pitch)             { self.track_accel_pitch = 0.5; }
 +              if(!self.track_accel_rotate)    { self.track_accel_rotate = 0.5; }
 +              if(!self.track_blendrate)               { self.track_blendrate = 0.35; }
 +      }
 +      
 +      self.respawntime                                = max(-1, ((!self.respawntime) ? 60 : self.respawntime));
 +      self.shot_refire                                = bound(0.01, ((!self.shot_refire) ? 1 : self.shot_refire), 9999);
 +      self.shot_dmg                                   = max(1, ((!self.shot_dmg) ? self.shot_refire * 50 : self.shot_dmg));
 +      self.shot_radius                                = max(1, ((!self.shot_radius) ? self.shot_dmg * 0.5 : self.shot_radius));
 +      self.shot_speed                                 = max(1, ((!self.shot_speed) ? 2500 : self.shot_speed));
 +      self.shot_spread                                = bound(0.0001, ((!self.shot_spread) ? 0.0125 : self.shot_spread), 500);
 +      self.shot_force                                 = bound(0.001, ((!self.shot_force) ? self.shot_dmg * 0.5 + self.shot_radius * 0.5 : self.shot_force), 5000);
 +      self.shot_volly                                 = bound(1, ((!self.shot_volly) ? 1 : self.shot_volly), floor(self.ammo_max / self.shot_dmg));
 +      self.shot_volly_refire                  = bound(self.shot_refire, ((!self.shot_volly_refire) ? self.shot_refire * self.shot_volly : self.shot_volly_refire), 60);
 +      self.target_range                               = bound(0, ((!self.target_range) ? self.shot_speed * 0.5 : self.target_range), MAX_SHOT_DISTANCE);
 +      self.target_range_min                   = bound(0, ((!self.target_range_min) ? self.shot_radius * 2 : self.target_range_min), MAX_SHOT_DISTANCE);
 +      self.target_range_optimal               = bound(0, ((!self.target_range_optimal) ? self.target_range * 0.5 : self.target_range_optimal), MAX_SHOT_DISTANCE);
 +      self.aim_maxrotate                              = bound(0, ((!self.aim_maxrotate) ? 90 : self.aim_maxrotate), 360);
 +      self.aim_maxpitch                               = bound(0, ((!self.aim_maxpitch) ? 20 : self.aim_maxpitch), 90);
 +      self.aim_speed                                  = bound(0.1, ((!self.aim_speed) ? 36 : self.aim_speed), 1000);
 +      self.aim_firetolerance_dist     = bound(0.1, ((!self.aim_firetolerance_dist) ? 5 + (self.shot_radius * 2) : self.aim_firetolerance_dist), MAX_SHOT_DISTANCE);
 +      self.target_select_rangebias    = bound(-10, ((!self.target_select_rangebias) ? 1 : self.target_select_rangebias), 10);
 +      self.target_select_samebias     = bound(-10, ((!self.target_select_samebias) ? 1 : self.target_select_samebias), 10);
 +      self.target_select_anglebias    = bound(-10, ((!self.target_select_anglebias) ? 1 : self.target_select_anglebias), 10);
 +      self.target_select_missilebias  = bound(-10, ((!self.target_select_missilebias) ? 1 : self.target_select_missilebias), 10);
 +      self.target_select_playerbias   = bound(-10, ((!self.target_select_playerbias) ? 1 : self.target_select_playerbias), 10);
 +      self.ammo_max                                   = max(self.shot_dmg, ((!self.ammo_max) ? self.shot_dmg * 10 : self.ammo_max));
 +      self.ammo_recharge                              = max(0, ((!self.ammo_recharge) ? self.shot_dmg * 0.5 : self.ammo_recharge));
 +      
 +      self.turret_flags = TUR_FLAG_ISTURRET | (tur.spawnflags);
 +      
 +      if(self.turret_flags & TUR_FLAG_SPLASH)
 +              self.aim_flags |= TFL_AIM_SPLASH;
 +              
 +      if(self.turret_flags & TUR_FLAG_MISSILE)
 +              self.target_select_flags |= TFL_TARGETSELECT_MISSILES;
 +
 +      if(self.turret_flags & TUR_FLAG_PLAYER)
 +              self.target_select_flags |= TFL_TARGETSELECT_PLAYERS;
 +              
 +      if(self.spawnflags & TSL_NO_RESPAWN)
 +              self.damage_flags |= TFL_DMG_DEATH_NORESPAWN;
 +              
 +      if (self.turret_flags & TUR_FLAG_SUPPORT)
 +              self.turret_score_target = turret_targetscore_support;
 +      else
 +              self.turret_score_target = turret_targetscore_generic;
 +              
 +      ++turret_count;
 +              
 +      setmodel(self, tur.model);
 +      setsize(self, tur.mins, tur.maxs);
 +      
 +      self.turretid                           = tur_id;
 +      self.classname                          = "turret_main";
 +      self.active                                     = ACTIVE_ACTIVE;
 +      self.effects                            = EF_NODRAW;
 +      self.netname                            = TUR_NAME(tur_id);
 +      self.ticrate                            = bound(sys_frametime, self.ticrate, 60);
 +      self.max_health                         = self.health;
 +      self.target_validate_flags      = self.target_select_flags;
 +      self.ammo                                       = self.ammo_max;
 +      self.ammo_recharge                 *= self.ticrate;
 +      self.solid                                      = SOLID_BBOX;
 +      self.takedamage                         = DAMAGE_AIM;
 +      self.movetype                           = MOVETYPE_NOCLIP;
 +      self.view_ofs                           = '0 0 0';
 +      self.turret_firecheckfunc       = turret_firecheck;
 +      self.event_damage                       = turret_damage;
 +      self.use                                        = turret_use;
 +      self.bot_attack                         = true;
 +      self.nextthink                          = time + 1;
 +      self.nextthink                     += turret_count * sys_frametime;
 +      
 +      self.tur_head = spawn();
 +      setmodel(self.tur_head, tur.head_model);
 +      setsize(self.tur_head, '0 0 0', '0 0 0');
 +      setorigin(self.tur_head, '0 0 0');
 +      setattachment(self.tur_head, self, "tag_head");
 +      
 +      self.tur_head.netname           = self.tur_head.classname = "turret_head";
 +      self.tur_head.team                      = self.team;
 +      self.tur_head.owner                     = self;
 +      self.tur_head.takedamage        = DAMAGE_NO;
 +      self.tur_head.solid                     = SOLID_NOT;
 +      self.tur_head.movetype          = self.movetype;
 +      
 +      if(!self.tur_defend)
 +      if(self.target != "")
 +      {
 +              self.tur_defend = find(world, targetname, self.target);
 +              if (self.tur_defend == world)
 +              {
 +                      self.target = "";
 +                      dprint("Turret has invalid defendpoint!\n");
 +              }
 +      }
 +      
 +      if (self.tur_defend)
 +              self.idle_aim = self.tur_head.angles + angleofs(self.tur_head, self.tur_defend);
 +      else
 +              self.idle_aim = '0 0 0';
 +              
 +#ifdef TURRET_DEBUG
 +      self.tur_debug_start = self.nextthink;
 +      while (vlen(self.tur_debug_rvec) < 2)
 +              self.tur_debug_rvec = randomvec() * 4;
 +
 +      self.tur_debug_rvec_x = fabs(self.tur_debug_rvec_x);
 +      self.tur_debug_rvec_y = fabs(self.tur_debug_rvec_y);
 +      self.tur_debug_rvec_z = fabs(self.tur_debug_rvec_z);
 +#endif
 +
 +      turret_link();
 +      turret_respawn();
 +      turret_tag_fire_update();
 +      
 +      TUR_ACTION(tur_id, TR_SETUP);
 +      
++      if(MUTATOR_CALLHOOK(TurretSpawn, self))
 +              return false;
 +
 +      return true;
 +}
 +#endif
index c4ff13e,0000000..8bba1c4
mode 100644,000000..100644
--- /dev/null
@@@ -1,113 -1,0 +1,117 @@@
 +#ifndef SV_TURRETS_H
 +#define SV_TURRETS_H
 +
 +// turret fields
 +.float ticrate; // interal ai think rate
 +.vector aim_idle; // where to aim while idle
 +.entity tur_head; // top part of the turret
 +.entity tur_defend; // defend this entity
 +.vector tur_shotorg; // shot origin
 +.vector tur_aimpos; // aiming location
 +.float tur_impacttime; // predicted projectile impact time
 +.entity tur_impactent; // entity the projectile hit
 +.float tur_dist_enemy; // distance to enemy
 +.float tur_dist_aimpos; // distance to aim location
 +.float tur_dist_impact_to_aimpos; // distance impact<->aim
 +.float volly_counter; // decrement counter from .shot_volly to 0
 +
 +.float shot_refire; // attack refire
 +.float shot_speed; // projectile speed
 +.float shot_spread; // inaccuracy
 +.float shot_dmg; // core damage of projectile
 +.float shot_radius; // projectile damage radius
 +.float shot_force; // projectile damage force
 +.float shot_volly; // smaller than 1 = shoot # times at target
 +.float shot_volly_refire; // refire after completed volly
 +
 +.float target_range;
 +.float target_range_min;
 +.float target_range_optimal;
 +
 +.float target_select_rangebias;
 +.float target_select_samebias;
 +.float target_select_anglebias;
 +.float target_select_missilebias;
 +.float target_select_playerbias;
 +.float target_select_time; // last time turret had a valid target
 +.float target_validate_time; // throttle re-validation of current target
 +
 +.float aim_firetolerance_dist;
 +.float aim_speed;
 +.float aim_maxpitch;
 +.float aim_maxrotate;
 +
 +.float ammo; // current ammo
 +.float ammo_recharge; // recharge rate
 +.float ammo_max; // maximum ammo
 +
 +.vector idle_aim;
 +
 +/// Map time control over pain inflicted
 +.float turret_scale_damage;
 +/// Map time control targetting range
 +.float turret_scale_range;
 +/// Map time control refire
 +.float turret_scale_refire;
 +/// Map time control ammo held and recharged
 +.float turret_scale_ammo;
 +/// Map time control aim speed
 +.float turret_scale_aim;
 +/// Map time control health
 +.float turret_scale_health;
 +/// Map time control respawn time
 +.float turret_scale_respawn;
 +
 +// tracking type
 +.float track_type;
 +const float TFL_TRACKTYPE_STEPMOTOR = 1; // hard angle increments, ugly for fast turning with best accuracy
 +const float TFL_TRACKTYPE_FLUIDPRECISE = 2; // smooth absolute movement, looks OK with fair accuracy
 +const float TFL_TRACKTYPE_FLUIDINERTIA = 3; // simulated inertia ("wobbly" mode), worst accuracy, depends on below flags
 +.float track_accel_pitch;
 +.float track_accel_rotate;
 +.float track_blendrate;
 +
 +void() turret_respawn;
 +
 +/// updates aim org, shot org, shot dir and enemy org for selected turret
 +void turret_do_updates(entity e_turret);
 +.vector tur_shotdir_updated;
 +
 +.float() turret_firecheckfunc; // TODO: deprecate!
 +
++void turrets_setframe(float _frame, float client_only);
++
++float turret_initialize(float tur_id);
++
 +/// Function to use for target evaluation. usualy turret_targetscore_generic
 +.float(entity _turret, entity _target) turret_score_target;
 +
 +.float(entity e_target,entity e_sender) turret_addtarget;
 +
 +.entity pathcurrent;
 +
 +float turret_count;
 +
 +// debugging
 +// Uncomment below to enable various debug output.
 +//#define TURRET_DEBUG
 +//#define TURRET_DEBUG_TARGETVALIDATE
 +//#define TURRET_DEBUG_TARGETSELECT
 +#ifdef TURRET_DEBUG
 +.float tur_debug_dmg_t_h; // total damage that hit something (can be more than tur_debug_dmg_t_f since it should count radius damage)
 +.float tur_debug_dmg_t_f; // total damage
 +.float tur_debug_start; // turret initialization time
 +.float tur_debug_tmr1; // random timer
 +.float tur_debug_tmr2; // random timer
 +.float tur_debug_tmr3; // random timer
 +.vector tur_debug_rvec; // random vector
 +#endif
 +
 +// aiming
 +vector tvt_thadv; // turret head angle diff vector, updated by a successful call to turret_validate_target
 +vector tvt_tadv; // turret angle diff vector, updated by a successful call to turret_validate_target
 +float tvt_thadf; // turret head angle diff float, updated by a successful call to turret_validate_target
 +float tvt_tadf; // turret angle diff float, updated by a successful call to turret_validate_target
 +float tvt_dist; // turret distance, updated by a successful call to turret_validate_target
 +
 +#endif
index 4c588e9,0000000..a99d1f1
mode 100644,000000..100644
--- /dev/null
@@@ -1,78 -1,0 +1,77 @@@
-       precache_model ("models/turrets/terrainbase.md3");
 +#include "all.qh"
 +
 +// TURRET PLUGIN SYSTEM
 +entity turret_info[TUR_MAXCOUNT];
 +entity dummy_turret_info;
 +
 +void turrets_common_precache()
 +{
 +      precache_sound ("weapons/rocket_impact.wav");
 +      precache_model ("models/turrets/base-gib1.md3");
 +      precache_model ("models/turrets/base-gib2.md3");
 +      precache_model ("models/turrets/base-gib3.md3");
 +      precache_model ("models/turrets/base-gib4.md3");
 +      precache_model ("models/turrets/head-gib1.md3");
 +      precache_model ("models/turrets/head-gib2.md3");
 +      precache_model ("models/turrets/head-gib3.md3");
 +      precache_model ("models/turrets/head-gib4.md3");
 +      precache_model ("models/turrets/base.md3");
 +      precache_model ("models/turrets/rocket.md3");
 +      
 +      precache_model ("models/turrets/c512.md3");
 +      precache_model ("models/marker.md3");
 +      
 +#ifdef TURRET_DEBUG
 +      precache_model ("models/turrets/c512.md3");
 +      precache_model ("models/pathlib/goodsquare.md3");
 +      precache_model ("models/pathlib/badsquare.md3");
 +      precache_model ("models/pathlib/square.md3");
 +      precache_model ("models/pathlib/edge.md3");
 +#endif
 +}
 +
 +void register_turret(float id, float(float) func, float turretflags, vector min_s, vector max_s, string modelname, string headmodelname, string shortname, string mname)
 +{
 +      entity e;
 +      turret_info[id - 1] = e = spawn();
 +      e.classname = "turret_info";
 +      e.turretid = id;
 +      e.netname = shortname;
 +      e.turret_name = mname;
 +      e.turret_func = func;
 +      e.mdl = modelname;
 +      e.cvar_basename = shortname;
 +      e.spawnflags = turretflags;
 +      e.mins = min_s;
 +      e.maxs = max_s;
 +      e.model = strzone(strcat("models/turrets/", modelname));
 +      e.head_model = strzone(strcat("models/turrets/", headmodelname));
 +      
 +      #ifndef MENUQC
 +      turrets_common_precache();
 +      #endif
 +}
 +float t_null(float dummy) { return 0; }
 +void register_turrets_done()
 +{
 +      dummy_turret_info = spawn();
 +      dummy_turret_info.classname = "turret_info";
 +      dummy_turret_info.turretid = 0; // you can recognize dummies by this
 +      dummy_turret_info.netname = "";
 +      dummy_turret_info.turret_name = "Turret";
 +      dummy_turret_info.turret_func = t_null;
 +      dummy_turret_info.mdl = "";
 +      dummy_turret_info.mins = '-0 -0 -0';
 +      dummy_turret_info.maxs = '0 0 0';
 +      dummy_turret_info.model = "";
 +}
 +entity get_turretinfo(float id)
 +{
 +      entity m;
 +      if(id < TUR_FIRST || id > TUR_LAST)
 +              return dummy_turret_info;
 +      m = turret_info[id - 1];
 +      if(m)
 +              return m;
 +      return dummy_turret_info;
 +}
index 414ec4e,0000000..495e60f
mode 100644,000000..100644
--- /dev/null
@@@ -1,311 -1,0 +1,311 @@@
-       // Are we close enougth to a path node to switch to the next?
-       if (vlen(self.origin  - self.pathcurrent.origin) < 64)
-               if (self.pathcurrent.path_next == world)
-               {
-                       // Path endpoint reached
-                       pathlib_deletepath(self.pathcurrent.owner);
-                       self.pathcurrent = world;
-                       if (self.pathgoal)
-                       {
-                               if (self.pathgoal.use)
-                                       self.pathgoal.use();
-                               if (self.pathgoal.enemy)
-                               {
-                                       self.pathcurrent = pathlib_astar(self.pathgoal.origin,self.pathgoal.enemy.origin);
-                                       self.pathgoal = self.pathgoal.enemy;
-                               }
-                       }
-                       else
-                               self.pathgoal = world;
-               }
-               else
-                       self.pathcurrent = self.pathcurrent.path_next;
 +#ifdef REGISTER_TURRET
 +REGISTER_TURRET(
 +/* TUR_##id   */ EWHEEL,
 +/* function   */ t_ewheel,
 +/* spawnflags */ TUR_FLAG_PLAYER | TUR_FLAG_MOVE | TUR_FLAG_ROAM,
 +/* mins,maxs  */ '-32 -32 0', '32 32 48',
 +/* model      */ "ewheel-base2.md3",
 +/* head_model */ "ewheel-gun1.md3",
 +/* netname    */ "ewheel",
 +/* fullname   */ _("eWheel Turret")
 +);
 +#else
 +#ifdef SVQC
 +float autocvar_g_turrets_unit_ewheel_speed_fast;
 +float autocvar_g_turrets_unit_ewheel_speed_slow;
 +float autocvar_g_turrets_unit_ewheel_speed_slower;
 +float autocvar_g_turrets_unit_ewheel_speed_stop;
 +float autocvar_g_turrets_unit_ewheel_turnrate;
 +
 +const float ewheel_anim_stop = 0;
 +const float ewheel_anim_fwd_slow = 1;
 +const float ewheel_anim_fwd_fast = 2;
 +const float ewheel_anim_bck_slow = 3;
 +const float ewheel_anim_bck_fast = 4;
 +
 +//#define EWHEEL_FANCYPATH
 +void ewheel_move_path()
 +{
 +#ifdef EWHEEL_FANCYPATH
-       if (vlen(self.origin - self.pathcurrent.origin) < 64)
-               self.pathcurrent = self.pathcurrent.enemy;
++    // Are we close enougth to a path node to switch to the next?
++    if (vlen(self.origin  - self.pathcurrent.origin) < 64)
++        if (self.pathcurrent.path_next == world)
++        {
++            // Path endpoint reached
++            pathlib_deletepath(self.pathcurrent.owner);
++            self.pathcurrent = world;
++
++            if (self.pathgoal)
++            {
++                if (self.pathgoal.use)
++                    self.pathgoal.use();
++
++                if (self.pathgoal.enemy)
++                {
++                    self.pathcurrent = pathlib_astar(self.pathgoal.origin,self.pathgoal.enemy.origin);
++                    self.pathgoal = self.pathgoal.enemy;
++                }
++            }
++            else
++                self.pathgoal = world;
++        }
++        else
++            self.pathcurrent = self.pathcurrent.path_next;
 +
 +#else
-       if (self.pathcurrent)
-       {
++    if (vlen(self.origin - self.pathcurrent.origin) < 64)
++        self.pathcurrent = self.pathcurrent.enemy;
 +#endif
 +
-               self.moveto = self.pathcurrent.origin;
-               self.steerto = steerlib_attract2(self.moveto, 0.5, 500, 0.95);
++    if (self.pathcurrent)
++    {
 +
-               movelib_move_simple(v_forward, (autocvar_g_turrets_unit_ewheel_speed_fast), 0.4);
-       }
++        self.moveto = self.pathcurrent.origin;
++        self.steerto = steerlib_attract2(self.moveto, 0.5, 500, 0.95);
 +
-       float newframe;
-       self.steerto = steerlib_arrive(self.enemy.origin,self.target_range_optimal);
-       
-       self.moveto  = self.origin + self.steerto * 128;
-       if (self.tur_dist_enemy > self.target_range_optimal)
-       {
-               if ( self.tur_head.spawnshieldtime < 1 )
-               {
-                       newframe = ewheel_anim_fwd_fast;
-                       movelib_move_simple(v_forward, (autocvar_g_turrets_unit_ewheel_speed_fast), 0.4);
-               }
-               else if (self.tur_head.spawnshieldtime < 2)
-               {
-                       newframe = ewheel_anim_fwd_slow;
-                       movelib_move_simple(v_forward, (autocvar_g_turrets_unit_ewheel_speed_slow), 0.4);
-          }
-               else
-               {
-                       newframe = ewheel_anim_fwd_slow;
-                       movelib_move_simple(v_forward, (autocvar_g_turrets_unit_ewheel_speed_slower), 0.4);
-               }
-       }
-       else if (self.tur_dist_enemy < self.target_range_optimal * 0.5)
-       {
-               newframe = ewheel_anim_bck_slow;
-               movelib_move_simple(v_forward * -1, (autocvar_g_turrets_unit_ewheel_speed_slow), 0.4);
-       }
-       else
-       {
-               newframe = ewheel_anim_stop;
-               movelib_beak_simple((autocvar_g_turrets_unit_ewheel_speed_stop));
-       }
-       turrets_setframe(newframe, false);
++        movelib_move_simple(v_forward, (autocvar_g_turrets_unit_ewheel_speed_fast), 0.4);
++    }
 +}
 +
 +void ewheel_move_enemy()
 +{
-       if(self.frame != 0)
-       {
-               self.SendFlags |= TNSF_ANIM;
-               self.anim_start_time = time;
-       }
-       self.frame = 0;
-       if (vlen(self.velocity))
-               movelib_beak_simple((autocvar_g_turrets_unit_ewheel_speed_stop));
++    float newframe;
++
++    self.steerto = steerlib_arrive(self.enemy.origin,self.target_range_optimal);
++
++    self.moveto  = self.origin + self.steerto * 128;
++
++    if (self.tur_dist_enemy > self.target_range_optimal)
++    {
++        if ( self.tur_head.spawnshieldtime < 1 )
++        {
++            newframe = ewheel_anim_fwd_fast;
++            movelib_move_simple(v_forward, (autocvar_g_turrets_unit_ewheel_speed_fast), 0.4);
++        }
++        else if (self.tur_head.spawnshieldtime < 2)
++        {
++
++            newframe = ewheel_anim_fwd_slow;
++            movelib_move_simple(v_forward, (autocvar_g_turrets_unit_ewheel_speed_slow), 0.4);
++       }
++        else
++        {
++            newframe = ewheel_anim_fwd_slow;
++            movelib_move_simple(v_forward, (autocvar_g_turrets_unit_ewheel_speed_slower), 0.4);
++        }
++    }
++    else if (self.tur_dist_enemy < self.target_range_optimal * 0.5)
++    {
++        newframe = ewheel_anim_bck_slow;
++        movelib_move_simple(v_forward * -1, (autocvar_g_turrets_unit_ewheel_speed_slow), 0.4);
++    }
++    else
++    {
++        newframe = ewheel_anim_stop;
++        movelib_beak_simple((autocvar_g_turrets_unit_ewheel_speed_stop));
++    }
++
++    turrets_setframe(newframe, false);
 +}
 +
 +void ewheel_move_idle()
 +{
-       switch(req)
-       {
-               case TR_ATTACK:
-               {
-                       float i;
-                       entity _mis;
-                       for (i = 0; i < 1; ++i)
-                       {
-                               turret_do_updates(self);
-                               _mis = turret_projectile("weapons/lasergun_fire.wav", 1, 0, DEATH_TURRET_EWHEEL, PROJECTILE_BLASTER, TRUE, TRUE);
-                               _mis.missile_flags = MIF_SPLASH;
-                               pointparticles(particleeffectnum("laser_muzzleflash"), self.tur_shotorg, self.tur_shotdir_updated * 1000, 1);
-                               self.tur_head.frame += 2;
-                               if (self.tur_head.frame > 3)
-                                       self.tur_head.frame = 0;
-                       }
-                       
-                       return true;
-               }
-               case TR_THINK:
-               {
-                       float vz;
-                       vector wish_angle, real_angle;
-                       vz = self.velocity_z;
-                       self.angles_x = anglemods(self.angles_x);
-                       self.angles_y = anglemods(self.angles_y);
-                       fixedmakevectors(self.angles);
-                       wish_angle = normalize(self.steerto);
-                       wish_angle = vectoangles(wish_angle);
-                       real_angle = wish_angle - self.angles;
-                       real_angle = shortangle_vxy(real_angle, self.tur_head.angles);
-                       self.tur_head.spawnshieldtime = fabs(real_angle_y);
-                       real_angle_y  = bound(-self.tur_head.aim_speed, real_angle_y, self.tur_head.aim_speed);
-                       self.angles_y = (self.angles_y + real_angle_y);
-                       if(self.enemy)
-                               ewheel_move_enemy();
-                       else if(self.pathcurrent)
-                               ewheel_move_path();
-                       else
-                               ewheel_move_idle();
-                       self.velocity_z = vz;
-                       if(vlen(self.velocity))
-                               self.SendFlags |= TNSF_MOVE;
-               
-                       return true;
-               }
-               case TR_DEATH:
-               {
-                       self.velocity = '0 0 0';
++    if(self.frame != 0)
++    {
++        self.SendFlags |= TNSF_ANIM;
++        self.anim_start_time = time;
++    }
++
++    self.frame = 0;
++    if (vlen(self.velocity))
++        movelib_beak_simple((autocvar_g_turrets_unit_ewheel_speed_stop));
 +}
 +
 +void spawnfunc_turret_ewheel() { if(!turret_initialize(TUR_EWHEEL)) remove(self); }
 +
 +float t_ewheel(float req)
 +{
-                       if (self.pathcurrent)
-                               pathlib_deletepath(self.pathcurrent.owner);
++    switch(req)
++    {
++        case TR_ATTACK:
++        {
++            float i;
++            entity _mis;
++
++            for (i = 0; i < 1; ++i)
++            {
++                turret_do_updates(self);
++
++                _mis = turret_projectile("weapons/lasergun_fire.wav", 1, 0, DEATH_TURRET_EWHEEL, PROJECTILE_BLASTER, TRUE, TRUE);
++                _mis.missile_flags = MIF_SPLASH;
++
++                Send_Effect("laser_muzzleflash", self.tur_shotorg, self.tur_shotdir_updated * 1000, 1);
++
++                self.tur_head.frame += 2;
++
++                if (self.tur_head.frame > 3)
++                    self.tur_head.frame = 0;
++            }
++
++            return true;
++        }
++        case TR_THINK:
++        {
++            float vz;
++            vector wish_angle, real_angle;
++
++            vz = self.velocity_z;
++
++            self.angles_x = anglemods(self.angles_x);
++            self.angles_y = anglemods(self.angles_y);
++
++            fixedmakevectors(self.angles);
++
++            wish_angle = normalize(self.steerto);
++            wish_angle = vectoangles(wish_angle);
++            real_angle = wish_angle - self.angles;
++            real_angle = shortangle_vxy(real_angle, self.tur_head.angles);
++
++            self.tur_head.spawnshieldtime = fabs(real_angle_y);
++            real_angle_y  = bound(-self.tur_head.aim_speed, real_angle_y, self.tur_head.aim_speed);
++            self.angles_y = (self.angles_y + real_angle_y);
++
++            if(self.enemy)
++                ewheel_move_enemy();
++            else if(self.pathcurrent)
++                ewheel_move_path();
++            else
++                ewheel_move_idle();
++
++            self.velocity_z = vz;
++
++            if(vlen(self.velocity))
++                self.SendFlags |= TNSF_MOVE;
++
++            return true;
++        }
++        case TR_DEATH:
++        {
++            self.velocity = '0 0 0';
 +
 +#ifdef EWHEEL_FANCYPATH
-                       self.pathcurrent = world;
-       
-                       return true;
-               }
-               case TR_SETUP:
-               {
-                       entity e;
-                       
-                       if(self.movetype == MOVETYPE_WALK)
-                       {
-                               self.velocity = '0 0 0';
-                               self.enemy = world;
-                               setorigin(self, self.pos1);
-                               if (self.target != "")
-                               {
-                                       e = find(world, targetname, self.target);
-                                       if (!e)
-                                       {
-                                               dprint("Initital waypoint for ewheel does NOT exsist, fix your map!\n");
-                                               self.target = "";
-                                       }
-                                       if (e.classname != "turret_checkpoint")
-                                               dprint("Warning: not a turrret path\n");
-                                       else
-                                       {
++            if (self.pathcurrent)
++                pathlib_deletepath(self.pathcurrent.owner);
 +#endif
-                                               self.pathcurrent = WALKER_PATH(self.origin,e.origin);
-                                               self.pathgoal = e;
++            self.pathcurrent = world;
++
++            return true;
++        }
++        case TR_SETUP:
++        {
++            entity e;
++
++            if(self.movetype == MOVETYPE_WALK)
++            {
++                self.velocity = '0 0 0';
++                self.enemy = world;
++
++                setorigin(self, self.pos1);
++
++                if (self.target != "")
++                {
++                    e = find(world, targetname, self.target);
++                    if (!e)
++                    {
++                        dprint("Initital waypoint for ewheel does NOT exsist, fix your map!\n");
++                        self.target = "";
++                    }
++
++                    if (e.classname != "turret_checkpoint")
++                        dprint("Warning: not a turrret path\n");
++                    else
++                    {
 +
 +#ifdef EWHEEL_FANCYPATH
-                                               self.pathcurrent  = e;
++                        self.pathcurrent = WALKER_PATH(self.origin,e.origin);
++                        self.pathgoal = e;
 +#else
-                                       }
-                               }
-                       }
-                       
-                       self.iscreature                         = true;
-                       self.teleportable                       = TELEPORT_NORMAL;
-                       self.damagedbycontents          = true;
-                       self.movetype                           = MOVETYPE_WALK;
-                       self.solid                                      = SOLID_SLIDEBOX;
-                       self.takedamage                         = DAMAGE_AIM;
-                       self.idle_aim                           = '0 0 0';
-                       self.pos1                                       = self.origin;
-                       self.target_select_flags        = TFL_TARGETSELECT_PLAYERS | TFL_TARGETSELECT_RANGELIMITS | TFL_TARGETSELECT_TEAMCHECK | TFL_TARGETSELECT_LOS;
-                       self.target_validate_flags      = TFL_TARGETSELECT_PLAYERS | TFL_TARGETSELECT_RANGELIMITS | TFL_TARGETSELECT_TEAMCHECK | TFL_TARGETSELECT_LOS;
-                       self.frame                                      = self.tur_head.frame = 1;
-                       self.ammo_flags                         = TFL_AMMO_ENERGY | TFL_AMMO_RECHARGE | TFL_AMMO_RECIEVE;
-                       
-                       // Convert from dgr / sec to dgr / tic
-                       self.tur_head.aim_speed = (autocvar_g_turrets_unit_ewheel_turnrate);
-                       self.tur_head.aim_speed = self.tur_head.aim_speed / (1 / self.ticrate);
-               
-                       return true;
-               }
-               case TR_PRECACHE:
-               {
-                       precache_model ("models/turrets/ewheel-base2.md3");
-                       precache_model ("models/turrets/ewheel-gun1.md3");
-                       return true;
-               }
-       }
-       return true;
++                        self.pathcurrent  = e;
 +#endif
-       float dt;
++                    }
++                }
++            }
++
++            self.iscreature                           = true;
++            self.teleportable                 = TELEPORT_NORMAL;
++            self.damagedbycontents            = true;
++            self.movetype                             = MOVETYPE_WALK;
++            self.solid                                        = SOLID_SLIDEBOX;
++            self.takedamage                           = DAMAGE_AIM;
++            self.idle_aim                             = '0 0 0';
++            self.pos1                                 = self.origin;
++            self.target_select_flags  = TFL_TARGETSELECT_PLAYERS | TFL_TARGETSELECT_RANGELIMITS | TFL_TARGETSELECT_TEAMCHECK | TFL_TARGETSELECT_LOS;
++            self.target_validate_flags        = TFL_TARGETSELECT_PLAYERS | TFL_TARGETSELECT_RANGELIMITS | TFL_TARGETSELECT_TEAMCHECK | TFL_TARGETSELECT_LOS;
++            self.frame                                        = self.tur_head.frame = 1;
++            self.ammo_flags                           = TFL_AMMO_ENERGY | TFL_AMMO_RECHARGE | TFL_AMMO_RECIEVE;
++
++            // Convert from dgr / sec to dgr / tic
++            self.tur_head.aim_speed = (autocvar_g_turrets_unit_ewheel_turnrate);
++            self.tur_head.aim_speed = self.tur_head.aim_speed / (1 / self.ticrate);
++
++            return true;
++        }
++        case TR_PRECACHE:
++        {
++            precache_model ("models/turrets/ewheel-base2.md3");
++            precache_model ("models/turrets/ewheel-gun1.md3");
++            return true;
++        }
++    }
++
++    return true;
 +}
 +
 +#endif // SVQC
 +#ifdef CSQC
 +
 +void ewheel_draw()
 +{
-       dt = time - self.move_time;
-       self.move_time = time;
-       if(dt <= 0)
-               return;
++    float dt;
 +
-       fixedmakevectors(self.angles);
-       setorigin(self, self.origin + self.velocity * dt);
-       self.tur_head.angles += dt * self.tur_head.move_avelocity;
-       self.angles_y = self.move_angles_y;
++    dt = time - self.move_time;
++    self.move_time = time;
++    if(dt <= 0)
++        return;
 +
-       if (self.health < 127)
-       if(random() < 0.05)
-               te_spark(self.origin + '0 0 40', randomvec() * 256 + '0 0 256', 16);
++    fixedmakevectors(self.angles);
++    setorigin(self, self.origin + self.velocity * dt);
++    self.tur_head.angles += dt * self.tur_head.move_avelocity;
++    self.angles_y = self.move_angles_y;
 +
-       switch(req)
-       {
-               case TR_SETUP:
-               {
-                       self.gravity            = 1;
-                       self.movetype           = MOVETYPE_BOUNCE;
-                       self.move_movetype      = MOVETYPE_BOUNCE;
-                       self.move_origin        = self.origin;
-                       self.move_time          = time;
-                       self.draw                       = ewheel_draw;
-                       
-                       return true;
-               }
-               case TR_PRECACHE:
-               {
-                       return true;
-               }
-       }
-       return true;
++    if (self.health < 127)
++    if(random() < 0.05)
++        te_spark(self.origin + '0 0 40', randomvec() * 256 + '0 0 256', 16);
 +}
 +
 +float t_ewheel(float req)
 +{
++    switch(req)
++    {
++        case TR_SETUP:
++        {
++            self.gravity              = 1;
++            self.movetype             = MOVETYPE_BOUNCE;
++            self.move_movetype        = MOVETYPE_BOUNCE;
++            self.move_origin  = self.origin;
++            self.move_time            = time;
++            self.draw                 = ewheel_draw;
++
++            return true;
++        }
++        case TR_PRECACHE:
++        {
++            return true;
++        }
++    }
++
++    return true;
 +}
 +
 +#endif // CSQC
 +#endif // REGISTER_TURRET
index 8068ab1,0000000..614df1d
mode 100644,000000..100644
--- /dev/null
@@@ -1,103 -1,0 +1,103 @@@
-       if(self.enemy != world)
-       if(vlen(self.origin - self.enemy.origin) < self.owner.shot_radius * 3)
-               setorigin(self,self.enemy.origin + randomvec() * self.owner.shot_radius);
 +#ifdef REGISTER_TURRET
 +REGISTER_TURRET(
 +/* TUR_##id   */ FLAC,
 +/* function   */ t_flac,
 +/* spawnflags */ TUR_FLAG_SPLASH | TUR_FLAG_FASTPROJ | TUR_FLAG_MISSILE,
 +/* mins,maxs  */ '-32 -32 0', '32 32 64',
 +/* model        */ "base.md3",
 +/* head_model */ "flac.md3",
 +/* netname      */ "flac",
 +/* fullname   */ _("FLAC Cannon")
 +);
 +#else
 +#ifdef SVQC
 +void turret_flac_projectile_think_explode()
 +{
-       float d;
-       d = RadiusDamage (self, self.owner, self.owner.shot_dmg, self.owner.shot_dmg, self.owner.shot_radius, self, world, self.owner.shot_force, self.totalfrags, world);
-       self.owner.tur_dbg_dmg_t_h = self.owner.tur_dbg_dmg_t_h + d;
-       self.owner.tur_dbg_dmg_t_f = self.owner.tur_dbg_dmg_t_f + self.owner.shot_dmg;
++    if(self.enemy != world)
++    if(vlen(self.origin - self.enemy.origin) < self.owner.shot_radius * 3)
++        setorigin(self,self.enemy.origin + randomvec() * self.owner.shot_radius);
 +
 +#ifdef TURRET_DEBUG
-       RadiusDamage (self, self.realowner, self.owner.shot_dmg, self.owner.shot_dmg, self.owner.shot_radius, self, world, self.owner.shot_force, self.totalfrags, world);
++    float d;
++    d = RadiusDamage (self, self.owner, self.owner.shot_dmg, self.owner.shot_dmg, self.owner.shot_radius, self, world, self.owner.shot_force, self.totalfrags, world);
++    self.owner.tur_dbg_dmg_t_h = self.owner.tur_dbg_dmg_t_h + d;
++    self.owner.tur_dbg_dmg_t_f = self.owner.tur_dbg_dmg_t_f + self.owner.shot_dmg;
 +#else
-       remove(self);
++    RadiusDamage (self, self.realowner, self.owner.shot_dmg, self.owner.shot_dmg, self.owner.shot_radius, self, world, self.owner.shot_force, self.totalfrags, world);
 +#endif
-       switch(req)
-       {
-               case TR_ATTACK:
-               {
-                       entity proj;
++    remove(self);
 +}
 +
 +void spawnfunc_turret_flac() { if(!turret_initialize(TUR_FLAC)) remove(self); }
 +
 +float t_flac(float req)
 +{
-                       turret_tag_fire_update();
++    switch(req)
++    {
++        case TR_ATTACK:
++        {
++            entity proj;
 +
-                       proj = turret_projectile("weapons/hagar_fire.wav", 5, 0, DEATH_TURRET_FLAC, PROJECTILE_HAGAR, TRUE, TRUE);
-                       pointparticles(particleeffectnum("laser_muzzleflash"), self.tur_shotorg, self.tur_shotdir_updated * 1000, 1);
-                       proj.think        = turret_flac_projectile_think_explode;
-                       proj.nextthink  = time + self.tur_impacttime + (random() * 0.01 - random() * 0.01);
-                       proj.missile_flags = MIF_SPLASH | MIF_PROXY;
++            turret_tag_fire_update();
 +
-                       self.tur_head.frame = self.tur_head.frame + 1;
-                       if (self.tur_head.frame >= 4)
-                               self.tur_head.frame = 0;
-                       
-                       return true;
-               }
-               case TR_THINK:
-               {
-                       return true;
-               }
-               case TR_DEATH:
-               {
-                       return true;
-               }
-               case TR_SETUP:
-               {
-                       self.ammo_flags = TFL_AMMO_ROCKETS | TFL_AMMO_RECHARGE;
-                       self.aim_flags = TFL_AIM_LEAD | TFL_AIM_SHOTTIMECOMPENSATE;
-                       self.damage_flags |= TFL_DMG_HEADSHAKE;
-                       self.target_select_flags |= TFL_TARGETSELECT_NOTURRETS | TFL_TARGETSELECT_MISSILESONLY;
-               
-                       return true;
-               }
-               case TR_PRECACHE:
-               {
-                       precache_model ("models/turrets/base.md3");
-                       precache_model ("models/turrets/flac.md3");
-                       return true;
-               }
-       }
++            proj = turret_projectile("weapons/hagar_fire.wav", 5, 0, DEATH_TURRET_FLAC, PROJECTILE_HAGAR, TRUE, TRUE);
++            Send_Effect("laser_muzzleflash", self.tur_shotorg, self.tur_shotdir_updated * 1000, 1);
++            proj.think          = turret_flac_projectile_think_explode;
++            proj.nextthink  = time + self.tur_impacttime + (random() * 0.01 - random() * 0.01);
++            proj.missile_flags = MIF_SPLASH | MIF_PROXY;
 +
-       return true;
++            self.tur_head.frame = self.tur_head.frame + 1;
++            if (self.tur_head.frame >= 4)
++                self.tur_head.frame = 0;
 +
-       switch(req)
-       {
-               case TR_SETUP:
-               {
-                       return true;
-               }
-               case TR_PRECACHE:
-               {
-                       return true;
-               }
-       }
++            return true;
++        }
++        case TR_THINK:
++        {
++            return true;
++        }
++        case TR_DEATH:
++        {
++            return true;
++        }
++        case TR_SETUP:
++        {
++            self.ammo_flags = TFL_AMMO_ROCKETS | TFL_AMMO_RECHARGE;
++            self.aim_flags = TFL_AIM_LEAD | TFL_AIM_SHOTTIMECOMPENSATE;
++            self.damage_flags |= TFL_DMG_HEADSHAKE;
++            self.target_select_flags |= TFL_TARGETSELECT_NOTURRETS | TFL_TARGETSELECT_MISSILESONLY;
++
++            return true;
++        }
++        case TR_PRECACHE:
++        {
++            precache_model ("models/turrets/base.md3");
++            precache_model ("models/turrets/flac.md3");
++            return true;
++        }
++    }
++
++    return true;
 +}
 +
 +#endif // SVQC
 +#ifdef CSQC
 +float t_flac(float req)
 +{
-       return true;
++    switch(req)
++    {
++        case TR_SETUP:
++        {
++            return true;
++        }
++        case TR_PRECACHE:
++        {
++            return true;
++        }
++    }
 +
++    return true;
 +}
 +
 +#endif // CSQC
 +#endif // REGISTER_TURRET
index db49745,0000000..459c126
mode 100644,000000..100644
--- /dev/null
@@@ -1,116 -1,0 +1,116 @@@
-       if (self.attack_finished_single > time)
-               return 0;
 +#ifdef REGISTER_TURRET
 +REGISTER_TURRET(
 +/* TUR_##id   */ FUSIONREACTOR,
 +/* function   */ t_fusionreactor,
 +/* spawnflags */ TUR_FLAG_SUPPORT | TUR_FLAG_AMMOSOURCE,
 +/* mins,maxs  */ '-34 -34 0', '34 34 90',
 +/* model        */ "base.md3",
 +/* head_model */ "reactor.md3",
 +/* netname      */ "fusionreactor",
 +/* fullname   */ _("Fusion Reactor")
 +);
 +#else
 +#ifdef SVQC
 +float turret_fusionreactor_firecheck()
 +{
-       if (self.enemy.deadflag != DEAD_NO)
-               return 0;
++    if (self.attack_finished_single > time)
++        return 0;
 +
-       if (self.enemy == world)
-               return 0;
++    if (self.enemy.deadflag != DEAD_NO)
++        return 0;
 +
-       if (self.ammo < self.shot_dmg)
-               return 0;
++    if (self.enemy == world)
++        return 0;
 +
-       if (self.enemy.ammo >= self.enemy.ammo_max)
-               return 0;
++    if (self.ammo < self.shot_dmg)
++        return 0;
 +
-       if (vlen(self.enemy.origin - self.origin) > self.target_range)
-               return 0;
++    if (self.enemy.ammo >= self.enemy.ammo_max)
++        return 0;
 +
-       if(self.team != self.enemy.team)
-               return 0;
++    if (vlen(self.enemy.origin - self.origin) > self.target_range)
++        return 0;
 +
-       if(!(self.enemy.ammo_flags & TFL_AMMO_ENERGY))
-               return 0;
++    if(self.team != self.enemy.team)
++        return 0;
 +
-       return 1;
++    if(!(self.enemy.ammo_flags & TFL_AMMO_ENERGY))
++        return 0;
 +
-       switch(req)
-       {
-               case TR_ATTACK:
-               {
-                       vector fl_org;
-                       self.enemy.ammo = min(self.enemy.ammo + self.shot_dmg,self.enemy.ammo_max);
-                       fl_org = 0.5 * (self.enemy.absmin + self.enemy.absmax);
-                       te_smallflash(fl_org);
-                       
-                       return true;
-               }
-               case TR_THINK:
-               {
-                       self.tur_head.avelocity = '0 250 0' * (self.ammo / self.ammo_max);
-               
-                       return true;
-               }
-               case TR_DEATH:
-               {
-                       return true;
-               }
-               case TR_SETUP:
-               {
-                       self.ammo_flags                         = TFL_AMMO_ENERGY | TFL_AMMO_RECHARGE;
-                       self.target_select_flags        = TFL_TARGETSELECT_TEAMCHECK | TFL_TARGETSELECT_OWNTEAM | TFL_TARGETSELECT_RANGELIMITS;
-                       self.firecheck_flags            = TFL_FIRECHECK_AMMO_OWN | TFL_FIRECHECK_AMMO_OTHER | TFL_FIRECHECK_DISTANCES | TFL_FIRECHECK_DEAD;
-                       self.shoot_flags                        = TFL_SHOOT_HITALLVALID;
-                       self.aim_flags                          = TFL_AIM_NO;
-                       self.track_flags                        = TFL_TRACK_NO;
-       
-                       self.tur_head.scale = 0.75;
-                       self.tur_head.avelocity = '0 50 0';
-                       
-                       self.turret_firecheckfunc = turret_fusionreactor_firecheck;
-               
-                       return true;
-               }
-               case TR_PRECACHE:
-               {
-                       precache_model ("models/turrets/base.md3");
-                       precache_model ("models/turrets/reactor.md3");
-                       return true;
-               }
-       }
-       return true;
++    return 1;
 +}
 +
 +void spawnfunc_turret_fusionreactor() { if(!turret_initialize(TUR_FUSIONREACTOR)) remove(self); }
 +
 +float t_fusionreactor(float req)
 +{
-       switch(req)
-       {
-               case TR_SETUP:
-               {
-                       return true;
-               }
-               case TR_PRECACHE:
-               {
-                       return true;
-               }
-       }
-       return true;
++    switch(req)
++    {
++        case TR_ATTACK:
++        {
++            vector fl_org;
++
++            self.enemy.ammo = min(self.enemy.ammo + self.shot_dmg,self.enemy.ammo_max);
++            fl_org = 0.5 * (self.enemy.absmin + self.enemy.absmax);
++            te_smallflash(fl_org);
++
++            return true;
++        }
++        case TR_THINK:
++        {
++            self.tur_head.avelocity = '0 250 0' * (self.ammo / self.ammo_max);
++
++            return true;
++        }
++        case TR_DEATH:
++        {
++            return true;
++        }
++        case TR_SETUP:
++        {
++            self.ammo_flags                           = TFL_AMMO_ENERGY | TFL_AMMO_RECHARGE;
++            self.target_select_flags  = TFL_TARGETSELECT_TEAMCHECK | TFL_TARGETSELECT_OWNTEAM | TFL_TARGETSELECT_RANGELIMITS;
++            self.firecheck_flags              = TFL_FIRECHECK_AMMO_OWN | TFL_FIRECHECK_AMMO_OTHER | TFL_FIRECHECK_DISTANCES | TFL_FIRECHECK_DEAD;
++            self.shoot_flags                  = TFL_SHOOT_HITALLVALID;
++            self.aim_flags                            = TFL_AIM_NO;
++            self.track_flags                  = TFL_TRACK_NO;
++
++            self.tur_head.scale = 0.75;
++            self.tur_head.avelocity = '0 50 0';
++
++            self.turret_firecheckfunc = turret_fusionreactor_firecheck;
++
++            return true;
++        }
++        case TR_PRECACHE:
++        {
++            precache_model ("models/turrets/base.md3");
++            precache_model ("models/turrets/reactor.md3");
++            return true;
++        }
++    }
++
++    return true;
 +}
 +
 +#endif // SVQC
 +#ifdef CSQC
 +float t_fusionreactor(float req)
 +{
++    switch(req)
++    {
++        case TR_SETUP:
++        {
++            return true;
++        }
++        case TR_PRECACHE:
++        {
++            return true;
++        }
++    }
++
++    return true;
 +}
 +
 +#endif // CSQC
 +#endif // REGISTER_TURRET
index d090ef7,0000000..f64534f
mode 100644,000000..100644
--- /dev/null
@@@ -1,160 -1,0 +1,160 @@@
-       vector olddir,newdir;
-       vector pre_pos;
-       float itime;
 +#ifdef REGISTER_TURRET
 +REGISTER_TURRET(
 +/* TUR_##id   */ HELLION,
 +/* function   */ t_hellion,
 +/* spawnflags */ TUR_FLAG_SPLASH | TUR_FLAG_FASTPROJ | TUR_FLAG_PLAYER | TUR_FLAG_MISSILE,
 +/* mins,maxs  */ '-32 -32 0', '32 32 64',
 +/* model        */ "base.md3",
 +/* head_model */ "hellion.md3",
 +/* netname      */ "hellion",
 +/* fullname   */ _("Hellion Missile Turret")
 +);
 +#else
 +#ifdef SVQC
 +float autocvar_g_turrets_unit_hellion_shot_speed_gain;
 +float autocvar_g_turrets_unit_hellion_shot_speed_max;
 +
 +void turret_hellion_missile_think()
 +{
-       self.nextthink = time + 0.05;
++    vector olddir,newdir;
++    vector pre_pos;
++    float itime;
 +
-       olddir = normalize(self.velocity);
++    self.nextthink = time + 0.05;
 +
-       if(self.max_health < time)
-               turret_projectile_explode();
++    olddir = normalize(self.velocity);
 +
-       // Enemy dead? just keep on the current heading then.
-       if ((self.enemy == world) || (self.enemy.deadflag != DEAD_NO))
-       {
++    if(self.max_health < time)
++        turret_projectile_explode();
 +
-               // Make sure we dont return to tracking a respawned player
-               self.enemy = world;
++    // Enemy dead? just keep on the current heading then.
++    if ((self.enemy == world) || (self.enemy.deadflag != DEAD_NO))
++    {
 +
-               // Turn model
-               self.angles = vectoangles(self.velocity);
++        // Make sure we dont return to tracking a respawned player
++        self.enemy = world;
 +
-               if ( (vlen(self.origin - self.owner.origin)) > (self.owner.shot_radius * 5) )
-                       turret_projectile_explode();
++        // Turn model
++        self.angles = vectoangles(self.velocity);
 +
-               // Accelerate
-               self.velocity = olddir * min(vlen(self.velocity) * (autocvar_g_turrets_unit_hellion_shot_speed_gain), (autocvar_g_turrets_unit_hellion_shot_speed_max));
++        if ( (vlen(self.origin - self.owner.origin)) > (self.owner.shot_radius * 5) )
++            turret_projectile_explode();
 +
-               UpdateCSQCProjectile(self);
++        // Accelerate
++        self.velocity = olddir * min(vlen(self.velocity) * (autocvar_g_turrets_unit_hellion_shot_speed_gain), (autocvar_g_turrets_unit_hellion_shot_speed_max));
 +
-               return;
-       }
++        UpdateCSQCProjectile(self);
 +
-       // Enemy in range?
-       if (vlen(self.origin - self.enemy.origin) < self.owner.shot_radius * 0.2)
-               turret_projectile_explode();
++        return;
++    }
 +
-       // Predict enemy position
-       itime = vlen(self.enemy.origin - self.origin) / vlen(self.velocity);
-       pre_pos = self.enemy.origin + self.enemy.velocity * itime;
++    // Enemy in range?
++    if (vlen(self.origin - self.enemy.origin) < self.owner.shot_radius * 0.2)
++        turret_projectile_explode();
 +
-       pre_pos = (pre_pos + self.enemy.origin) * 0.5;
++    // Predict enemy position
++    itime = vlen(self.enemy.origin - self.origin) / vlen(self.velocity);
++    pre_pos = self.enemy.origin + self.enemy.velocity * itime;
 +
-       // Find out the direction to that place
-       newdir = normalize(pre_pos - self.origin);
++    pre_pos = (pre_pos + self.enemy.origin) * 0.5;
 +
-       // Turn
-       newdir = normalize(olddir + newdir * 0.35);
++    // Find out the direction to that place
++    newdir = normalize(pre_pos - self.origin);
 +
-       // Turn model
-       self.angles = vectoangles(self.velocity);
++    // Turn
++    newdir = normalize(olddir + newdir * 0.35);
 +
-       // Accelerate
-       self.velocity = newdir * min(vlen(self.velocity) * (autocvar_g_turrets_unit_hellion_shot_speed_gain), (autocvar_g_turrets_unit_hellion_shot_speed_max));
++    // Turn model
++    self.angles = vectoangles(self.velocity);
 +
-       if (itime < 0.05)
-               self.think = turret_projectile_explode;
++    // Accelerate
++    self.velocity = newdir * min(vlen(self.velocity) * (autocvar_g_turrets_unit_hellion_shot_speed_gain), (autocvar_g_turrets_unit_hellion_shot_speed_max));
 +
-       UpdateCSQCProjectile(self);
++    if (itime < 0.05)
++        self.think = turret_projectile_explode;
 +
-       switch(req)
-       {
-               case TR_ATTACK:
-               {
-                       entity missile;
-                       if(self.tur_head.frame != 0)
-                               self.tur_shotorg = gettaginfo(self.tur_head, gettagindex(self.tur_head, "tag_fire"));
-                       else
-                               self.tur_shotorg = gettaginfo(self.tur_head, gettagindex(self.tur_head, "tag_fire2"));
-                       missile = turret_projectile("weapons/rocket_fire.wav", 6, 10, DEATH_TURRET_HELLION, PROJECTILE_ROCKET, FALSE, FALSE);
-                       te_explosion (missile.origin);
-                       missile.think           = turret_hellion_missile_think;
-                       missile.nextthink       = time;
-                       missile.flags           = FL_PROJECTILE;
-                       missile.max_health   = time + 9;
-                       missile.tur_aimpos   = randomvec() * 128;
-                       missile.missile_flags = MIF_SPLASH | MIF_PROXY | MIF_GUIDED_HEAT;
-                       self.tur_head.frame += 1;
-                       
-                       return true;
-               }
-               case TR_THINK:
-               {
-                       if (self.tur_head.frame != 0)
-                               self.tur_head.frame += 1;
-                       if (self.tur_head.frame >= 7)
-                               self.tur_head.frame = 0;
-               
-                       return true;
-               }
-               case TR_DEATH:
-               {
-                       return true;
-               }
-               case TR_SETUP:
-               {
-                       self.aim_flags = TFL_AIM_SIMPLE;
-                       self.target_select_flags = TFL_TARGETSELECT_LOS | TFL_TARGETSELECT_PLAYERS | TFL_TARGETSELECT_RANGELIMITS | TFL_TARGETSELECT_TEAMCHECK ;
-                       self.firecheck_flags = TFL_FIRECHECK_DEAD | TFL_FIRECHECK_DISTANCES | TFL_FIRECHECK_TEAMCHECK | TFL_FIRECHECK_REFIRE | TFL_FIRECHECK_AFF | TFL_FIRECHECK_AMMO_OWN;
-                       self.ammo_flags = TFL_AMMO_ROCKETS | TFL_AMMO_RECHARGE;
-               
-                       return true;
-               }
-               case TR_PRECACHE:
-               {
-                       precache_model ("models/turrets/base.md3");
-                       precache_model ("models/turrets/hellion.md3");
-                       return true;
-               }
-       }
-       return true;
++    UpdateCSQCProjectile(self);
 +}
 +
 +void spawnfunc_turret_hellion() { if(!turret_initialize(TUR_HELLION)) remove(self); }
 +
 +float t_hellion(float req)
 +{
-       switch(req)
-       {
-               case TR_SETUP:
-               {
-                       return true;
-               }
-               case TR_PRECACHE:
-               {
-                       return true;
-               }
-       }
-       return true;
++    switch(req)
++    {
++        case TR_ATTACK:
++        {
++            entity missile;
++
++            if(self.tur_head.frame != 0)
++                self.tur_shotorg = gettaginfo(self.tur_head, gettagindex(self.tur_head, "tag_fire"));
++            else
++                self.tur_shotorg = gettaginfo(self.tur_head, gettagindex(self.tur_head, "tag_fire2"));
++
++            missile = turret_projectile("weapons/rocket_fire.wav", 6, 10, DEATH_TURRET_HELLION, PROJECTILE_ROCKET, FALSE, FALSE);
++            te_explosion (missile.origin);
++            missile.think             = turret_hellion_missile_think;
++            missile.nextthink = time;
++            missile.flags             = FL_PROJECTILE;
++            missile.max_health   = time + 9;
++            missile.tur_aimpos   = randomvec() * 128;
++            missile.missile_flags = MIF_SPLASH | MIF_PROXY | MIF_GUIDED_HEAT;
++            self.tur_head.frame += 1;
++
++            return true;
++        }
++        case TR_THINK:
++        {
++            if (self.tur_head.frame != 0)
++                self.tur_head.frame += 1;
++
++            if (self.tur_head.frame >= 7)
++                self.tur_head.frame = 0;
++
++            return true;
++        }
++        case TR_DEATH:
++        {
++            return true;
++        }
++        case TR_SETUP:
++        {
++            self.aim_flags = TFL_AIM_SIMPLE;
++            self.target_select_flags = TFL_TARGETSELECT_LOS | TFL_TARGETSELECT_PLAYERS | TFL_TARGETSELECT_RANGELIMITS | TFL_TARGETSELECT_TEAMCHECK ;
++            self.firecheck_flags = TFL_FIRECHECK_DEAD | TFL_FIRECHECK_DISTANCES | TFL_FIRECHECK_TEAMCHECK | TFL_FIRECHECK_REFIRE | TFL_FIRECHECK_AFF | TFL_FIRECHECK_AMMO_OWN;
++            self.ammo_flags = TFL_AMMO_ROCKETS | TFL_AMMO_RECHARGE;
++
++            return true;
++        }
++        case TR_PRECACHE:
++        {
++            precache_model ("models/turrets/base.md3");
++            precache_model ("models/turrets/hellion.md3");
++            return true;
++        }
++    }
++
++    return true;
 +}
 +
 +#endif // SVQC
 +#ifdef CSQC
 +float t_hellion(float req)
 +{
++    switch(req)
++    {
++        case TR_SETUP:
++        {
++            return true;
++        }
++        case TR_PRECACHE:
++        {
++            return true;
++        }
++    }
++
++    return true;
 +}
 +
 +#endif // CSQC
 +#endif // REGISTER_TURRET
index 414c71e,0000000..64d9a8c
mode 100644,000000..100644
--- /dev/null
@@@ -1,361 -1,0 +1,361 @@@
-       if (e_target == world)
-               return 0;
 +#ifdef REGISTER_TURRET
 +REGISTER_TURRET(
 +/* TUR_##id   */ HK,
 +/* function   */ t_hk,
 +/* spawnflags */ TUR_FLAG_SPLASH | TUR_FLAG_MEDPROJ | TUR_FLAG_PLAYER | TUR_FLAG_RECIEVETARGETS,
 +/* mins,maxs  */ '-32 -32 0', '32 32 64',
 +/* model        */ "base.md3",
 +/* head_model */ "hk.md3",
 +/* netname      */ "hk",
 +/* fullname   */ _("Hunter-Killer Turret")
 +);
 +#else
 +#ifdef SVQC
 +float autocvar_g_turrets_unit_hk_shot_speed;
 +float autocvar_g_turrets_unit_hk_shot_speed_accel;
 +float autocvar_g_turrets_unit_hk_shot_speed_accel2;
 +float autocvar_g_turrets_unit_hk_shot_speed_decel;
 +float autocvar_g_turrets_unit_hk_shot_speed_max;
 +float autocvar_g_turrets_unit_hk_shot_speed_turnrate;
 +
 +//#define TURRET_DEBUG_HK
 +
 +#ifdef TURRET_DEBUG_HK
 +.float atime;
 +#endif
 +
 +float hk_is_valid_target(entity e_target)
 +{
-       // If only this was used more..
-       if (e_target.flags & FL_NOTARGET)
-               return 0;
++    if (e_target == world)
++        return 0;
 +
-       // Cant touch this
-       if ((e_target.takedamage == DAMAGE_NO) || (e_target.health < 0))
-               return 0;
++    // If only this was used more..
++    if (e_target.flags & FL_NOTARGET)
++        return 0;
 +
-       // player
-       if (IS_CLIENT(e_target))
-       {
-               if (self.owner.target_select_playerbias < 0)
-                       return 0;
++    // Cant touch this
++    if ((e_target.takedamage == DAMAGE_NO) || (e_target.health < 0))
++        return 0;
 +
-               if (e_target.deadflag != DEAD_NO)
-                       return 0;
-       }
++    // player
++    if (IS_CLIENT(e_target))
++    {
++        if (self.owner.target_select_playerbias < 0)
++            return 0;
 +
-       // Missile
-       if ((e_target.flags & FL_PROJECTILE) && (self.owner.target_select_missilebias < 0))
-               return 0;
++        if (e_target.deadflag != DEAD_NO)
++            return 0;
++    }
 +
-       // Team check
-       if ((e_target.team == self.owner.team) || (self.owner.team == e_target.owner.team))
-               return 0;
++    // Missile
++    if ((e_target.flags & FL_PROJECTILE) && (self.owner.target_select_missilebias < 0))
++        return 0;
 +
-       return 1;
++    // Team check
++    if ((e_target.team == self.owner.team) || (self.owner.team == e_target.owner.team))
++        return 0;
 +
-       vector vu, vd, vf, vl, vr, ve;  // Vector (direction)
-       float  fu, fd, ff, fl, fr, fe;  // Fraction to solid
-       vector olddir,wishdir,newdir;   // Final direction
-       float lt_for;   // Length of Trace FORwrad
-       float lt_seek;  // Length of Trace SEEK (left, right, up down)
-       float pt_seek;  // Pitch of Trace SEEK (How mutch to angele left, right up, down trace towards v_forward)
-       vector pre_pos;
-       float myspeed;
-       entity e;
-       float ad,edist;
-       self.nextthink = time + self.ticrate;
-       //if (self.cnt < time)
-       //      turret_hk_missile_explode();
-       if (self.enemy.deadflag != DEAD_NO)
-               self.enemy = world;
-       // Pick the closest valid target.
-       if (!self.enemy)
-       {
-               e = findradius(self.origin, 5000);
-               while (e)
-               {
-                       if (hk_is_valid_target(e))
-                       {
-                               if (!self.enemy)
-                                       self.enemy = e;
-                               else
-                                       if (vlen(self.origin - e.origin) < vlen(self.origin - self.enemy.origin))
-                                               self.enemy = e;
-                       }
-                       e = e.chain;
-               }
-       }
-       self.angles = vectoangles(self.velocity);
-       self.angles_x = self.angles_x * -1;
-       makevectors(self.angles);
-       self.angles_x = self.angles_x * -1;
-       if (self.enemy)
-       {
-               edist = vlen(self.origin - self.enemy.origin);
-               // Close enougth to do decent damage?
-               if ( edist <= (self.owner.shot_radius * 0.25) )
-               {
-                       turret_projectile_explode();
-                       return;
-               }
-               // Get data on enemy position
-               pre_pos = self.enemy.origin +
-                                 self.enemy.velocity *
-                                 min((vlen(self.enemy.origin - self.origin) / vlen(self.velocity)),0.5);
-               traceline(self.origin, pre_pos,true,self.enemy);
-               ve = normalize(pre_pos - self.origin);
-               fe = trace_fraction;
-       }
-       else
-       {
-       edist = 0;
-       ve = '0 0 0';
-               fe = 0;
-       }
-       if ((fe != 1) || (self.enemy == world) || (edist > 1000))
-       {
-               myspeed = vlen(self.velocity);
-               lt_for  = myspeed * 3;
-               lt_seek = myspeed * 2.95;
-               // Trace forward
-               traceline(self.origin, self.origin + v_forward * lt_for,false,self);
-               vf = trace_endpos;
-               ff = trace_fraction;
-               // Find angular offset
-               ad = vlen(vectoangles(normalize(self.enemy.origin - self.origin)) - self.angles);
-               // To close to something, Slow down!
-               if ( ((ff < 0.7) || (ad > 4)) && (myspeed > (autocvar_g_turrets_unit_hk_shot_speed)) )
-                       myspeed = max(myspeed * (autocvar_g_turrets_unit_hk_shot_speed_decel), (autocvar_g_turrets_unit_hk_shot_speed));
-               // Failry clear, accelerate.
-               if ( (ff > 0.7) && (myspeed < (autocvar_g_turrets_unit_hk_shot_speed_max)) )
-                       myspeed = min(myspeed * (autocvar_g_turrets_unit_hk_shot_speed_accel), (autocvar_g_turrets_unit_hk_shot_speed_max));
-               // Setup trace pitch
-               pt_seek = 1 - ff;
-               pt_seek = bound(0.15,pt_seek,0.8);
-               if (ff < 0.5) pt_seek = 1;
-               // Trace left
-               traceline(self.origin, self.origin + (-1 * (v_right * pt_seek) + (v_forward * ff)) * lt_seek,false,self);
-               vl = trace_endpos;
-               fl = trace_fraction;
-               // Trace right
-               traceline(self.origin,  self.origin + ((v_right * pt_seek) + (v_forward * ff)) * lt_seek ,false,self);
-               vr = trace_endpos;
-               fr = trace_fraction;
-               // Trace up
-               traceline(self.origin,  self.origin + ((v_up * pt_seek) + (v_forward * ff)) * lt_seek ,false,self);
-               vu = trace_endpos;
-               fu = trace_fraction;
-               // Trace down
-               traceline(self.origin,  self.origin + (-1 * (v_up * pt_seek) + (v_forward * ff)) * lt_seek ,false,self);
-               vd = trace_endpos;
-               fd = trace_fraction;
-               vl = normalize(vl - self.origin);
-               vr = normalize(vr - self.origin);
-               vu = normalize(vu - self.origin);
-               vd = normalize(vd - self.origin);
-               // Panic tresh passed, find a single direction and turn as hard as we can
-               if (pt_seek == 1)
-               {
-                       wishdir = v_right;
-                       if (fl > fr) wishdir = -1 * v_right;
-                       if (fu > fl) wishdir = v_up;
-                       if (fd > fu) wishdir = -1 * v_up;
-               }
-               else
-               {
-                       // Normalize our trace vectors to make a smooth path
-                       wishdir = normalize( (vl * fl) + (vr * fr) +  (vu * fu) +  (vd * fd) );
-               }
-               if (self.enemy)
-               {
-                       if (fe < 0.1) fe = 0.1; // Make sure we always try to move sligtly towards our target
-                       wishdir = (wishdir * (1 - fe)) + (ve * fe);
-               }
-       }
-       else
-       {
-               // Got a clear path to target, speed up fast (if not at full speed) and go straight for it.
-               myspeed = vlen(self.velocity);
-               if (myspeed < (autocvar_g_turrets_unit_hk_shot_speed_max))
-                       myspeed = min(myspeed * (autocvar_g_turrets_unit_hk_shot_speed_accel2),(autocvar_g_turrets_unit_hk_shot_speed_max));
-               wishdir = ve;
-       }
-       if ((myspeed > (autocvar_g_turrets_unit_hk_shot_speed)) && (self.cnt > time))
-               myspeed = min(myspeed * (autocvar_g_turrets_unit_hk_shot_speed_accel2),(autocvar_g_turrets_unit_hk_shot_speed_max));
-       // Ranoutagazfish?
-       if (self.cnt < time)
-       {
-               self.cnt = time + 0.25;
-               self.nextthink = 0;
-               self.movetype            = MOVETYPE_BOUNCE;
-               return;
-       }
-       // Calculate new heading
-       olddir = normalize(self.velocity);
-       newdir = normalize(olddir + wishdir * (autocvar_g_turrets_unit_hk_shot_speed_turnrate));
-       // Set heading & speed
-       self.velocity = newdir * myspeed;
-       // Align model with new heading
-       self.angles = vectoangles(self.velocity);
++    return 1;
 +}
 +
 +void turret_hk_missile_think()
 +{
-       //if(self.atime < time) {
-       if ((fe <= 0.99)||(edist > 1000))
-       {
-               te_lightning2(world,self.origin, self.origin + vr * lt_seek);
-               te_lightning2(world,self.origin, self.origin + vl * lt_seek);
-               te_lightning2(world,self.origin, self.origin + vu * lt_seek);
-               te_lightning2(world,self.origin, self.origin + vd * lt_seek);
-               te_lightning2(world,self.origin, vf);
-       }
-       else
-       {
-               te_lightning2(world,self.origin, self.enemy.origin);
-       }
-       bprint("Speed: ", ftos(rint(myspeed)), "\n");
-       bprint("Trace to solid: ", ftos(rint(ff * 100)), "%\n");
-       bprint("Trace to target:", ftos(rint(fe * 100)), "%\n");
-       self.atime = time + 0.2;
-       //}
++    vector vu, vd, vf, vl, vr, ve;  // Vector (direction)
++    float  fu, fd, ff, fl, fr, fe;  // Fraction to solid
++    vector olddir,wishdir,newdir;   // Final direction
++    float lt_for;   // Length of Trace FORwrad
++    float lt_seek;  // Length of Trace SEEK (left, right, up down)
++    float pt_seek;  // Pitch of Trace SEEK (How mutch to angele left, right up, down trace towards v_forward)
++    vector pre_pos;
++    float myspeed;
++    entity e;
++    float ad,edist;
++
++    self.nextthink = time + self.ticrate;
++
++    //if (self.cnt < time)
++    //        turret_hk_missile_explode();
++
++    if (self.enemy.deadflag != DEAD_NO)
++        self.enemy = world;
++
++    // Pick the closest valid target.
++    if (!self.enemy)
++    {
++        e = findradius(self.origin, 5000);
++        while (e)
++        {
++            if (hk_is_valid_target(e))
++            {
++                if (!self.enemy)
++                    self.enemy = e;
++                else
++                    if (vlen(self.origin - e.origin) < vlen(self.origin - self.enemy.origin))
++                        self.enemy = e;
++            }
++            e = e.chain;
++        }
++    }
++
++    self.angles = vectoangles(self.velocity);
++    self.angles_x = self.angles_x * -1;
++    makevectors(self.angles);
++    self.angles_x = self.angles_x * -1;
++
++    if (self.enemy)
++    {
++        edist = vlen(self.origin - self.enemy.origin);
++        // Close enougth to do decent damage?
++        if ( edist <= (self.owner.shot_radius * 0.25) )
++        {
++            turret_projectile_explode();
++            return;
++        }
++
++        // Get data on enemy position
++        pre_pos = self.enemy.origin +
++                  self.enemy.velocity *
++                  min((vlen(self.enemy.origin - self.origin) / vlen(self.velocity)),0.5);
++
++        traceline(self.origin, pre_pos,true,self.enemy);
++        ve = normalize(pre_pos - self.origin);
++        fe = trace_fraction;
++
++    }
++    else
++    {
++    edist = 0;
++    ve = '0 0 0';
++        fe = 0;
++    }
++
++    if ((fe != 1) || (self.enemy == world) || (edist > 1000))
++    {
++        myspeed = vlen(self.velocity);
++
++        lt_for  = myspeed * 3;
++        lt_seek = myspeed * 2.95;
++
++        // Trace forward
++        traceline(self.origin, self.origin + v_forward * lt_for,false,self);
++        vf = trace_endpos;
++        ff = trace_fraction;
++
++        // Find angular offset
++        ad = vlen(vectoangles(normalize(self.enemy.origin - self.origin)) - self.angles);
++
++        // To close to something, Slow down!
++        if ( ((ff < 0.7) || (ad > 4)) && (myspeed > (autocvar_g_turrets_unit_hk_shot_speed)) )
++            myspeed = max(myspeed * (autocvar_g_turrets_unit_hk_shot_speed_decel), (autocvar_g_turrets_unit_hk_shot_speed));
++
++        // Failry clear, accelerate.
++        if ( (ff > 0.7) && (myspeed < (autocvar_g_turrets_unit_hk_shot_speed_max)) )
++            myspeed = min(myspeed * (autocvar_g_turrets_unit_hk_shot_speed_accel), (autocvar_g_turrets_unit_hk_shot_speed_max));
++
++        // Setup trace pitch
++        pt_seek = 1 - ff;
++        pt_seek = bound(0.15,pt_seek,0.8);
++        if (ff < 0.5) pt_seek = 1;
++
++        // Trace left
++        traceline(self.origin, self.origin + (-1 * (v_right * pt_seek) + (v_forward * ff)) * lt_seek,false,self);
++        vl = trace_endpos;
++        fl = trace_fraction;
++
++        // Trace right
++        traceline(self.origin,  self.origin + ((v_right * pt_seek) + (v_forward * ff)) * lt_seek ,false,self);
++        vr = trace_endpos;
++        fr = trace_fraction;
++
++        // Trace up
++        traceline(self.origin,  self.origin + ((v_up * pt_seek) + (v_forward * ff)) * lt_seek ,false,self);
++        vu = trace_endpos;
++        fu = trace_fraction;
++
++        // Trace down
++        traceline(self.origin,  self.origin + (-1 * (v_up * pt_seek) + (v_forward * ff)) * lt_seek ,false,self);
++        vd = trace_endpos;
++        fd = trace_fraction;
++
++        vl = normalize(vl - self.origin);
++        vr = normalize(vr - self.origin);
++        vu = normalize(vu - self.origin);
++        vd = normalize(vd - self.origin);
++
++        // Panic tresh passed, find a single direction and turn as hard as we can
++        if (pt_seek == 1)
++        {
++            wishdir = v_right;
++            if (fl > fr) wishdir = -1 * v_right;
++            if (fu > fl) wishdir = v_up;
++            if (fd > fu) wishdir = -1 * v_up;
++        }
++        else
++        {
++            // Normalize our trace vectors to make a smooth path
++            wishdir = normalize( (vl * fl) + (vr * fr) +  (vu * fu) +  (vd * fd) );
++        }
++
++        if (self.enemy)
++        {
++            if (fe < 0.1) fe = 0.1; // Make sure we always try to move sligtly towards our target
++            wishdir = (wishdir * (1 - fe)) + (ve * fe);
++        }
++    }
++    else
++    {
++        // Got a clear path to target, speed up fast (if not at full speed) and go straight for it.
++        myspeed = vlen(self.velocity);
++        if (myspeed < (autocvar_g_turrets_unit_hk_shot_speed_max))
++            myspeed = min(myspeed * (autocvar_g_turrets_unit_hk_shot_speed_accel2),(autocvar_g_turrets_unit_hk_shot_speed_max));
++
++        wishdir = ve;
++    }
++
++    if ((myspeed > (autocvar_g_turrets_unit_hk_shot_speed)) && (self.cnt > time))
++        myspeed = min(myspeed * (autocvar_g_turrets_unit_hk_shot_speed_accel2),(autocvar_g_turrets_unit_hk_shot_speed_max));
++
++    // Ranoutagazfish?
++    if (self.cnt < time)
++    {
++        self.cnt = time + 0.25;
++        self.nextthink = 0;
++        self.movetype          = MOVETYPE_BOUNCE;
++        return;
++    }
++
++    // Calculate new heading
++    olddir = normalize(self.velocity);
++    newdir = normalize(olddir + wishdir * (autocvar_g_turrets_unit_hk_shot_speed_turnrate));
++
++    // Set heading & speed
++    self.velocity = newdir * myspeed;
++
++    // Align model with new heading
++    self.angles = vectoangles(self.velocity);
 +
 +
 +#ifdef TURRET_DEBUG_HK
-       UpdateCSQCProjectile(self);
++    //if(self.atime < time) {
++    if ((fe <= 0.99)||(edist > 1000))
++    {
++        te_lightning2(world,self.origin, self.origin + vr * lt_seek);
++        te_lightning2(world,self.origin, self.origin + vl * lt_seek);
++        te_lightning2(world,self.origin, self.origin + vu * lt_seek);
++        te_lightning2(world,self.origin, self.origin + vd * lt_seek);
++        te_lightning2(world,self.origin, vf);
++    }
++    else
++    {
++        te_lightning2(world,self.origin, self.enemy.origin);
++    }
++    bprint("Speed: ", ftos(rint(myspeed)), "\n");
++    bprint("Trace to solid: ", ftos(rint(ff * 100)), "%\n");
++    bprint("Trace to target:", ftos(rint(fe * 100)), "%\n");
++    self.atime = time + 0.2;
++    //}
 +#endif
 +
-       if (e_target)
-       {
-               if (turret_validate_target(self,e_target,self.target_validate_flags) > 0)
-               {
-                       self.enemy = e_target;
-                       return 1;
-               }
-       }
-       return 0;
++    UpdateCSQCProjectile(self);
 +}
 +
 +float turret_hk_addtarget(entity e_target,entity e_sender)
 +{
-       switch(req)
-       {
-               case TR_ATTACK:
-               {
-                       entity missile;
-                       missile = turret_projectile("weapons/rocket_fire.wav", 6, 10, DEATH_TURRET_HK, PROJECTILE_ROCKET, FALSE, FALSE);
-                       te_explosion (missile.origin);
-                       missile.think                   = turret_hk_missile_think;
-                       missile.nextthink               = time + 0.25;
-                       missile.movetype                 = MOVETYPE_BOUNCEMISSILE;
-                       missile.velocity                 = self.tur_shotdir_updated * (self.shot_speed * 0.75);
-                       missile.angles             = vectoangles(missile.velocity);
-                       missile.cnt                       = time + 30;
-                       missile.ticrate           = max(autocvar_sys_ticrate, 0.05);
-                       missile.missile_flags = MIF_SPLASH | MIF_PROXY | MIF_GUIDED_AI;
-                       if (self.tur_head.frame == 0)
-                               self.tur_head.frame = self.tur_head.frame + 1;
-                       return true;
-               }
-               case TR_THINK:
-               {
-                       if (self.tur_head.frame != 0)
-                               self.tur_head.frame = self.tur_head.frame + 1;
-                       if (self.tur_head.frame > 5)
-                               self.tur_head.frame = 0;
-                       return true;
-               }
-               case TR_DEATH:
-               {
-                       return true;
-               }
-               case TR_SETUP:
-               {
-                       self.ammo_flags = TFL_AMMO_ROCKETS | TFL_AMMO_RECHARGE;
-                       self.aim_flags = TFL_AIM_SIMPLE;
-                       self.target_select_flags = TFL_TARGETSELECT_LOS | TFL_TARGETSELECT_PLAYERS | TFL_TARGETSELECT_TRIGGERTARGET | TFL_TARGETSELECT_RANGELIMITS | TFL_TARGETSELECT_TEAMCHECK;
-                       self.firecheck_flags = TFL_FIRECHECK_DEAD | TFL_FIRECHECK_TEAMCHECK  | TFL_FIRECHECK_REFIRE | TFL_FIRECHECK_AFF;
-                       self.shoot_flags = TFL_SHOOT_CLEARTARGET;
-                       self.target_validate_flags = TFL_TARGETSELECT_PLAYERS | TFL_TARGETSELECT_TEAMCHECK;
-                       self.turret_addtarget = turret_hk_addtarget;
-                       return true;
-               }
-               case TR_PRECACHE:
-               {
-                       precache_model ("models/turrets/base.md3");
-                       precache_model ("models/turrets/hk.md3");
-                       return true;
-               }
-       }
-       return true;
++    if (e_target)
++    {
++        if (turret_validate_target(self,e_target,self.target_validate_flags) > 0)
++        {
++            self.enemy = e_target;
++            return 1;
++        }
++    }
++
++    return 0;
 +}
 +
 +void spawnfunc_turret_hk() { if(!turret_initialize(TUR_HK)) remove(self); }
 +
 +float t_hk(float req)
 +{
-       switch(req)
-       {
-               case TR_SETUP:
-               {
-                       return true;
-               }
-               case TR_PRECACHE:
-               {
-                       return true;
-               }
-       }
-       return true;
++    switch(req)
++    {
++        case TR_ATTACK:
++        {
++            entity missile;
++
++            missile = turret_projectile("weapons/rocket_fire.wav", 6, 10, DEATH_TURRET_HK, PROJECTILE_ROCKET, FALSE, FALSE);
++            te_explosion (missile.origin);
++
++            missile.think                     = turret_hk_missile_think;
++            missile.nextthink         = time + 0.25;
++            missile.movetype           = MOVETYPE_BOUNCEMISSILE;
++            missile.velocity           = self.tur_shotdir_updated * (self.shot_speed * 0.75);
++            missile.angles               = vectoangles(missile.velocity);
++            missile.cnt                         = time + 30;
++            missile.ticrate             = max(autocvar_sys_ticrate, 0.05);
++            missile.missile_flags = MIF_SPLASH | MIF_PROXY | MIF_GUIDED_AI;
++
++            if (self.tur_head.frame == 0)
++                self.tur_head.frame = self.tur_head.frame + 1;
++
++            return true;
++        }
++        case TR_THINK:
++        {
++            if (self.tur_head.frame != 0)
++                self.tur_head.frame = self.tur_head.frame + 1;
++
++            if (self.tur_head.frame > 5)
++                self.tur_head.frame = 0;
++
++            return true;
++        }
++        case TR_DEATH:
++        {
++            return true;
++        }
++        case TR_SETUP:
++        {
++            self.ammo_flags = TFL_AMMO_ROCKETS | TFL_AMMO_RECHARGE;
++            self.aim_flags = TFL_AIM_SIMPLE;
++            self.target_select_flags = TFL_TARGETSELECT_LOS | TFL_TARGETSELECT_PLAYERS | TFL_TARGETSELECT_TRIGGERTARGET | TFL_TARGETSELECT_RANGELIMITS | TFL_TARGETSELECT_TEAMCHECK;
++            self.firecheck_flags = TFL_FIRECHECK_DEAD | TFL_FIRECHECK_TEAMCHECK  | TFL_FIRECHECK_REFIRE | TFL_FIRECHECK_AFF;
++            self.shoot_flags = TFL_SHOOT_CLEARTARGET;
++            self.target_validate_flags = TFL_TARGETSELECT_PLAYERS | TFL_TARGETSELECT_TEAMCHECK;
++
++            self.turret_addtarget = turret_hk_addtarget;
++
++            return true;
++        }
++        case TR_PRECACHE:
++        {
++            precache_model ("models/turrets/base.md3");
++            precache_model ("models/turrets/hk.md3");
++            return true;
++        }
++    }
++
++    return true;
 +}
 +
 +#endif // SVQC
 +#ifdef CSQC
 +float t_hk(float req)
 +{
++    switch(req)
++    {
++        case TR_SETUP:
++        {
++            return true;
++        }
++        case TR_PRECACHE:
++        {
++            return true;
++        }
++    }
++
++    return true;
 +}
 +
 +#endif // CSQC
 +#endif // REGISTER_TURRET
index f4a4621,0000000..f952d4b
mode 100644,000000..100644
--- /dev/null
@@@ -1,79 -1,0 +1,81 @@@
-       switch(req)
-       {
-               case TR_ATTACK:
-               {
-                       fireBullet (self.tur_shotorg, self.tur_shotdir_updated, self.shot_spread, 0, self.shot_dmg, self.shot_force, DEATH_TURRET_MACHINEGUN, 0);
 +#ifdef REGISTER_TURRET
 +REGISTER_TURRET(
 +/* TUR_##id   */ MACHINEGUN,
 +/* function   */ t_machinegun,
 +/* spawnflags */ TUR_FLAG_PLAYER,
 +/* mins,maxs  */ '-32 -32 0', '32 32 64',
 +/* model        */ "base.md3",
 +/* head_model */ "machinegun.md3",
 +/* netname      */ "machinegun",
 +/* fullname   */ _("Machinegun Turret")
 +);
 +#else
 +#ifdef SVQC
 +void spawnfunc_turret_machinegun() { if(!turret_initialize(TUR_MACHINEGUN)) remove(self); }
 +
++void W_MachineGun_MuzzleFlash(void);
++
 +float t_machinegun(float req)
 +{
-                       W_MachineGun_MuzzleFlash();
-                       setattachment(self.muzzle_flash, self.tur_head, "tag_fire");
++    switch(req)
++    {
++        case TR_ATTACK:
++        {
++            fireBullet (self.tur_shotorg, self.tur_shotdir_updated, self.shot_spread, 0, self.shot_dmg, self.shot_force, DEATH_TURRET_MACHINEGUN, 0);
 +
-                       return true;
-               }
-               case TR_THINK:
-               {
-                       return true;
-               }
-               case TR_DEATH:
-               {
-                       return true;
-               }
-               case TR_SETUP:
-               {
-                       self.damage_flags |= TFL_DMG_HEADSHAKE;
-                       self.target_select_flags = TFL_TARGETSELECT_PLAYERS | TFL_TARGETSELECT_RANGELIMITS | TFL_TARGETSELECT_TEAMCHECK;
-                       self.ammo_flags = TFL_AMMO_BULLETS | TFL_AMMO_RECHARGE | TFL_AMMO_RECIEVE;
-                       self.aim_flags = TFL_AIM_LEAD | TFL_AIM_SHOTTIMECOMPENSATE;
-                       self.turret_flags |= TUR_FLAG_HITSCAN;
++            W_MachineGun_MuzzleFlash();
++            setattachment(self.muzzle_flash, self.tur_head, "tag_fire");
 +
-                       return true;
-               }
-               case TR_PRECACHE:
-               {
-                       precache_model ("models/turrets/base.md3");
-                       precache_model ("models/turrets/machinegun.md3");
-                       precache_sound ("weapons/uzi_fire.wav");
-                       return true;
-               }
-       }
++            return true;
++        }
++        case TR_THINK:
++        {
++            return true;
++        }
++        case TR_DEATH:
++        {
++            return true;
++        }
++        case TR_SETUP:
++        {
++            self.damage_flags |= TFL_DMG_HEADSHAKE;
++            self.target_select_flags = TFL_TARGETSELECT_PLAYERS | TFL_TARGETSELECT_RANGELIMITS | TFL_TARGETSELECT_TEAMCHECK;
++            self.ammo_flags = TFL_AMMO_BULLETS | TFL_AMMO_RECHARGE | TFL_AMMO_RECIEVE;
++            self.aim_flags = TFL_AIM_LEAD | TFL_AIM_SHOTTIMECOMPENSATE;
++            self.turret_flags |= TUR_FLAG_HITSCAN;
 +
-       return true;
++            return true;
++        }
++        case TR_PRECACHE:
++        {
++            precache_model ("models/turrets/base.md3");
++            precache_model ("models/turrets/machinegun.md3");
++            precache_sound ("weapons/uzi_fire.wav");
++            return true;
++        }
++    }
 +
-       switch(req)
-       {
-               case TR_SETUP:
-               {
-                       return true;
-               }
-               case TR_PRECACHE:
-               {
-                       return true;
-               }
-       }
++    return true;
 +}
 +
 +#endif // SVQC
 +#ifdef CSQC
 +float t_machinegun(float req)
 +{
-       return true;
++    switch(req)
++    {
++        case TR_SETUP:
++        {
++            return true;
++        }
++        case TR_PRECACHE:
++        {
++            return true;
++        }
++    }
 +
++    return true;
 +}
 +
 +#endif // CSQC
 +#endif // REGISTER_TURRET
index 254a589,0000000..0142202
mode 100644,000000..100644
--- /dev/null
@@@ -1,90 -1,0 +1,90 @@@
-       switch(req)
-       {
-               case TR_ATTACK:
-               {
-                       entity missile;
 +#ifdef REGISTER_TURRET
 +REGISTER_TURRET(
 +/* TUR_##id   */ MLRS,
 +/* function   */ t_mlrs,
 +/* spawnflags */ TUR_FLAG_SPLASH | TUR_FLAG_MEDPROJ | TUR_FLAG_PLAYER,
 +/* mins,maxs  */ '-32 -32 0', '32 32 64',
 +/* model        */ "base.md3",
 +/* head_model */ "mlrs.md3",
 +/* netname      */ "mlrs",
 +/* fullname   */ _("MLRS Turret")
 +);
 +#else
 +#ifdef SVQC
 +void spawnfunc_turret_mlrs() { if(!turret_initialize(TUR_MLRS)) remove(self); }
 +
 +float t_mlrs(float req)
 +{
-                       turret_tag_fire_update();
-                       missile = turret_projectile("weapons/rocket_fire.wav", 6, 10, DEATH_TURRET_MLRS, PROJECTILE_ROCKET, TRUE, TRUE);
-                       missile.nextthink = time + max(self.tur_impacttime,(self.shot_radius * 2) / self.shot_speed);
-                       missile.missile_flags = MIF_SPLASH;
-                       te_explosion (missile.origin);
++    switch(req)
++    {
++        case TR_ATTACK:
++        {
++            entity missile;
 +
-                       return true;
-               }
-               case TR_THINK:
-               {
-                       // 0 = full, 6 = empty
-                       self.tur_head.frame = bound(0, 6 - floor(0.1 + self.ammo / self.shot_dmg), 6);
-                       if(self.tur_head.frame < 0)
-                       {
-                               dprint("ammo:",ftos(self.ammo),"\n");
-                               dprint("shot_dmg:",ftos(self.shot_dmg),"\n");
-                       }
-               
-                       return true;
-               }
-               case TR_DEATH:
-               {
-                       return true;
-               }
-               case TR_SETUP:
-               {
-                       self.ammo_flags = TFL_AMMO_ROCKETS | TFL_AMMO_RECHARGE;
-                       self.aim_flags = TFL_AIM_LEAD | TFL_AIM_SHOTTIMECOMPENSATE;
-               
-                       self.damage_flags |= TFL_DMG_HEADSHAKE;
-                       self.shoot_flags  |= TFL_SHOOT_VOLLYALWAYS;
-                       self.volly_counter = self.shot_volly;
++            turret_tag_fire_update();
++            missile = turret_projectile("weapons/rocket_fire.wav", 6, 10, DEATH_TURRET_MLRS, PROJECTILE_ROCKET, TRUE, TRUE);
++            missile.nextthink = time + max(self.tur_impacttime,(self.shot_radius * 2) / self.shot_speed);
++            missile.missile_flags = MIF_SPLASH;
++            te_explosion (missile.origin);
 +
-                       return true;
-               }
-               case TR_PRECACHE:
-               {
-                       precache_model ("models/turrets/base.md3");
-                       precache_model ("models/turrets/mlrs.md3");
-                       return true;
-               }
-       }
++            return true;
++        }
++        case TR_THINK:
++        {
++            // 0 = full, 6 = empty
++            self.tur_head.frame = bound(0, 6 - floor(0.1 + self.ammo / self.shot_dmg), 6);
++            if(self.tur_head.frame < 0)
++            {
++                dprint("ammo:",ftos(self.ammo),"\n");
++                dprint("shot_dmg:",ftos(self.shot_dmg),"\n");
++            }
 +
-       return true;
++            return true;
++        }
++        case TR_DEATH:
++        {
++            return true;
++        }
++        case TR_SETUP:
++        {
++            self.ammo_flags = TFL_AMMO_ROCKETS | TFL_AMMO_RECHARGE;
++            self.aim_flags = TFL_AIM_LEAD | TFL_AIM_SHOTTIMECOMPENSATE;
 +
-       switch(req)
-       {
-               case TR_SETUP:
-               {
-                       return true;
-               }
-               case TR_PRECACHE:
-               {
-                       return true;
-               }
-       }
++            self.damage_flags |= TFL_DMG_HEADSHAKE;
++            self.shoot_flags  |= TFL_SHOOT_VOLLYALWAYS;
++            self.volly_counter = self.shot_volly;
++
++            return true;
++        }
++        case TR_PRECACHE:
++        {
++            precache_model ("models/turrets/base.md3");
++            precache_model ("models/turrets/mlrs.md3");
++            return true;
++        }
++    }
++
++    return true;
 +}
 +
 +#endif // SVQC
 +#ifdef CSQC
 +float t_mlrs(float req)
 +{
-       return true;
++    switch(req)
++    {
++        case TR_SETUP:
++        {
++            return true;
++        }
++        case TR_PRECACHE:
++        {
++            return true;
++        }
++    }
 +
++    return true;
 +}
 +
 +#endif // CSQC
 +#endif // REGISTER_TURRET
index 32c392b,0000000..449c09f
mode 100644,000000..100644
--- /dev/null
@@@ -1,173 -1,0 +1,173 @@@
-       if (self.fireflag != 0) return 0;
-       return turret_firecheck();
 +#ifdef REGISTER_TURRET
 +REGISTER_TURRET(
 +/* TUR_##id   */ PHASER,
 +/* function   */ t_phaser,
 +/* spawnflags */ TUR_FLAG_SNIPER | TUR_FLAG_HITSCAN | TUR_FLAG_PLAYER,
 +/* mins,maxs  */ '-32 -32 0', '32 32 64',
 +/* model        */ "base.md3",
 +/* head_model */ "phaser.md3",
 +/* netname      */ "phaser",
 +/* fullname   */ _("Phaser Cannon")
 +);
 +#else
 +#ifdef SVQC
 +.float fireflag;
 +
 +float turret_phaser_firecheck()
 +{
-       if ((time > self.cnt) || (self.owner.deadflag != DEAD_NO))
-       {
-               self.owner.attack_finished_single = time + self.owner.shot_refire;
-               self.owner.fireflag = 2;
-               self.owner.tur_head.frame = 10;
-               sound (self, CH_SHOTS_SINGLE, "misc/null.wav", VOL_BASE, ATTEN_NORM);
-               remove(self);
-               return;
-       }
-       turret_do_updates(self.owner);
-       if (time - self.shot_spread > 0)
-       {
-               self.shot_spread = time + 2;
-               sound (self, CH_SHOTS_SINGLE, "turrets/phaser.wav", VOL_BASE, ATTEN_NORM);
-       }
-       self.nextthink = time + self.ticrate;
-       self.owner.attack_finished_single = time + frametime;
-       entity oldself;
-       oldself = self;
-       self = self.owner;
-       FireImoBeam (   self.tur_shotorg,
-                                       self.tur_shotorg + self.tur_shotdir_updated * self.target_range,
-                                       '-1 -1 -1' * self.shot_radius,
-                                       '1 1 1' * self.shot_radius,
-                                       self.shot_force,
-                                       oldself.shot_dmg,
-                                       0.75,
-                                       DEATH_TURRET_PHASER);
-       self = oldself;
-       self.scale = vlen(self.owner.tur_shotorg - trace_endpos) / 256;
++    if (self.fireflag != 0) return 0;
++    return turret_firecheck();
 +}
 +
 +void beam_think()
 +{
-       switch(req)
-       {
-               case TR_ATTACK:
-               {
-                       entity beam;
-                       beam = spawn();
-                       beam.ticrate = 0.1; //autocvar_sys_ticrate;
-                       setmodel(beam,"models/turrets/phaser_beam.md3");
-                       beam.effects = EF_LOWPRECISION;
-                       beam.solid = SOLID_NOT;
-                       beam.think = beam_think;
-                       beam.cnt = time + self.shot_speed;
-                       beam.shot_spread = time + 2;
-                       beam.nextthink = time;
-                       beam.owner = self;
-                       beam.shot_dmg = self.shot_dmg / (self.shot_speed / beam.ticrate);
-                       beam.scale = self.target_range / 256;
-                       beam.movetype = MOVETYPE_NONE;
-                       beam.enemy = self.enemy;
-                       beam.bot_dodge = true;
-                       beam.bot_dodgerating = beam.shot_dmg;
-                       sound (beam, CH_SHOTS_SINGLE, "turrets/phaser.wav", VOL_BASE, ATTEN_NORM);
-                       self.fireflag = 1;
-                       beam.attack_finished_single = self.attack_finished_single;
-                       self.attack_finished_single = time; // + autocvar_sys_ticrate;
-                       setattachment(beam,self.tur_head,"tag_fire");
-                       soundat (self, trace_endpos, CH_SHOTS, "weapons/neximpact.wav", VOL_BASE, ATTEN_NORM);
-                       if (self.tur_head.frame == 0)
-                               self.tur_head.frame = 1;
-                       return true;
-               }
-               case TR_THINK:
-               {
-                       if (self.tur_head.frame != 0)
-                       {
-                               if (self.fireflag == 1)
-                               {
-                                       if (self.tur_head.frame == 10)
-                                               self.tur_head.frame = 1;
-                                       else
-                                               self.tur_head.frame = self.tur_head.frame +1;
-                               }
-                               else if (self.fireflag == 2 )
-                               {
-                                       self.tur_head.frame = self.tur_head.frame +1;
-                                       if (self.tur_head.frame == 15)
-                                       {
-                                               self.tur_head.frame = 0;
-                                               self.fireflag = 0;
-                                       }
-                               }
-                       }
-                       return true;
-               }
-               case TR_DEATH:
-               {
-                       return true;
-               }
-               case TR_SETUP:
-               {
-                       self.ammo_flags = TFL_AMMO_ENERGY | TFL_AMMO_RECHARGE | TFL_AMMO_RECIEVE;
-                       self.aim_flags = TFL_AIM_LEAD;
-                       self.turret_firecheckfunc = turret_phaser_firecheck;
-                       return true;
-               }
-               case TR_PRECACHE:
-               {
-                       precache_model ("models/turrets/base.md3");
-                       precache_model ("models/turrets/phaser.md3");
-                       precache_model ("models/turrets/phaser_beam.md3");
-                       precache_sound ("turrets/phaser.wav");
-                       return true;
-               }
-       }
-       return true;
++    if ((time > self.cnt) || (self.owner.deadflag != DEAD_NO))
++    {
++        self.owner.attack_finished_single = time + self.owner.shot_refire;
++        self.owner.fireflag = 2;
++        self.owner.tur_head.frame = 10;
++        sound (self, CH_SHOTS_SINGLE, "misc/null.wav", VOL_BASE, ATTEN_NORM);
++        remove(self);
++        return;
++    }
++
++    turret_do_updates(self.owner);
++
++    if (time - self.shot_spread > 0)
++    {
++        self.shot_spread = time + 2;
++        sound (self, CH_SHOTS_SINGLE, "turrets/phaser.wav", VOL_BASE, ATTEN_NORM);
++    }
++
++
++    self.nextthink = time + self.ticrate;
++
++    self.owner.attack_finished_single = time + frametime;
++    entity oldself;
++    oldself = self;
++    self = self.owner;
++    FireImoBeam (   self.tur_shotorg,
++                    self.tur_shotorg + self.tur_shotdir_updated * self.target_range,
++                    '-1 -1 -1' * self.shot_radius,
++                    '1 1 1' * self.shot_radius,
++                    self.shot_force,
++                    oldself.shot_dmg,
++                    0.75,
++                    DEATH_TURRET_PHASER);
++    self = oldself;
++    self.scale = vlen(self.owner.tur_shotorg - trace_endpos) / 256;
 +
 +}
 +
 +void spawnfunc_turret_phaser() { if(!turret_initialize(TUR_PHASER)) remove(self); }
 +
 +float t_phaser(float req)
 +{
-       switch(req)
-       {
-               case TR_SETUP:
-               {
-                       return true;
-               }
-               case TR_PRECACHE:
-               {
-                       return true;
-               }
-       }
-       return true;
++    switch(req)
++    {
++        case TR_ATTACK:
++        {
++            entity beam;
++
++            beam = spawn();
++            beam.ticrate = 0.1; //autocvar_sys_ticrate;
++            setmodel(beam,"models/turrets/phaser_beam.md3");
++            beam.effects = EF_LOWPRECISION;
++            beam.solid = SOLID_NOT;
++            beam.think = beam_think;
++            beam.cnt = time + self.shot_speed;
++            beam.shot_spread = time + 2;
++            beam.nextthink = time;
++            beam.owner = self;
++            beam.shot_dmg = self.shot_dmg / (self.shot_speed / beam.ticrate);
++            beam.scale = self.target_range / 256;
++            beam.movetype = MOVETYPE_NONE;
++            beam.enemy = self.enemy;
++            beam.bot_dodge = true;
++            beam.bot_dodgerating = beam.shot_dmg;
++            sound (beam, CH_SHOTS_SINGLE, "turrets/phaser.wav", VOL_BASE, ATTEN_NORM);
++            self.fireflag = 1;
++
++            beam.attack_finished_single = self.attack_finished_single;
++            self.attack_finished_single = time; // + autocvar_sys_ticrate;
++
++            setattachment(beam,self.tur_head,"tag_fire");
++
++            soundat (self, trace_endpos, CH_SHOTS, "weapons/neximpact.wav", VOL_BASE, ATTEN_NORM);
++
++            if (self.tur_head.frame == 0)
++                self.tur_head.frame = 1;
++
++            return true;
++        }
++        case TR_THINK:
++        {
++            if (self.tur_head.frame != 0)
++            {
++                if (self.fireflag == 1)
++                {
++                    if (self.tur_head.frame == 10)
++                        self.tur_head.frame = 1;
++                    else
++                        self.tur_head.frame = self.tur_head.frame +1;
++                }
++                else if (self.fireflag == 2 )
++                {
++                    self.tur_head.frame = self.tur_head.frame +1;
++                    if (self.tur_head.frame == 15)
++                    {
++                        self.tur_head.frame = 0;
++                        self.fireflag = 0;
++                    }
++                }
++            }
++
++            return true;
++        }
++        case TR_DEATH:
++        {
++            return true;
++        }
++        case TR_SETUP:
++        {
++            self.ammo_flags = TFL_AMMO_ENERGY | TFL_AMMO_RECHARGE | TFL_AMMO_RECIEVE;
++            self.aim_flags = TFL_AIM_LEAD;
++
++            self.turret_firecheckfunc = turret_phaser_firecheck;
++
++            return true;
++        }
++        case TR_PRECACHE:
++        {
++            precache_model ("models/turrets/base.md3");
++            precache_model ("models/turrets/phaser.md3");
++            precache_model ("models/turrets/phaser_beam.md3");
++            precache_sound ("turrets/phaser.wav");
++            return true;
++        }
++    }
++
++    return true;
 +}
 +
 +#endif // SVQC
 +#ifdef CSQC
 +float t_phaser(float req)
 +{
++    switch(req)
++    {
++        case TR_SETUP:
++        {
++            return true;
++        }
++        case TR_PRECACHE:
++        {
++            return true;
++        }
++    }
++
++    return true;
 +}
 +
 +#endif // CSQC
 +#endif // REGISTER_TURRET
index 095aa9d,0000000..da86d3b
mode 100644,000000..100644
--- /dev/null
@@@ -1,111 -1,0 +1,111 @@@
-       switch(req)
-       {
-               case TR_ATTACK:
-               {
-                       if(g_instagib)
-                       {
-                               float flying;
-                               flying = IsFlying(self); // do this BEFORE to make the trace values from FireRailgunBullet last
-                               FireRailgunBullet (self.tur_shotorg, self.tur_shotorg + self.tur_shotdir_updated * MAX_SHOT_DISTANCE, 10000000000,
-                                                                  800, 0, 0, 0, 0, DEATH_TURRET_PLASMA);
-                               pointparticles(particleeffectnum("nex_muzzleflash"), self.tur_shotorg, self.tur_shotdir_updated * 1000, 1);
-                               // teamcolor / hit beam effect
-                               vector v;
-                               string s;
-                               v = WarpZone_UnTransformOrigin(WarpZone_trace_transform, trace_endpos);
-                               s = strcat("TE_TEI_G3", ((self.team) ? Static_Team_ColorName_Upper(self.team) : ""));
-                               
-                               WarpZone_TrailParticles(world, particleeffectnum(s), self.tur_shotorg, v);
-                               
-                               if (self.tur_head.frame == 0)
-                                       self.tur_head.frame = 1;
-                       }
-                       else
-                       {
-                               entity missile = turret_projectile("weapons/hagar_fire.wav", 1, 0, DEATH_TURRET_PLASMA, PROJECTILE_ELECTRO_BEAM, TRUE, TRUE);
-                               missile.missile_flags = MIF_SPLASH;
-                               pointparticles(particleeffectnum("laser_muzzleflash"), self.tur_shotorg, self.tur_shotdir_updated * 1000, 1);
-                               if (self.tur_head.frame == 0)
-                                       self.tur_head.frame = 1;
-                       }
-                       return true;
-               }
-               case TR_THINK:
-               {
-                       if (self.tur_head.frame != 0)
-                               self.tur_head.frame = self.tur_head.frame + 1;
-                       if (self.tur_head.frame > 5)
-                               self.tur_head.frame = 0;
-                       return true;
-               }
-               case TR_DEATH:
-               {
-                       return true;
-               }
-               case TR_SETUP:
-               {
-                       self.ammo_flags = TFL_AMMO_ENERGY | TFL_AMMO_RECHARGE | TFL_AMMO_RECIEVE;
-                       self.damage_flags |= TFL_DMG_HEADSHAKE;
-                       self.firecheck_flags |= TFL_FIRECHECK_AFF;
-                       self.aim_flags = TFL_AIM_LEAD | TFL_AIM_SHOTTIMECOMPENSATE | TFL_AIM_SPLASH;
-                       
-                       turret_do_updates(self);
-                       return true;
-               }
-               case TR_PRECACHE:
-               {
-                       precache_model ("models/turrets/base.md3");
-                       precache_model ("models/turrets/plasma.md3");
-                       return true;
-               }
-       }
-       return true;
 +#ifdef REGISTER_TURRET
 +REGISTER_TURRET(
 +/* TUR_##id   */ PLASMA,
 +/* function   */ t_plasma,
 +/* spawnflags */ TUR_FLAG_SPLASH | TUR_FLAG_MEDPROJ | TUR_FLAG_PLAYER,
 +/* mins,maxs  */ '-32 -32 0', '32 32 64',
 +/* model        */ "base.md3",
 +/* head_model */ "plasma.md3",
 +/* netname      */ "plasma",
 +/* fullname   */ _("Plasma Cannon")
 +);
 +#else
 +#ifdef SVQC
 +void spawnfunc_turret_plasma() { if(!turret_initialize(TUR_PLASMA)) remove(self); }
 +
 +float t_plasma(float req)
 +{
-       switch(req)
-       {
-               case TR_SETUP:
-               {
-                       return true;
-               }
-               case TR_PRECACHE:
-               {
-                       return true;
-               }
-       }
-       return true;
++    switch(req)
++    {
++        case TR_ATTACK:
++        {
++            if(g_instagib)
++            {
++                float flying;
++                flying = IsFlying(self); // do this BEFORE to make the trace values from FireRailgunBullet last
++
++                FireRailgunBullet (self.tur_shotorg, self.tur_shotorg + self.tur_shotdir_updated * MAX_SHOT_DISTANCE, 10000000000,
++                                   800, 0, 0, 0, 0, DEATH_TURRET_PLASMA);
++
++                Send_Effect("nex_muzzleflash", self.tur_shotorg, self.tur_shotdir_updated * 1000, 1);
++
++                // teamcolor / hit beam effect
++                vector v;
++                string s;
++                v = WarpZone_UnTransformOrigin(WarpZone_trace_transform, trace_endpos);
++                s = strcat("TE_TEI_G3", ((self.team) ? Static_Team_ColorName_Upper(self.team) : ""));
++
++                WarpZone_TrailParticles(world, particleeffectnum(s), self.tur_shotorg, v);
++
++                if (self.tur_head.frame == 0)
++                    self.tur_head.frame = 1;
++            }
++            else
++            {
++                entity missile = turret_projectile("weapons/hagar_fire.wav", 1, 0, DEATH_TURRET_PLASMA, PROJECTILE_ELECTRO_BEAM, TRUE, TRUE);
++                missile.missile_flags = MIF_SPLASH;
++
++                Send_Effect("laser_muzzleflash", self.tur_shotorg, self.tur_shotdir_updated * 1000, 1);
++                if (self.tur_head.frame == 0)
++                    self.tur_head.frame = 1;
++            }
++
++            return true;
++        }
++        case TR_THINK:
++        {
++            if (self.tur_head.frame != 0)
++                self.tur_head.frame = self.tur_head.frame + 1;
++
++            if (self.tur_head.frame > 5)
++                self.tur_head.frame = 0;
++
++            return true;
++        }
++        case TR_DEATH:
++        {
++            return true;
++        }
++        case TR_SETUP:
++        {
++            self.ammo_flags = TFL_AMMO_ENERGY | TFL_AMMO_RECHARGE | TFL_AMMO_RECIEVE;
++            self.damage_flags |= TFL_DMG_HEADSHAKE;
++            self.firecheck_flags |= TFL_FIRECHECK_AFF;
++            self.aim_flags = TFL_AIM_LEAD | TFL_AIM_SHOTTIMECOMPENSATE | TFL_AIM_SPLASH;
++
++            turret_do_updates(self);
++
++            return true;
++        }
++        case TR_PRECACHE:
++        {
++            precache_model ("models/turrets/base.md3");
++            precache_model ("models/turrets/plasma.md3");
++            return true;
++        }
++    }
++
++    return true;
 +}
 +
 +#endif // SVQC
 +#ifdef CSQC
 +float t_plasma(float req)
 +{
++    switch(req)
++    {
++        case TR_SETUP:
++        {
++            return true;
++        }
++        case TR_PRECACHE:
++        {
++            return true;
++        }
++    }
++
++    return true;
 +}
 +
 +#endif // CSQC
 +#endif // REGISTER_TURRET
index 110ae1d,0000000..f7cf549
mode 100644,000000..100644
--- /dev/null
@@@ -1,109 -1,0 +1,109 @@@
-       switch(req)
-       {
-               case TR_ATTACK:
-               {
-                       if(g_instagib)
-                       {
-                               float flying;
-                               flying = IsFlying(self); // do this BEFORE to make the trace values from FireRailgunBullet last
-                               FireRailgunBullet (self.tur_shotorg, self.tur_shotorg + self.tur_shotdir_updated * MAX_SHOT_DISTANCE, 10000000000,
-                                                                  800, 0, 0, 0, 0, DEATH_TURRET_PLASMA);
-                               pointparticles(particleeffectnum("nex_muzzleflash"), self.tur_shotorg, self.tur_shotdir_updated * 1000, 1);
-                               // teamcolor / hit beam effect
-                               vector v;
-                               string s;
-                               v = WarpZone_UnTransformOrigin(WarpZone_trace_transform, trace_endpos);
-                               s = strcat("TE_TEI_G3", ((self.team) ? Static_Team_ColorName_Upper(self.team) : ""));
-                               
-                               WarpZone_TrailParticles(world, particleeffectnum(s), self.tur_shotorg, v);
-                                       
-                               self.tur_head.frame += 1;
-                       }
-                       else
-                       {
-                               entity missile = turret_projectile("weapons/hagar_fire.wav", 1, 0, DEATH_TURRET_PLASMA, PROJECTILE_ELECTRO_BEAM, TRUE, TRUE);
-                               missile.missile_flags = MIF_SPLASH;
-                               pointparticles(particleeffectnum("laser_muzzleflash"), self.tur_shotorg, self.tur_shotdir_updated * 1000, 1);
-                               self.tur_head.frame += 1;
-                       }
-                       return true;
-               }
-               case TR_THINK:
-               {
-                       if ((self.tur_head.frame != 0) && (self.tur_head.frame != 3))
-                               self.tur_head.frame = self.tur_head.frame + 1;
-                       if (self.tur_head.frame > 6)
-                               self.tur_head.frame = 0;
-                       return true;
-               }
-               case TR_DEATH:
-               {
-                       return true;
-               }
-               case TR_SETUP:
-               {
-                       self.ammo_flags = TFL_AMMO_ENERGY | TFL_AMMO_RECHARGE | TFL_AMMO_RECIEVE;
-                       self.damage_flags |= TFL_DMG_HEADSHAKE;
-                       self.firecheck_flags |= TFL_FIRECHECK_AFF;
-                       self.aim_flags = TFL_AIM_LEAD | TFL_AIM_SHOTTIMECOMPENSATE | TFL_AIM_SPLASH;
-                       
-                       turret_do_updates(self);
-                       return true;
-               }
-               case TR_PRECACHE:
-               {
-                       precache_model ("models/turrets/base.md3");
-                       precache_model ("models/turrets/plasmad.md3");
-                       return true;
-               }
-       }
-       return true;
 +#ifdef REGISTER_TURRET
 +REGISTER_TURRET(
 +/* TUR_##id   */ PLASMA_DUAL,
 +/* function   */ t_plasma_dual,
 +/* spawnflags */ TUR_FLAG_SPLASH | TUR_FLAG_MEDPROJ | TUR_FLAG_PLAYER,
 +/* mins,maxs  */ '-32 -32 0', '32 32 64',
 +/* model        */ "base.md3",
 +/* head_model */ "plasmad.md3",
 +/* netname      */ "plasma_dual",
 +/* fullname   */ _("Dual Plasma Cannon")
 +);
 +#else
 +#ifdef SVQC
 +void spawnfunc_turret_plasma_dual() { if(!turret_initialize(TUR_PLASMA_DUAL)) remove(self); }
 +
 +float t_plasma_dual(float req)
 +{
-       switch(req)
-       {
-               case TR_SETUP:
-               {
-                       return true;
-               }
-               case TR_PRECACHE:
-               {
-                       return true;
-               }
-       }
-       return true;
++    switch(req)
++    {
++        case TR_ATTACK:
++        {
++            if(g_instagib)
++            {
++                float flying;
++                flying = IsFlying(self); // do this BEFORE to make the trace values from FireRailgunBullet last
++
++                FireRailgunBullet (self.tur_shotorg, self.tur_shotorg + self.tur_shotdir_updated * MAX_SHOT_DISTANCE, 10000000000,
++                                   800, 0, 0, 0, 0, DEATH_TURRET_PLASMA);
++
++
++                Send_Effect("nex_muzzleflash", self.tur_shotorg, self.tur_shotdir_updated * 1000, 1);
++
++                // teamcolor / hit beam effect
++                vector v;
++                string s;
++                v = WarpZone_UnTransformOrigin(WarpZone_trace_transform, trace_endpos);
++                s = strcat("TE_TEI_G3", ((self.team) ? Static_Team_ColorName_Upper(self.team) : ""));
++
++                WarpZone_TrailParticles(world, particleeffectnum(s), self.tur_shotorg, v);
++
++                self.tur_head.frame += 1;
++            }
++            else
++            {
++                entity missile = turret_projectile("weapons/hagar_fire.wav", 1, 0, DEATH_TURRET_PLASMA, PROJECTILE_ELECTRO_BEAM, TRUE, TRUE);
++                missile.missile_flags = MIF_SPLASH;
++                Send_Effect("laser_muzzleflash", self.tur_shotorg, self.tur_shotdir_updated * 1000, 1);
++                self.tur_head.frame += 1;
++            }
++
++            return true;
++        }
++        case TR_THINK:
++        {
++            if ((self.tur_head.frame != 0) && (self.tur_head.frame != 3))
++                self.tur_head.frame = self.tur_head.frame + 1;
++
++            if (self.tur_head.frame > 6)
++                self.tur_head.frame = 0;
++
++            return true;
++        }
++        case TR_DEATH:
++        {
++            return true;
++        }
++        case TR_SETUP:
++        {
++            self.ammo_flags = TFL_AMMO_ENERGY | TFL_AMMO_RECHARGE | TFL_AMMO_RECIEVE;
++            self.damage_flags |= TFL_DMG_HEADSHAKE;
++            self.firecheck_flags |= TFL_FIRECHECK_AFF;
++            self.aim_flags = TFL_AIM_LEAD | TFL_AIM_SHOTTIMECOMPENSATE | TFL_AIM_SPLASH;
++
++            turret_do_updates(self);
++
++            return true;
++        }
++        case TR_PRECACHE:
++        {
++            precache_model ("models/turrets/base.md3");
++            precache_model ("models/turrets/plasmad.md3");
++            return true;
++        }
++    }
++
++    return true;
 +}
 +
 +#endif // SVQC
 +#ifdef CSQC
 +float t_plasma_dual(float req)
 +{
++    switch(req)
++    {
++        case TR_SETUP:
++        {
++            return true;
++        }
++        case TR_PRECACHE:
++        {
++            return true;
++        }
++    }
++
++    return true;
 +}
 +
 +#endif // CSQC
 +#endif // REGISTER_TURRET
index 61a9f5e,0000000..05dbffb
mode 100644,000000..100644
--- /dev/null
@@@ -1,217 -1,0 +1,217 @@@
-       entity e;
-       entity etarget = world;
-       float d,dd;
-       float r;
-       dd = range + 1;
-       e = findradius(from.origin,range);
-       while (e)
-       {
-               if ((e.railgunhit != 1) && (e != from))
-               {
-                       r = turret_validate_target(self,e,self.target_validate_flags);
-                       if (r > 0)
-                       {
-                               traceline(from.origin,0.5 * (e.absmin + e.absmax),MOVE_WORLDONLY,from);
-                               if (trace_fraction == 1.0)
-                               {
-                                       d = vlen(e.origin - from.origin);
-                                       if (d < dd)
-                                       {
-                                               dd = d;
-                                               etarget = e;
-                                       }
-                               }
-                       }
-               }
-               e = e.chain;
-       }
-       if (etarget)
-       {
-               te_csqc_lightningarc(from.origin,etarget.origin);
-               Damage(etarget, self, self, damage, DEATH_TURRET_TESLA, etarget.origin, '0 0 0');
-               etarget.railgunhit = 1;
-       }
-       return etarget;
 +#ifdef REGISTER_TURRET
 +REGISTER_TURRET(
 +/* TUR_##id   */ TESLA,
 +/* function   */ t_tesla,
 +/* spawnflags */ TUR_FLAG_HITSCAN | TUR_FLAG_PLAYER | TUR_FLAG_MISSILE,
 +/* mins,maxs  */ '-60 -60 0', '60 60 128',
 +/* model        */ "tesla_base.md3",
 +/* head_model */ "tesla_head.md3",
 +/* netname      */ "tesla",
 +/* fullname   */ _("Tesla Coil")
 +);
 +#else
 +#ifdef SVQC
 +entity toast(entity from, float range, float damage)
 +{
-       // g_turrets_targetscan_maxdelay forces a target re-scan at least this often
-       float do_target_scan = 0;
-       if((self.target_select_time + autocvar_g_turrets_targetscan_maxdelay) < time)
-               do_target_scan = 1;
-       // Old target (if any) invalid?
-       if(self.target_validate_time < time)
-       if (turret_validate_target(self, self.enemy, self.target_validate_flags) <= 0)
-       {
-               self.enemy = world;
-               self.target_validate_time = time + 0.5;
-               do_target_scan = 1;
-       }
-       // But never more often then g_turrets_targetscan_mindelay!
-       if (self.target_select_time + autocvar_g_turrets_targetscan_mindelay > time)
-               do_target_scan = 0;
-       if(do_target_scan)
-       {
-               self.enemy = turret_select_target();
-               self.target_select_time = time;
-       }
-       if(!turret_firecheck())
-               return 0;
-       if(self.enemy)
-               return 1;
-       return 0;
++    entity e;
++    entity etarget = world;
++    float d,dd;
++    float r;
++
++    dd = range + 1;
++
++    e = findradius(from.origin,range);
++    while (e)
++    {
++        if ((e.railgunhit != 1) && (e != from))
++        {
++            r = turret_validate_target(self,e,self.target_validate_flags);
++            if (r > 0)
++            {
++                traceline(from.origin,0.5 * (e.absmin + e.absmax),MOVE_WORLDONLY,from);
++                if (trace_fraction == 1.0)
++                {
++                    d = vlen(e.origin - from.origin);
++                    if (d < dd)
++                    {
++                        dd = d;
++                        etarget = e;
++                    }
++                }
++            }
++        }
++        e = e.chain;
++    }
++
++    if (etarget)
++    {
++        te_csqc_lightningarc(from.origin,etarget.origin);
++        Damage(etarget, self, self, damage, DEATH_TURRET_TESLA, etarget.origin, '0 0 0');
++        etarget.railgunhit = 1;
++    }
++
++    return etarget;
 +}
 +
 +float turret_tesla_firecheck()
 +{
-       switch(req)
-       {
-               case TR_ATTACK:
-               {
-                       entity e, t;
-                       float d, r, i;
-                       d = self.shot_dmg;
-                       r = self.target_range;
-                       e = spawn();
-                       setorigin(e,self.tur_shotorg);
-                       self.target_validate_flags = TFL_TARGETSELECT_PLAYERS | TFL_TARGETSELECT_MISSILES | TFL_TARGETSELECT_RANGELIMITS | TFL_TARGETSELECT_TEAMCHECK;
-                       t = toast(e,r,d);
-                       remove(e);
-                       if (t == world) return true;
-                       self.target_validate_flags = TFL_TARGETSELECT_PLAYERS | TFL_TARGETSELECT_MISSILES | TFL_TARGETSELECT_TEAMCHECK;
-                       self.attack_finished_single = time + self.shot_refire;
-                       for (i = 0; i < 10; ++i)
-                       {
-                               d *= 0.75;
-                               r *= 0.85;
-                               t = toast(t, r, d);
-                               if (t == world) break;
-                       }
-                       e = findchainfloat(railgunhit, 1);
-                       while (e)
-                       {
-                               e.railgunhit = 0;
-                               e = e.chain;
-                       }
-                       return true;
-               }
-               case TR_THINK:
-               {
-                       if(!self.active)
-                       {
-                               self.tur_head.avelocity = '0 0 0';
-                               return true;
-                       }
-                       if(self.ammo < self.shot_dmg)
-                       {
-                               self.tur_head.avelocity = '0 45 0' * (self.ammo / self.shot_dmg);
-                       }
-                       else
-                       {
-                               self.tur_head.avelocity = '0 180 0' * (self.ammo / self.shot_dmg);
-                               if(self.attack_finished_single > time)
-                                       return true;
-                               float f;
-                               f = (self.ammo / self.ammo_max);
-                               f = f * f;
-                               if(f > random())
-                                       if(random() < 0.1)
-                                               te_csqc_lightningarc(self.tur_shotorg,self.tur_shotorg + (randomvec() * 350));
-                       }
-                       return true;
-               }
-               case TR_DEATH:
-               {
-                       return true;
-               }
-               case TR_SETUP:
-               {
-                       self.target_validate_flags = TFL_TARGETSELECT_PLAYERS | TFL_TARGETSELECT_MISSILES |
-                                                                TFL_TARGETSELECT_RANGELIMITS | TFL_TARGETSELECT_TEAMCHECK;
-                                                                
-                       self.turret_firecheckfunc = turret_tesla_firecheck;
-                       self.target_select_flags = TFL_TARGETSELECT_PLAYERS | TFL_TARGETSELECT_MISSILES |
-                                                          TFL_TARGETSELECT_RANGELIMITS | TFL_TARGETSELECT_TEAMCHECK;
-                       self.firecheck_flags    = TFL_FIRECHECK_REFIRE | TFL_FIRECHECK_AMMO_OWN;
-                       self.shoot_flags                = TFL_SHOOT_CUSTOM;
-                       self.ammo_flags                 = TFL_AMMO_ENERGY | TFL_AMMO_RECHARGE | TFL_AMMO_RECIEVE;
-                       self.aim_flags                  = TFL_AIM_NO;
-                       self.track_flags                = TFL_TRACK_NO;
-                       return true;
-               }
-               case TR_PRECACHE:
-               {
-                       precache_model ("models/turrets/tesla_base.md3");
-                       precache_model ("models/turrets/tesla_head.md3");
-                       return true;
-               }
-       }
-       return true;
++    // g_turrets_targetscan_maxdelay forces a target re-scan at least this often
++    float do_target_scan = 0;
++
++    if((self.target_select_time + autocvar_g_turrets_targetscan_maxdelay) < time)
++        do_target_scan = 1;
++
++    // Old target (if any) invalid?
++    if(self.target_validate_time < time)
++    if (turret_validate_target(self, self.enemy, self.target_validate_flags) <= 0)
++    {
++        self.enemy = world;
++        self.target_validate_time = time + 0.5;
++        do_target_scan = 1;
++    }
++
++    // But never more often then g_turrets_targetscan_mindelay!
++    if (self.target_select_time + autocvar_g_turrets_targetscan_mindelay > time)
++        do_target_scan = 0;
++
++    if(do_target_scan)
++    {
++        self.enemy = turret_select_target();
++        self.target_select_time = time;
++    }
++
++    if(!turret_firecheck())
++        return 0;
++
++    if(self.enemy)
++        return 1;
++
++    return 0;
 +}
 +
 +void spawnfunc_turret_tesla() { if(!turret_initialize(TUR_TESLA)) remove(self); }
 +
 +float t_tesla(float req)
 +{
-       switch(req)
-       {
-               case TR_SETUP:
-               {
-                       return true;
-               }
-               case TR_PRECACHE:
-               {
-                       return true;
-               }
-       }
-       return true;
++    switch(req)
++    {
++        case TR_ATTACK:
++        {
++            entity e, t;
++            float d, r, i;
++
++            d = self.shot_dmg;
++            r = self.target_range;
++            e = spawn();
++            setorigin(e,self.tur_shotorg);
++
++            self.target_validate_flags = TFL_TARGETSELECT_PLAYERS | TFL_TARGETSELECT_MISSILES | TFL_TARGETSELECT_RANGELIMITS | TFL_TARGETSELECT_TEAMCHECK;
++
++            t = toast(e,r,d);
++            remove(e);
++
++            if (t == world) return true;
++
++            self.target_validate_flags = TFL_TARGETSELECT_PLAYERS | TFL_TARGETSELECT_MISSILES | TFL_TARGETSELECT_TEAMCHECK;
++
++            self.attack_finished_single = time + self.shot_refire;
++            for (i = 0; i < 10; ++i)
++            {
++                d *= 0.75;
++                r *= 0.85;
++                t = toast(t, r, d);
++                if (t == world) break;
++
++            }
++
++            e = findchainfloat(railgunhit, 1);
++            while (e)
++            {
++                e.railgunhit = 0;
++                e = e.chain;
++            }
++
++            return true;
++        }
++        case TR_THINK:
++        {
++            if(!self.active)
++            {
++                self.tur_head.avelocity = '0 0 0';
++                return true;
++            }
++
++            if(self.ammo < self.shot_dmg)
++            {
++                self.tur_head.avelocity = '0 45 0' * (self.ammo / self.shot_dmg);
++            }
++            else
++            {
++                self.tur_head.avelocity = '0 180 0' * (self.ammo / self.shot_dmg);
++
++                if(self.attack_finished_single > time)
++                    return true;
++
++                float f;
++                f = (self.ammo / self.ammo_max);
++                f = f * f;
++                if(f > random())
++                    if(random() < 0.1)
++                        te_csqc_lightningarc(self.tur_shotorg,self.tur_shotorg + (randomvec() * 350));
++            }
++
++            return true;
++        }
++        case TR_DEATH:
++        {
++            return true;
++        }
++        case TR_SETUP:
++        {
++            self.target_validate_flags = TFL_TARGETSELECT_PLAYERS | TFL_TARGETSELECT_MISSILES |
++                                 TFL_TARGETSELECT_RANGELIMITS | TFL_TARGETSELECT_TEAMCHECK;
++
++            self.turret_firecheckfunc = turret_tesla_firecheck;
++            self.target_select_flags = TFL_TARGETSELECT_PLAYERS | TFL_TARGETSELECT_MISSILES |
++                               TFL_TARGETSELECT_RANGELIMITS | TFL_TARGETSELECT_TEAMCHECK;
++
++            self.firecheck_flags      = TFL_FIRECHECK_REFIRE | TFL_FIRECHECK_AMMO_OWN;
++            self.shoot_flags          = TFL_SHOOT_CUSTOM;
++            self.ammo_flags                   = TFL_AMMO_ENERGY | TFL_AMMO_RECHARGE | TFL_AMMO_RECIEVE;
++            self.aim_flags                    = TFL_AIM_NO;
++            self.track_flags          = TFL_TRACK_NO;
++
++            return true;
++        }
++        case TR_PRECACHE:
++        {
++            precache_model ("models/turrets/tesla_base.md3");
++            precache_model ("models/turrets/tesla_head.md3");
++            return true;
++        }
++    }
++
++    return true;
 +}
 +
 +#endif // SVQC
 +#ifdef CSQC
 +float t_tesla(float req)
 +{
++    switch(req)
++    {
++        case TR_SETUP:
++        {
++            return true;
++        }
++        case TR_PRECACHE:
++        {
++            return true;
++        }
++    }
++
++    return true;
 +}
 +
 +#endif // CSQC
 +#endif // REGISTER_TURRET
index 0d5d317,0000000..4a63f9d
mode 100644,000000..100644
--- /dev/null
@@@ -1,698 -1,0 +1,698 @@@
-       if (self.animflag == ANIM_MELEE)
-               return 0;
 +#ifdef REGISTER_TURRET
 +REGISTER_TURRET(
 +/* TUR_##id   */ WALKER,
 +/* function   */ t_walker,
 +/* spawnflags */ TUR_FLAG_PLAYER | TUR_FLAG_MOVE,
 +/* mins,maxs  */ '-70 -70 0', '70 70 95',
 +/* model        */ "walker_body.md3",
 +/* head_model */ "walker_head_minigun.md3",
 +/* netname      */ "walker",
 +/* fullname   */ _("Walker Turret")
 +);
 +#else
 +#ifdef SVQC
 +float autocvar_g_turrets_unit_walker_melee_damage;
 +float autocvar_g_turrets_unit_walker_melee_force;
 +float autocvar_g_turrets_unit_walker_melee_range;
 +float autocvar_g_turrets_unit_walker_rocket_damage;
 +float autocvar_g_turrets_unit_walker_rocket_radius;
 +float autocvar_g_turrets_unit_walker_rocket_force;
 +float autocvar_g_turrets_unit_walker_rocket_speed;
 +float autocvar_g_turrets_unit_walker_rocket_range;
 +float autocvar_g_turrets_unit_walker_rocket_range_min;
 +float autocvar_g_turrets_unit_walker_rocket_refire;
 +float autocvar_g_turrets_unit_walker_rocket_turnrate;
 +float autocvar_g_turrets_unit_walker_speed_stop;
 +float autocvar_g_turrets_unit_walker_speed_walk;
 +float autocvar_g_turrets_unit_walker_speed_run;
 +float autocvar_g_turrets_unit_walker_speed_jump;
 +float autocvar_g_turrets_unit_walker_speed_swim;
 +float autocvar_g_turrets_unit_walker_speed_roam;
 +float autocvar_g_turrets_unit_walker_turn;
 +float autocvar_g_turrets_unit_walker_turn_walk;
 +float autocvar_g_turrets_unit_walker_turn_strafe;
 +float autocvar_g_turrets_unit_walker_turn_swim;
 +float autocvar_g_turrets_unit_walker_turn_run;
 +
 +#define ANIM_NO         0
 +#define ANIM_TURN       1
 +#define ANIM_WALK       2
 +#define ANIM_RUN        3
 +#define ANIM_STRAFE_L   4
 +#define ANIM_STRAFE_R   5
 +#define ANIM_JUMP       6
 +#define ANIM_LAND       7
 +#define ANIM_PAIN       8
 +#define ANIM_MELEE      9
 +#define ANIM_SWIM       10
 +#define ANIM_ROAM       11
 +
 +.float animflag;
 +.float idletime;
 +
 +#define WALKER_PATH(s,e) pathlib_astar(s,e)
 +
 +float walker_firecheck()
 +{
-       return turret_firecheck();
++    if (self.animflag == ANIM_MELEE)
++        return 0;
 +
-       vector where;
-       entity e;
++    return turret_firecheck();
 +}
 +
 +void walker_melee_do_dmg()
 +{
-       makevectors(self.angles);
-       where = self.origin + v_forward * 128;
++    vector where;
++    entity e;
 +
-       e = findradius(where,32);
-       while (e)
-       {
-               if (turret_validate_target(self, e, self.target_validate_flags))
-                       if (e != self && e.owner != self)
-                               Damage(e, self, self, (autocvar_g_turrets_unit_walker_melee_damage), DEATH_TURRET_WALK_MELEE, '0 0 0', v_forward * (autocvar_g_turrets_unit_walker_melee_force));
++    makevectors(self.angles);
++    where = self.origin + v_forward * 128;
 +
-               e = e.chain;
-       }
++    e = findradius(where,32);
++    while (e)
++    {
++        if (turret_validate_target(self, e, self.target_validate_flags))
++            if (e != self && e.owner != self)
++                Damage(e, self, self, (autocvar_g_turrets_unit_walker_melee_damage), DEATH_TURRET_WALK_MELEE, '0 0 0', v_forward * (autocvar_g_turrets_unit_walker_melee_force));
 +
-       turrets_setframe(ANIM_NO, false);
-       self.animflag = self.frame;
++        e = e.chain;
++    }
 +}
 +
 +void walker_setnoanim()
 +{
-       RadiusDamage (self, self.owner, (autocvar_g_turrets_unit_walker_rocket_damage), 0, (autocvar_g_turrets_unit_walker_rocket_radius), self, world, (autocvar_g_turrets_unit_walker_rocket_force), DEATH_TURRET_WALK_ROCKET, world);
-       remove (self);
++    turrets_setframe(ANIM_NO, false);
++    self.animflag = self.frame;
 +}
 +void walker_rocket_explode()
 +{
-       self.health = self.health - damage;
-       self.velocity = self.velocity + vforce;
++    RadiusDamage (self, self.owner, (autocvar_g_turrets_unit_walker_rocket_damage), 0, (autocvar_g_turrets_unit_walker_rocket_radius), self, world, (autocvar_g_turrets_unit_walker_rocket_force), DEATH_TURRET_WALK_ROCKET, world);
++    remove (self);
 +}
 +
 +void walker_rocket_damage (entity inflictor, entity attacker, float damage, float deathtype, vector hitloc, vector vforce)
 +{
-       if (self.health <= 0)
-               W_PrepareExplosionByDamage(self.owner, walker_rocket_explode);
++    self.health = self.health - damage;
++    self.velocity = self.velocity + vforce;
 +
-       vector newdir;
-       float edist;
-       float itime;
-       float m_speed;
-       self.nextthink = time;
-       edist = vlen(self.enemy.origin - self.origin);
-       // Simulate crude guidance
-       if (self.cnt < time)
-       {
-               if (edist < 1000)
-                       self.tur_shotorg = randomvec() * min(edist, 64);
-               else
-                       self.tur_shotorg = randomvec() * min(edist, 256);
-               self.cnt = time + 0.5;
-       }
-       if (edist < 128)
-               self.tur_shotorg = '0 0 0';
-       if (self.max_health < time)
-       {
-               self.think        = walker_rocket_explode;
-               self.nextthink  = time;
-               return;
-       }
-       if (self.shot_dmg != 1337 && random() < 0.01)
-       {
-               walker_rocket_loop();
-               return;
-       }
-       m_speed = vlen(self.velocity);
-       // Enemy dead? just keep on the current heading then.
-       if (self.enemy == world || self.enemy.deadflag != DEAD_NO)
-               self.enemy = world;
-       if (self.enemy)
-       {
-               itime = max(edist / m_speed, 1);
-               newdir = steerlib_pull(self.enemy.origin + self.tur_shotorg);
-       }
-       else
-               newdir  = normalize(self.velocity);
-       WALKER_ROCKET_MOVE;
++    if (self.health <= 0)
++        W_PrepareExplosionByDamage(self.owner, walker_rocket_explode);
 +}
 +
 +#define WALKER_ROCKET_MOVE movelib_move_simple(newdir, (autocvar_g_turrets_unit_walker_rocket_speed), (autocvar_g_turrets_unit_walker_rocket_turnrate)); UpdateCSQCProjectile(self)
 +void walker_rocket_loop();
 +void walker_rocket_think()
 +{
-       vector newdir;
-       self.nextthink = time;
++    vector newdir;
++    float edist;
++    float itime;
++    float m_speed;
++
++    self.nextthink = time;
++
++    edist = vlen(self.enemy.origin - self.origin);
++
++    // Simulate crude guidance
++    if (self.cnt < time)
++    {
++        if (edist < 1000)
++            self.tur_shotorg = randomvec() * min(edist, 64);
++        else
++            self.tur_shotorg = randomvec() * min(edist, 256);
++
++        self.cnt = time + 0.5;
++    }
++
++    if (edist < 128)
++        self.tur_shotorg = '0 0 0';
++
++    if (self.max_health < time)
++    {
++        self.think      = walker_rocket_explode;
++        self.nextthink  = time;
++        return;
++    }
++
++    if (self.shot_dmg != 1337 && random() < 0.01)
++    {
++        walker_rocket_loop();
++        return;
++    }
++
++    m_speed = vlen(self.velocity);
++
++    // Enemy dead? just keep on the current heading then.
++    if (self.enemy == world || self.enemy.deadflag != DEAD_NO)
++        self.enemy = world;
++
++    if (self.enemy)
++    {
++        itime = max(edist / m_speed, 1);
++        newdir = steerlib_pull(self.enemy.origin + self.tur_shotorg);
++    }
++    else
++        newdir  = normalize(self.velocity);
++
++    WALKER_ROCKET_MOVE;
 +}
 +
 +void walker_rocket_loop3()
 +{
-       if (self.max_health < time)
-       {
-               self.think = walker_rocket_explode;
-               return;
-       }
++    vector newdir;
++    self.nextthink = time;
 +
-       if (vlen(self.origin - self.tur_shotorg) < 100 )
-       {
-               self.think = walker_rocket_think;
-               return;
-       }
++    if (self.max_health < time)
++    {
++        self.think = walker_rocket_explode;
++        return;
++    }
 +
-       newdir = steerlib_pull(self.tur_shotorg);
-       WALKER_ROCKET_MOVE;
++    if (vlen(self.origin - self.tur_shotorg) < 100 )
++    {
++        self.think = walker_rocket_think;
++        return;
++    }
 +
-       self.angles = vectoangles(self.velocity);
++    newdir = steerlib_pull(self.tur_shotorg);
++    WALKER_ROCKET_MOVE;
 +
-       vector newdir;
++    self.angles = vectoangles(self.velocity);
 +}
 +
 +void walker_rocket_loop2()
 +{
-       self.nextthink = time;
++    vector newdir;
 +
-       if (self.max_health < time)
-       {
-               self.think = walker_rocket_explode;
-               return;
-       }
++    self.nextthink = time;
 +
-       if (vlen(self.origin - self.tur_shotorg) < 100 )
-       {
-               self.tur_shotorg = self.origin - '0 0 200';
-               self.think = walker_rocket_loop3;
-               return;
-       }
++    if (self.max_health < time)
++    {
++        self.think = walker_rocket_explode;
++        return;
++    }
 +
-       newdir = steerlib_pull(self.tur_shotorg);
-       WALKER_ROCKET_MOVE;
++    if (vlen(self.origin - self.tur_shotorg) < 100 )
++    {
++        self.tur_shotorg = self.origin - '0 0 200';
++        self.think = walker_rocket_loop3;
++        return;
++    }
 +
-       self.nextthink = time;
-       self.tur_shotorg = self.origin + '0 0 300';
-       self.think = walker_rocket_loop2;
-       self.shot_dmg = 1337;
++    newdir = steerlib_pull(self.tur_shotorg);
++    WALKER_ROCKET_MOVE;
 +}
 +
 +void walker_rocket_loop()
 +{
-       entity rocket;
-       fixedmakevectors(self.angles);
-       te_explosion (org);
-       rocket = spawn ();
-       setorigin(rocket, org);
-       sound (self, CH_WEAPON_A, "weapons/hagar_fire.wav", VOL_BASE, ATTEN_NORM);
-       setsize (rocket, '-3 -3 -3', '3 3 3'); // give it some size so it can be shot
-       rocket.classname                  = "walker_rocket";
-       rocket.owner                      = self;
-       rocket.bot_dodge                  = true;
-       rocket.bot_dodgerating  = 50;
-       rocket.takedamage                = DAMAGE_YES;
-       rocket.damageforcescale   = 2;
-       rocket.health                    = 25;
-       rocket.tur_shotorg              = randomvec() * 512;
-       rocket.cnt                              = time + 1;
-       rocket.enemy                      = self.enemy;
-       if (random() < 0.01)
-               rocket.think              = walker_rocket_loop;
-       else
-               rocket.think              = walker_rocket_think;
-       rocket.event_damage        = walker_rocket_damage;
-       rocket.nextthink                  = time;
-       rocket.movetype            = MOVETYPE_FLY;
-       rocket.velocity            = normalize((v_forward + v_up * 0.5) + (randomvec() * 0.2)) * (autocvar_g_turrets_unit_walker_rocket_speed);
-       rocket.angles                    = vectoangles(rocket.velocity);
-       rocket.touch                      = walker_rocket_explode;
-       rocket.flags                      = FL_PROJECTILE;
-       rocket.solid                      = SOLID_BBOX;
-       rocket.max_health                = time + 9;
-       rocket.missile_flags = MIF_SPLASH | MIF_PROXY | MIF_GUIDED_HEAT;
-       CSQCProjectile(rocket, false, PROJECTILE_ROCKET, false); // no culling, has fly sound
++    self.nextthink = time;
++    self.tur_shotorg = self.origin + '0 0 300';
++    self.think = walker_rocket_loop2;
++    self.shot_dmg = 1337;
 +}
 +
 +void walker_fire_rocket(vector org)
 +{
-       switch (self.waterlevel)
-       {
-               case WATERLEVEL_NONE:
-                       if (_dist > 500)
-                               self.animflag = ANIM_RUN;
-                       else
-                               self.animflag = ANIM_WALK;
-               case WATERLEVEL_WETFEET:
-               case WATERLEVEL_SWIMMING:
-                       if (self.animflag != ANIM_SWIM)
-                               self.animflag = ANIM_WALK;
-                       else
-                               self.animflag = ANIM_SWIM;
-                       break;
-               case WATERLEVEL_SUBMERGED:
-                       self.animflag = ANIM_SWIM;
-       }
-       self.moveto = _target;
-       self.steerto = steerlib_attract2(self.moveto, 0.5, 500, 0.95);
-       if(self.enemy)
-       {
-               self.enemy_last_loc = _target;
-               self.enemy_last_time = time;
-       }
++    entity rocket;
++
++    fixedmakevectors(self.angles);
++
++    te_explosion (org);
++
++    rocket = spawn ();
++    setorigin(rocket, org);
++
++    sound (self, CH_WEAPON_A, "weapons/hagar_fire.wav", VOL_BASE, ATTEN_NORM);
++    setsize (rocket, '-3 -3 -3', '3 3 3'); // give it some size so it can be shot
++
++    rocket.classname            = "walker_rocket";
++    rocket.owner                        = self;
++    rocket.bot_dodge            = true;
++    rocket.bot_dodgerating    = 50;
++    rocket.takedamage          = DAMAGE_YES;
++    rocket.damageforcescale   = 2;
++    rocket.health                      = 25;
++    rocket.tur_shotorg                = randomvec() * 512;
++    rocket.cnt                                = time + 1;
++    rocket.enemy                        = self.enemy;
++
++    if (random() < 0.01)
++        rocket.think            = walker_rocket_loop;
++    else
++        rocket.think            = walker_rocket_think;
++
++    rocket.event_damage          = walker_rocket_damage;
++
++    rocket.nextthink            = time;
++    rocket.movetype              = MOVETYPE_FLY;
++    rocket.velocity              = normalize((v_forward + v_up * 0.5) + (randomvec() * 0.2)) * (autocvar_g_turrets_unit_walker_rocket_speed);
++    rocket.angles                      = vectoangles(rocket.velocity);
++    rocket.touch                        = walker_rocket_explode;
++    rocket.flags                        = FL_PROJECTILE;
++    rocket.solid                        = SOLID_BBOX;
++    rocket.max_health          = time + 9;
++    rocket.missile_flags = MIF_SPLASH | MIF_PROXY | MIF_GUIDED_HEAT;
++
++    CSQCProjectile(rocket, false, PROJECTILE_ROCKET, false); // no culling, has fly sound
 +}
 +
 +.vector enemy_last_loc;
 +.float enemy_last_time;
 +void walker_move_to(vector _target, float _dist)
 +{
-       // Are we close enougth to a path node to switch to the next?
-       if (vlen(self.origin  - self.pathcurrent.origin) < 64)
-               if (self.pathcurrent.path_next == world)
-               {
-                       // Path endpoint reached
-                       pathlib_deletepath(self.pathcurrent.owner);
-                       self.pathcurrent = world;
-                       if (self.pathgoal)
-                       {
-                               if (self.pathgoal.use)
-                                       self.pathgoal.use();
-                               if (self.pathgoal.enemy)
-                               {
-                                       self.pathcurrent = WALKER_PATH(self.pathgoal.origin,self.pathgoal.enemy.origin);
-                                       self.pathgoal = self.pathgoal.enemy;
-                               }
-                       }
-                       else
-                               self.pathgoal = world;
-               }
-               else
-                       self.pathcurrent = self.pathcurrent.path_next;
-       self.moveto = self.pathcurrent.origin;
-       self.steerto = steerlib_attract2(self.moveto,0.5,500,0.95);
-       walker_move_to(self.moveto, 0);
++    switch (self.waterlevel)
++    {
++        case WATERLEVEL_NONE:
++            if (_dist > 500)
++                self.animflag = ANIM_RUN;
++            else
++                self.animflag = ANIM_WALK;
++        case WATERLEVEL_WETFEET:
++        case WATERLEVEL_SWIMMING:
++            if (self.animflag != ANIM_SWIM)
++                self.animflag = ANIM_WALK;
++            else
++                self.animflag = ANIM_SWIM;
++            break;
++        case WATERLEVEL_SUBMERGED:
++            self.animflag = ANIM_SWIM;
++    }
++
++    self.moveto = _target;
++    self.steerto = steerlib_attract2(self.moveto, 0.5, 500, 0.95);
++
++    if(self.enemy)
++    {
++        self.enemy_last_loc = _target;
++        self.enemy_last_time = time;
++    }
 +}
 +
 +//#define WALKER_FANCYPATHING
 +
 +void walker_move_path()
 +{
 +#ifdef WALKER_FANCYPATHING
-       if (vlen(self.origin - self.pathcurrent.origin) < 64)
-               self.pathcurrent = self.pathcurrent.enemy;
++    // Are we close enougth to a path node to switch to the next?
++    if (vlen(self.origin  - self.pathcurrent.origin) < 64)
++        if (self.pathcurrent.path_next == world)
++        {
++            // Path endpoint reached
++            pathlib_deletepath(self.pathcurrent.owner);
++            self.pathcurrent = world;
++
++            if (self.pathgoal)
++            {
++                if (self.pathgoal.use)
++                    self.pathgoal.use();
++
++                if (self.pathgoal.enemy)
++                {
++                    self.pathcurrent = WALKER_PATH(self.pathgoal.origin,self.pathgoal.enemy.origin);
++                    self.pathgoal = self.pathgoal.enemy;
++                }
++            }
++            else
++                self.pathgoal = world;
++        }
++        else
++            self.pathcurrent = self.pathcurrent.path_next;
++
++    self.moveto = self.pathcurrent.origin;
++    self.steerto = steerlib_attract2(self.moveto,0.5,500,0.95);
++    walker_move_to(self.moveto, 0);
 +
 +#else
-       if(!self.pathcurrent)
-               return;
++    if (vlen(self.origin - self.pathcurrent.origin) < 64)
++        self.pathcurrent = self.pathcurrent.enemy;
 +
-       self.moveto = self.pathcurrent.origin;
-       self.steerto = steerlib_attract2(self.moveto, 0.5, 500, 0.95);
-       walker_move_to(self.moveto, 0);
++    if(!self.pathcurrent)
++        return;
 +
-       switch(req)
-       {
-               case TR_ATTACK:
-               {
-                       sound (self, CH_WEAPON_A, "weapons/uzi_fire.wav", VOL_BASE, ATTEN_NORM);
-                       fireBullet (self.tur_shotorg, self.tur_shotdir_updated, self.shot_spread, 0, self.shot_dmg, self.shot_force, DEATH_TURRET_WALK_GUN, 0);
-                       pointparticles(particleeffectnum("laser_muzzleflash"), self.tur_shotorg, self.tur_shotdir_updated * 1000, 1);
-                       return true;
-               }
-               case TR_THINK:
-               {
-                       fixedmakevectors(self.angles);
-                       if (self.spawnflags & TSF_NO_PATHBREAK && self.pathcurrent)
-                               walker_move_path();
-                       else if (self.enemy == world)
-                       {
-                               if(self.pathcurrent)
-                                       walker_move_path();
-                               else
-                               {
-                                       if(self.enemy_last_time != 0)
-                                       {
-                                               if(vlen(self.origin - self.enemy_last_loc) < 128 || time - self.enemy_last_time > 10)
-                                                       self.enemy_last_time = 0;
-                                               else
-                                                       walker_move_to(self.enemy_last_loc, 0);
-                                       }
-                                       else
-                                       {
-                                               if(self.animflag != ANIM_NO)
-                                               {
-                                                       traceline(self.origin + '0 0 64', self.origin + '0 0 64' + v_forward * 128, MOVE_NORMAL, self);
-                                                       if(trace_fraction != 1.0)
-                                                               self.tur_head.idletime = -1337;
-                                                       else
-                                                       {
-                                                               traceline(trace_endpos, trace_endpos - '0 0 256', MOVE_NORMAL, self);
-                                                               if(trace_fraction == 1.0)
-                                                                       self.tur_head.idletime = -1337;
-                                                       }
-                                                       if(self.tur_head.idletime == -1337)
-                                                       {
-                                                               self.moveto = self.origin + randomvec() * 256;
-                                                               self.tur_head.idletime = 0;
-                                                       }
-                                                       self.moveto = self.moveto * 0.9 + ((self.origin + v_forward * 500) + randomvec() * 400) * 0.1;
-                                                       self.moveto_z = self.origin_z + 64;
-                                                       walker_move_to(self.moveto, 0);
-                                               }
-                                               if(self.idletime < time)
-                                               {
-                                                       if(random() < 0.5 || !(self.spawnflags & TSL_ROAM))
-                                                       {
-                                                               self.idletime = time + 1 + random() * 5;
-                                                               self.moveto = self.origin;
-                                                               self.animflag = ANIM_NO;
-                                                       }
-                                                       else
-                                                       {
-                                                               self.animflag = ANIM_WALK;
-                                                               self.idletime = time + 4 + random() * 2;
-                                                               self.moveto = self.origin + randomvec() * 256;
-                                                               self.tur_head.moveto = self.moveto;
-                                                               self.tur_head.idletime = 0;
-                                                       }
-                                               }
-                                       }
-                               }
-                       }
-                       else
-                       {
-                               if (self.tur_dist_enemy < (autocvar_g_turrets_unit_walker_melee_range) && self.animflag != ANIM_MELEE)
-                               {
-                                       vector wish_angle;
-                                       wish_angle = angleofs(self, self.enemy);
-                                       if (self.animflag != ANIM_SWIM)
-                                       if (fabs(wish_angle_y) < 15)
-                                       {
-                                               self.moveto   = self.enemy.origin;
-                                               self.steerto  = steerlib_attract2(self.moveto, 0.5, 500, 0.95);
-                                               self.animflag = ANIM_MELEE;
-                                       }
-                               }
-                               else if (self.tur_head.attack_finished_single < time)
-                               {
-                                       if(self.tur_head.shot_volly)
-                                       {
-                                               self.animflag = ANIM_NO;
-                                               self.tur_head.shot_volly = self.tur_head.shot_volly -1;
-                                               if(self.tur_head.shot_volly == 0)
-                                                       self.tur_head.attack_finished_single = time + (autocvar_g_turrets_unit_walker_rocket_refire);
-                                               else
-                                                       self.tur_head.attack_finished_single = time + 0.2;
-                                               if(self.tur_head.shot_volly > 1)
-                                                       walker_fire_rocket(gettaginfo(self, gettagindex(self, "tag_rocket01")));
-                                               else
-                                                       walker_fire_rocket(gettaginfo(self, gettagindex(self, "tag_rocket02")));
-                                       }
-                                       else
-                                       {
-                                               if (self.tur_dist_enemy > (autocvar_g_turrets_unit_walker_rocket_range_min))
-                                               if (self.tur_dist_enemy < (autocvar_g_turrets_unit_walker_rocket_range))
-                                                       self.tur_head.shot_volly = 4;
-                                       }
-                               }
-                               else
-                               {
-                                       if (self.animflag != ANIM_MELEE)
-                                               walker_move_to(self.enemy.origin, self.tur_dist_enemy);
-                               }
-                       }
-                       
-                       {
-                               vector real_angle;
-                               float turny = 0, turnx = 0;
-                               float vz;
-                               real_angle = vectoangles(self.steerto) - self.angles;
-                               vz = self.velocity_z;
-                               switch (self.animflag)
-                               {
-                                       case ANIM_NO:
-                                               movelib_beak_simple((autocvar_g_turrets_unit_walker_speed_stop));
-                                               break;
-                                       case ANIM_TURN:
-                                               turny = (autocvar_g_turrets_unit_walker_turn);
-                                               movelib_beak_simple((autocvar_g_turrets_unit_walker_speed_stop));
-                                               break;
-                                       case ANIM_WALK:
-                                               turny = (autocvar_g_turrets_unit_walker_turn_walk);
-                                               movelib_move_simple(v_forward, (autocvar_g_turrets_unit_walker_speed_walk), 0.6);
-                                               break;
-                                       case ANIM_RUN:
-                                               turny = (autocvar_g_turrets_unit_walker_turn_run);
-                                               movelib_move_simple(v_forward, (autocvar_g_turrets_unit_walker_speed_run), 0.6);
-                                               break;
-                                       case ANIM_STRAFE_L:
-                                               turny = (autocvar_g_turrets_unit_walker_turn_strafe);
-                                               movelib_move_simple(v_right * -1, (autocvar_g_turrets_unit_walker_speed_walk), 0.8);
-                                               break;
-                                       case ANIM_STRAFE_R:
-                                               turny = (autocvar_g_turrets_unit_walker_turn_strafe);
-                                               movelib_move_simple(v_right, (autocvar_g_turrets_unit_walker_speed_walk), 0.8);
-                                               break;
-                                       case ANIM_JUMP:
-                                               self.velocity += '0 0 1' * (autocvar_g_turrets_unit_walker_speed_jump);
-                                               break;
-                                       case ANIM_LAND:
-                                               break;
-                                       case ANIM_PAIN:
-                                               if(self.frame != ANIM_PAIN)
-                                                       defer(0.25, walker_setnoanim);
-                                               break;
-                                       case ANIM_MELEE:
-                                               if(self.frame != ANIM_MELEE)
-                                               {
-                                                       defer(0.41, walker_setnoanim);
-                                                       defer(0.21, walker_melee_do_dmg);
-                                               }
-                                               movelib_beak_simple((autocvar_g_turrets_unit_walker_speed_stop));
-                                               break;
-                                       case ANIM_SWIM:
-                                               turny = (autocvar_g_turrets_unit_walker_turn_swim);
-                                               turnx = (autocvar_g_turrets_unit_walker_turn_swim);
-                                               self.angles_x += bound(-10, shortangle_f(real_angle_x, self.angles_x), 10);
-                                               movelib_move_simple(v_forward, (autocvar_g_turrets_unit_walker_speed_swim), 0.3);
-                                               vz = self.velocity_z + sin(time * 4) * 8;
-                                               break;
-                                       case ANIM_ROAM:
-                                               turny = (autocvar_g_turrets_unit_walker_turn_walk);
-                                               movelib_move_simple(v_forward ,(autocvar_g_turrets_unit_walker_speed_roam), 0.5);
-                                               break;
-                               }
-                               if(turny)
-                               {
-                                       turny = bound( turny * -1, shortangle_f(real_angle_y, self.angles_y), turny );
-                                       self.angles_y += turny;
-                               }
-                               if(turnx)
-                               {
-                                       turnx = bound( turnx * -1, shortangle_f(real_angle_x, self.angles_x), turnx );
-                                       self.angles_x += turnx;
-                               }
-                               self.velocity_z = vz;
-                       }
-                       if(self.origin != self.oldorigin)
-                               self.SendFlags |= TNSF_MOVE;
-                       self.oldorigin = self.origin;
-                       turrets_setframe(self.animflag, false);
-                       return true;
-               }
-               case TR_DEATH:
-               {
++    self.moveto = self.pathcurrent.origin;
++    self.steerto = steerlib_attract2(self.moveto, 0.5, 500, 0.95);
++    walker_move_to(self.moveto, 0);
 +#endif
 +}
 +
 +void spawnfunc_turret_walker() { if(!turret_initialize(TUR_WALKER)) remove(self); }
 +
 +float t_walker(float req)
 +{
-                       if (self.pathcurrent)
-                               pathlib_deletepath(self.pathcurrent.owner);
++    switch(req)
++    {
++        case TR_ATTACK:
++        {
++            sound (self, CH_WEAPON_A, "weapons/uzi_fire.wav", VOL_BASE, ATTEN_NORM);
++            fireBullet (self.tur_shotorg, self.tur_shotdir_updated, self.shot_spread, 0, self.shot_dmg, self.shot_force, DEATH_TURRET_WALK_GUN, 0);
++            Send_Effect("laser_muzzleflash", self.tur_shotorg, self.tur_shotdir_updated * 1000, 1);
++
++            return true;
++        }
++        case TR_THINK:
++        {
++            fixedmakevectors(self.angles);
++
++            if (self.spawnflags & TSF_NO_PATHBREAK && self.pathcurrent)
++                walker_move_path();
++            else if (self.enemy == world)
++            {
++                if(self.pathcurrent)
++                    walker_move_path();
++                else
++                {
++                    if(self.enemy_last_time != 0)
++                    {
++                        if(vlen(self.origin - self.enemy_last_loc) < 128 || time - self.enemy_last_time > 10)
++                            self.enemy_last_time = 0;
++                        else
++                            walker_move_to(self.enemy_last_loc, 0);
++                    }
++                    else
++                    {
++                        if(self.animflag != ANIM_NO)
++                        {
++                            traceline(self.origin + '0 0 64', self.origin + '0 0 64' + v_forward * 128, MOVE_NORMAL, self);
++
++                            if(trace_fraction != 1.0)
++                                self.tur_head.idletime = -1337;
++                            else
++                            {
++                                traceline(trace_endpos, trace_endpos - '0 0 256', MOVE_NORMAL, self);
++                                if(trace_fraction == 1.0)
++                                    self.tur_head.idletime = -1337;
++                            }
++
++                            if(self.tur_head.idletime == -1337)
++                            {
++                                self.moveto = self.origin + randomvec() * 256;
++                                self.tur_head.idletime = 0;
++                            }
++
++                            self.moveto = self.moveto * 0.9 + ((self.origin + v_forward * 500) + randomvec() * 400) * 0.1;
++                            self.moveto_z = self.origin_z + 64;
++                            walker_move_to(self.moveto, 0);
++                        }
++
++                        if(self.idletime < time)
++                        {
++                            if(random() < 0.5 || !(self.spawnflags & TSL_ROAM))
++                            {
++                                self.idletime = time + 1 + random() * 5;
++                                self.moveto = self.origin;
++                                self.animflag = ANIM_NO;
++                            }
++                            else
++                            {
++                                self.animflag = ANIM_WALK;
++                                self.idletime = time + 4 + random() * 2;
++                                self.moveto = self.origin + randomvec() * 256;
++                                self.tur_head.moveto = self.moveto;
++                                self.tur_head.idletime = 0;
++                            }
++                        }
++                    }
++                }
++            }
++            else
++            {
++                if (self.tur_dist_enemy < (autocvar_g_turrets_unit_walker_melee_range) && self.animflag != ANIM_MELEE)
++                {
++                    vector wish_angle;
++
++                    wish_angle = angleofs(self, self.enemy);
++                    if (self.animflag != ANIM_SWIM)
++                    if (fabs(wish_angle_y) < 15)
++                    {
++                        self.moveto   = self.enemy.origin;
++                        self.steerto  = steerlib_attract2(self.moveto, 0.5, 500, 0.95);
++                        self.animflag = ANIM_MELEE;
++                    }
++                }
++                else if (self.tur_head.attack_finished_single < time)
++                {
++                    if(self.tur_head.shot_volly)
++                    {
++                        self.animflag = ANIM_NO;
++
++                        self.tur_head.shot_volly = self.tur_head.shot_volly -1;
++                        if(self.tur_head.shot_volly == 0)
++                            self.tur_head.attack_finished_single = time + (autocvar_g_turrets_unit_walker_rocket_refire);
++                        else
++                            self.tur_head.attack_finished_single = time + 0.2;
++
++                        if(self.tur_head.shot_volly > 1)
++                            walker_fire_rocket(gettaginfo(self, gettagindex(self, "tag_rocket01")));
++                        else
++                            walker_fire_rocket(gettaginfo(self, gettagindex(self, "tag_rocket02")));
++                    }
++                    else
++                    {
++                        if (self.tur_dist_enemy > (autocvar_g_turrets_unit_walker_rocket_range_min))
++                        if (self.tur_dist_enemy < (autocvar_g_turrets_unit_walker_rocket_range))
++                            self.tur_head.shot_volly = 4;
++                    }
++                }
++                else
++                {
++                    if (self.animflag != ANIM_MELEE)
++                        walker_move_to(self.enemy.origin, self.tur_dist_enemy);
++                }
++            }
++
++            {
++                vector real_angle;
++                float turny = 0, turnx = 0;
++                float vz;
++
++                real_angle = vectoangles(self.steerto) - self.angles;
++                vz = self.velocity_z;
++
++                switch (self.animflag)
++                {
++                    case ANIM_NO:
++                        movelib_beak_simple((autocvar_g_turrets_unit_walker_speed_stop));
++                        break;
++
++                    case ANIM_TURN:
++                        turny = (autocvar_g_turrets_unit_walker_turn);
++                        movelib_beak_simple((autocvar_g_turrets_unit_walker_speed_stop));
++                        break;
++
++                    case ANIM_WALK:
++                        turny = (autocvar_g_turrets_unit_walker_turn_walk);
++                        movelib_move_simple(v_forward, (autocvar_g_turrets_unit_walker_speed_walk), 0.6);
++                        break;
++
++                    case ANIM_RUN:
++                        turny = (autocvar_g_turrets_unit_walker_turn_run);
++                        movelib_move_simple(v_forward, (autocvar_g_turrets_unit_walker_speed_run), 0.6);
++                        break;
++
++                    case ANIM_STRAFE_L:
++                        turny = (autocvar_g_turrets_unit_walker_turn_strafe);
++                        movelib_move_simple(v_right * -1, (autocvar_g_turrets_unit_walker_speed_walk), 0.8);
++                        break;
++
++                    case ANIM_STRAFE_R:
++                        turny = (autocvar_g_turrets_unit_walker_turn_strafe);
++                        movelib_move_simple(v_right, (autocvar_g_turrets_unit_walker_speed_walk), 0.8);
++                        break;
++
++                    case ANIM_JUMP:
++                        self.velocity += '0 0 1' * (autocvar_g_turrets_unit_walker_speed_jump);
++                        break;
++
++                    case ANIM_LAND:
++                        break;
++
++                    case ANIM_PAIN:
++                        if(self.frame != ANIM_PAIN)
++                            defer(0.25, walker_setnoanim);
++
++                        break;
++
++                    case ANIM_MELEE:
++                        if(self.frame != ANIM_MELEE)
++                        {
++                            defer(0.41, walker_setnoanim);
++                            defer(0.21, walker_melee_do_dmg);
++                        }
++
++                        movelib_beak_simple((autocvar_g_turrets_unit_walker_speed_stop));
++                        break;
++
++                    case ANIM_SWIM:
++                        turny = (autocvar_g_turrets_unit_walker_turn_swim);
++                        turnx = (autocvar_g_turrets_unit_walker_turn_swim);
++
++                        self.angles_x += bound(-10, shortangle_f(real_angle_x, self.angles_x), 10);
++                        movelib_move_simple(v_forward, (autocvar_g_turrets_unit_walker_speed_swim), 0.3);
++                        vz = self.velocity_z + sin(time * 4) * 8;
++                        break;
++
++                    case ANIM_ROAM:
++                        turny = (autocvar_g_turrets_unit_walker_turn_walk);
++                        movelib_move_simple(v_forward ,(autocvar_g_turrets_unit_walker_speed_roam), 0.5);
++                        break;
++                }
++
++                if(turny)
++                {
++                    turny = bound( turny * -1, shortangle_f(real_angle_y, self.angles_y), turny );
++                    self.angles_y += turny;
++                }
++
++                if(turnx)
++                {
++                    turnx = bound( turnx * -1, shortangle_f(real_angle_x, self.angles_x), turnx );
++                    self.angles_x += turnx;
++                }
++
++                self.velocity_z = vz;
++            }
++
++
++            if(self.origin != self.oldorigin)
++                self.SendFlags |= TNSF_MOVE;
++
++            self.oldorigin = self.origin;
++            turrets_setframe(self.animflag, false);
++
++            return true;
++        }
++        case TR_DEATH:
++        {
 +#ifdef WALKER_FANCYPATHING
-                       self.pathcurrent = world;
-               
-                       return true;
-               }
-               case TR_SETUP:
-               {
-                       self.ticrate = 0.05;
-                       
-                       entity e;
-                       // Respawn is called & first spawn to, to set team. need to make sure we do not move the initial spawn.
-                       if(self.movetype == MOVETYPE_WALK)
-                       {
-                               if(self.pos1)
-                                       setorigin(self, self.pos1);
-                               if(self.pos2)
-                                       self.angles = self.pos2;
-                       }
-                       
-                       self.ammo_flags = TFL_AMMO_BULLETS | TFL_AMMO_RECHARGE | TFL_AMMO_RECIEVE;
-                       self.aim_flags = TFL_AIM_LEAD;
-                       self.turret_flags |= TUR_FLAG_HITSCAN;
-                               
-                       self.target_select_flags = TFL_TARGETSELECT_PLAYERS | TFL_TARGETSELECT_RANGELIMITS | TFL_TARGETSELECT_TEAMCHECK | TFL_TARGETSELECT_LOS;
-                       self.target_validate_flags = TFL_TARGETSELECT_PLAYERS | TFL_TARGETSELECT_RANGELIMITS | TFL_TARGETSELECT_TEAMCHECK | TFL_TARGETSELECT_LOS;
-                       self.iscreature = true;
-                       self.teleportable = TELEPORT_NORMAL;
-                       self.damagedbycontents = true;
-                       self.solid = SOLID_SLIDEBOX;
-                       self.takedamage = DAMAGE_AIM;
-                       if(self.movetype != MOVETYPE_WALK)
-                       {
-                               setorigin(self, self.origin);
-                               tracebox(self.origin + '0 0 128', self.mins, self.maxs, self.origin - '0 0 10000', MOVE_NORMAL, self);
-                               setorigin(self, trace_endpos + '0 0 4');
-                               self.pos1 = self.origin;
-                               self.pos2 = self.angles;
-                       }
-                       self.movetype = MOVETYPE_WALK;
-                       self.idle_aim = '0 0 0';
-                       self.turret_firecheckfunc = walker_firecheck;
-                       
-                       if (self.target != "")
-                       {
-                               e = find(world, targetname, self.target);
-                               if (!e)
-                               {
-                                       dprint("Initital waypoint for walker does NOT exsist, fix your map!\n");
-                                       self.target = "";
-                               }
-                               if (e.classname != "turret_checkpoint")
-                                       dprint("Warning: not a turrret path\n");
-                               else
-                               {
++            if (self.pathcurrent)
++                pathlib_deletepath(self.pathcurrent.owner);
 +#endif
-                                       self.pathcurrent = WALKER_PATH(self.origin, e.origin);
-                                       self.pathgoal = e;
++            self.pathcurrent = world;
++
++            return true;
++        }
++        case TR_SETUP:
++        {
++            self.ticrate = 0.05;
++
++            entity e;
++
++            // Respawn is called & first spawn to, to set team. need to make sure we do not move the initial spawn.
++            if(self.movetype == MOVETYPE_WALK)
++            {
++                if(self.pos1)
++                    setorigin(self, self.pos1);
++                if(self.pos2)
++                    self.angles = self.pos2;
++            }
++
++            self.ammo_flags = TFL_AMMO_BULLETS | TFL_AMMO_RECHARGE | TFL_AMMO_RECIEVE;
++            self.aim_flags = TFL_AIM_LEAD;
++            self.turret_flags |= TUR_FLAG_HITSCAN;
++
++            self.target_select_flags = TFL_TARGETSELECT_PLAYERS | TFL_TARGETSELECT_RANGELIMITS | TFL_TARGETSELECT_TEAMCHECK | TFL_TARGETSELECT_LOS;
++            self.target_validate_flags = TFL_TARGETSELECT_PLAYERS | TFL_TARGETSELECT_RANGELIMITS | TFL_TARGETSELECT_TEAMCHECK | TFL_TARGETSELECT_LOS;
++            self.iscreature = true;
++            self.teleportable = TELEPORT_NORMAL;
++            self.damagedbycontents = true;
++            self.solid = SOLID_SLIDEBOX;
++            self.takedamage = DAMAGE_AIM;
++            if(self.movetype != MOVETYPE_WALK)
++            {
++                setorigin(self, self.origin);
++                tracebox(self.origin + '0 0 128', self.mins, self.maxs, self.origin - '0 0 10000', MOVE_NORMAL, self);
++                setorigin(self, trace_endpos + '0 0 4');
++                self.pos1 = self.origin;
++                self.pos2 = self.angles;
++            }
++            self.movetype = MOVETYPE_WALK;
++            self.idle_aim = '0 0 0';
++            self.turret_firecheckfunc = walker_firecheck;
++
++            if (self.target != "")
++            {
++                e = find(world, targetname, self.target);
++                if (!e)
++                {
++                    dprint("Initital waypoint for walker does NOT exsist, fix your map!\n");
++                    self.target = "";
++                }
++
++                if (e.classname != "turret_checkpoint")
++                    dprint("Warning: not a turrret path\n");
++                else
++                {
 +#ifdef WALKER_FANCYPATHING
-                                       self.pathcurrent = e;
++                    self.pathcurrent = WALKER_PATH(self.origin, e.origin);
++                    self.pathgoal = e;
 +#else
-                               }
-                       }
-                       return true;
-               }
-               case TR_PRECACHE:
-               {
-                       precache_model ("models/turrets/walker_body.md3");
-                       precache_model ("models/turrets/walker_head_minigun.md3");
-                       precache_model ("models/turrets/rocket.md3");
-                       precache_sound ("weapons/rocket_impact.wav");
-                       return true;
-               }
-       }
-       return true;
++                    self.pathcurrent = e;
 +#endif
-       float dt;
-       dt = time - self.move_time;
-       self.move_time = time;
-       if(dt <= 0)
-               return;
-       fixedmakevectors(self.angles);
-       movelib_groundalign4point(300, 100, 0.25, 45);
-       setorigin(self, self.origin + self.velocity * dt);
-       self.tur_head.angles += dt * self.tur_head.move_avelocity;
-       self.angles_y = self.move_angles_y;
-       if (self.health < 127)
-       if(random() < 0.15)
-               te_spark(self.origin + '0 0 40', randomvec() * 256 + '0 0 256', 16);
++                }
++            }
++
++            return true;
++        }
++        case TR_PRECACHE:
++        {
++            precache_model ("models/turrets/walker_body.md3");
++            precache_model ("models/turrets/walker_head_minigun.md3");
++            precache_model ("models/turrets/rocket.md3");
++            precache_sound ("weapons/rocket_impact.wav");
++            return true;
++        }
++    }
++
++    return true;
 +}
 +
 +#endif // SVQC
 +#ifdef CSQC
 +
 +#include "../../../server/movelib.qh"
 +
 +void walker_draw()
 +{
-       switch(req)
-       {
-               case TR_SETUP:
-               {
-                       self.gravity            = 1;
-                       self.movetype           = MOVETYPE_BOUNCE;
-                       self.move_movetype      = MOVETYPE_BOUNCE;
-                       self.move_origin        = self.origin;
-                       self.move_time          = time;
-                       self.draw                       = walker_draw;
-                       
-                       return true;
-               }
-               case TR_PRECACHE:
-               {
-                       return true;
-               }
-       }
-       return true;
++    float dt;
++
++    dt = time - self.move_time;
++    self.move_time = time;
++    if(dt <= 0)
++        return;
++
++    fixedmakevectors(self.angles);
++    movelib_groundalign4point(300, 100, 0.25, 45);
++    setorigin(self, self.origin + self.velocity * dt);
++    self.tur_head.angles += dt * self.tur_head.move_avelocity;
++    self.angles_y = self.move_angles_y;
++
++    if (self.health < 127)
++    if(random() < 0.15)
++        te_spark(self.origin + '0 0 40', randomvec() * 256 + '0 0 256', 16);
 +}
 +
 +float t_walker(float req)
 +{
++    switch(req)
++    {
++        case TR_SETUP:
++        {
++            self.gravity              = 1;
++            self.movetype             = MOVETYPE_BOUNCE;
++            self.move_movetype        = MOVETYPE_BOUNCE;
++            self.move_origin  = self.origin;
++            self.move_time            = time;
++            self.draw                 = walker_draw;
++
++            return true;
++        }
++        case TR_PRECACHE:
++        {
++            return true;
++        }
++    }
++
++    return true;
 +}
 +
 +#endif // CSQC
 +#endif // REGISTER_TURRET
index 3d6d95a,0000000..477df7b
mode 100644,000000..100644
--- /dev/null
@@@ -1,330 -1,0 +1,330 @@@
-                                 float bforce, float f_dmg, float f_velfactor, float deathtype)
 +/*
 +* Return a angle within +/- 360.
 +*/
 +float anglemods(float v)
 +{
 +      v = v - 360 * floor(v / 360);
 +
 +      if(v >= 180)
 +              return v - 360;
 +      else if(v <= -180)
 +              return v + 360;
 +      else
 +              return v;
 +}
 +
 +/*
 +* Return the short angle
 +*/
 +float shortangle_f(float ang1, float ang2)
 +{
 +      if(ang1 > ang2)
 +      {
 +              if(ang1 > 180)
 +                      return ang1 - 360;
 +      }
 +      else
 +      {
 +              if(ang1 < -180)
 +                      return ang1 + 360;
 +      }
 +
 +      return ang1;
 +}
 +
 +vector shortangle_v(vector ang1, vector ang2)
 +{
 +      vector vtmp;
 +
 +      vtmp_x = shortangle_f(ang1_x,ang2_x);
 +      vtmp_y = shortangle_f(ang1_y,ang2_y);
 +      vtmp_z = shortangle_f(ang1_z,ang2_z);
 +
 +      return vtmp;
 +}
 +
 +vector shortangle_vxy(vector ang1, vector ang2)
 +{
 +      vector vtmp = '0 0 0';
 +
 +      vtmp_x = shortangle_f(ang1_x,ang2_x);
 +      vtmp_y = shortangle_f(ang1_y,ang2_y);
 +
 +      return vtmp;
 +}
 +
 +
 +/*
 +* Get "real" origin, in worldspace, even if ent is attached to something else.
 +*/
 +vector real_origin(entity ent)
 +{
 +      entity e;
 +      vector v = ((ent.absmin + ent.absmax) * 0.5);
 +
 +      e = ent.tag_entity;
 +      while(e)
 +      {
 +              v = v + ((e.absmin + e.absmax) * 0.5);
 +              e = e.tag_entity;
 +      }
 +
 +      return v;
 +}
 +
 +/*
 +* Return the angle between two enteties
 +*/
 +vector angleofs(entity from, entity to)
 +{
 +      vector v_res;
 +
 +      v_res = normalize(to.origin - from.origin);
 +      v_res = vectoangles(v_res);
 +      v_res = v_res - from.angles;
 +
 +      if (v_res_x < 0)        v_res_x += 360;
 +      if (v_res_x > 180)      v_res_x -= 360;
 +
 +      if (v_res_y < 0)        v_res_y += 360;
 +      if (v_res_y > 180)      v_res_y -= 360;
 +
 +      return v_res;
 +}
 +
 +vector angleofs3(vector from, vector from_a, entity to)
 +{
 +      vector v_res;
 +
 +      v_res = normalize(to.origin - from);
 +      v_res = vectoangles(v_res);
 +      v_res = v_res - from_a;
 +
 +      if (v_res_x < 0)        v_res_x += 360;
 +      if (v_res_x > 180)      v_res_x -= 360;
 +
 +      if (v_res_y < 0)        v_res_y += 360;
 +      if (v_res_y > 180)      v_res_y -= 360;
 +
 +      return v_res;
 +}
 +
 +/*
 +* Update self.tur_shotorg by getting up2date bone info
 +* NOTICE this func overwrites the global v_forward, v_right and v_up vectors.
 +*/
 +float turret_tag_fire_update()
 +{
 +      if(!self.tur_head)
 +      {
 +              error("Call to turret_tag_fire_update with self.tur_head missing!\n");
 +              self.tur_shotorg = '0 0 0';
 +              return false;
 +      }
 +
 +      self.tur_shotorg = gettaginfo(self.tur_head, gettagindex(self.tur_head, "tag_fire"));
 +      v_forward = normalize(v_forward);
 +
 +      return true;
 +}
 +
 +/*
 +* Railgun-like beam, but has thickness and suppots slowing of target
 +*/
 +void FireImoBeam (vector start, vector end, vector smin, vector smax,
++                                float bforce, float f_dmg, float f_velfactor, int deathtype)
 +
 +{
 +      vector hitloc, force, endpoint, dir;
 +      entity ent;
 +
 +      dir = normalize(end - start);
 +      force = dir * bforce;
 +
 +      // go a little bit into the wall because we need to hit this wall later
 +      end = end + dir;
 +
 +      // trace multiple times until we hit a wall, each obstacle will be made unsolid.
 +      // note down which entities were hit so we can damage them later
 +      while (1)
 +      {
 +              tracebox(start, smin, smax, end, false, self);
 +
 +              // if it is world we can't hurt it so stop now
 +              if (trace_ent == world || trace_fraction == 1)
 +                     &nbs