]> git.rm.cloudns.org Git - xonotic/xonotic-data.pk3dir.git/commitdiff
Merge branch 'master' into Mario/turrets
authorMario <zacjardine@y7mail.com>
Tue, 14 Apr 2015 22:22:35 +0000 (08:22 +1000)
committerMario <zacjardine@y7mail.com>
Tue, 14 Apr 2015 22:22:35 +0000 (08:22 +1000)
Conflicts:
qcsrc/client/progs.src
qcsrc/client/tturrets.qh
qcsrc/server/mutators/gamemode_onslaught.qc
qcsrc/server/progs.src
qcsrc/server/tturrets/include/turrets.qh
qcsrc/server/tturrets/include/turrets_early.qh
qcsrc/server/tturrets/system/system_aimprocs.qc
qcsrc/server/tturrets/system/system_damage.qc
qcsrc/server/tturrets/system/system_misc.qc
qcsrc/server/tturrets/units/unit_hellion.qc
qcsrc/server/tturrets/units/unit_hk.qc
qcsrc/server/tturrets/units/unit_mlrs.qc
qcsrc/server/tturrets/units/unit_phaser.qc

49 files changed:
1  2 
qcsrc/client/damage.qc
qcsrc/client/main.qc
qcsrc/client/progs.src
qcsrc/client/tturrets.qc
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/turrets/cl_turrets.qc
qcsrc/common/turrets/cl_turrets.qh
qcsrc/common/turrets/config.qh
qcsrc/common/turrets/sv_turrets.qc
qcsrc/common/turrets/sv_turrets.qh
qcsrc/common/turrets/turrets.qh
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/turrets/util.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/mutators/gamemode_assault.qc
qcsrc/server/mutators/gamemode_onslaught.qc
qcsrc/server/mutators/mutators_include.qc
qcsrc/server/progs.src
qcsrc/server/t_teleporters.qc
qcsrc/server/tturrets/system/system_main.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_plasma.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

Simple merge
index 0000000000000000000000000000000000000000,36ec4f7b8c2525c2712566410ae80be9977ab50f..b753139c4615115c2f318c1efc86f18e77bb3935
mode 000000,100644..100644
--- /dev/null
@@@ -1,0 -1,1317 +1,1319 @@@
 -#include "tturrets.qh"
+ #include "mapvoting.qh"
+ #include "modeleffects.qh"
+ #include "particles.qh"
+ #include "scoreboard.qh"
+ #include "shownames.qh"
+ #include "target_music.qh"
 -      turrets_precache();
+ #include "tuba.qh"
+ #include "wall.qh"
+ #include "waypointsprites.qh"
+ #include "vehicles/vehicles.qh"
+ #include "../server/vehicles/bumblebee.qh"
+ #include "../common/net_notice.qh"
+ #include "../common/monsters/monsters.qh"
++#include "../common/turrets/cl_turrets.qh"
++#include "../common/turrets/turrets.qh"
++
+ #include "../warpzonelib/client.qh"
+ // --------------------------------------------------------------------------
+ // BEGIN REQUIRED CSQC FUNCTIONS
+ //include "main.qh"
+ entity clearentity_ent;
+ void clearentity(entity e)
+ {
+       if (!clearentity_ent)
+       {
+               clearentity_ent = spawn();
+               clearentity_ent.classname = "clearentity";
+       }
+       int n = e.entnum;
+       copyentity(clearentity_ent, e);
+       e.entnum = n;
+ }
+ #define DP_CSQC_ENTITY_REMOVE_IS_B0RKED
+ void menu_show_error()
+ {
+       drawstring('0 200 0', _("ERROR - MENU IS VISIBLE BUT NO MENU WAS DEFINED!"), '8 8 0', '1 0 0', 1, 0);
+ }
+ // CSQC_Init : Called every time the CSQC code is initialized (essentially at map load)
+ // Useful for precaching things
+ void menu_sub_null()
+ {
+ }
+ string forcefog;
+ void WaypointSprite_Load();
+ void ConsoleCommand_macro_init();
+ void CSQC_Init(void)
+ {
+       prvm_language = cvar_string("prvm_language");
+ #ifdef WATERMARK
+       dprintf("^4CSQC Build information: ^1%s\n", WATERMARK);
+ #endif
+       int i;
+       binddb = db_create();
+       tempdb = db_create();
+       ClientProgsDB = db_load("client.db");
+       compressShortVector_init();
+       draw_endBoldFont();
+       menu_visible = false;
+       menu_show = menu_show_error;
+       menu_action = func_null;
+       for(i = 0; i < 255; ++i)
+               if(getplayerkeyvalue(i, "viewentity") == "")
+                       break;
+       maxclients = i;
+       //registercommand("hud_configure");
+       //registercommand("hud_save");
+       //registercommand("menu_action");
+       ConsoleCommand_macro_init();
+       registercvar("hud_usecsqc", "1");
+       registercvar("scoreboard_columns", "default");
+       registercvar("cl_nade_type", "3");
+       registercvar("cl_pokenade_type", "zombie");
+       gametype = 0;
+       // hud_fields uses strunzone on the titles!
+       for(i = 0; i < MAX_HUD_FIELDS; ++i)
+               hud_title[i] = strzone("(null)");
+       Cmd_HUD_SetFields(0);
+       postinit = false;
+       calledhooks = 0;
+       teams = Sort_Spawn();
+       players = Sort_Spawn();
+       GetTeam(NUM_SPECTATOR, true); // add specs first
+       // needs to be done so early because of the constants they create
+       CALL_ACCUMULATED_FUNCTION(RegisterWeapons);
++      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);
+       CALL_ACCUMULATED_FUNCTION(RegisterBuffs);
+       WaypointSprite_Load();
+       // precaches
+       precache_model("null");
+       precache_sound("misc/hit.wav");
+       precache_sound("misc/typehit.wav");
+       Projectile_Precache();
+       Hook_Precache();
+       GibSplash_Precache();
+       Casings_Precache();
+       Vehicles_Precache();
+       Tuba_Precache();
+       CSQCPlayer_Precache();
+       if(autocvar_cl_reticle)
+       {
+               precache_pic("gfx/reticle_normal");
+               // weapon reticles are precached in weapon files
+       }
+       get_mi_min_max_texcoords(1); // try the CLEVER way first
+       minimapname = strcat("gfx/", mi_shortname, "_radar.tga");
+       shortmapname = mi_shortname;
+       if(precache_pic(minimapname) == "")
+       {
+               // but maybe we have a non-clever minimap
+               minimapname = strcat("gfx/", mi_shortname, "_mini.tga");
+               if(precache_pic(minimapname) == "")
+                       minimapname = ""; // FAIL
+               else
+                       get_mi_min_max_texcoords(0); // load new texcoords
+       }
+       mi_center = (mi_min + mi_max) * 0.5;
+       mi_scale = mi_max - mi_min;
+       minimapname = strzone(minimapname);
+       WarpZone_Init();
+       hud_skin_path = strzone(strcat("gfx/hud/", autocvar_hud_skin));
+       draw_currentSkin = strzone(strcat("gfx/menu/", cvar_string("menu_skin")));
+ }
+ // CSQC_Shutdown : Called every time the CSQC code is shutdown (changing maps, quitting, etc)
+ void Shutdown(void)
+ {
+       WarpZone_Shutdown();
+       remove(teams);
+       remove(players);
+       db_close(binddb);
+       db_close(tempdb);
+       if(autocvar_cl_db_saveasdump)
+               db_dump(ClientProgsDB, "client.db");
+       else
+               db_save(ClientProgsDB, "client.db");
+       db_close(ClientProgsDB);
+       if(camera_active)
+               cvar_set("chase_active",ftos(chase_active_backup));
+       // unset the event chasecam's chase_active
+       if(autocvar_chase_active < 0)
+               cvar_set("chase_active", "0");
+       if (!isdemo())
+       {
+               if (!(calledhooks & HOOK_START))
+                       localcmd("\n_cl_hook_gamestart nop\n");
+               if (!(calledhooks & HOOK_END))
+                       localcmd("\ncl_hook_gameend\n");
+       }
+ }
+ .float has_team;
+ float SetTeam(entity o, int Team)
+ {
+       entity tm;
+       if(teamplay)
+       {
+               switch(Team)
+               {
+                       case -1:
+                       case NUM_TEAM_1:
+                       case NUM_TEAM_2:
+                       case NUM_TEAM_3:
+                       case NUM_TEAM_4:
+                               break;
+                       default:
+                               if(GetTeam(Team, false) == world)
+                               {
+                                       dprintf("trying to switch to unsupported team %d\n", Team);
+                                       Team = NUM_SPECTATOR;
+                               }
+                               break;
+               }
+       }
+       else
+       {
+               switch(Team)
+               {
+                       case -1:
+                       case 0:
+                               break;
+                       default:
+                               if(GetTeam(Team, false) == world)
+                               {
+                                       dprintf("trying to switch to unsupported team %d\n", Team);
+                                       Team = NUM_SPECTATOR;
+                               }
+                               break;
+               }
+       }
+       if(Team == -1) // leave
+       {
+               if(o.has_team)
+               {
+                       tm = GetTeam(o.team, false);
+                       tm.team_size -= 1;
+                       o.has_team = 0;
+                       return true;
+               }
+       }
+       else
+       {
+               if (!o.has_team)
+               {
+                       o.team = Team;
+                       tm = GetTeam(Team, true);
+                       tm.team_size += 1;
+                       o.has_team = 1;
+                       return true;
+               }
+               else if(Team != o.team)
+               {
+                       tm = GetTeam(o.team, false);
+                       tm.team_size -= 1;
+                       o.team = Team;
+                       tm = GetTeam(Team, true);
+                       tm.team_size += 1;
+                       return true;
+               }
+       }
+       return false;
+ }
+ void Playerchecker_Think()
+ {
+     int i;
+       entity e;
+       for(i = 0; i < maxclients; ++i)
+       {
+               e = playerslots[i];
+               if(GetPlayerName(i) == "")
+               {
+                       if(e.sort_prev)
+                       {
+                               // player disconnected
+                               SetTeam(e, -1);
+                               RemovePlayer(e);
+                               e.sort_prev = world;
+                               //e.gotscores = 0;
+                       }
+               }
+               else
+               {
+                       if (!e.sort_prev)
+                       {
+                               // player connected
+                               if (!e)
+                                       playerslots[i] = e = spawn();
+                               e.sv_entnum = i;
+                               e.ping = 0;
+                               e.ping_packetloss = 0;
+                               e.ping_movementloss = 0;
+                               //e.gotscores = 0; // we might already have the scores...
+                               SetTeam(e, GetPlayerColor(i)); // will not hurt; later updates come with HUD_UpdatePlayerTeams
+                               RegisterPlayer(e);
+                               HUD_UpdatePlayerPos(e);
+                       }
+               }
+       }
+       self.nextthink = time + 0.2;
+ }
+ void Porto_Init();
+ void TrueAim_Init();
+ void PostInit(void)
+ {
+       entity playerchecker;
+       playerchecker = spawn();
+       playerchecker.think = Playerchecker_Think;
+       playerchecker.nextthink = time + 0.2;
+       Porto_Init();
+       TrueAim_Init();
+       postinit = true;
+ }
+ // CSQC_InputEvent : Used to perform actions based on any key pressed, key released and mouse on the client.
+ // Return value should be 1 if CSQC handled the input, otherwise return 0 to have the input passed to the engine.
+ // All keys are in ascii.
+ // bInputType = 0 is key pressed, 1 is key released, 2 and 3 are mouse input.
+ // In the case of keyboard input, nPrimary is the ascii code, and nSecondary is 0.
+ // In the case of mouse input, nPrimary is xdelta, nSecondary is ydelta.
+ // In the case of mouse input after a setcursormode(1) call, nPrimary is xpos, nSecondary is ypos.
+ float CSQC_InputEvent(float bInputType, float nPrimary, float nSecondary)
+ {
+       float bSkipKey;
+       bSkipKey = false;
+       if (HUD_Panel_InputEvent(bInputType, nPrimary, nSecondary))
+               return true;
+       if (MapVote_InputEvent(bInputType, nPrimary, nSecondary))
+               return true;
+       if(menu_visible && menu_action)
+               if(menu_action(bInputType, nPrimary, nSecondary))
+                       return true;
+       return bSkipKey;
+ }
+ // END REQUIRED CSQC FUNCTIONS
+ // --------------------------------------------------------------------------
+ // --------------------------------------------------------------------------
+ // BEGIN OPTIONAL CSQC FUNCTIONS
+ void Ent_RemoveEntCS()
+ {
+       entcs_receiver[self.sv_entnum] = world;
+ }
+ void Ent_ReadEntCS()
+ {
+     int sf;
+       InterpolateOrigin_Undo();
+       self.classname = "entcs_receiver";
+       sf = ReadByte();
+       if(sf & 1)
+               self.sv_entnum = ReadByte();
+       if(sf & 2)
+       {
+               self.origin_x = ReadShort();
+               self.origin_y = ReadShort();
+               self.origin_z = ReadShort();
+               setorigin(self, self.origin);
+       }
+       if(sf & 4)
+       {
+               self.angles_y = ReadByte() * 360.0 / 256;
+               self.angles_x = self.angles_z = 0;
+       }
+       if(sf & 8)
+               self.healthvalue = ReadByte() * 10;
+       if(sf & 16)
+               self.armorvalue = ReadByte() * 10;
+       entcs_receiver[self.sv_entnum] = self;
+       self.entremove = Ent_RemoveEntCS;
+       self.iflags |= IFLAG_ORIGIN;
+       InterpolateOrigin_Note();
+ }
+ void Ent_Remove();
+ void Ent_RemovePlayerScore()
+ {
+       if(self.owner) {
+               SetTeam(self.owner, -1);
+               self.owner.gotscores = 0;
+               for(int i = 0; i < MAX_SCORE; ++i) {
+                       self.owner.(scores[i]) = 0; // clear all scores
+               }
+       }
+ }
+ void Ent_ReadPlayerScore()
+ {
+       int i, n;
+       bool isNew;
+       entity o;
+       // damnit -.- don't want to go change every single .sv_entnum in hud.qc AGAIN
+       // (no I've never heard of M-x replace-string, sed, or anything like that)
+       isNew = !self.owner; // workaround for DP bug
+       n = ReadByte()-1;
+ #ifdef DP_CSQC_ENTITY_REMOVE_IS_B0RKED
+       if(!isNew && n != self.sv_entnum)
+       {
+               //print("A CSQC entity changed its owner!\n");
+               printf("A CSQC entity changed its owner! (edict: %d, classname: %s)\n", num_for_edict(self), self.classname);
+               isNew = true;
+               Ent_Remove();
+               self.enttype = ENT_CLIENT_SCORES;
+       }
+ #endif
+       self.sv_entnum = n;
+       if (!(playerslots[self.sv_entnum]))
+               playerslots[self.sv_entnum] = spawn();
+       o = self.owner = playerslots[self.sv_entnum];
+       o.sv_entnum = self.sv_entnum;
+       o.gotscores = 1;
+       //if (!o.sort_prev)
+       //      RegisterPlayer(o);
+       //playerchecker will do this for us later, if it has not already done so
+     int sf, lf;
+ #if MAX_SCORE <= 8
+       sf = ReadByte();
+       lf = ReadByte();
+ #else
+       sf = ReadShort();
+       lf = ReadShort();
+ #endif
+     int p;
+       for(i = 0, p = 1; i < MAX_SCORE; ++i, p *= 2)
+               if(sf & p)
+               {
+                       if(lf & p)
+                               o.(scores[i]) = ReadInt24_t();
+                       else
+                               o.(scores[i]) = ReadChar();
+               }
+       if(o.sort_prev)
+               HUD_UpdatePlayerPos(o); // if not registered, we cannot do this yet!
+       self.entremove = Ent_RemovePlayerScore;
+ }
+ void Ent_ReadTeamScore()
+ {
+       int i;
+       entity o;
+       self.team = ReadByte();
+       o = self.owner = GetTeam(self.team, true); // these team numbers can always be trusted
+     int sf, lf;
+ #if MAX_TEAMSCORE <= 8
+       sf = ReadByte();
+       lf = ReadByte();
+ #else
+       sf = ReadShort();
+       lf = ReadShort();
+ #endif
+       int p;
+       for(i = 0, p = 1; i < MAX_TEAMSCORE; ++i, p *= 2)
+               if(sf & p)
+               {
+                       if(lf & p)
+                               o.(teamscores[i]) = ReadInt24_t();
+                       else
+                               o.(teamscores[i]) = ReadChar();
+               }
+       HUD_UpdateTeamPos(o);
+ }
+ void Ent_ClientData()
+ {
+       float newspectatee_status;
+     int f = ReadByte();
+       scoreboard_showscores_force = (f & 1);
+       if(f & 2)
+       {
+               newspectatee_status = ReadByte();
+               if(newspectatee_status == player_localnum + 1)
+                       newspectatee_status = -1; // observing
+       }
+       else
+               newspectatee_status = 0;
+       spectatorbutton_zoom = (f & 4);
+       if(f & 8)
+       {
+               angles_held_status = 1;
+               angles_held.x = ReadAngle();
+               angles_held.y = ReadAngle();
+               angles_held.z = 0;
+       }
+       else
+               angles_held_status = 0;
+       if(newspectatee_status != spectatee_status)
+       {
+               // clear race stuff
+               race_laptime = 0;
+               race_checkpointtime = 0;
+       }
+       if (autocvar_hud_panel_healtharmor_progressbar_gfx)
+       {
+               if ( (spectatee_status == -1 && newspectatee_status > 0) //before observing, now spectating
+                 || (spectatee_status > 0 && newspectatee_status > 0 && spectatee_status != newspectatee_status) //changed spectated player
+               )
+                       prev_p_health = -1;
+               else if(spectatee_status && !newspectatee_status) //before observing/spectating, now playing
+                       prev_health = -1;
+       }
+       spectatee_status = newspectatee_status;
+       // we could get rid of spectatee_status, and derive it from player_localentnum and player_localnum
+ }
+ void Ent_Nagger()
+ {
+     int i, j, b, f;
+     int nags = ReadByte(); // NAGS NAGS NAGS NAGS NAGS NAGS NADZ NAGS NAGS NAGS
+       if(!(nags & 4))
+       {
+               if(vote_called_vote)
+                       strunzone(vote_called_vote);
+               vote_called_vote = string_null;
+               vote_active = 0;
+       }
+       else
+       {
+               vote_active = 1;
+       }
+       if(nags & 64)
+       {
+               vote_yescount = ReadByte();
+               vote_nocount = ReadByte();
+               vote_needed = ReadByte();
+               vote_highlighted = ReadChar();
+       }
+       if(nags & 128)
+       {
+               if(vote_called_vote)
+                       strunzone(vote_called_vote);
+               vote_called_vote = strzone(ColorTranslateRGB(ReadString()));
+       }
+       if(nags & 1)
+       {
+               for(j = 0; j < maxclients; ++j)
+                       if(playerslots[j])
+                               playerslots[j].ready = 1;
+               for(i = 1; i <= maxclients; i += 8)
+               {
+                       f = ReadByte();
+                       for(j = i-1, b = 1; b < 256; b *= 2, ++j)
+                               if (!(f & b))
+                                       if(playerslots[j])
+                                               playerslots[j].ready = 0;
+               }
+       }
+       ready_waiting = (nags & 1);
+       ready_waiting_for_me = (nags & 2);
+       vote_waiting = (nags & 4);
+       vote_waiting_for_me = (nags & 8);
+       warmup_stage = (nags & 16);
+ }
+ void Ent_EliminatedPlayers()
+ {
+     int i, j, b, f;
+     int sf = ReadByte();
+       if(sf & 1)
+       {
+               for(j = 0; j < maxclients; ++j)
+                       if(playerslots[j])
+                               playerslots[j].eliminated = 1;
+               for(i = 1; i <= maxclients; i += 8)
+               {
+                       f = ReadByte();
+                       for(j = i-1, b = 1; b < 256; b *= 2, ++j)
+                               if (!(f & b))
+                                       if(playerslots[j])
+                                               playerslots[j].eliminated = 0;
+               }
+       }
+ }
+ void Ent_RandomSeed()
+ {
+       float s;
+       prandom_debug();
+       s = ReadShort();
+       psrandom(s);
+ }
+ void Ent_ReadAccuracy(void)
+ {
+     int f, w;
+     int sf = ReadInt24_t();
+       if(sf == 0)
+       {
+               for(w = 0; w <= WEP_LAST - WEP_FIRST; ++w)
+                       weapon_accuracy[w] = -1;
+               return;
+       }
+       for(w = 0, f = 1; w <= WEP_LAST - WEP_FIRST; ++w)
+       {
+               if(sf & f)
+               {
+             int b = ReadByte();
+                       if(b == 0)
+                               weapon_accuracy[w] = -1;
+                       else if(b == 255)
+                               weapon_accuracy[w] = 1.0; // no better error handling yet, sorry
+                       else
+                               weapon_accuracy[w] = (b - 1.0) / 100.0;
+               }
+               if(f == 0x800000)
+                       f = 1;
+               else
+                       f *= 2;
+       }
+ }
+ void Spawn_Draw(void)
+ {
+       pointparticles(self.cnt, self.origin + '0 0 28', '0 0 2', bound(0, frametime, 0.1));
+ }
+ void Ent_ReadSpawnPoint(float is_new) // entity for spawnpoint
+ {
+       float teamnum = (ReadByte() - 1);
+       vector spn_origin;
+       spn_origin.x = ReadShort();
+       spn_origin.y = ReadShort();
+       spn_origin.z = ReadShort();
+       if(is_new)
+       {
+               self.origin = spn_origin;
+               setsize(self, PL_MIN, PL_MAX);
+               droptofloor();
+               /*if(autocvar_cl_spawn_point_model) // needs a model first
+               {
+                       self.mdl = "models/spawnpoint.md3";
+                       self.colormod = Team_ColorRGB(teamnum);
+                       precache_model(self.mdl);
+                       setmodel(self, self.mdl);
+                       self.drawmask = MASK_NORMAL;
+                       //self.movetype = MOVETYPE_NOCLIP;
+                       //self.draw = Spawn_Draw;
+               }*/
+               if(autocvar_cl_spawn_point_particles)
+               {
+                       if((serverflags & SERVERFLAG_TEAMPLAY))
+                       {
+                               switch(teamnum)
+                               {
+                                       case NUM_TEAM_1: self.cnt = particleeffectnum("spawn_point_red"); break;
+                                       case NUM_TEAM_2: self.cnt = particleeffectnum("spawn_point_blue"); break;
+                                       case NUM_TEAM_3: self.cnt = particleeffectnum("spawn_point_yellow"); break;
+                                       case NUM_TEAM_4: self.cnt = particleeffectnum("spawn_point_pink"); break;
+                                       default: self.cnt = particleeffectnum("spawn_point_neutral"); break;
+                               }
+                       }
+                       else { self.cnt = particleeffectnum("spawn_point_neutral"); }
+                       self.draw = Spawn_Draw;
+               }
+       }
+       //printf("Ent_ReadSpawnPoint(is_new = %d); origin = %s, team = %d, effect = %d\n", is_new, vtos(self.origin), teamnum, self.cnt);
+ }
+ void Ent_ReadSpawnEvent(float is_new)
+ {
+       // If entnum is 0, ONLY do the local spawn actions
+       // this way the server can disable the sending of
+       // spawn origin or such to clients if wanted.
+       float entnum = ReadByte();
+       if(entnum)
+       {
+               self.origin_x = ReadShort();
+               self.origin_y = ReadShort();
+               self.origin_z = ReadShort();
+               if(is_new)
+               {
+                       float teamnum = GetPlayerColor(entnum - 1);
+                       if(autocvar_cl_spawn_event_particles)
+                       {
+                               switch(teamnum)
+                               {
+                                       case NUM_TEAM_1: pointparticles(particleeffectnum("spawn_event_red"), self.origin, '0 0 0', 1); break;
+                                       case NUM_TEAM_2: pointparticles(particleeffectnum("spawn_event_blue"), self.origin, '0 0 0', 1); break;
+                                       case NUM_TEAM_3: pointparticles(particleeffectnum("spawn_event_yellow"), self.origin, '0 0 0', 1); break;
+                                       case NUM_TEAM_4: pointparticles(particleeffectnum("spawn_event_pink"), self.origin, '0 0 0', 1); break;
+                                       default: pointparticles(particleeffectnum("spawn_event_neutral"), self.origin, '0 0 0', 1); break;
+                               }
+                       }
+                       if(autocvar_cl_spawn_event_sound)
+                       {
+                               sound(self, CH_TRIGGER, "misc/spawn.wav", VOL_BASE, ATTEN_NORM);
+                       }
+               }
+       }
+       // local spawn actions
+       if(is_new && (!entnum || (entnum == player_localentnum)))
+       {
+               zoomin_effect = 1;
+               current_viewzoom = (1 / bound(1, autocvar_cl_spawnzoom_factor, 16));
+               if(autocvar_cl_unpress_zoom_on_spawn)
+               {
+                       localcmd("-zoom\n");
+                       button_zoom = false;
+               }
+       }
+       //printf("Ent_ReadSpawnEvent(is_new = %d); origin = %s, entnum = %d, localentnum = %d\n", is_new, vtos(self.origin), entnum, player_localentnum);
+ }
+ // CSQC_Ent_Update : Called every frame that the server has indicated an update to the SSQC / CSQC entity has occured.
+ // The only parameter reflects if the entity is "new" to the client, meaning it just came into the client's PVS.
+ void Ent_RadarLink();
+ void Ent_Init();
+ void Ent_ScoresInfo();
+ void CSQC_Ent_Update(float bIsNewEntity)
+ {
+       float t;
+       float savetime;
+       t = ReadByte();
+       if(autocvar_developer_csqcentities)
+               printf("CSQC_Ent_Update(%d) with self=%i self.entnum=%d self.enttype=%d t=%d\n", bIsNewEntity, self, self.entnum, self.enttype, t);
+       // set up the "time" global for received entities to be correct for interpolation purposes
+       savetime = time;
+       if(servertime)
+       {
+               time = servertime;
+       }
+       else
+       {
+               serverprevtime = time;
+               serverdeltatime = getstatf(STAT_MOVEVARS_TICRATE) * getstatf(STAT_MOVEVARS_TIMESCALE);
+               time = serverprevtime + serverdeltatime;
+       }
+ #ifdef DP_CSQC_ENTITY_REMOVE_IS_B0RKED
+       if(self.enttype)
+       {
+               if(t != self.enttype || bIsNewEntity)
+               {
+                       //print("A CSQC entity changed its type!\n");
+                       printf("A CSQC entity changed its type! (edict: %d, server: %d, type: %d -> %d)\n", num_for_edict(self), self.entnum, self.enttype, t);
+                       Ent_Remove();
+                       clearentity(self);
+                       bIsNewEntity = 1;
+               }
+       }
+       else
+       {
+               if(!bIsNewEntity)
+               {
+                       printf("A CSQC entity appeared out of nowhere! (edict: %d, server: %d, type: %d)\n", num_for_edict(self), self.entnum, t);
+                       bIsNewEntity = 1;
+               }
+       }
+ #endif
+       self.enttype = t;
+       switch(t)
+       {
+               case ENT_CLIENT_ENTCS: Ent_ReadEntCS(); break;
+               case ENT_CLIENT_SCORES: Ent_ReadPlayerScore(); break;
+               case ENT_CLIENT_TEAMSCORES: Ent_ReadTeamScore(); break;
+               case ENT_CLIENT_POINTPARTICLES: Ent_PointParticles(); break;
+               case ENT_CLIENT_RAINSNOW: Ent_RainOrSnow(); break;
+               case ENT_CLIENT_LASER: Ent_Laser(); break;
+               case ENT_CLIENT_NAGGER: Ent_Nagger(); break;
+               case ENT_CLIENT_ELIMINATEDPLAYERS: Ent_EliminatedPlayers(); break;
+               case ENT_CLIENT_WAYPOINT: Ent_WaypointSprite(); break;
+               case ENT_CLIENT_RADARLINK: Ent_RadarLink(); break;
+               case ENT_CLIENT_PROJECTILE: Ent_Projectile(); break;
+               case ENT_CLIENT_GIBSPLASH: Ent_GibSplash(bIsNewEntity); break;
+               case ENT_CLIENT_DAMAGEINFO: Ent_DamageInfo(bIsNewEntity); break;
+               case ENT_CLIENT_CASING: Ent_Casing(bIsNewEntity); break;
+               case ENT_CLIENT_INIT: Ent_Init(); break;
+               case ENT_CLIENT_SCORES_INFO: Ent_ScoresInfo(); break;
+               case ENT_CLIENT_MAPVOTE: Ent_MapVote(); break;
+               case ENT_CLIENT_CLIENTDATA: Ent_ClientData(); break;
+               case ENT_CLIENT_RANDOMSEED: Ent_RandomSeed(); break;
+               case ENT_CLIENT_WALL: Ent_Wall(); break;
+               case ENT_CLIENT_MODELEFFECT: Ent_ModelEffect(bIsNewEntity); break;
+               case ENT_CLIENT_TUBANOTE: Ent_TubaNote(bIsNewEntity); break;
+               case ENT_CLIENT_WARPZONE: WarpZone_Read(bIsNewEntity); break;
+               case ENT_CLIENT_WARPZONE_CAMERA: WarpZone_Camera_Read(bIsNewEntity); break;
+               case ENT_CLIENT_WARPZONE_TELEPORTED: WarpZone_Teleported_Read(bIsNewEntity); break;
+               case ENT_CLIENT_TRIGGER_MUSIC: Ent_ReadTriggerMusic(); break;
+               case ENT_CLIENT_HOOK: Ent_ReadHook(bIsNewEntity, ENT_CLIENT_HOOK); break;
+               case ENT_CLIENT_ARC_BEAM: Ent_ReadArcBeam(bIsNewEntity); break;
+               case ENT_CLIENT_ACCURACY: Ent_ReadAccuracy(); break;
+               case ENT_CLIENT_AUXILIARYXHAIR: Net_AuXair2(bIsNewEntity); break;
+               case ENT_CLIENT_TURRET: ent_turret(); break;
+               case ENT_CLIENT_MODEL: CSQCModel_Read(bIsNewEntity); break;
+               case ENT_CLIENT_ITEM: ItemRead(bIsNewEntity); break;
+               case ENT_CLIENT_BUMBLE_RAYGUN: bumble_raygun_read(bIsNewEntity); break;
+               case ENT_CLIENT_SPAWNPOINT: Ent_ReadSpawnPoint(bIsNewEntity); break;
+               case ENT_CLIENT_SPAWNEVENT: Ent_ReadSpawnEvent(bIsNewEntity); break;
+               case ENT_CLIENT_NOTIFICATION: Read_Notification(bIsNewEntity); break;
+               case ENT_CLIENT_HEALING_ORB: ent_healer(); break;
+               default:
+                       //error(strcat(_("unknown entity type in CSQC_Ent_Update: %d\n"), self.enttype));
+                       error(sprintf("Unknown entity type in CSQC_Ent_Update (enttype: %d, edict: %d, classname: %s)\n", self.enttype, num_for_edict(self), self.classname));
+                       break;
+       }
+       time = savetime;
+ }
+ // Destructor, but does NOT deallocate the entity by calling remove(). Also
+ // used when an entity changes its type. For an entity that someone interacts
+ // with others, make sure it can no longer do so.
+ void Ent_Remove()
+ {
+       if(self.entremove)
+               self.entremove();
+       if(self.skeletonindex)
+       {
+               skel_delete(self.skeletonindex);
+               self.skeletonindex = 0;
+       }
+       if(self.snd_looping > 0)
+       {
+               sound(self, self.snd_looping, "misc/null.wav", VOL_BASE, autocvar_g_jetpack_attenuation);
+               self.snd_looping = 0;
+       }
+       self.enttype = 0;
+       self.classname = "";
+       self.draw = menu_sub_null;
+       self.entremove = menu_sub_null;
+       // TODO possibly set more stuff to defaults
+ }
+ // CSQC_Ent_Remove : Called when the server requests a SSQC / CSQC entity to be removed.  Essentially call remove(self) as well.
+ void CSQC_Ent_Remove()
+ {
+       if(autocvar_developer_csqcentities)
+               printf("CSQC_Ent_Remove() with self=%i self.entnum=%d self.enttype=%d\n", self, self.entnum, self.enttype);
+       if(wasfreed(self))
+       {
+               print("WARNING: CSQC_Ent_Remove called for already removed entity. Packet loss?\n");
+               return;
+       }
+       if(self.enttype)
+               Ent_Remove();
+       remove(self);
+ }
+ void Gamemode_Init()
+ {
+       if (!isdemo())
+       {
+               if(!(calledhooks & HOOK_START))
+                       localcmd("\n_cl_hook_gamestart ", MapInfo_Type_ToString(gametype), "\n");
+               calledhooks |= HOOK_START;
+       }
+ }
+ // CSQC_Parse_StuffCmd : Provides the stuffcmd string in the first parameter that the server provided.  To execute standard behavior, simply execute localcmd with the string.
+ void CSQC_Parse_StuffCmd(string strMessage)
+ {
+       if(autocvar_developer_csqcentities)
+               printf("CSQC_Parse_StuffCmd(\"%s\")\n", strMessage);
+       localcmd(strMessage);
+ }
+ // CSQC_Parse_Print : Provides the print string in the first parameter that the server provided.  To execute standard behavior, simply execute print with the string.
+ void CSQC_Parse_Print(string strMessage)
+ {
+       if(autocvar_developer_csqcentities)
+               printf("CSQC_Parse_Print(\"%s\")\n", strMessage);
+       print(ColorTranslateRGB(strMessage));
+ }
+ // CSQC_Parse_CenterPrint : Provides the centerprint_hud string in the first parameter that the server provided.
+ void CSQC_Parse_CenterPrint(string strMessage)
+ {
+       if(autocvar_developer_csqcentities)
+               printf("CSQC_Parse_CenterPrint(\"%s\")\n", strMessage);
+       centerprint_hud(strMessage);
+ }
+ string notranslate_fogcmd1 = "\nfog ";
+ string notranslate_fogcmd2 = "\nr_fog_exp2 0\nr_drawfog 1\n";
+ void Fog_Force()
+ {
+       // TODO somehow thwart prvm_globalset client ...
+       if(autocvar_cl_orthoview && autocvar_cl_orthoview_nofog)
+               { localcmd("\nr_drawfog 0\n"); }
+       else if(forcefog != "")
+               { localcmd(strcat(notranslate_fogcmd1, forcefog, notranslate_fogcmd2)); }
+ }
+ void Gamemode_Init();
+ void Ent_ScoresInfo()
+ {
+     int i;
+       self.classname = "ent_client_scores_info";
+       gametype = ReadInt24_t();
+       HUD_ModIcons_SetFunc();
+       for(i = 0; i < MAX_SCORE; ++i)
+       {
+               if(scores_label[i])
+                       strunzone(scores_label[i]);
+               scores_label[i] = strzone(ReadString());
+               scores_flags[i] = ReadByte();
+       }
+       for(i = 0; i < MAX_TEAMSCORE; ++i)
+       {
+               if(teamscores_label[i])
+                       strunzone(teamscores_label[i]);
+               teamscores_label[i] = strzone(ReadString());
+               teamscores_flags[i] = ReadByte();
+       }
+       HUD_InitScores();
+       Gamemode_Init();
+ }
+ void Ent_Init()
+ {
+       self.classname = "ent_client_init";
+       nb_pb_period = ReadByte() / 32; //Accuracy of 1/32th
+       hook_shotorigin[0] = decompressShotOrigin(ReadInt24_t());
+       hook_shotorigin[1] = decompressShotOrigin(ReadInt24_t());
+       hook_shotorigin[2] = decompressShotOrigin(ReadInt24_t());
+       hook_shotorigin[3] = decompressShotOrigin(ReadInt24_t());
+       arc_shotorigin[0] = decompressShotOrigin(ReadInt24_t());
+       arc_shotorigin[1] = decompressShotOrigin(ReadInt24_t());
+       arc_shotorigin[2] = decompressShotOrigin(ReadInt24_t());
+       arc_shotorigin[3] = decompressShotOrigin(ReadInt24_t());
+       if(forcefog)
+               strunzone(forcefog);
+       forcefog = strzone(ReadString());
+       armorblockpercent = ReadByte() / 255.0;
+       g_balance_mortar_bouncefactor = ReadCoord();
+       g_balance_mortar_bouncestop = ReadCoord();
+       g_balance_electro_secondary_bouncefactor = ReadCoord();
+       g_balance_electro_secondary_bouncestop = ReadCoord();
+       vortex_scope = !ReadByte();
+       rifle_scope = !ReadByte();
+       serverflags = ReadByte();
+       minelayer_maxmines = ReadByte();
+       hagar_maxrockets = ReadByte();
+       g_trueaim_minrange = ReadCoord();
+       g_balance_porto_secondary = ReadByte();
+       if(!postinit)
+               PostInit();
+ }
+ void Net_ReadRace()
+ {
+       float b;
+       b = ReadByte();
+       switch(b)
+       {
+               case RACE_NET_CHECKPOINT_HIT_QUALIFYING:
+                       race_checkpoint = ReadByte();
+                       race_time = ReadInt24_t();
+                       race_previousbesttime = ReadInt24_t();
+                       if(race_previousbestname)
+                               strunzone(race_previousbestname);
+                       race_previousbestname = strzone(ColorTranslateRGB(ReadString()));
+                       race_checkpointtime = time;
+                       if(race_checkpoint == 0 || race_checkpoint == 254)
+                       {
+                               race_penaltyaccumulator = 0;
+                               race_laptime = time; // valid
+                       }
+                       break;
+               case RACE_NET_CHECKPOINT_CLEAR:
+                       race_laptime = 0;
+                       race_checkpointtime = 0;
+                       break;
+               case RACE_NET_CHECKPOINT_NEXT_SPEC_QUALIFYING:
+                       race_laptime = ReadCoord();
+                       race_checkpointtime = -99999;
+                       // fall through
+               case RACE_NET_CHECKPOINT_NEXT_QUALIFYING:
+                       race_nextcheckpoint = ReadByte();
+                       race_nextbesttime = ReadInt24_t();
+                       if(race_nextbestname)
+                               strunzone(race_nextbestname);
+                       race_nextbestname = strzone(ColorTranslateRGB(ReadString()));
+                       break;
+               case RACE_NET_CHECKPOINT_HIT_RACE:
+                       race_mycheckpoint = ReadByte();
+                       race_mycheckpointtime = time;
+                       race_mycheckpointdelta = ReadInt24_t();
+                       race_mycheckpointlapsdelta = ReadByte();
+                       if(race_mycheckpointlapsdelta >= 128)
+                               race_mycheckpointlapsdelta -= 256;
+                       if(race_mycheckpointenemy)
+                               strunzone(race_mycheckpointenemy);
+                       race_mycheckpointenemy = strzone(ColorTranslateRGB(ReadString()));
+                       break;
+               case RACE_NET_CHECKPOINT_HIT_RACE_BY_OPPONENT:
+                       race_othercheckpoint = ReadByte();
+                       race_othercheckpointtime = time;
+                       race_othercheckpointdelta = ReadInt24_t();
+                       race_othercheckpointlapsdelta = ReadByte();
+                       if(race_othercheckpointlapsdelta >= 128)
+                               race_othercheckpointlapsdelta -= 256;
+                       if(race_othercheckpointenemy)
+                               strunzone(race_othercheckpointenemy);
+                       race_othercheckpointenemy = strzone(ColorTranslateRGB(ReadString()));
+                       break;
+               case RACE_NET_PENALTY_RACE:
+                       race_penaltyeventtime = time;
+                       race_penaltytime = ReadShort();
+                       //race_penaltyaccumulator += race_penaltytime;
+                       if(race_penaltyreason)
+                               strunzone(race_penaltyreason);
+                       race_penaltyreason = strzone(ReadString());
+                       break;
+               case RACE_NET_PENALTY_QUALIFYING:
+                       race_penaltyeventtime = time;
+                       race_penaltytime = ReadShort();
+                       race_penaltyaccumulator += race_penaltytime;
+                       if(race_penaltyreason)
+                               strunzone(race_penaltyreason);
+                       race_penaltyreason = strzone(ReadString());
+                       break;
+               case RACE_NET_SERVER_RECORD:
+                       race_server_record = ReadInt24_t();
+                       break;
+               case RACE_NET_SPEED_AWARD:
+                       race_speedaward = ReadInt24_t();
+                       if(race_speedaward_holder)
+                               strunzone(race_speedaward_holder);
+                       race_speedaward_holder = strzone(ReadString());
+                       break;
+               case RACE_NET_SPEED_AWARD_BEST:
+                       race_speedaward_alltimebest = ReadInt24_t();
+                       if(race_speedaward_alltimebest_holder)
+                               strunzone(race_speedaward_alltimebest_holder);
+                       race_speedaward_alltimebest_holder = strzone(ReadString());
+                       break;
+               case RACE_NET_SERVER_RANKINGS:
+                       float prevpos, del;
+             int pos = ReadShort();
+                       prevpos = ReadShort();
+                       del = ReadShort();
+                       // move other rankings out of the way
+             int i;
+                       if (prevpos) {
+                               for (i=prevpos-1;i>pos-1;--i) {
+                                       grecordtime[i] = grecordtime[i-1];
+                                       if(grecordholder[i])
+                                               strunzone(grecordholder[i]);
+                                       grecordholder[i] = strzone(grecordholder[i-1]);
+                               }
+                       } else if (del) { // a record has been deleted by the admin
+                               for (i=pos-1; i<= RANKINGS_CNT-1; ++i) {
+                                       if (i == RANKINGS_CNT-1) { // clear out last record
+                                               grecordtime[i] = 0;
+                                               if (grecordholder[i])
+                                                       strunzone(grecordholder[i]);
+                                               grecordholder[i] = string_null;
+                                       }
+                                       else {
+                                               grecordtime[i] = grecordtime[i+1];
+                                               if (grecordholder[i])
+                                                       strunzone(grecordholder[i]);
+                                               grecordholder[i] = strzone(grecordholder[i+1]);
+                                       }
+                               }
+                       } else { // player has no ranked record yet
+                               for (i=RANKINGS_CNT-1;i>pos-1;--i) {
+                                       grecordtime[i] = grecordtime[i-1];
+                                       if(grecordholder[i])
+                                               strunzone(grecordholder[i]);
+                                       grecordholder[i] = strzone(grecordholder[i-1]);
+                               }
+                       }
+                       // store new ranking
+                       if(grecordholder[pos-1] != "")
+                               strunzone(grecordholder[pos-1]);
+                       grecordholder[pos-1] = strzone(ReadString());
+                       grecordtime[pos-1] = ReadInt24_t();
+                       if(grecordholder[pos-1] == GetPlayerName(player_localnum))
+                               race_myrank = pos;
+                       break;
+               case RACE_NET_SERVER_STATUS:
+                       race_status = ReadShort();
+                       if(race_status_name)
+                               strunzone(race_status_name);
+                       race_status_name = strzone(ReadString());
+       }
+ }
+ void Net_TeamNagger()
+ {
+       teamnagger = 1;
+ }
+ void Net_ReadPingPLReport()
+ {
+       int e, pi, pl, ml;
+       e = ReadByte();
+       pi = ReadShort();
+       pl = ReadByte();
+       ml = ReadByte();
+       if (!(playerslots[e]))
+               return;
+       playerslots[e].ping = pi;
+       playerslots[e].ping_packetloss = pl / 255.0;
+       playerslots[e].ping_movementloss = ml / 255.0;
+ }
+ void Net_WeaponComplain()
+ {
+       complain_weapon = ReadByte();
+       if(complain_weapon_name)
+               strunzone(complain_weapon_name);
+       complain_weapon_name = strzone(WEP_NAME(complain_weapon));
+       complain_weapon_type = ReadByte();
+       complain_weapon_time = time;
+       weapontime = time; // ping the weapon panel
+       switch(complain_weapon_type)
+       {
+               case 0: Local_Notification(MSG_MULTI, ITEM_WEAPON_NOAMMO, complain_weapon); break;
+               case 1: Local_Notification(MSG_MULTI, ITEM_WEAPON_DONTHAVE, complain_weapon); break;
+               default: Local_Notification(MSG_MULTI, ITEM_WEAPON_UNAVAILABLE, complain_weapon); break;
+       }
+ }
+ // CSQC_Parse_TempEntity : Handles all temporary entity network data in the CSQC layer.
+ // You must ALWAYS first acquire the temporary ID, which is sent as a byte.
+ // Return value should be 1 if CSQC handled the temporary entity, otherwise return 0 to have the engine process the event.
+ float CSQC_Parse_TempEntity()
+ {
+       float bHandled;
+               bHandled  = true;
+       // Acquire TE ID
+       float nTEID;
+               nTEID = ReadByte();
+       if(autocvar_developer_csqcentities)
+               printf("CSQC_Parse_TempEntity() with nTEID=%d\n", nTEID);
+               // NOTE: Could just do return instead of break...
+       switch(nTEID)
+       {
+               case TE_CSQC_TARGET_MUSIC:
+                       Net_TargetMusic();
+                       bHandled = true;
+                       break;
+               case TE_CSQC_PICTURE:
+                       Net_MapVote_Picture();
+                       bHandled = true;
+                       break;
+               case TE_CSQC_RACE:
+                       Net_ReadRace();
+                       bHandled = true;
+                       break;
+               case TE_CSQC_VORTEXBEAMPARTICLE:
+                       Net_ReadVortexBeamParticle();
+                       bHandled = true;
+                       break;
+               case TE_CSQC_TEAMNAGGER:
+                       Net_TeamNagger();
+                       bHandled = true;
+                       break;
+               case TE_CSQC_ARC:
+                       Net_ReadArc();
+                       bHandled = true;
+                       break;
+               case TE_CSQC_PINGPLREPORT:
+                       Net_ReadPingPLReport();
+                       bHandled = true;
+                       break;
+               case TE_CSQC_WEAPONCOMPLAIN:
+                       Net_WeaponComplain();
+                       bHandled = true;
+                       break;
+               case TE_CSQC_VEHICLESETUP:
+                       Net_VehicleSetup();
+                       bHandled = true;
+                       break;
+               case TE_CSQC_SVNOTICE:
+                       cl_notice_read();
+                       bHandled = true;
+                       break;
+               case TE_CSQC_SHOCKWAVEPARTICLE:
+                       Net_ReadShockwaveParticle();
+                       bHandled = true;
+                       break;
+               default:
+                       // No special logic for this temporary entity; return 0 so the engine can handle it
+                       bHandled = false;
+                       break;
+       }
+       return bHandled;
+ }
+ string getcommandkey(string text, string command)
+ {
+       string keys;
+       float n, j, k, l = 0;
+       if (!autocvar_hud_showbinds)
+               return text;
+       keys = db_get(binddb, command);
+       if (keys == "")
+       {
+               n = tokenize(findkeysforcommand(command, 0)); // uses '...' strings
+               for(j = 0; j < n; ++j)
+               {
+                       k = stof(argv(j));
+                       if(k != -1)
+                       {
+                               if ("" == keys)
+                                       keys = keynumtostring(k);
+                               else
+                                       keys = strcat(keys, ", ", keynumtostring(k));
+                               ++l;
+                               if (autocvar_hud_showbinds_limit > 0 && autocvar_hud_showbinds_limit <= l)
+                                       break;
+                       }
+               }
+               if (keys == "")
+                       keys = "NO_KEY";
+               db_put(binddb, command, keys);
+       }
+       if (keys == "NO_KEY") {
+               if (autocvar_hud_showbinds > 1)
+                       return sprintf(_("%s (not bound)"), text);
+               else
+                       return text;
+       }
+       else if (autocvar_hud_showbinds > 1)
+               return sprintf("%s (%s)", text, keys);
+       else
+               return keys;
+ }
index d14edd5d3625d08a5c185beafaad2e8c56473fe7,f80da18d67309ace7482be0dd4ac37ac784cd1c0..cdd0b09d1fbade0c6fe08e79b7053add507da7e3
  ../../csprogs.dat
  
  ../common/util-pre.qh
- sys-pre.qh
- ../dpdefs/csprogsdefs.qc
- sys-post.qh
+ ../dpdefs/csprogsdefs.qh
  
- Defs.qc
- ../dpdefs/keycodes.qc
- ../common/constants.qh
- ../common/stats.qh
- ../warpzonelib/anglestransform.qh
- ../warpzonelib/mathlib.qh
- ../warpzonelib/common.qh
- ../warpzonelib/client.qh
- ../common/playerstats.qh
- ../common/teams.qh
- ../common/util.qh
- ../common/nades.qh
- ../common/buffs.qh
- ../common/test.qh
- ../common/counting.qh
- ../common/weapons/weapons.qh // TODO
- ../common/mapinfo.qh
- ../common/command/markup.qh
- ../common/command/rpn.qh
- ../common/command/generic.qh
- ../common/command/shared_defs.qh
- ../common/urllib.qh
- ../common/animdecide.qh
- command/cl_cmd.qh
- ../common/monsters/monsters.qh
- autocvars.qh
- ../common/notifications.qh // must be after autocvars
- ../common/deathtypes.qh // must be after notifications
- ../common/turrets/turrets.qh
- ../common/turrets/cl_turrets.qh
- damage.qh
- ../csqcmodellib/interpolate.qh
- teamradar.qh
- hud.qh
- scoreboard.qh
- waypointsprites.qh
- movetypes.qh
- prandom.qh
- bgmscript.qh
- noise.qh
- ../server/movelib.qc
- main.qh
- vehicles/vehicles.qh
- ../common/csqcmodel_settings.qh
- ../csqcmodellib/common.qh
- ../csqcmodellib/cl_model.qh
- ../csqcmodellib/cl_player.qh
- weapons/projectile.qh // TODO
- player_skeleton.qh
- sortlist.qc
- miscfunctions.qc
- ../server/t_items.qh
- ../server/t_items.qc
- teamradar.qc
- hud_config.qc
- hud.qc
- scoreboard.qc
- mapvoting.qc
+ announcer.qc
+ bgmscript.qc
+ casings.qc
  csqcmodel_hooks.qc
- ../common/net_notice.qc
- rubble.qc
- hook.qc
- particles.qc
- laser.qc
- weapons/projectile.qc // TODO
- gibs.qc
  damage.qc
- casings.qc
- ../csqcmodellib/cl_model.qc
- ../csqcmodellib/cl_player.qc
  effects.qc
- wall.qc
+ gibs.qc
+ hook.qc
+ hud_config.qc
+ hud.qc
+ laser.qc
+ main.qc
+ mapvoting.qc
+ miscfunctions.qc
  modeleffects.qc
- tuba.qc
+ movetypes.qc
+ noise.qc
+ particles.qc
+ player_skeleton.qc
+ prandom.qc
+ rubble.qc
+ scoreboard.qc
+ shownames.qc
+ sortlist.qc
  target_music.qc
+ teamradar.qc
 -tturrets.qc
+ tuba.qc
  vehicles/vehicles.qc
- ../server/vehicles/bumblebee.qc
- shownames.qh
- shownames.qc
- announcer.qc
- Main.qc
- View.qc
- ../csqcmodellib/interpolate.qc
+ view.qc
+ wall.qc
  waypointsprites.qc
- movetypes.qc
- prandom.qc
- bgmscript.qc
- noise.qc
  
+ command/cl_cmd.qc
+ weapons/projectile.qc // TODO
+ ../common/animdecide.qc
+ ../common/buffs.qc
+ ../common/mapinfo.qc
+ ../common/nades.qc
+ ../common/net_notice.qc
+ ../common/notifications.qc
+ ../common/playerstats.qc
  ../common/test.qc
+ ../common/urllib.qc
  ../common/util.qc
- ../common/playerstats.qc
- ../common/notifications.qc
+ ../common/command/generic.qc
  ../common/command/markup.qc
  ../common/command/rpn.qc
- ../common/command/generic.qc
- ../common/mapinfo.qc
- ../common/weapons/weapons.qc // TODO
- ../common/urllib.qc
- command/cl_cmd.qc
  
  ../common/monsters/monsters.qc
  
- ../common/nades.qc
- ../common/buffs.qc
++../common/turrets/cl_turrets.qc
++../common/turrets/turrets.qc
++
+ ../common/weapons/weapons.qc // TODO
+ ../csqcmodellib/cl_model.qc
+ ../csqcmodellib/cl_player.qc
+ ../csqcmodellib/interpolate.qc
+ ../server/movelib.qc
+ ../server/t_items.qc
+ ../server/vehicles/bumblebee.qc
  
  ../warpzonelib/anglestransform.qc
- ../warpzonelib/mathlib.qc
- ../warpzonelib/common.qc
  ../warpzonelib/client.qc
- ../common/turrets/cl_turrets.qc
- ../common/turrets/turrets.qc
- player_skeleton.qc
- ../common/animdecide.qc
 +
+ ../warpzonelib/common.qc
+ ../warpzonelib/mathlib.qc
diff --cc qcsrc/client/tturrets.qc
index ba640068ef82e7db0495d4b23d0a06850da215de,d2469851ca53f21c813d5bd629b01833f57f1847..0000000000000000000000000000000000000000
deleted file mode 100644,100644
+++ /dev/null
@@@ -1,685 -1,687 +1,0 @@@
 -#include "tturrets.qh"
 -#include "waypointsprites.qh"
 -
 -#include "../server/movelib.qh"
 -
--string tid2info_base;
--string tid2info_head;
--string tid2info_name;
--vector  tid2info_min;
--vector  tid2info_max;
--
--void turret_tid2info(float _tid);
--void turret_precache(float _tid);
--float turret_is_precache[TID_LAST];
--
--void turrets_precache()
--{
--    turret_precache(TID_COMMON);
--}
--
- void turret_precache(float _tid)
 -void turret_precache(int _tid)
--{
--    if (!turret_is_precache[TID_COMMON])
--    {
--        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/terrainbase.md3");
--        precache_model ("models/turrets/base.md3");
--        precache_model ("models/turrets/rocket.md3");
--    }
--    turret_tid2info(_tid);
--    if(turret_is_precache[_tid])
--        return;
--
--    switch(_tid)
--    {
--        case TID_EWHEEL:
--            precache_model ("models/turrets/ewheel-base2.md3");
--            precache_model ("models/turrets/ewheel-gun1.md3");
--            break;
--        case TID_FLAC:
--            precache_model ("models/turrets/flac.md3");
--            break;
--        case TID_FUSION:
--            precache_model ("models/turrets/reactor.md3");
--            break;
--        case TID_HELLION:
--            precache_model ("models/turrets/hellion.md3");
--            break;
--        case TID_HK:
--            precache_model ("models/turrets/hk.md3");
--            break;
--        case TID_MACHINEGUN:
--            precache_model ("models/turrets/machinegun.md3");
--            precache_sound ("weapons/uzi_fire.wav");
--            break;
--        case TID_MLRS:
--            precache_model ("models/turrets/mlrs.md3");
--            break;
--        case TID_PHASER:
--            precache_model ("models/turrets/phaser.md3");
--            precache_model ("models/turrets/phaser_beam.md3");
--            precache_sound ("turrets/phaser.wav");
--            break;
--        case TID_PLASMA:
--            precache_model ("models/turrets/plasma.md3");
--            break;
--        case TID_PLASMA_DUAL:
--            precache_model ("models/turrets/plasmad.md3");
--            break;
--        case TID_TESLA:
--            precache_model ("models/turrets/tesla_head.md3");
--            precache_model ("models/turrets/tesla_base.md3");
--            break;
--        case TID_WALKER:
--            precache_model ("models/turrets/walker_head_minigun.md3");
--            precache_model ("models/turrets/walker_body.md3");
--            precache_sound ("weapons/uzi_fire.wav");
--            break;
--    }
-     turret_is_precache[_tid] = TRUE;
 -    turret_is_precache[_tid] = true;
--}
--
--void turret_tid2info(float _tid)
--{
--    tid2info_base = "models/turrets/base.md3";
--    tid2info_min = '-32 -32 0';
--    tid2info_max = '32 32 64';
--
--    switch(_tid)
--    {
--        case TID_EWHEEL:
--            tid2info_base = "models/turrets/ewheel-base2.md3";
--            tid2info_head = "models/turrets/ewheel-gun1.md3";
--            tid2info_name = "eWheel";
--            break;
--        case TID_FLAC:
--            tid2info_head = "models/turrets/flac.md3";
--            tid2info_name = "Flac Cannon";
--            break;
--        case TID_FUSION:
--            tid2info_head = "models/turrets/reactor.md3";
--            tid2info_name = "Fusion Reactor";
--            tid2info_min = '-34 -34 0';
--            tid2info_max = '34 34 90';
--            break;
--        case TID_HELLION:
--            tid2info_head = "models/turrets/hellion.md3";
--            tid2info_name = "Hellion";
--            break;
--        case TID_HK:
--            tid2info_head = "models/turrets/hk.md3";
--            tid2info_name = "Hunter-Killer";
--            break;
--        case TID_MACHINEGUN:
--            tid2info_head = "models/turrets/machinegun.md3";
--            tid2info_name = "Machinegun";
--            break;
--        case TID_MLRS:
--            tid2info_head = "models/turrets/mlrs.md3";
--            tid2info_name = "MLRS";
--            break;
--        case TID_PHASER:
--            tid2info_head = "models/turrets/phaser.md3";
--            tid2info_name = "Phaser";
--            break;
--        case TID_PLASMA:
--            tid2info_head = "models/turrets/plasma.md3";
--            tid2info_name = "Plasma";
--            break;
--        case TID_PLASMA_DUAL:
--            tid2info_head = "models/turrets/plasmad.md3";
--            tid2info_name = "Dual Plasma";
--            break;
--        case TID_TESLA:
--            tid2info_base = "models/turrets/tesla_base.md3";
--            tid2info_head = "models/turrets/tesla_head.md3";
--            tid2info_name = "Tesla coil";
--            tid2info_min = '-60 -60 0';
--            tid2info_max  ='60 60 128';
--            break;
--        case TID_WALKER:
--            tid2info_base = "models/turrets/walker_body.md3";
--            tid2info_head = "models/turrets/walker_head_minigun.md3";
--            tid2info_name = "Walker";
--            tid2info_min = '-70 -70 0';
--            tid2info_max = '70 70 95';
--            break;
--    }
--}
--
--void turret_remove()
--{
--    remove(self.tur_head);
--    //remove(self.enemy);
--    self.tur_head = world;
--}
--
--.vector glowmod;
--void turret_changeteam()
--{
--      switch(self.team - 1)
--      {
--        case NUM_TEAM_1: // Red
--            self.glowmod = '2 0 0';
--            self.teamradar_color = '1 0 0';
--            break;
--
--        case NUM_TEAM_2: // Blue
--            self.glowmod = '0 0 2';
--            self.teamradar_color = '0 0 1';
--            break;
--
--        case NUM_TEAM_3: // Yellow
--            self.glowmod = '1 1 0';
--            self.teamradar_color = '1 1 0';
--            break;
--
--        case NUM_TEAM_4: // Pink
--            self.glowmod = '1 0 1';
--            self.teamradar_color = '1 0 1';
--            break;
--      }
--
--      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)))
 -        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;
 -        o.z = 0;
--        if(hud != HUD_NORMAL)
--        {
--            switch(hud)
--            {
--                case HUD_SPIDERBOT:
--                case HUD_WAKIZASHI:
--                case HUD_RAPTOR:
--                case HUD_BUMBLEBEE:
--                    if(self.turret_type == TID_EWHEEL || self.turret_type == TID_WALKER)
--                        txt = "gfx/vehicles/vth-mover.tga";
--                    else
--                        txt = "gfx/vehicles/vth-stationary.tga";
--
--                    vector pz = drawgetimagesize(txt) * 0.25;
--                    drawpic(o - pz * 0.5, txt, pz , '1 1 1', 0.75, DRAWFLAG_NORMAL);
--                    break;
--            }
--        }
--      }
--
--      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)))
 -      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;
 -      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);
 -              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) );
 -      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_walker_draw()
--{
--    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;
 -    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);
--}
--
--void turret_ewheel_draw()
--{
--    float dt;
--
--    dt = time - self.move_time;
--    self.move_time = time;
--    if(dt <= 0)
--        return;
--
--    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;
 -    self.angles_y = self.move_angles.y;
--
--    if (self.health < 127)
--    if(random() < 0.05)
--        te_spark(self.origin + '0 0 40', randomvec() * 256 + '0 0 256', 16);
--}
--
- void(entity e, entity tagentity, string tagname) setattachment = #443;
--void turret_construct()
--{
--    if(self.tur_head == world)
--        self.tur_head = spawn();
--
--    turret_tid2info(self.turret_type);
--    self.netname = tid2info_name;
--
--    setorigin(self, self.origin);
--    setmodel(self, tid2info_base);
--    setmodel(self.tur_head, tid2info_head);
--    setsize(self, tid2info_min, tid2info_max);
--    setsize(self.tur_head, '0 0 0', '0 0 0');
--
--    if(self.turret_type == TID_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;
--
--    if(self.turret_type == TID_EWHEEL || self.turret_type == TID_WALKER)
--    {
--        self.gravity            = 1;
--        self.movetype           = MOVETYPE_BOUNCE;
--        self.move_movetype      = MOVETYPE_BOUNCE;
--        self.move_origin        = self.origin;
--        self.move_time          = time;
--        switch(self.turret_type)
--        {
--            case TID_EWHEEL:
--                self.draw               = turret_ewheel_draw;
--                break;
--            case TID_WALKER:
--                self.draw               = turret_walker_draw;
--                break;
--
--        }
--    }
--}
--
--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);
 -        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);
--    turret_tid2info(self.turret_type);
--    if (!autocvar_cl_nogibs)
--    {
--        // Base
--        if(self.turret_type == TID_EWHEEL)
-             turret_gibtoss(tid2info_base, self.origin + '0 0 18', self.velocity + '0 0 400' + '0.1 0.1 1' * (random() * 400), '-1 -1 -1', TRUE);
 -            turret_gibtoss(tid2info_base, self.origin + '0 0 18', self.velocity + '0 0 400' + '0.1 0.1 1' * (random() * 400), '-1 -1 -1', true);
--        else if (self.turret_type == TID_WALKER)
-             turret_gibtoss(tid2info_base, self.origin + '0 0 18', self.velocity + '0 0 300' + '0.1 0.1 1' * (random() * 200), '-1 -1 -1', TRUE);
 -            turret_gibtoss(tid2info_base, self.origin + '0 0 18', self.velocity + '0 0 300' + '0.1 0.1 1' * (random() * 200), '-1 -1 -1', true);
--        else if (self.turret_type == TID_TESLA)
-             turret_gibtoss(tid2info_base, self.origin + '0 0 18', '0 0 200', '-1 -1 -1', FALSE);
 -            turret_gibtoss(tid2info_base, 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);
 -                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);
 -                turret_gibtoss("models/turrets/base-gib1.md3", self.origin + '0 0 8', '0 0 0', '0 0 0', true);
--
-             entity headgib = turret_gibtoss(tid2info_head, self.origin + '0 0 32', '0 0 200' + randomvec() * 200, '-1 -1 -1', TRUE);
 -            entity headgib = turret_gibtoss(tid2info_head, 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.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();
 -    int sf = ReadByte();
--
--      if(sf & TNSF_SETUP)
--      {
--          self.turret_type = 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_precache(self.turret_type);
--          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();
 -        int _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 2438c0173623c892ddfad2c75f54a0aadf237fa8,7f302e0a27e3e25eff4a196eca39d71bfd7179f5..460410c289a91ca97fb0f49a5024202409f25f0a
@@@ -1,3 -1,6 +1,7 @@@
+ #include "generic.qh"
+ #include "shared_defs.qh"
++#include "../turrets/config.qh"
  // =========================================================
  //  Generic program common command code, written by Samual
  //  Last updated: February 19th, 2012
Simple merge
index fd966f5d2edf20499aa7adf681b3aebd2a88fc4a,28430e9617e8a9a6666519a444d39df47303a103..4c443495feae22255bbaa372168611ccaa7b34ad
@@@ -1,3 -1,29 +1,27 @@@
 -    #include "../../server/tturrets/include/turrets_early.qh"
+ #if defined(CSQC)
+ #elif defined(MENUQC)
+ #elif defined(SVQC)
+       #include "../../dpdefs/progsdefs.qh"
+     #include "../../dpdefs/dpextensions.qh"
+     #include "../../warpzonelib/common.qh"
+     #include "../constants.qh"
+     #include "../teams.qh"
+     #include "../util.qh"
+     #include "monsters.qh"
+     #include "sv_monsters.qh"
+     #include "../weapons/weapons.qh"
+     #include "../../server/autocvars.qh"
+     #include "../../server/defs.qh"
+     #include "../deathtypes.qh"
+     #include "../../server/mutators/mutators_include.qh"
 -    #include "../../server/tturrets/include/turrets.qh"
+     #include "../../server/vehicles/vehicles_def.qh"
+     #include "../../server/campaign.qh"
+     #include "../../server/command/common.qh"
+     #include "../../server/command/cmd.qh"
+     #include "../../csqcmodellib/sv_model.qh"
+     #include "../../server/round_handler.qh"
+ #endif
  // =========================
  //    SVQC Monster Properties
  // =========================
index 03b15525cf3b90547e41bc91b8cf0da1000258c6,4225a19f03cb76e98b5afa198312d94f2c575cfc..07a91a8ccdd7432d2fae81e76b85ced184efe8b6
@@@ -1,8 -1,22 +1,21 @@@
- .float healer_lifetime;
- .float healer_radius;
+ #if defined(CSQC)
+       #include "../dpdefs/csprogsdefs.qh"
+       #include "../client/defs.qh"
+       #include "nades.qh"
+       #include "buffs.qh"
+       #include "../client/movetypes.qh"
 -      #include "../server/tturrets/include/turrets_early.qh"
+       #include "../client/main.qh"
+       #include "../csqcmodellib/cl_model.qh"
+ #elif defined(MENUQC)
+ #elif defined(SVQC)
+       #include "../dpdefs/progsdefs.qh"
+     #include "constants.qh"
+     #include "../server/constants.qh"
+ #endif
  
  #ifdef SVQC
- float healer_send(entity to, float sf)
+ float healer_send(entity to, int sf)
  {
        WriteByte(MSG_ENTITY, ENT_CLIENT_HEALING_ORB);
        WriteByte(MSG_ENTITY, sf);
Simple merge
index 3365b92029a82b7a176a516aaaf4675960c39dc5,0000000000000000000000000000000000000000..2f8e77d2d20b7f2bbdb57bbc1cb267fcf48c1f8b
mode 100644,000000..100644
--- /dev/null
@@@ -1,446 -1,0 +1,445 @@@
- void(entity e, entity tagentity, string tagname) setattachment = #443;
 +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-mover.tga";
 +                      else
 +                              txt = "gfx/vehicles/vth-stationary.tga";
 +
 +                      vector pz = drawgetimagesize(txt) * 0.25;
 +                      drawpic(o - pz * 0.5, txt, pz , '1 1 1', 0.75, 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
 +                      );
 +}
 +
-               turret_gibtoss(strcat("models/turrets/head-gib", ftos(i), ".md3"), self.origin + '0 0 2', self.velocity + randomvec() * 700, '0 0 0', FALSE);
 +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((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);
++              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 300' + '0.1 0.1 1' * (random() * 200), '-1 -1 -1', TRUE);
++                      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', '0 0 200', '-1 -1 -1', FALSE);
++                      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("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);
++                      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-gib1.md3", self.origin + '0 0 8', '0 0 0', '0 0 0', TRUE);
++                              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
-                       entity headgib = turret_gibtoss((get_turretinfo(self.turretid)).head_model, self.origin + '0 0 32', '0 0 200' + randomvec() * 200, '-1 -1 -1', TRUE);
++                              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 b61678218725c18e354ad0dbb43281fd7a998489,0000000000000000000000000000000000000000..0f8ff9485117807a5f7e752a54b17eba6e3f3d42
mode 100644,000000..100644
--- /dev/null
@@@ -1,1 -1,0 +1,6 @@@
++#ifndef CL_TURRETS_H
++#define CL_TURRETS_H
++
 +void ent_turret();
++
++#endif
index ad3a0c72fefafc0da3b2c255052aadaafedcbd81,0000000000000000000000000000000000000000..85cbd2006c75e7abedfe63c81fe555788225b1a0
mode 100644,000000..100644
--- /dev/null
@@@ -1,29 -1,0 +1,34 @@@
- // ==========================
- //  Turret Config Generator
- // ==========================
++#ifndef TURRETS_CONFIG_H
++#define TURRETS_CONFIG_H
++
++#ifdef SVQC
 +
 +void Dump_Turret_Settings(void);
 +float tur_config_file;
 +float tur_config_alsoprint;
 +
 +#define MAX_TUR_CONFIG 256
 +float TUR_CONFIG_COUNT;
 +string tur_config_queue[MAX_TUR_CONFIG];
 +
 +#define TUR_CONFIG_QUEUE(a) { \
 +      tur_config_queue[TUR_CONFIG_COUNT] = a; \
 +      ++TUR_CONFIG_COUNT; }
 +
 +#define TUR_CONFIG_WRITETOFILE(a) { \
 +      fputs(tur_config_file, a); \
 +      if(tur_config_alsoprint) { print(a); } }
 +
 +#define TUR_CONFIG_WRITE_CVARS(turret,name) \
 +              { TUR_CONFIG_QUEUE( \
 +                      sprintf("set g_turrets_unit_%s_%s %g\n", #turret, #name, \
 +                      cvar(sprintf("g_turrets_unit_%s_%s", #turret, #name)))) } \
 +
 +#define TUR_CONFIG_SETTINGS(tursettings) \
 +      #define TUR_ADD_CVAR(turret,name) TUR_CONFIG_WRITE_CVARS(turret,name) \
 +      tursettings \
 +      #undef TUR_ADD_CVAR
++
++#endif
++
++#endif
index aca2b8ead796d3d99361517f160a7f0cc47f902f,0000000000000000000000000000000000000000..91d427fd80342a82d4f0a8c32e8e78c03e7b14b0
mode 100644,000000..100644
--- /dev/null
@@@ -1,1396 -1,0 +1,1394 @@@
- // =========================
- //  SVQC Turret Properties
- // =========================
++#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_respawn;
 +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_damage (entity inflictor, entity attacker, float damage, float deathtype, vector hitloc, vector vforce)
 +{
-       // Enougth allready!
++      // 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;
++      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();
 +}
 +
 +void turret_projectile_damage(entity inflictor, entity attacker, float damage, float 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_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_target.vehicle_flags & VHF_ISVEHICLE)
 +      {
 +              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);
++      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 (e.turret_flags & TUR_FLAG_ISTURRET)
 +                      {
 +                              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;
++              return false;
 +
 +      entity e;
 +      entity tur = get_turretinfo(tur_id);
 +      if(tur.turretid == 0)
-               return FALSE; // invalid turret
++              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.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))
-               return FALSE;
++              return false;
 +
-       return TRUE;
++      return true;
 +}
++#endif
index f89ef1581ba8f46866d15bbd8055a706440df33d,0000000000000000000000000000000000000000..c4ff13e91d3b18edbed79544d1cd14ad0d3b67e2
mode 100644,000000..100644
--- /dev/null
@@@ -1,106 -1,0 +1,113 @@@
++#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!
 +
 +/// 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 5491746e9c32dc0728a77d33b8111e22e34ccd63,0000000000000000000000000000000000000000..b3736aff9cbe4d17bc34820cd3be5f494ea4591b
mode 100644,000000..100644
--- /dev/null
@@@ -1,197 -1,0 +1,202 @@@
- entity get_turretinfo(float id);
++#ifndef TURRETS_H
++#define TURRETS_H
++
 +// turret requests
 +#define TR_SETUP          1 // (BOTH) setup turret data
 +#define TR_THINK                2 // (SERVER) logic to run every frame
 +#define TR_DEATH          3 // (SERVER) called when turret dies
 +#define TR_PRECACHE       4 // (BOTH) precaches models/sounds used by this turret
 +#define TR_ATTACK         5 // (SERVER) called when turret attacks
 +#define TR_CONFIG         6 // (ALL)
 +
 +// functions:
- .float target_select_flags;
- .float target_validate_flags;
- const float TFL_TARGETSELECT_NO = 2; // don't automatically find targets
- const float TFL_TARGETSELECT_LOS = 4; // require line of sight to find targets
- const float TFL_TARGETSELECT_PLAYERS = 8; // target players
- const float TFL_TARGETSELECT_MISSILES = 16; // target projectiles
- const float TFL_TARGETSELECT_TRIGGERTARGET = 32; // respond to turret_trigger_target events
- const float TFL_TARGETSELECT_ANGLELIMITS = 64; // apply extra angular limits to target selection
- const float TFL_TARGETSELECT_RANGELIMITS = 128; // limit target selection range
- const float TFL_TARGETSELECT_TEAMCHECK = 256; // don't attack teammates
- const float TFL_TARGETSELECT_NOBUILTIN = 512; // only attack targets when triggered
- const float TFL_TARGETSELECT_OWNTEAM = 1024; // only attack teammates
- const float TFL_TARGETSELECT_NOTURRETS = 2048; // don't attack other turrets
- const float TFL_TARGETSELECT_FOV = 4096; // extra limits to attack range
- const float TFL_TARGETSELECT_MISSILESONLY = 8192; // only attack missiles
++entity get_turretinfo(int id);
 +
 +// fields:
 +.entity tur_head;
 +
 +// target selection flags
- .float aim_flags;
- const float TFL_AIM_NO = 1; // no aiming
- const float TFL_AIM_SPLASH = 2; // aim for ground around the target's feet
- const float TFL_AIM_LEAD = 4; // try to predict target movement
- const float TFL_AIM_SHOTTIMECOMPENSATE = 8; // compensate for shot traveltime when leading
- const float TFL_AIM_ZPREDICT = 16; // predict target's z position at impact
- const float TFL_AIM_SIMPLE = 32; // aim at player's current location
++.int target_select_flags;
++.int target_validate_flags;
++const int TFL_TARGETSELECT_NO = 2; // don't automatically find targets
++const int TFL_TARGETSELECT_LOS = 4; // require line of sight to find targets
++const int TFL_TARGETSELECT_PLAYERS = 8; // target players
++const int TFL_TARGETSELECT_MISSILES = 16; // target projectiles
++const int TFL_TARGETSELECT_TRIGGERTARGET = 32; // respond to turret_trigger_target events
++const int TFL_TARGETSELECT_ANGLELIMITS = 64; // apply extra angular limits to target selection
++const int TFL_TARGETSELECT_RANGELIMITS = 128; // limit target selection range
++const int TFL_TARGETSELECT_TEAMCHECK = 256; // don't attack teammates
++const int TFL_TARGETSELECT_NOBUILTIN = 512; // only attack targets when triggered
++const int TFL_TARGETSELECT_OWNTEAM = 1024; // only attack teammates
++const int TFL_TARGETSELECT_NOTURRETS = 2048; // don't attack other turrets
++const int TFL_TARGETSELECT_FOV = 4096; // extra limits to attack range
++const int TFL_TARGETSELECT_MISSILESONLY = 8192; // only attack missiles
 +
 +// aim flags
- .float track_flags;
- const float TFL_TRACK_NO = 2; // don't move head
- const float TFL_TRACK_PITCH = 4; // pitch head
- const float TFL_TRACK_ROTATE = 8; // rotate head
++.int aim_flags;
++const int TFL_AIM_NO = 1; // no aiming
++const int TFL_AIM_SPLASH = 2; // aim for ground around the target's feet
++const int TFL_AIM_LEAD = 4; // try to predict target movement
++const int TFL_AIM_SHOTTIMECOMPENSATE = 8; // compensate for shot traveltime when leading
++const int TFL_AIM_ZPREDICT = 16; // predict target's z position at impact
++const int TFL_AIM_SIMPLE = 32; // aim at player's current location
 +
 +// tracking flags
- .float firecheck_flags;
- const float TFL_FIRECHECK_DEAD = 4; // don't attack dead targets (zombies?)
- const float TFL_FIRECHECK_DISTANCES = 8; // another range check
- const float TFL_FIRECHECK_LOS = 16; // line of sight
- const float TFL_FIRECHECK_AIMDIST = 32; // consider distance impactpoint<->aimspot
- const float TFL_FIRECHECK_REALDIST = 64; // consider enemy origin<->impactpoint
- const float TFL_FIRECHECK_ANGLEDIST = 128; // consider angular diff head<->aimspot
- const float TFL_FIRECHECK_TEAMCHECK = 256; // don't attack teammates
- const float TFL_FIRECHECK_AFF = 512; // try to avoid any friendly fire
- const float TFL_FIRECHECK_AMMO_OWN = 1024; // own ammo needs to be larger than damage dealt
- const float TFL_FIRECHECK_AMMO_OTHER = 2048; // target's ammo needs to be less than max
- const float TFL_FIRECHECK_REFIRE = 4096; // check single attack finished delays
- const float TFL_FIRECHECK_NO = 16384; // no prefire checks
++.int track_flags;
++const int TFL_TRACK_NO = 2; // don't move head
++const int TFL_TRACK_PITCH = 4; // pitch head
++const int TFL_TRACK_ROTATE = 8; // rotate head
 +
 +// prefire checks
- .float shoot_flags;
- const float TFL_SHOOT_NO = 64; // no attacking
- const float TFL_SHOOT_VOLLY = 2; // fire in vollies
- const float TFL_SHOOT_VOLLYALWAYS = 4; // always do a full volly, even if target is lost
- const float TFL_SHOOT_HITALLVALID = 8; // loop through all valid targets
- const float TFL_SHOOT_CLEARTARGET = 16; // lose target after attack (after volly is done if in volly mode)
- const float TFL_SHOOT_CUSTOM = 32; // custom attacking
++.int firecheck_flags;
++const int TFL_FIRECHECK_DEAD = 4; // don't attack dead targets (zombies?)
++const int TFL_FIRECHECK_DISTANCES = 8; // another range check
++const int TFL_FIRECHECK_LOS = 16; // line of sight
++const int TFL_FIRECHECK_AIMDIST = 32; // consider distance impactpoint<->aimspot
++const int TFL_FIRECHECK_REALDIST = 64; // consider enemy origin<->impactpoint
++const int TFL_FIRECHECK_ANGLEDIST = 128; // consider angular diff head<->aimspot
++const int TFL_FIRECHECK_TEAMCHECK = 256; // don't attack teammates
++const int TFL_FIRECHECK_AFF = 512; // try to avoid any friendly fire
++const int TFL_FIRECHECK_AMMO_OWN = 1024; // own ammo needs to be larger than damage dealt
++const int TFL_FIRECHECK_AMMO_OTHER = 2048; // target's ammo needs to be less than max
++const int TFL_FIRECHECK_REFIRE = 4096; // check single attack finished delays
++const int TFL_FIRECHECK_NO = 16384; // no prefire checks
 +
 +// attack flags
- .float turret_flags;
- const float TUR_FLAG_NONE = 0; // no abilities
- const float TUR_FLAG_SNIPER = 2; // sniping turret
- const float TUR_FLAG_SPLASH = 4; // can deal splash damage
- const float TUR_FLAG_HITSCAN = 8; // hit scan
- const float TUR_FLAG_MULTIGUN = 16; // multiple guns
- const float TUR_FLAG_GUIDED = 32; // laser guided projectiles
- const float TUR_FLAG_SLOWPROJ = 64; // turret fires slow projectiles
- const float TUR_FLAG_MEDPROJ = 128; // turret fires medium projectiles
- const float TUR_FLAG_FASTPROJ = 256; // turret fires fast projectiles
- const float TUR_FLAG_PLAYER = 512; // can damage players
- const float TUR_FLAG_MISSILE = 1024; // can damage missiles
- const float TUR_FLAG_SUPPORT = 2048; // supports other units
- const float TUR_FLAG_AMMOSOURCE = 4096; // can provide ammunition
- const float TUR_FLAG_RECIEVETARGETS = 8192; // can recieve targets from external sources
- const float TUR_FLAG_MOVE = 16384; // can move
- const float TUR_FLAG_ROAM = 32768; // roams around if not attacking
- const float TUR_FLAG_ISTURRET = 65536; // identifies this unit as a turret
++.int shoot_flags;
++const int TFL_SHOOT_NO = 64; // no attacking
++const int TFL_SHOOT_VOLLY = 2; // fire in vollies
++const int TFL_SHOOT_VOLLYALWAYS = 4; // always do a full volly, even if target is lost
++const int TFL_SHOOT_HITALLVALID = 8; // loop through all valid targets
++const int TFL_SHOOT_CLEARTARGET = 16; // lose target after attack (after volly is done if in volly mode)
++const int TFL_SHOOT_CUSTOM = 32; // custom attacking
 +
 +// turret capabilities
- const float TFL_AMMO_NONE = 64; // doesn't use ammo
- const float TFL_AMMO_ENERGY = 2; // uses power
- const float TFL_AMMO_BULLETS = 4; // uses bullets
- const float TFL_AMMO_ROCKETS = 8; // uses explosives
- const float TFL_AMMO_RECHARGE = 16; // regenerates ammo
- const float TFL_AMMO_RECIEVE = 32; // can recieve ammo from support units
++.int turret_flags;
++const int TUR_FLAG_NONE = 0; // no abilities
++const int TUR_FLAG_SNIPER = 2; // sniping turret
++const int TUR_FLAG_SPLASH = 4; // can deal splash damage
++const int TUR_FLAG_HITSCAN = 8; // hit scan
++const int TUR_FLAG_MULTIGUN = 16; // multiple guns
++const int TUR_FLAG_GUIDED = 32; // laser guided projectiles
++const int TUR_FLAG_SLOWPROJ = 64; // turret fires slow projectiles
++const int TUR_FLAG_MEDPROJ = 128; // turret fires medium projectiles
++const int TUR_FLAG_FASTPROJ = 256; // turret fires fast projectiles
++const int TUR_FLAG_PLAYER = 512; // can damage players
++const int TUR_FLAG_MISSILE = 1024; // can damage missiles
++const int TUR_FLAG_SUPPORT = 2048; // supports other units
++const int TUR_FLAG_AMMOSOURCE = 4096; // can provide ammunition
++const int TUR_FLAG_RECIEVETARGETS = 8192; // can recieve targets from external sources
++const int TUR_FLAG_MOVE = 16384; // can move
++const int TUR_FLAG_ROAM = 32768; // roams around if not attacking
++const int TUR_FLAG_ISTURRET = 65536; // identifies this unit as a turret
 +
 +// ammo types
 +#define ammo_flags currentammo
- .float damage_flags;
- const float TFL_DMG_NO = 256; // doesn't take damage
- const float TFL_DMG_YES = 2; // can be damaged
- const float TFL_DMG_TEAM = 4; // can be damaged by teammates
- const float TFL_DMG_RETALIATE = 8; // target attackers
- const float TFL_DMG_RETALIATE_TEAM = 16; // target attackers, even if on same team
- const float TFL_DMG_TARGETLOSS = 32; // loses target when damaged
- const float TFL_DMG_AIMSHAKE = 64; // damage throws off aim
- const float TFL_DMG_HEADSHAKE = 128; // damage shakes head
- const float TFL_DMG_DEATH_NORESPAWN = 256; // no re-spawning
++const int TFL_AMMO_NONE = 64; // doesn't use ammo
++const int TFL_AMMO_ENERGY = 2; // uses power
++const int TFL_AMMO_BULLETS = 4; // uses bullets
++const int TFL_AMMO_ROCKETS = 8; // uses explosives
++const int TFL_AMMO_RECHARGE = 16; // regenerates ammo
++const int TFL_AMMO_RECIEVE = 32; // can recieve ammo from support units
 +
 +// damage flags
- const float TSF_SUSPENDED = 1;
- const float TSF_TERRAINBASE = 2; // currently unused
- const float TSF_NO_AMMO_REGEN = 4; // disable builtin ammo regeneration
- const float TSF_NO_PATHBREAK = 8; // don't break path to chase enemies, will still fire at them if possible
- const float TSL_NO_RESPAWN = 16; // don't re-spawn
- const float TSL_ROAM = 32; // roam while idle
++.int damage_flags;
++const int TFL_DMG_NO = 256; // doesn't take damage
++const int TFL_DMG_YES = 2; // can be damaged
++const int TFL_DMG_TEAM = 4; // can be damaged by teammates
++const int TFL_DMG_RETALIATE = 8; // target attackers
++const int TFL_DMG_RETALIATE_TEAM = 16; // target attackers, even if on same team
++const int TFL_DMG_TARGETLOSS = 32; // loses target when damaged
++const int TFL_DMG_AIMSHAKE = 64; // damage throws off aim
++const int TFL_DMG_HEADSHAKE = 128; // damage shakes head
++const int TFL_DMG_DEATH_NORESPAWN = 256; // no re-spawning
 +
 +// spawn flags
- const float TNSF_UPDATE       = 2;
- const float TNSF_STATUS       = 4;
- const float TNSF_SETUP        = 8;
- const float TNSF_ANG          = 16;
- const float TNSF_AVEL         = 32;
- const float TNSF_MOVE         = 64;
++const int TSF_SUSPENDED = 1;
++const int TSF_TERRAINBASE = 2; // currently unused
++const int TSF_NO_AMMO_REGEN = 4; // disable builtin ammo regeneration
++const int TSF_NO_PATHBREAK = 8; // don't break path to chase enemies, will still fire at them if possible
++const int TSL_NO_RESPAWN = 16; // don't re-spawn
++const int TSL_ROAM = 32; // roam while idle
 +
 +// send flags
- const float TNSF_ANIM         = 128;
++const int TNSF_UPDATE       = 2;
++const int TNSF_STATUS       = 4;
++const int TNSF_SETUP        = 8;
++const int TNSF_ANG          = 16;
++const int TNSF_AVEL         = 32;
++const int TNSF_MOVE         = 64;
 +.float anim_start_time;
- const float TNSF_FULL_UPDATE  = 16777215;
++const int TNSF_ANIM         = 128;
 +
- .float turretid; // TUR_...
++const int TNSF_FULL_UPDATE  = 16777215;
 +
 +
 +// entity properties of turretinfo:
++.int turretid; // TUR_...
 +.string netname; // short name
 +.string turret_name; // human readable name
 +.float(float) turret_func; // m_...
 +.string mdl; // currently a copy of the model
 +.string model; // full name of model
 +.string head_model; // full name of tur_head model
 +.string cvar_basename; // TODO: deprecate!
 +.float spawnflags;
 +.vector mins, maxs; // turret hitbox size
 +
 +// other useful macros
 +#define TUR_ACTION(turrettype,mrequest) (get_turretinfo(turrettype)).turret_func(mrequest)
 +#define TUR_NAME(turrettype) (get_turretinfo(turrettype)).turret_name
 +
 +// =====================
 +//  Turret Registration
 +// =====================
 +
 +float t_null(float dummy);
 +void register_turret(float id, float(float) func, float turretflags, vector min_s, vector max_s, string modelname, string headmodelname, string shortname, string mname);
 +void register_turrets_done();
 +
 +const float TUR_MAXCOUNT = 24;
 +#define TUR_FIRST 1
 +float TUR_COUNT;
 +float TUR_LAST;
 +
 +#define REGISTER_TURRET_2(id,func,turretflags,min_s,max_s,modelname,headmodelname,shortname,mname) \
 +      float id; \
 +      float func(float); \
 +      void RegisterTurrets_##id() \
 +      { \
 +              TUR_LAST = (id = TUR_FIRST + TUR_COUNT); \
 +              ++TUR_COUNT; \
 +              register_turret(id,func,turretflags,min_s,max_s,modelname,headmodelname,shortname,mname); \
 +      } \
 +      ACCUMULATE_FUNCTION(RegisterTurrets, RegisterTurrets_##id)
 +#ifdef MENUQC
 +#define REGISTER_TURRET(id,func,turretflags,min_s,max_s,modelname,headmodelname,shortname,mname) \
 +      REGISTER_TURRET_2(TUR_##id,t_null,turretflags,min_s,max_s,modelname,headmodelname,shortname,mname)
 +#else
 +#define REGISTER_TURRET(id,func,turretflags,min_s,max_s,modelname,headmodelname,shortname,mname) \
 +      REGISTER_TURRET_2(TUR_##id,func,turretflags,min_s,max_s,modelname,headmodelname,shortname,mname)
 +#endif
 +
 +#define TUR_DUPECHECK(dupecheck,cvar) \
 +      #ifndef dupecheck \
 +              #define dupecheck \
 +              float cvar; \
 +      #else \
 +              #error DUPLICATE TURRET CVAR: cvar \
 +      #endif
 +
 +#define TUR_ADD_CVAR(turret,name) \
 +              TUR_DUPECHECK(TUR_CVAR_##turret##_##name, autocvar_g_turrets_unit_##turret##_##name)
 +
 +#define TUR_CVAR(turret,name) autocvar_g_turrets_unit_##turret##_##name
 +
 +#include "all.qh"
 +
 +#undef TUR_ADD_CVAR
 +#undef REGISTER_TURRET
 +ACCUMULATE_FUNCTION(RegisterTurrets, register_turrets_done);
++
++#endif
index 1c2dc556459431ef247f67951618fe198ee68fe9,0000000000000000000000000000000000000000..414ec4e822b6d3b0d17d6b909f2a7a6302c039ee
mode 100644,000000..100644
--- /dev/null
@@@ -1,311 -1,0 +1,311 @@@
-       turrets_setframe(newframe, FALSE);
 +#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
 +      // 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 (vlen(self.origin - self.pathcurrent.origin) < 64)
 +              self.pathcurrent = self.pathcurrent.enemy;
 +#endif
 +
 +      if (self.pathcurrent)
 +      {
 +
 +              self.moveto = self.pathcurrent.origin;
 +              self.steerto = steerlib_attract2(self.moveto, 0.5, 500, 0.95);
 +
 +              movelib_move_simple(v_forward, (autocvar_g_turrets_unit_ewheel_speed_fast), 0.4);
 +      }
 +}
 +
 +void ewheel_move_enemy()
 +{
 +      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));
 +      }
 +
-                       return TRUE;
++      turrets_setframe(newframe, false);
 +}
 +
 +void ewheel_move_idle()
 +{
 +      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)
 +{
 +      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;
++                      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;
++                      return true;
 +              }
 +              case TR_DEATH:
 +              {
 +                      self.velocity = '0 0 0';
 +
 +#ifdef EWHEEL_FANCYPATH
 +                      if (self.pathcurrent)
 +                              pathlib_deletepath(self.pathcurrent.owner);
 +#endif
 +                      self.pathcurrent = world;
 +      
-                       self.iscreature                         = TRUE;
++                      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 = WALKER_PATH(self.origin,e.origin);
 +                                              self.pathgoal = e;
 +#else
 +                                              self.pathcurrent  = e;
 +#endif
 +                                      }
 +                              }
 +                      }
 +                      
-                       self.damagedbycontents          = TRUE;
++                      self.iscreature                         = true;
 +                      self.teleportable                       = TELEPORT_NORMAL;
-                       return TRUE;
++                      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;
++                      return true;
 +              }
 +              case TR_PRECACHE:
 +              {
 +                      precache_model ("models/turrets/ewheel-base2.md3");
 +                      precache_model ("models/turrets/ewheel-gun1.md3");
-       return TRUE;
++                      return true;
 +              }
 +      }
 +
-                       return TRUE;
++      return true;
 +}
 +
 +#endif // SVQC
 +#ifdef CSQC
 +
 +void ewheel_draw()
 +{
 +      float dt;
 +
 +      dt = time - self.move_time;
 +      self.move_time = time;
 +      if(dt <= 0)
 +              return;
 +
 +      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;
 +
 +      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;
++                      return true;
 +              }
 +              case TR_PRECACHE:
 +              {
-       return TRUE;
++                      return true;
 +              }
 +      }
 +
++      return true;
 +}
 +
 +#endif // CSQC
 +#endif // REGISTER_TURRET
index 8c131e76e0401fe7db1aad6509e7c754e0cb293e,0000000000000000000000000000000000000000..8068ab1d7e8d97c49ecb22ad90932cec40d33844
mode 100644,000000..100644
--- /dev/null
@@@ -1,103 -1,0 +1,103 @@@
-                       return TRUE;
 +#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()
 +{
 +      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
 +      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
 +      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
 +      remove(self);
 +}
 +
 +void spawnfunc_turret_flac() { if(!turret_initialize(TUR_FLAC)) remove(self); }
 +
 +float t_flac(float req)
 +{
 +      switch(req)
 +      {
 +              case TR_ATTACK:
 +              {
 +                      entity proj;
 +
 +                      turret_tag_fire_update();
 +
 +                      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;
 +
 +                      self.tur_head.frame = self.tur_head.frame + 1;
 +                      if (self.tur_head.frame >= 4)
 +                              self.tur_head.frame = 0;
 +                      
-                       return TRUE;
++                      return true;
 +              }
 +              case TR_THINK:
 +              {
-                       return TRUE;
++                      return true;
 +              }
 +              case TR_DEATH:
 +              {
-                       return TRUE;
++                      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;
++                      return true;
 +              }
 +              case TR_PRECACHE:
 +              {
 +                      precache_model ("models/turrets/base.md3");
 +                      precache_model ("models/turrets/flac.md3");
-       return TRUE;
++                      return true;
 +              }
 +      }
 +
-                       return TRUE;
++      return true;
 +}
 +
 +#endif // SVQC
 +#ifdef CSQC
 +float t_flac(float req)
 +{
 +      switch(req)
 +      {
 +              case TR_SETUP:
 +              {
-                       return TRUE;
++                      return true;
 +              }
 +              case TR_PRECACHE:
 +              {
-       return TRUE;
++                      return true;
 +              }
 +      }
 +
++      return true;
 +}
 +
 +#endif // CSQC
 +#endif // REGISTER_TURRET
index d2a3c408e5be68b39c1f2062cc9187e3fafc7cf8,0000000000000000000000000000000000000000..db49745667e515d58a49697f446c122c94c22199
mode 100644,000000..100644
--- /dev/null
@@@ -1,116 -1,0 +1,116 @@@
-                       return TRUE;
 +#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.attack_finished_single > time)
 +              return 0;
 +
 +      if (self.enemy.deadflag != DEAD_NO)
 +              return 0;
 +
 +      if (self.enemy == world)
 +              return 0;
 +
 +      if (self.ammo < self.shot_dmg)
 +              return 0;
 +
 +      if (self.enemy.ammo >= self.enemy.ammo_max)
 +              return 0;
 +
 +      if (vlen(self.enemy.origin - self.origin) > self.target_range)
 +              return 0;
 +
 +      if(self.team != self.enemy.team)
 +              return 0;
 +
 +      if(!(self.enemy.ammo_flags & TFL_AMMO_ENERGY))
 +              return 0;
 +
 +      return 1;
 +}
 +
 +void spawnfunc_turret_fusionreactor() { if(!turret_initialize(TUR_FUSIONREACTOR)) remove(self); }
 +
 +float t_fusionreactor(float req)
 +{
 +      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;
++                      return true;
 +              }
 +              case TR_THINK:
 +              {
 +                      self.tur_head.avelocity = '0 250 0' * (self.ammo / self.ammo_max);
 +              
-                       return TRUE;
++                      return true;
 +              }
 +              case TR_DEATH:
 +              {
-                       return TRUE;
++                      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;
++                      return true;
 +              }
 +              case TR_PRECACHE:
 +              {
 +                      precache_model ("models/turrets/base.md3");
 +                      precache_model ("models/turrets/reactor.md3");
-       return TRUE;
++                      return true;
 +              }
 +      }
 +
-                       return TRUE;
++      return true;
 +}
 +
 +#endif // SVQC
 +#ifdef CSQC
 +float t_fusionreactor(float req)
 +{
 +      switch(req)
 +      {
 +              case TR_SETUP:
 +              {
-                       return TRUE;
++                      return true;
 +              }
 +              case TR_PRECACHE:
 +              {
-       return TRUE;
++                      return true;
 +              }
 +      }
 +
++      return true;
 +}
 +
 +#endif // CSQC
 +#endif // REGISTER_TURRET
index 57dca3b79101d70894d31c871de87da3deb63fe7,0000000000000000000000000000000000000000..d090ef7ce52135f62458bb3232246cd24298e1f5
mode 100644,000000..100644
--- /dev/null
@@@ -1,160 -1,0 +1,160 @@@
-                       return TRUE;
 +#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()
 +{
 +      vector olddir,newdir;
 +      vector pre_pos;
 +      float itime;
 +
 +      self.nextthink = time + 0.05;
 +
 +      olddir = normalize(self.velocity);
 +
 +      if(self.max_health < time)
 +              turret_projectile_explode();
 +
 +      // Enemy dead? just keep on the current heading then.
 +      if ((self.enemy == world) || (self.enemy.deadflag != DEAD_NO))
 +      {
 +
 +              // Make sure we dont return to tracking a respawned player
 +              self.enemy = world;
 +
 +              // Turn model
 +              self.angles = vectoangles(self.velocity);
 +
 +              if ( (vlen(self.origin - self.owner.origin)) > (self.owner.shot_radius * 5) )
 +                      turret_projectile_explode();
 +
 +              // Accelerate
 +              self.velocity = olddir * min(vlen(self.velocity) * (autocvar_g_turrets_unit_hellion_shot_speed_gain), (autocvar_g_turrets_unit_hellion_shot_speed_max));
 +
 +              UpdateCSQCProjectile(self);
 +
 +              return;
 +      }
 +
 +      // Enemy in range?
 +      if (vlen(self.origin - self.enemy.origin) < self.owner.shot_radius * 0.2)
 +              turret_projectile_explode();
 +
 +      // Predict enemy position
 +      itime = vlen(self.enemy.origin - self.origin) / vlen(self.velocity);
 +      pre_pos = self.enemy.origin + self.enemy.velocity * itime;
 +
 +      pre_pos = (pre_pos + self.enemy.origin) * 0.5;
 +
 +      // Find out the direction to that place
 +      newdir = normalize(pre_pos - self.origin);
 +
 +      // Turn
 +      newdir = normalize(olddir + newdir * 0.35);
 +
 +      // Turn model
 +      self.angles = vectoangles(self.velocity);
 +
 +      // Accelerate
 +      self.velocity = newdir * min(vlen(self.velocity) * (autocvar_g_turrets_unit_hellion_shot_speed_gain), (autocvar_g_turrets_unit_hellion_shot_speed_max));
 +
 +      if (itime < 0.05)
 +              self.think = turret_projectile_explode;
 +
 +      UpdateCSQCProjectile(self);
 +}
 +
 +void spawnfunc_turret_hellion() { if(!turret_initialize(TUR_HELLION)) remove(self); }
 +
 +float t_hellion(float req)
 +{
 +      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;
++                      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;
++                      return true;
 +              }
 +              case TR_DEATH:
 +              {
-                       return TRUE;
++                      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;
++                      return true;
 +              }
 +              case TR_PRECACHE:
 +              {
 +                      precache_model ("models/turrets/base.md3");
 +                      precache_model ("models/turrets/hellion.md3");
-       return TRUE;
++                      return true;
 +              }
 +      }
 +
-                       return TRUE;
++      return true;
 +}
 +
 +#endif // SVQC
 +#ifdef CSQC
 +float t_hellion(float req)
 +{
 +      switch(req)
 +      {
 +              case TR_SETUP:
 +              {
-                       return TRUE;
++                      return true;
 +              }
 +              case TR_PRECACHE:
 +              {
-       return TRUE;
++                      return true;
 +              }
 +      }
 +
++      return true;
 +}
 +
 +#endif // CSQC
 +#endif // REGISTER_TURRET
index c0f55fa0f06da0614ba1d8230e37c731a00782b4,0000000000000000000000000000000000000000..414c71e4b8286c87879842d68f67abff9f38cc66
mode 100644,000000..100644
--- /dev/null
@@@ -1,361 -1,0 +1,361 @@@
-               traceline(self.origin, pre_pos,TRUE,self.enemy);
 +#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 (e_target == world)
 +              return 0;
 +
 +      // If only this was used more..
 +      if (e_target.flags & FL_NOTARGET)
 +              return 0;
 +
 +      // Cant touch this
 +      if ((e_target.takedamage == DAMAGE_NO) || (e_target.health < 0))
 +              return 0;
 +
 +      // player
 +      if (IS_CLIENT(e_target))
 +      {
 +              if (self.owner.target_select_playerbias < 0)
 +                      return 0;
 +
 +              if (e_target.deadflag != DEAD_NO)
 +                      return 0;
 +      }
 +
 +      // Missile
 +      if ((e_target.flags & FL_PROJECTILE) && (self.owner.target_select_missilebias < 0))
 +              return 0;
 +
 +      // Team check
 +      if ((e_target.team == self.owner.team) || (self.owner.team == e_target.owner.team))
 +              return 0;
 +
 +      return 1;
 +}
 +
 +void turret_hk_missile_think()
 +{
 +      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, self.origin + v_forward * lt_for,FALSE,self);
++              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 + (-1 * (v_right * pt_seek) + (v_forward * ff)) * lt_seek,FALSE,self);
++              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 + ((v_right * pt_seek) + (v_forward * ff)) * lt_seek ,FALSE,self);
++              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_up * pt_seek) + (v_forward * ff)) * lt_seek ,FALSE,self);
++              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 + (-1 * (v_up * pt_seek) + (v_forward * ff)) * lt_seek ,FALSE,self);
++              traceline(self.origin,  self.origin + ((v_up * pt_seek) + (v_forward * ff)) * lt_seek ,false,self);
 +              vu = trace_endpos;
 +              fu = trace_fraction;
 +
 +              // Trace down
-                       return TRUE;
++              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
 +      //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
 +
 +      UpdateCSQCProjectile(self);
 +}
 +
 +float turret_hk_addtarget(entity e_target,entity e_sender)
 +{
 +      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_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;
++                      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;
++                      return true;
 +              }
 +              case TR_DEATH:
 +              {
-                       return TRUE;
++                      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;
++                      return true;
 +              }
 +              case TR_PRECACHE:
 +              {
 +                      precache_model ("models/turrets/base.md3");
 +                      precache_model ("models/turrets/hk.md3");
-       return TRUE;
++                      return true;
 +              }
 +      }
 +
-                       return TRUE;
++      return true;
 +}
 +
 +#endif // SVQC
 +#ifdef CSQC
 +float t_hk(float req)
 +{
 +      switch(req)
 +      {
 +              case TR_SETUP:
 +              {
-                       return TRUE;
++                      return true;
 +              }
 +              case TR_PRECACHE:
 +              {
-       return TRUE;
++                      return true;
 +              }
 +      }
 +
++      return true;
 +}
 +
 +#endif // CSQC
 +#endif // REGISTER_TURRET
index 26cbc4882835075114623361fb7342f10fe371cb,0000000000000000000000000000000000000000..f4a46212fc0645d9688223635177a5d159754df8
mode 100644,000000..100644
--- /dev/null
@@@ -1,79 -1,0 +1,79 @@@
-                       return TRUE;
 +#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); }
 +
 +float t_machinegun(float req)
 +{
 +      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);
 +
 +                      W_MachineGun_MuzzleFlash();
 +                      setattachment(self.muzzle_flash, self.tur_head, "tag_fire");
 +
-                       return TRUE;
++                      return true;
 +              }
 +              case TR_THINK:
 +              {
-                       return TRUE;
++                      return true;
 +              }
 +              case TR_DEATH:
 +              {
-                       return TRUE;
++                      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;
++                      return true;
 +              }
 +      }
 +
-                       return TRUE;
++      return true;
 +}
 +
 +#endif // SVQC
 +#ifdef CSQC
 +float t_machinegun(float req)
 +{
 +      switch(req)
 +      {
 +              case TR_SETUP:
 +              {
-                       return TRUE;
++                      return true;
 +              }
 +              case TR_PRECACHE:
 +              {
-       return TRUE;
++                      return true;
 +              }
 +      }
 +
++      return true;
 +}
 +
 +#endif // CSQC
 +#endif // REGISTER_TURRET
index fa3c30efcd879f7b13f262b1d124366853eef0a8,0000000000000000000000000000000000000000..254a589484b0302606d130ddc4374c3765be8085
mode 100644,000000..100644
--- /dev/null
@@@ -1,90 -1,0 +1,90 @@@
-                       return TRUE;
 +#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)
 +{
 +      switch(req)
 +      {
 +              case TR_ATTACK:
 +              {
 +                      entity missile;
 +
 +                      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;
++                      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;
++                      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;
 +
-                       return TRUE;
++                      return true;
 +              }
 +              case TR_PRECACHE:
 +              {
 +                      precache_model ("models/turrets/base.md3");
 +                      precache_model ("models/turrets/mlrs.md3");
-       return TRUE;
++                      return true;
 +              }
 +      }
 +
-                       return TRUE;
++      return true;
 +}
 +
 +#endif // SVQC
 +#ifdef CSQC
 +float t_mlrs(float req)
 +{
 +      switch(req)
 +      {
 +              case TR_SETUP:
 +              {
-                       return TRUE;
++                      return true;
 +              }
 +              case TR_PRECACHE:
 +              {
-       return TRUE;
++                      return true;
 +              }
 +      }
 +
++      return true;
 +}
 +
 +#endif // CSQC
 +#endif // REGISTER_TURRET
index 441e041c7356fc4cec2f6f20713b36c9611f8efd,0000000000000000000000000000000000000000..32c392b6648b853ca57d9603af0a9830836f773e
mode 100644,000000..100644
--- /dev/null
@@@ -1,173 -1,0 +1,173 @@@
-                       beam.bot_dodge = TRUE;
 +#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 (self.fireflag != 0) return 0;
 +      return turret_firecheck();
 +}
 +
 +void beam_think()
 +{
 +      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_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;
-                       return TRUE;
++                      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;
++                      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;
++                      return true;
 +              }
 +              case TR_DEATH:
 +              {
-                       return TRUE;
++                      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;
++                      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;
 +              }
 +      }
 +
-                       return TRUE;
++      return true;
 +}
 +
 +#endif // SVQC
 +#ifdef CSQC
 +float t_phaser(float req)
 +{
 +      switch(req)
 +      {
 +              case TR_SETUP:
 +              {
-                       return TRUE;
++                      return true;
 +              }
 +              case TR_PRECACHE:
 +              {
-       return TRUE;
++                      return true;
 +              }
 +      }
 +
++      return true;
 +}
 +
 +#endif // CSQC
 +#endif // REGISTER_TURRET
index ac623371f59d531d320e9425f655ddedce9a9d41,0000000000000000000000000000000000000000..095aa9d02d749485d7b30d5e97c94bf059123432
mode 100644,000000..100644
--- /dev/null
@@@ -1,111 -1,0 +1,111 @@@
-                       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_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;
++                      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;
++                      return true;
 +              }
 +              case TR_DEATH:
 +              {
-                       return TRUE;
++                      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;
++                      return true;
 +              }
 +              case TR_PRECACHE:
 +              {
 +                      precache_model ("models/turrets/base.md3");
 +                      precache_model ("models/turrets/plasma.md3");
-       return TRUE;
++                      return true;
 +              }
 +      }
 +
-                       return TRUE;
++      return true;
 +}
 +
 +#endif // SVQC
 +#ifdef CSQC
 +float t_plasma(float req)
 +{
 +      switch(req)
 +      {
 +              case TR_SETUP:
 +              {
-                       return TRUE;
++                      return true;
 +              }
 +              case TR_PRECACHE:
 +              {
-       return TRUE;
++                      return true;
 +              }
 +      }
 +
++      return true;
 +}
 +
 +#endif // CSQC
 +#endif // REGISTER_TURRET
index 279b41ec401c7599daa0cc6f5f0a8505f8540720,0000000000000000000000000000000000000000..110ae1dea7d26075ef64665e8ae69af027b7d13a
mode 100644,000000..100644
--- /dev/null
@@@ -1,109 -1,0 +1,109 @@@
-                       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_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;
++                      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;
++                      return true;
 +              }
 +              case TR_DEATH:
 +              {
-                       return TRUE;
++                      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;
++                      return true;
 +              }
 +              case TR_PRECACHE:
 +              {
 +                      precache_model ("models/turrets/base.md3");
 +                      precache_model ("models/turrets/plasmad.md3");
-       return TRUE;
++                      return true;
 +              }
 +      }
 +
-                       return TRUE;
++      return true;
 +}
 +
 +#endif // SVQC
 +#ifdef CSQC
 +float t_plasma_dual(float req)
 +{
 +      switch(req)
 +      {
 +              case TR_SETUP:
 +              {
-                       return TRUE;
++                      return true;
 +              }
 +              case TR_PRECACHE:
 +              {
-       return TRUE;
++                      return true;
 +              }
 +      }
 +
++      return true;
 +}
 +
 +#endif // CSQC
 +#endif // REGISTER_TURRET
index 2878c318789f7ea6e77f70f11eae97cf0f2dbaf9,0000000000000000000000000000000000000000..61a9f5e30437fa7b20f5bc6d18065c4864445e70
mode 100644,000000..100644
--- /dev/null
@@@ -1,217 -1,0 +1,217 @@@
-                       if (t == world) return TRUE;
 +#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)
 +{
 +      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()
 +{
 +      // 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_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);
 +
-                       return TRUE;
++                      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;
++                      return true;
 +              }
 +              case TR_THINK:
 +              {
 +                      if(!self.active)
 +                      {
 +                              self.tur_head.avelocity = '0 0 0';
-                                       return TRUE;
++                              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;
++                                      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;
++                      return true;
 +              }
 +              case TR_DEATH:
 +              {
-                       return TRUE;
++                      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;
++                      return true;
 +              }
 +              case TR_PRECACHE:
 +              {
 +                      precache_model ("models/turrets/tesla_base.md3");
 +                      precache_model ("models/turrets/tesla_head.md3");
-       return TRUE;
++                      return true;
 +              }
 +      }
 +
-                       return TRUE;
++      return true;
 +}
 +
 +#endif // SVQC
 +#ifdef CSQC
 +float t_tesla(float req)
 +{
 +      switch(req)
 +      {
 +              case TR_SETUP:
 +              {
-                       return TRUE;
++                      return true;
 +              }
 +              case TR_PRECACHE:
 +              {
-       return TRUE;
++                      return true;
 +              }
 +      }
 +
++      return true;
 +}
 +
 +#endif // CSQC
 +#endif // REGISTER_TURRET
index fa89d5a3e4ceaf39389ebabca070db339fc2678e,0000000000000000000000000000000000000000..0d5d3170572c8caaa60b7881d67f14219668cd25
mode 100644,000000..100644
--- /dev/null
@@@ -1,696 -1,0 +1,698 @@@
-       turrets_setframe(ANIM_NO, FALSE);
 +#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()
 +{
 +      if (self.animflag == ANIM_MELEE)
 +              return 0;
 +
 +      return turret_firecheck();
 +}
 +
 +void walker_melee_do_dmg()
 +{
 +      vector where;
 +      entity e;
 +
 +      makevectors(self.angles);
 +      where = self.origin + v_forward * 128;
 +
 +      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));
 +
 +              e = e.chain;
 +      }
 +}
 +
 +void walker_setnoanim()
 +{
-       rocket.bot_dodge                  = TRUE;
++      turrets_setframe(ANIM_NO, false);
 +      self.animflag = self.frame;
 +}
 +void walker_rocket_explode()
 +{
 +      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)
 +{
 +      self.health = self.health - damage;
 +      self.velocity = self.velocity + vforce;
 +
 +      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;
 +      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()
 +{
 +      vector newdir;
 +      self.nextthink = time;
 +
 +      if (self.max_health < time)
 +      {
 +              self.think = walker_rocket_explode;
 +              return;
 +      }
 +
 +      if (vlen(self.origin - self.tur_shotorg) < 100 )
 +      {
 +              self.think = walker_rocket_think;
 +              return;
 +      }
 +
 +      newdir = steerlib_pull(self.tur_shotorg);
 +      WALKER_ROCKET_MOVE;
 +
 +      self.angles = vectoangles(self.velocity);
 +}
 +
 +void walker_rocket_loop2()
 +{
 +      vector newdir;
 +
 +      self.nextthink = time;
 +
 +      if (self.max_health < time)
 +      {
 +              self.think = walker_rocket_explode;
 +              return;
 +      }
 +
 +      if (vlen(self.origin - self.tur_shotorg) < 100 )
 +      {
 +              self.tur_shotorg = self.origin - '0 0 200';
 +              self.think = walker_rocket_loop3;
 +              return;
 +      }
 +
 +      newdir = steerlib_pull(self.tur_shotorg);
 +      WALKER_ROCKET_MOVE;
 +}
 +
 +void walker_rocket_loop()
 +{
 +      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)
 +{
 +      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;
-       CSQCProjectile(rocket, FALSE, PROJECTILE_ROCKET, FALSE); // no culling, has fly sound
++      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;
 +
-                       return TRUE;
++      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)
 +{
 +      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
 +      // 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 (vlen(self.origin - self.pathcurrent.origin) < 64)
 +              self.pathcurrent = self.pathcurrent.enemy;
 +
 +      if(!self.pathcurrent)
 +              return;
 +
 +      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)
 +{
 +      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);
 +
-                       turrets_setframe(self.animflag, FALSE);
++                      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;
-                       return TRUE;
++                      turrets_setframe(self.animflag, false);
 +
-                       return TRUE;
++                      return true;
 +              }
 +              case TR_DEATH:
 +              {
 +#ifdef WALKER_FANCYPATHING
 +                      if (self.pathcurrent)
 +                              pathlib_deletepath(self.pathcurrent.owner);
 +#endif
 +                      self.pathcurrent = world;
 +              
-                       self.iscreature = TRUE;
++                      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.damagedbycontents = TRUE;
++                      self.iscreature = true;
 +                      self.teleportable = TELEPORT_NORMAL;
-                       return TRUE;
++                      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 = WALKER_PATH(self.origin, e.origin);
 +                                      self.pathgoal = e;
 +#else
 +                                      self.pathcurrent = e;
 +#endif
 +                              }
 +                      }
 +
-                       return TRUE;
++                      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;
 +              }
 +      }
 +
-                       return TRUE;
++      return true;
 +}
 +
 +#endif // SVQC
 +#ifdef CSQC
 +
++#include "../../../server/movelib.qh"
++
 +void walker_draw()
 +{
 +      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;
++                      return true;
 +              }
 +              case TR_PRECACHE:
 +              {
-       return TRUE;
++                      return true;
 +              }
 +      }
 +
++      return true;
 +}
 +
 +#endif // CSQC
 +#endif // REGISTER_TURRET
index 6de59027e38bdc668a9071f398a9bb1955cc73d9,0000000000000000000000000000000000000000..3d6d95a76a42504e5dda204de447114867890ea1
mode 100644,000000..100644
--- /dev/null
@@@ -1,331 -1,0 +1,330 @@@
- #define turret_tag_fire_update() self.tur_shotorg = gettaginfo(self.tur_head, gettagindex(self.tur_head, "tag_fire"));v_forward = normalize(v_forward)
- float turret_tag_fire_update_s()
 +/*
 +* 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.
 +*/
-               return FALSE;
++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 TRUE;
++              return false;
 +      }
 +
 +      self.tur_shotorg = gettaginfo(self.tur_head, gettagindex(self.tur_head, "tag_fire"));
 +      v_forward = normalize(v_forward);
 +
-               tracebox(start, smin, smax, end, FALSE, self);
++      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, float 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)
 +      {
-               trace_ent.railgunhit = TRUE;
++              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)
 +                      break;
 +
 +              if (trace_ent.solid == SOLID_BSP)
 +                      break;
 +
 +              // make the entity non-solid so we can hit the next one
-       ent = findfloat(world, railgunhit, TRUE);
++              trace_ent.railgunhit = true;
 +              trace_ent.railgunhitloc = end;
 +              trace_ent.railgunhitsolidbackup = trace_ent.solid;
 +
 +              // stop if this is a wall
 +
 +              // make the entity non-solid
 +              trace_ent.solid = SOLID_NOT;
 +      }
 +
 +      endpoint = trace_endpos;
 +
 +      // find all the entities the railgun hit and restore their solid state
-               ent = findfloat(ent, railgunhit, TRUE);
++      ent = findfloat(world, railgunhit, true);
 +      while (ent)
 +      {
 +              // restore their solid type
 +              ent.solid = ent.railgunhitsolidbackup;
-       ent = findfloat(world, railgunhit, TRUE);
++              ent = findfloat(ent, railgunhit, true);
 +      }
 +
 +      // find all the entities the railgun hit and hurt them
-               ent.railgunhit = FALSE;
++      ent = findfloat(world, railgunhit, true);
 +      while (ent)
 +      {
 +              // get the details we need to call the damage function
 +              hitloc = ent.railgunhitloc;
 +              ent.railgunhitloc = '0 0 0';
 +              ent.railgunhitsolidbackup = SOLID_NOT;
-               ent = findfloat(ent, railgunhit, TRUE);
++              ent.railgunhit = false;
 +
 +              // apply the damage
 +              if (ent.takedamage)
 +              {
 +                      Damage (ent, self, self, f_dmg, deathtype, hitloc, force);
 +                      ent.velocity = ent.velocity * f_velfactor;
 +                      //ent.alpha = 0.25 + random() * 0.75;
 +              }
 +
 +              // advance to the next entity
++              ent = findfloat(ent, railgunhit, true);
 +      }
 +      trace_endpos = endpoint;
 +}
 +
 +#ifdef TURRET_DEBUG
 +void SUB_Remove();
 +void marker_think()
 +{
 +      if(self.cnt)
 +      if(self.cnt < time)
 +      {
 +              self.think = SUB_Remove;
 +              self.nextthink = time;
 +              return;
 +      }
 +
 +      self.frame += 1;
 +      if(self.frame > 29)
 +              self.frame = 0;
 +
 +      self.nextthink = time;
 +}
 +
 +void mark_error(vector where,float lifetime)
 +{
 +      entity err;
 +
 +      err = spawn();
 +      err.classname = "error_marker";
 +      setmodel(err,"models/marker.md3");
 +      setorigin(err,where);
 +      err.movetype = MOVETYPE_NONE;
 +      err.think = marker_think;
 +      err.nextthink = time;
 +      err.skin = 0;
 +      if(lifetime)
 +              err.cnt = lifetime + time;
 +}
 +
 +void mark_info(vector where,float lifetime)
 +{
 +      entity err;
 +
 +      err = spawn();
 +      err.classname = "info_marker";
 +      setmodel(err,"models/marker.md3");
 +      setorigin(err,where);
 +      err.movetype = MOVETYPE_NONE;
 +      err.think = marker_think;
 +      err.nextthink = time;
 +      err.skin = 1;
 +      if(lifetime)
 +              err.cnt = lifetime + time;
 +}
 +
 +entity mark_misc(vector where,float lifetime)
 +{
 +      entity err;
 +
 +      err = spawn();
 +      err.classname = "mark_misc";
 +      setmodel(err,"models/marker.md3");
 +      setorigin(err,where);
 +      err.movetype = MOVETYPE_NONE;
 +      err.think = marker_think;
 +      err.nextthink = time;
 +      err.skin = 3;
 +      if(lifetime)
 +              err.cnt = lifetime + time;
 +      return err;
 +}
 +
 +/*
 +* Paint a v_color colord circle on target onwho
 +* that fades away over f_time
 +*/
 +void paint_target(entity onwho, float f_size, vector v_color, float f_time)
 +{
 +      entity e;
 +
 +      e = spawn();
 +      setmodel(e, "models/turrets/c512.md3"); // precision set above
 +      e.scale = (f_size/512);
 +      //setsize(e, '0 0 0', '0 0 0');
 +      //setattachment(e,onwho,"");
 +      setorigin(e,onwho.origin + '0 0 1');
 +      e.alpha = 0.15;
 +      e.movetype = MOVETYPE_FLY;
 +
 +      e.velocity = (v_color * 32); // + '0 0 1' * 64;
 +
 +      e.colormod = v_color;
 +      SUB_SetFade(e,time,f_time);
 +}
 +
 +void paint_target2(entity onwho, float f_size, vector v_color, float f_time)
 +{
 +      entity e;
 +
 +      e = spawn();
 +      setmodel(e, "models/turrets/c512.md3"); // precision set above
 +      e.scale = (f_size/512);
 +      setsize(e, '0 0 0', '0 0 0');
 +
 +      setorigin(e,onwho.origin + '0 0 1');
 +      e.alpha = 0.15;
 +      e.movetype = MOVETYPE_FLY;
 +
 +      e.velocity = (v_color * 32); // + '0 0 1' * 64;
 +      e.avelocity_x = -128;
 +
 +      e.colormod = v_color;
 +      SUB_SetFade(e,time,f_time);
 +}
 +
 +void paint_target3(vector where, float f_size, vector v_color, float f_time)
 +{
 +      entity e;
 +      e = spawn();
 +      setmodel(e, "models/turrets/c512.md3"); // precision set above
 +      e.scale = (f_size/512);
 +      setsize(e, '0 0 0', '0 0 0');
 +      setorigin(e,where+ '0 0 1');
 +      e.movetype = MOVETYPE_NONE;
 +      e.velocity = '0 0 0';
 +      e.colormod = v_color;
 +      SUB_SetFade(e,time,f_time);
 +}
 +#endif
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..71ba0662e6f4fdfd87fb0cef48eb0b71ea21eb02
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,13 @@@
++#ifndef TURRETS_UTIL_H
++#define TURRETS_UTIL_H
++
++vector real_origin(entity ent);
++float shortangle_f(float ang1, float ang2);
++float anglemods(float v);
++float turret_tag_fire_update();
++vector shortangle_vxy(vector ang1, vector ang2);
++vector angleofs(entity from, entity to);
++vector angleofs3(vector from, vector from_a, entity to);
++void FireImoBeam (vector start, vector end, vector smin, vector smax, float bforce, float f_dmg, float f_velfactor, float deathtype);
++
++#endif
Simple merge
index 3f5ba0d6216fb2f5f48253cfdef98ab0f2ca85db,d170cf4c020db0b7e229777a858fb5c55afb6825..aab2f9ced5567164b401596cfe34a70d4972491f
@@@ -1,7 -1,31 +1,32 @@@
- .float dmg;
- .float dmg_edge;
- .float dmg_force;
- .float dmg_radius;
+ #include "g_damage.qh"
+ #if defined(CSQC)
+ #elif defined(MENUQC)
+ #elif defined(SVQC)
+     #include "../warpzonelib/common.qh"
+     #include "../common/constants.qh"
+     #include "../common/teams.qh"
+     #include "../common/util.qh"
+     #include "../common/weapons/weapons.qh"
+     #include "weapons/accuracy.qh"
+     #include "weapons/csqcprojectile.qh"
+     #include "weapons/selection.qh"
+     #include "t_items.qh"
+     #include "autocvars.qh"
+     #include "constants.qh"
+     #include "defs.qh"
+     #include "../common/notifications.qh"
+     #include "../common/deathtypes.qh"
+     #include "mutators/mutators_include.qh"
 -    #include "tturrets/include/turrets_early.qh"
++    #include "../common/turrets/turrets.qh"
++    #include "../common/turrets/sv_turrets.qh"
+     #include "vehicles/vehicles_def.qh"
+     #include "../csqcmodellib/sv_model.qh"
+     #include "../common/playerstats.qh"
+     #include "g_hook.qh"
+     #include "scores.qh"
+     #include "spawnpoints.qh"
+ #endif
  
  float Damage_DamageInfo_SendEntity(entity to, float sf)
  {
index 0000000000000000000000000000000000000000,4cc3f6f63e901d05e4fc863ad89ca76ce5606144..68f9a0a3855c64658c7baf20070c825bcf693946
mode 000000,100644..100644
--- /dev/null
@@@ -1,0 -1,123 +1,122 @@@
 -    #include "tturrets/include/turrets_early.qh"
+ #ifndef G_DAMAGE_H
+ #define G_DAMAGE_H
+ #if defined(CSQC)
+ #elif defined(MENUQC)
+ #elif defined(SVQC)
+       #include "../dpdefs/progsdefs.qh"
+     #include "../dpdefs/dpextensions.qh"
+     #include "../warpzonelib/common.qh"
+     #include "../common/constants.qh"
+     #include "../common/teams.qh"
+     #include "../common/util.qh"
+     #include "../common/weapons/weapons.qh"
+     #include "weapons/accuracy.qh"
+     #include "weapons/csqcprojectile.qh"
+     #include "weapons/selection.qh"
+     #include "t_items.qh"
+     #include "autocvars.qh"
+     #include "constants.qh"
+     #include "defs.qh"
+     #include "../common/notifications.qh"
+     #include "../common/deathtypes.qh"
+     #include "mutators/mutators_include.qh"
+     #include "vehicles/vehicles_def.qh"
+     #include "../csqcmodellib/sv_model.qh"
+     #include "../common/playerstats.qh"
+     #include "g_hook.qh"
+     #include "scores.qh"
+     #include "spawnpoints.qh"
+ #endif
+ .float dmg;
+ .float dmg_edge;
+ .float dmg_force;
+ .float dmg_radius;
+ float Damage_DamageInfo_SendEntity(entity to, float sf);
+ void Damage_DamageInfo(vector org, float coredamage, float edgedamage, float rad, vector force, float deathtype, float bloodtype, entity dmgowner);
+ float checkrules_firstblood;
+ float yoda;
+ float damage_goodhits;
+ float damage_gooddamage;
+ .float dmg_team;
+ .float teamkill_complain;
+ .float teamkill_soundtime;
+ .entity teamkill_soundsource;
+ .entity pusher;
+ .float istypefrag;
+ .float taunt_soundtime;
+ float IsFlying(entity a);
+ void UpdateFrags(entity player, float f);
+ // NOTE: f=0 means still count as a (positive) kill, but count no frags for it
+ void W_SwitchWeapon_Force(entity e, float w);
+ entity GiveFrags_randomweapons;
+ void GiveFrags (entity attacker, entity targ, float f, float deathtype);
+ string AppendItemcodes(string s, entity player);
+ void LogDeath(string mode, float deathtype, entity killer, entity killed);
+ void Obituary_SpecialDeath(
+       entity notif_target,
+       float murder,
+       float deathtype,
+       string s1, string s2, string s3,
+       float f1, float f2, float f3);
+ float w_deathtype;
+ float Obituary_WeaponDeath(
+       entity notif_target,
+       float murder,
+       float deathtype,
+       string s1, string s2, string s3,
+       float f1, float f2);
+ void Obituary(entity attacker, entity inflictor, entity targ, float deathtype);
+ void Ice_Think();
+ void Freeze (entity targ, float freeze_time, float frozen_type, float show_waypoint);
+ void Unfreeze (entity targ);
+ // these are updated by each Damage call for use in button triggering and such
+ entity damage_targ;
+ entity damage_inflictor;
+ entity damage_attacker;
+ void Damage (entity targ, entity inflictor, entity attacker, float damage, float deathtype, vector hitloc, vector force);
+ float RadiusDamage_running;
+ float RadiusDamageForSource (entity inflictor, vector inflictororigin, vector inflictorvelocity, entity attacker, float coredamage, float edgedamage, float rad, entity cantbe, entity mustbe, float inflictorselfdamage, float forceintensity, float deathtype, entity directhitentity);
+       // Returns total damage applies to creatures
+ float RadiusDamage (entity inflictor, entity attacker, float coredamage, float edgedamage, float rad, entity cantbe, entity mustbe, float forceintensity, float deathtype, entity directhitentity);
+ .float fire_damagepersec;
+ .float fire_endtime;
+ .float fire_deathtype;
+ .entity fire_owner;
+ .float fire_hitsound;
+ .entity fire_burner;
+ void fireburner_think();
+ float Fire_IsBurning(entity e);
+ float Fire_AddDamage(entity e, entity o, float d, float t, float dt);
+ void Fire_ApplyDamage(entity e);
+ void Fire_ApplyEffect(entity e);
+ void fireburner_think();
+ #endif
index dc5d9d6e30eff6baff355026d80cc7b8af631183,04f8ff7b38afbf7551a2a162bf1153acc043c6cd..24a3d211cce9e908378baba167d9a0adbc2a854b
@@@ -1,4 -1,41 +1,42 @@@
- #define LATENCY_THINKRATE 10
+ #include "g_world.qh"
+ #include "../common/buffs.qh"
+ #if defined(CSQC)
+ #elif defined(MENUQC)
+ #elif defined(SVQC)
+     #include "../common/constants.qh"
+     #include "../common/stats.qh"
+     #include "../common/teams.qh"
+     #include "../common/util.qh"
+     #include "../common/monsters/sv_monsters.qh"
+     #include "../common/weapons/weapons.qh"
+     #include "weapons/weaponstats.qh"
+     #include "autocvars.qh"
+     #include "constants.qh"
+     #include "defs.qh"
+     #include "../common/notifications.qh"
+     #include "mutators/mutators_include.qh"
+     #include "campaign.qh"
+     #include "../common/mapinfo.qh"
+     #include "command/common.qh"
+     #include "command/vote.qh"
+     #include "command/getreplies.qh"
+     #include "command/sv_cmd.qh"
+     #include "anticheat.qh"
+     #include "cheats.qh"
++      #include "../common/turrets/turrets.qh"
+     #include "../common/playerstats.qh"
+     #include "g_hook.qh"
+     #include "scores.qh"
+     #include "mapvoting.qh"
+     #include "ipban.qh"
+     #include "race.qh"
+     #include "antilag.qh"
+     #include "secret.qh"
+ #endif
+ const float LATENCY_THINKRATE = 10;
  .float latency_sum;
  .float latency_cnt;
  .float latency_time;
index db706003be07673ea998e31750af5d38551da21c,d998ea7999b836763b21472eedd131204983e1b2..eb457449ec61aca0073cd66fd5fd2d80d52757b6
@@@ -1,9 -1,35 +1,34 @@@
- var void remove(entity e);
- void objerror(string s);
- void droptofloor();
- .vector dropped_origin;
+ #if defined(CSQC)
+ #elif defined(MENUQC)
+ #elif defined(SVQC)
+       #include "miscfunctions.qh"
+       #include "../dpdefs/progsdefs.qh"
+     #include "../dpdefs/dpextensions.qh"
+     #include "../common/playerstats.qh"
+     #include "../warpzonelib/anglestransform.qh"
+     #include "../warpzonelib/server.qh"
+     #include "../common/constants.qh"
+     #include "../common/teams.qh"
+     #include "../common/util.qh"
+     #include "../common/urllib.qh"
+     #include "../common/command/generic.qh"
+     #include "../common/weapons/weapons.qh"
+     #include "weapons/accuracy.qh"
+     #include "weapons/csqcprojectile.qh"
+     #include "weapons/selection.qh"
+     #include "t_items.qh"
+     #include "autocvars.qh"
+     #include "constants.qh"
+     #include "defs.qh"
+     #include "../common/notifications.qh"
+     #include "../common/deathtypes.qh"
+     #include "mutators/mutators_include.qh"
 -    #include "tturrets/include/turrets_early.qh"
+     #include "../common/mapinfo.qh"
+     #include "command/common.qh"
+     #include "../csqcmodellib/sv_model.qh"
+     #include "ipban.qh"
+ #endif
  
- void traceline_antilag (entity source, vector v1, vector v2, float nomonst, entity forent, float lag);
  void crosshair_trace(entity pl)
  {
        traceline_antilag(pl, pl.cursor_trace_start, pl.cursor_trace_start + normalize(pl.cursor_trace_endpos - pl.cursor_trace_start) * MAX_SHOT_DISTANCE, MOVE_NORMAL, pl, ANTILAG_LATENCY(pl));
index 0f52e34f033aa6b9f6f1231f9043494cea3d3e59,a0170e4803f04ae82fad8c363f97f3fa5f27d454..95f9604a0d3c298488e0026cef07d45781e6e756
@@@ -1,3 -1,85 +1,83 @@@
 -    #include "../tturrets/include/turrets_early.qh"
+ #if defined(CSQC)
+ #elif defined(MENUQC)
+ #elif defined(SVQC)
+     #include "../../dpdefs/progsdefs.qh"
+     #include "../../dpdefs/dpextensions.qh"
+     #include "../../warpzonelib/anglestransform.qh"
+     #include "../../warpzonelib/mathlib.qh"
+     #include "../../warpzonelib/common.qh"
+     #include "../../warpzonelib/util_server.qh"
+     #include "../../warpzonelib/server.qh"
+     #include "../../common/constants.qh"
+     #include "../../common/stats.qh"
+     #include "../../common/teams.qh"
+     #include "../../common/util.qh"
+     #include "../../common/nades.qh"
+     #include "../../common/buffs.qh"
+     #include "../../common/test.qh"
+     #include "../../common/counting.qh"
+     #include "../../common/urllib.qh"
+     #include "../../common/command/markup.qh"
+     #include "../../common/command/rpn.qh"
+     #include "../../common/command/generic.qh"
+     #include "../../common/command/shared_defs.qh"
+     #include "../../common/net_notice.qh"
+     #include "../../common/animdecide.qh"
+     #include "../../common/monsters/monsters.qh"
+     #include "../../common/monsters/sv_monsters.qh"
+     #include "../../common/monsters/spawn.qh"
+     #include "../../common/weapons/config.qh"
+     #include "../../common/weapons/weapons.qh"
+     #include "../weapons/accuracy.qh"
+     #include "../weapons/common.qh"
+     #include "../weapons/csqcprojectile.qh"
+     #include "../weapons/hitplot.qh"
+     #include "../weapons/selection.qh"
+     #include "../weapons/spawning.qh"
+     #include "../weapons/throwing.qh"
+     #include "../weapons/tracing.qh"
+     #include "../weapons/weaponstats.qh"
+     #include "../weapons/weaponsystem.qh"
+     #include "../t_items.qh"
+     #include "../autocvars.qh"
+     #include "../constants.qh"
+     #include "../defs.qh"
+     #include "../../common/notifications.qh"
+     #include "../../common/deathtypes.qh"
+     #include "mutators_include.qh"
 -    #include "../tturrets/include/turrets.qh"
+     #include "../vehicles/vehicles_def.qh"
+     #include "../campaign.qh"
+     #include "../../common/campaign_common.qh"
+     #include "../../common/mapinfo.qh"
+     #include "../command/common.qh"
+     #include "../command/banning.qh"
+     #include "../command/radarmap.qh"
+     #include "../command/vote.qh"
+     #include "../command/getreplies.qh"
+     #include "../command/cmd.qh"
+     #include "../command/sv_cmd.qh"
+     #include "../../common/csqcmodel_settings.qh"
+     #include "../../csqcmodellib/common.qh"
+     #include "../../csqcmodellib/sv_model.qh"
+     #include "../anticheat.qh"
+     #include "../cheats.qh"
+     #include "../../common/playerstats.qh"
+     #include "../portals.qh"
+     #include "../g_hook.qh"
+     #include "../scores.qh"
+     #include "../spawnpoints.qh"
+     #include "../mapvoting.qh"
+     #include "../ipban.qh"
+     #include "../race.qh"
+     #include "../antilag.qh"
+     #include "../playerdemo.qh"
+     #include "../round_handler.qh"
+     #include "../item_key.qh"
+     #include "../secret.qh"
+     #include "../pathlib/pathlib.qh"
+     #include "../vehicles/vehicles.qh"
+ #endif
  #include "base.qc"
  #include "gamemode_assault.qc"
  #include "gamemode_ca.qc"
index 68ded63d8836a71f8411f309b10fff654471eb89,85e75cda9e2fce18b2f2715b0bd1c10e8452b7bb..527c427124f162f2df61320d6e9d85ea29c4ec6f
@@@ -163,104 -83,32 +83,38 @@@ weapons/throwing.q
  weapons/tracing.qc
  weapons/weaponstats.qc
  weapons/weaponsystem.qc
- ../common/weapons/config.qc
- ../common/weapons/weapons.qc // TODO
  
- t_items.qc
- cl_impulse.qc
- ent_cs.qc
- cl_player.qc
- cl_client.qc
- t_plats.qc
- antilag.qc
- //ctf.qc
- //domination.qc
- //mode_onslaught.qc
- //nexball.qc
- g_hook.qc
- t_swamp.qc
- campaign.qc
+ ../common/animdecide.qc
+ ../common/buffs.qc
  ../common/campaign_file.qc
  ../common/campaign_setup.qc
- ../common/urllib.qc
+ ../common/command/generic.qc
  ../common/command/markup.qc
  ../common/command/rpn.qc
- ../common/command/generic.qc
- ../common/net_notice.qc
- command/common.qc
- command/banning.qc
- command/radarmap.qc
- command/vote.qc
- command/getreplies.qc
- command/cmd.qc
- command/sv_cmd.qc
- //assault.qc
- ipban.qc
  ../common/mapinfo.qc
- t_quake3.qc
- t_halflife.qc
- t_quake.qc
- race.qc
- //// tZork Vehicles ////
- vehicles/vehicles.qh
- scores.qc
- spawnpoints.qc
- portals.qc
- target_spawn.qc
- func_breakable.qc
- target_music.qc
+ ../common/monsters/monsters.qc
+ ../common/monsters/spawn.qc
+ ../common/monsters/sv_monsters.qc
  ../common/nades.qc
- ../common/buffs.qc
- ../csqcmodellib/sv_model.qc
- playerdemo.qc
- anticheat.qc
- cheats.qc
+ ../common/net_notice.qc
+ ../common/notifications.qc
  ../common/playerstats.qc
- round_handler.qc
+ ../common/test.qc
+ ../common/urllib.qc
+ ../common/util.qc
 +../common/turrets/sv_turrets.qc
 +../common/turrets/config.qc
++../common/turrets/util.qc
 +../common/turrets/turrets.qc
 +../common/turrets/checkpoint.qc
 +../common/turrets/targettrigger.qc
+ ../common/weapons/config.qc
+ ../common/weapons/weapons.qc // TODO
  
- ../common/monsters/sv_monsters.qc
- ../common/monsters/monsters.qc
- ../common/monsters/spawn.qc
- mutators/mutators_include.qc
+ ../csqcmodellib/sv_model.qc
  
  ../warpzonelib/anglestransform.qc
- ../warpzonelib/mathlib.qc
  ../warpzonelib/common.qc
- ../warpzonelib/util_server.qc
+ ../warpzonelib/mathlib.qc
  ../warpzonelib/server.qc
- ../common/animdecide.qc
- ../common/test.qc
- ../common/util.qc
- ../common/notifications.qc
+ ../warpzonelib/util_server.qc
index 5bed9ec930030747e981ae09a17a3e0d935dd7f2,46df0eb78636d45f82d5cab7e64ff1f2cdfa412f..53704a06f7e35a6c5b64923d9f10af9b4395552a
@@@ -1,3 -1,24 +1,23 @@@
 -    #include "tturrets/include/turrets_early.qh"
+ #include "t_teleporters.qh"
+ #if defined(CSQC)
+ #elif defined(MENUQC)
+ #elif defined(SVQC)
+     #include "../warpzonelib/common.qh"
+     #include "../warpzonelib/util_server.qh"
+     #include "../warpzonelib/server.qh"
+     #include "../common/constants.qh"
+     #include "../common/util.qh"
+     #include "weapons/csqcprojectile.qh"
+     #include "autocvars.qh"
+     #include "constants.qh"
+     #include "defs.qh"
+     #include "../common/deathtypes.qh"
+     #include "vehicles/vehicles_def.qh"
+     #include "../common/mapinfo.qh"
+     #include "anticheat.qh"
+ #endif
  void trigger_teleport_use()
  {
        if(teamplay)
diff --cc qcsrc/server/tturrets/system/system_main.qc
index d56a81bbf06b029c389010de5629bf4fd7e66012,f2b0c56ce846d596cdd486772c89faa98d3b2160..0000000000000000000000000000000000000000
deleted file mode 100644,100644
+++ /dev/null
@@@ -1,1378 -1,1378 +1,0 @@@
--#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.turret_type);
--
-           WriteCoord(MSG_ENTITY, self.origin_x);
-           WriteCoord(MSG_ENTITY, self.origin_y);
-           WriteCoord(MSG_ENTITY, self.origin_z);
 -          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);
 -          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));
 -        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));
 -        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.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.velocity.x));
 -        WriteShort(MSG_ENTITY, rint(self.velocity.y));
 -        WriteShort(MSG_ENTITY, rint(self.velocity.z));
--
-         WriteShort(MSG_ENTITY, rint(self.angles_y));
 -        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.tur_health) * 255));
--    }
--
-       return TRUE;
 -      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_maxrot   = 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_rot   = cvar(strcat(sbase,"_track_accel_rot"));
--    ent.track_blendrate   = cvar(strcat(sbase,"_track_blendrate"));
--
--    if(is_reload)
--        if(ent.turret_respawnhook)
--            ent.turret_respawnhook();
--}
--
--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_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
--    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();
--}
--
--void turret_projectile_damage(entity inflictor, entity attacker, float damage, float 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_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;
--}
--
--/*
--vector turret_fovsearch_pingpong()
--{
--    vector wish_angle;
--    if(self.phase < time)
--    {
--        if( self.tur_head.phase )
--            self.tur_head.phase = 0;
--        else
--            self.tur_head.phase = 1;
--        self.phase = time + 5;
--    }
--
--    if( self.tur_head.phase)
--        wish_angle = self.idle_aim + '0 1 0' * (self.aim_maxrot * (self.target_select_fov / 360));
--    else
--        wish_angle = self.idle_aim - '0 1 0' * (self.aim_maxrot * (self.target_select_fov / 360));
--
--    return wish_angle;
--}
--
--vector turret_fovsearch_steprot()
--{
--    vector wish_angle;
--    //float rot_add;
--
--    wish_angle   = self.tur_head.angles;
--    wish_angle_x = self.idle_aim_x;
--
--    if (self.phase < time)
--    {
--        //rot_add = self.aim_maxrot / self.target_select_fov;
--        wish_angle_y += (self.target_select_fov * 2);
--
--        if(wish_angle_y > 360)
--            wish_angle_y = wish_angle_y - 360;
--
--         self.phase = time + 1.5;
--    }
--
--    return wish_angle;
--}
--
--vector turret_fovsearch_random()
--{
--    vector wish_angle;
--
--    if (self.phase < time)
--    {
--        wish_angle_y = random() * self.aim_maxrot;
--        if(random() < 0.5)
--            wish_angle_y *= -1;
--
--        wish_angle_x = random() * self.aim_maxpitch;
--        if(random() < 0.5)
--            wish_angle_x *= -1;
--
--        self.phase = time + 5;
--
--        self.tur_aimpos = wish_angle;
--    }
--
--    return self.idle_aim + self.tur_aimpos;
--}
--*/
--
--/**
--** Handles head rotation according to
--** the units .track_type and .track_flags
--**/
--.float turret_framecounter;
--void turret_stdproc_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);
 -    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 += 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)
 -                if(self.tur_head.angles.x  < -self.aim_maxpitch)
--                    self.tur_head.angles_x = self.aim_maxpitch;
--            }
--
--            if (self.track_flags & TFL_TRACK_ROT)
--            {
-                 self.tur_head.angles_y += bound(-f_tmp, move_angle_y, f_tmp);
-                 if(self.tur_head.angles_y > self.aim_maxrot)
 -                self.tur_head.angles_y += bound(-f_tmp, move_angle.y, f_tmp);
 -                if(self.tur_head.angles.y > self.aim_maxrot)
--                    self.tur_head.angles_y = self.aim_maxrot;
--
-                 if(self.tur_head.angles_y  < -self.aim_maxrot)
 -                if(self.tur_head.angles.y  < -self.aim_maxrot)
--                    self.tur_head.angles_y = self.aim_maxrot;
--            }
--
--            // 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_rot * f_tmp, self.aim_speed);
 -            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_rot * 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);
 -            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 = 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)
 -        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_ROT)
--    {
-         self.tur_head.avelocity_y = move_angle_y;
 -        self.tur_head.avelocity_y = move_angle.y;
--
-         if((self.tur_head.angles_y + self.tur_head.avelocity_y * self.ticrate) > self.aim_maxrot)
 -        if((self.tur_head.angles.y + self.tur_head.avelocity.y * self.ticrate) > self.aim_maxrot)
--        {
--            self.tur_head.avelocity_y = 0;
--            self.tur_head.angles_y = self.aim_maxrot;
--
--            self.SendFlags  |= TNSF_ANG;
--        }
--
-         if((self.tur_head.angles_y + self.tur_head.avelocity_y * self.ticrate) < -self.aim_maxrot)
 -        if((self.tur_head.angles.y + self.tur_head.avelocity.y * self.ticrate) < -self.aim_maxrot)
--        {
--            self.tur_head.avelocity_y = 0;
--            self.tur_head.angles_y = -self.aim_maxrot;
--
--            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;
--    }
--}
--
--
--/*
-- + = 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_OWM_AMMO
-- + TFL_FIRECHECK_OTHER_AMMO
-- + TFL_FIRECHECK_REFIRE
--*/
--
--/**
--** Preforms pre-fire checks based on the uints firecheck_flags
--**/
--float turret_stdproc_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_OWM_AMMO)
--        if (self.ammo < self.shot_dmg)
--            return 0;
--
--    // Other's ammo? (support-supply units)
--    if (self.firecheck_flags & TFL_FIRECHECK_OTHER_AMMO)
--        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;
--}
--
--/*
-- + TFL_TARGETSELECT_NO
-- + TFL_TARGETSELECT_LOS
-- + TFL_TARGETSELECT_PLAYERS
-- + TFL_TARGETSELECT_MISSILES
-- - TFL_TARGETSELECT_TRIGGERTARGET
-- + TFL_TARGETSELECT_ANGLELIMITS
-- + TFL_TARGETSELECT_RANGELIMTS
-- + 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.owner == e_turret)
--        return -0.5;
--
--    if (!checkpvs(e_target.origin, e_turret))
--        return -1;
--
--    if (!e_target)
--        return -2;
--
--      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_target.vehicle_flags & VHF_ISVEHICLE)
--    {
--        if (e_target.vehicle_health <= 0)
--            return -6;
--    }
--    else if (e_target.health <= 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.turret_firefunc || 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_RANGELIMTS)
--    {
--        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)
 -        if (fabs(tvt_tadv.x) > e_turret.aim_maxpitch)
--            return -17;
--
-         if (fabs(tvt_tadv_y) > e_turret.aim_maxrot)
 -        if (fabs(tvt_tadv.y) > e_turret.aim_maxrot)
--            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;
--}
--
--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_stdproc_respawn();
--    }
--
--#ifdef TURRET_DEBUG
--    if (self.tur_dbg_tmr1 < time)
--    {
--        if (self.enemy) paint_target (self.enemy,128,self.tur_dbg_rvec,0.9);
--        paint_target(self,256,self.tur_dbg_rvec,0.9);
--        self.tur_dbg_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_stdproc_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_stdproc_aim_generic();
--
--        // Turn & pitch?
--        if (!(self.track_flags & TFL_TRACK_NO))
--            turret_stdproc_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_stdproc_aim_generic();
--
--                // Turn & pitch
--                if (!(self.track_flags & TFL_TRACK_NO))
--                    turret_stdproc_track();
--
--                turret_do_updates(self);
--
--                // Fire!
--                if (self.turret_firecheckfunc() != 0)
--                    turret_fire();
--
--                if(self.turret_postthink)
--                    self.turret_postthink();
--
--                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_stdproc_track();
--
--            // do any per-turret stuff
--            if(self.turret_postthink)
--                self.turret_postthink();
--
--            // 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_stdproc_aim_generic();
--
--        // Turn & pitch?
--        if (!(self.track_flags & TFL_TRACK_NO))
--            turret_stdproc_track();
--
--        turret_do_updates(self);
--
--        // Fire?
--        if (self.turret_firecheckfunc())
--            turret_fire();
--    }
--
--    // do any custom per-turret stuff
--    if(self.turret_postthink)
--        self.turret_postthink();
--}
--
--void turret_fire()
--{
--    if (autocvar_g_turrets_nofire != 0)
--        return;
--
--    self.turret_firefunc();
--
--    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_dbg_rvec, self.tur_impacttime + 0.25);
--#endif
--}
--
--void turret_stdproc_fire()
--{
--    dprint("^1Bang, ^3your dead^7 ",self.enemy.netname,"! ^1(turret with no real firefunc)\n");
--}
--
--/*
--    When .used a turret switch team to activator.team.
--    If activator is world, the turret go inactive.
--*/
--void turret_stdproc_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);
 -    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 (e.turrcaps_flags & TFL_TURRCAPS_ISTURRET)
--            {
--                load_unit_settings(e,e.cvar_basename,1);
--                if(e.turret_postthink)
--                    e.turret_postthink();
--            }
--
--            e = nextent(e);
--        }
--        cvar_set("g_turrets_reloadcvars","0");
--    }
--}
--
--/*
--* Standard turret initialization. use this!
--* (unless you have a very good reason not to)
--* if the return value is 0, the turret should be removed.
--*/
--float turret_stdproc_init (string cvar_base_name, string base, string head, float _turret_type)
--{
--      entity e, ee = world;
--
--    // Are turrets allowed?
--    if (autocvar_g_turrets == 0)
--        return 0;
--
--    if(_turret_type < 1 || _turret_type > TID_LAST)
--    {
--        dprint("Invalid / Unkown turret type\"", ftos(_turret_type), "\", aborting!\n");
--        return 0;
--    }
--    self.turret_type = _turret_type;
--
--    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(); // why can't we use regular droptofloor here?
--
--    // Terrainbase spawnflag. This puts a enlongated model
--    // under the turret, so it looks ok on uneaven surfaces.
--    /*  TODO: Handle this with CSQC
--    if (self.spawnflags & TSF_TERRAINBASE)
--    {
--        entity tb;
--        tb = spawn();
--        setmodel(tb,"models/turrets/terrainbase.md3");
--        setorigin(tb,self.origin);
--        tb.solid = SOLID_BBOX;
--    }
--    */
--
--    self.cvar_basename = cvar_base_name;
--    load_unit_settings(self, self.cvar_basename, 0);
--
--    self.effects = EF_NODRAW;
--
--    // Handle turret teams.
--    if (!teamplay)
--              self.team = MAX_SHOT_DISTANCE; // Group all turrets into the same team, so they dont kill eachother.
--      else if(g_onslaught && self.targetname)
--      {
--              e = find(world,target,self.targetname);
--              if(e != world)
--              {
--                      self.team = e.team;
--                      ee = e;
--              }
--      }
--      else if(!self.team)
--              self.team = MAX_SHOT_DISTANCE; // Group all turrets into the same team, so they dont kill eachother.
--
--    /*
--    * Try to guess some reasonaly defaults
--    * for missing params and do sanety checks
--    * thise checks could produce some "interesting" results
--    * if it hits a glitch in my logic :P so try to set as mutch
--    * as possible beforehand.
--    */
--    if (!self.ticrate)
--    {
--        if (self.turrcaps_flags & TFL_TURRCAPS_SUPPORT)
--            self.ticrate = 0.2;     // Support units generaly dont need to have a high speed ai-loop
--        else
--            self.ticrate = 0.1;     // 10 fps for normal turrets
--    }
--
--    self.ticrate = bound(sys_frametime, self.ticrate, 60);  // keep it sane
--
--// General stuff
--    if (self.netname == "")
--        self.netname = self.classname;
--
--    if (!self.respawntime)
--        self.respawntime = 60;
--    self.respawntime = max(-1, self.respawntime);
--
--    if (!self.health)
--        self.health = 1000;
--    self.tur_health = max(1, self.health);
-     self.bot_attack = TRUE;
-     self.monster_attack = TRUE;
 -    self.bot_attack = true;
 -    self.monster_attack = true;
--
--    if (!self.turrcaps_flags)
--        self.turrcaps_flags = TFL_TURRCAPS_RADIUSDMG | TFL_TURRCAPS_MEDPROJ | TFL_TURRCAPS_PLAYERKILL;
--
--    if (!self.damage_flags)
--        self.damage_flags = TFL_DMG_YES | TFL_DMG_RETALIATE | TFL_DMG_AIMSHAKE;
--
--// Shot stuff.
--    if (!self.shot_refire)
--        self.shot_refire = 1;
--    self.shot_refire = bound(0.01, self.shot_refire, 9999);
--
--    if (!self.shot_dmg)
--        self.shot_dmg  = self.shot_refire * 50;
--    self.shot_dmg = max(1, self.shot_dmg);
--
--    if (!self.shot_radius)
--        self.shot_radius = self.shot_dmg * 0.5;
--    self.shot_radius = max(1, self.shot_radius);
--
--    if (!self.shot_speed)
--        self.shot_speed = 2500;
--    self.shot_speed = max(1, self.shot_speed);
--
--    if (!self.shot_spread)
--        self.shot_spread = 0.0125;
--    self.shot_spread = bound(0.0001, self.shot_spread, 500);
--
--    if (!self.shot_force)
--        self.shot_force = self.shot_dmg * 0.5 + self.shot_radius * 0.5;
--    self.shot_force = bound(0.001, self.shot_force, 5000);
--
--    if (!self.shot_volly)
--        self.shot_volly = 1;
--    self.shot_volly = bound(1, self.shot_volly, floor(self.ammo_max / self.shot_dmg));
--
--    if (!self.shot_volly_refire)
--        self.shot_volly_refire = self.shot_refire * self.shot_volly;
--    self.shot_volly_refire = bound(self.shot_refire, self.shot_volly_refire, 60);
--
--    if (!self.firecheck_flags)
--        self.firecheck_flags = TFL_FIRECHECK_DEAD | TFL_FIRECHECK_DISTANCES |
--                               TFL_FIRECHECK_LOS | TFL_FIRECHECK_AIMDIST | TFL_FIRECHECK_TEAMCECK |
--                               TFL_FIRECHECK_OWM_AMMO | TFL_FIRECHECK_REFIRE;
--
--// Range stuff.
--    if (!self.target_range)
--        self.target_range = self.shot_speed * 0.5;
--    self.target_range = bound(0, self.target_range, MAX_SHOT_DISTANCE);
--
--    if (!self.target_range_min)
--        self.target_range_min = self.shot_radius * 2;
--    self.target_range_min = bound(0, self.target_range_min, MAX_SHOT_DISTANCE);
--
--    if (!self.target_range_optimal)
--        self.target_range_optimal = self.target_range * 0.5;
--    self.target_range_optimal = bound(0, self.target_range_optimal, MAX_SHOT_DISTANCE);
--
--
--// Aim stuff.
--    if (!self.aim_maxrot)
--        self.aim_maxrot = 90;
--    self.aim_maxrot = bound(0, self.aim_maxrot, 360);
--
--    if (!self.aim_maxpitch)
--        self.aim_maxpitch = 20;
--    self.aim_maxpitch = bound(0, self.aim_maxpitch, 90);
--
--    if (!self.aim_speed)
--        self.aim_speed = 36;
--    self.aim_speed  = bound(0.1, self.aim_speed, 1000);
--
--    if (!self.aim_firetolerance_dist)
--        self.aim_firetolerance_dist  = 5 + (self.shot_radius * 2);
--    self.aim_firetolerance_dist = bound(0.1, self.aim_firetolerance_dist, MAX_SHOT_DISTANCE);
--
--    if (!self.aim_flags)
--    {
--        self.aim_flags = TFL_AIM_LEAD | TFL_AIM_SHOTTIMECOMPENSATE;
--        if(self.turrcaps_flags & TFL_TURRCAPS_RADIUSDMG)
--            self.aim_flags |= TFL_AIM_GROUNDGROUND;
--    }
--
--    if (!self.track_type)
--        self.track_type = TFL_TRACKTYPE_STEPMOTOR;
--
--    if (self.track_type != TFL_TRACKTYPE_STEPMOTOR)
--    {
--        // Fluid / Ineria mode. Looks mutch nicer.
--        // Can reduce aim preformance alot, needs a bit diffrent aimspeed
--
--        if (!self.aim_speed)
--            self.aim_speed = 180;
--        self.aim_speed = bound(0.1, self.aim_speed, 1000);
--
--        if (!self.track_accel_pitch)
--            self.track_accel_pitch = 0.5;
--
--        if (!self.track_accel_rot)
--            self.track_accel_rot   = 0.5;
--
--        if (!self.track_blendrate)
--            self.track_blendrate   = 0.35;
--    }
--
--    if (!self.track_flags)
--        self.track_flags = TFL_TRACK_PITCH | TFL_TRACK_ROT;
--
--
--// Target selection stuff.
--    if (!self.target_select_rangebias)
--        self.target_select_rangebias = 1;
--    self.target_select_rangebias = bound(-10, self.target_select_rangebias, 10);
--
--    if (!self.target_select_samebias)
--        self.target_select_samebias = 1;
--    self.target_select_samebias = bound(-10, self.target_select_samebias, 10);
--
--    if (!self.target_select_anglebias)
--        self.target_select_anglebias = 1;
--    self.target_select_anglebias = bound(-10, self.target_select_anglebias, 10);
--
--    if (!self.target_select_missilebias)
--        self.target_select_missilebias = -10;
--
--    self.target_select_missilebias = bound(-10, self.target_select_missilebias, 10);
--    self.target_select_playerbias = bound(-10, self.target_select_playerbias, 10);
--
--    if (!self.target_select_flags)
--    {
--            self.target_select_flags = TFL_TARGETSELECT_LOS | TFL_TARGETSELECT_TEAMCHECK
--                                     | TFL_TARGETSELECT_RANGELIMTS | TFL_TARGETSELECT_ANGLELIMITS;
--
--        if (self.turrcaps_flags & TFL_TURRCAPS_MISSILEKILL)
--            self.target_select_flags |= TFL_TARGETSELECT_MISSILES;
--
--        if (self.turrcaps_flags & TFL_TURRCAPS_PLAYERKILL)
--            self.target_select_flags |= TFL_TARGETSELECT_PLAYERS;
--        //else
--        //    self.target_select_flags = TFL_TARGETSELECT_NO;
--    }
--
--    self.target_validate_flags = self.target_select_flags;
--
--// Ammo stuff
--    if (!self.ammo_max)
--        self.ammo_max = self.shot_dmg * 10;
--    self.ammo_max = max(self.shot_dmg, self.ammo_max);
--
--    if (!self.ammo)
--        self.ammo = self.shot_dmg * 5;
--    self.ammo = bound(0,self.ammo, self.ammo_max);
--
--    if (!self.ammo_recharge)
--        self.ammo_recharge = self.shot_dmg * 0.5;
--    self.ammo_recharge = max(0 ,self.ammo_recharge);
--
--    // Convert the recharge from X per sec to X per ticrate
--    self.ammo_recharge = self.ammo_recharge * self.ticrate;
--
--    if (!self.ammo_flags)
--        self.ammo_flags = TFL_AMMO_ENERGY | TFL_AMMO_RECHARGE;
--
--// Damage stuff
--    if(self.spawnflags & TSL_NO_RESPAWN)
--        if (!(self.damage_flags & TFL_DMG_DEATH_NORESPAWN))
--            self.damage_flags |= TFL_DMG_DEATH_NORESPAWN;
--
--// Offsets & origins
--    if (!self.tur_shotorg)   self.tur_shotorg = '50 0 50';
--
--    if (!self.health)
--        self.health = 150;
--
--// Game hooks
--      if(MUTATOR_CALLHOOK(TurretSpawn))
--              return 0;
--
--// End of default & sanety checks, start building the turret.
--
--// Spawn extra bits
--    self.tur_head         = spawn();
--    self.tur_head.netname = self.tur_head.classname = "turret_head";
--    self.tur_head.team    = self.team;
--    self.tur_head.owner   = self;
--
--    setmodel(self, base);
--    setmodel(self.tur_head, head);
--
--    setsize(self, '-32 -32 0', '32 32 64');
--    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_health          = self.health;
--    self.solid               = SOLID_BBOX;
--    self.tur_head.solid      = SOLID_NOT;
--    self.takedamage          = DAMAGE_AIM;
--    self.tur_head.takedamage = DAMAGE_NO;
--    self.movetype            = MOVETYPE_NOCLIP;
--    self.tur_head.movetype   = MOVETYPE_NOCLIP;
--
--    // Defend mode?
--    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");
--        }
--    }
--
--    // In target defend mode, aim on the spot to defend when idle.
--    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';
--
--    // Attach stdprocs. override when and what needed
--    self.turret_firecheckfunc   = turret_stdproc_firecheck;
--    self.turret_firefunc        = turret_stdproc_fire;
--    self.event_damage           = turret_stdproc_damage;
--
--    if (self.turrcaps_flags & TFL_TURRCAPS_SUPPORT)
--        self.turret_score_target    = turret_stdproc_targetscore_support;
--    else
--        self.turret_score_target    = turret_stdproc_targetscore_generic;
--
--    self.use = turret_stdproc_use;
--
--    ++turret_count;
--    self.nextthink = time + 1;
--    self.nextthink +=  turret_count * sys_frametime;
--
--    self.tur_head.team = self.team;
--    self.view_ofs = '0 0 0';
--
--#ifdef TURRET_DEBUG
--    self.tur_dbg_start = self.nextthink;
--    while (vlen(self.tur_dbg_rvec) < 2)
--        self.tur_dbg_rvec  = randomvec() * 4;
--
-     self.tur_dbg_rvec_x = fabs(self.tur_dbg_rvec_x);
-     self.tur_dbg_rvec_y = fabs(self.tur_dbg_rvec_y);
-     self.tur_dbg_rvec_z = fabs(self.tur_dbg_rvec_z);
 -    self.tur_dbg_rvec_x = fabs(self.tur_dbg_rvec.x);
 -    self.tur_dbg_rvec_y = fabs(self.tur_dbg_rvec.y);
 -    self.tur_dbg_rvec_z = fabs(self.tur_dbg_rvec.z);
--#endif
--
--    // Its all good.
--    self.turrcaps_flags |= TFL_TURRCAPS_ISTURRET;
--
--    self.classname = "turret_main";
--
--    self.active = ACTIVE_ACTIVE;
--
--    // In ONS mode, and linked to a ONS ent. need to call the use to set team.
--    if (g_onslaught && ee)
--    {
--        activator = ee;
--        self.use();
--    }
--
--      turret_link();
--      turret_stdproc_respawn();
--    turret_tag_fire_update();
--
--    return 1;
--}
--
--
diff --cc qcsrc/server/tturrets/units/unit_ewheel.qc
index e8e677ac8c1dd4a6b36c5a83d72a5b35283846fe,7eb1622baf102b80fd1aba8407559613c6b10bf5..0000000000000000000000000000000000000000
deleted file mode 100644,100644
+++ /dev/null
@@@ -1,310 -1,310 +1,0 @@@
- #define ewheel_amin_stop 0
- #define ewheel_amin_fwd_slow 1
- #define ewheel_amin_fwd_fast 2
- #define ewheel_amin_bck_slow 3
- #define ewheel_amin_bck_fast 4
 -const float ewheel_amin_stop = 0;
 -const float ewheel_amin_fwd_slow = 1;
 -const float ewheel_amin_fwd_fast = 2;
 -const float ewheel_amin_bck_slow = 3;
 -const float ewheel_amin_bck_fast = 4;
--
--void ewheel_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); // WEAPONTODO: this is not a projectile made by the blaster, add separate effect for it
 -        _mis = turret_projectile("weapons/lasergun_fire.wav", 1, 0, DEATH_TURRET_EWHEEL, PROJECTILE_BLASTER, true, true); // WEAPONTODO: this is not a projectile made by the blaster, add separate effect for it
--        _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;
--    }
--
--}
--//#define EWHEEL_FANCYPATH
--void ewheel_move_path()
--{
--#ifdef EWHEEL_FANCYPATH
--    // 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 (vlen(self.origin - self.pathcurrent.origin) < 64)
--        self.pathcurrent = self.pathcurrent.enemy;
--#endif
--
--    if (self.pathcurrent)
--    {
--
--        self.moveto = self.pathcurrent.origin;
--        self.steerto = steerlib_attract2(self.moveto, 0.5, 500, 0.95);
--
--        movelib_move_simple(v_forward, autocvar_g_turrets_unit_ewheel_speed_fast, 0.4);
--    }
--}
--
--void  ewheel_move_enemy()
--{
--
--    float newframe;
--
--    self.steerto = steerlib_arrive(self.enemy.origin,self.target_range_optimal);
--
--    //self.steerto = steerlib_standoff(self.enemy.origin,self.target_range_optimal);
--    //self.steerto = steerlib_beamsteer(self.steerto,1024,64,68,256);
--    self.moveto  = self.origin + self.steerto * 128;
--
--    if (self.tur_dist_enemy > self.target_range_optimal)
--    {
--        if ( self.tur_head.spawnshieldtime < 1 )
--        {
--            newframe = ewheel_amin_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_amin_fwd_slow;
--            movelib_move_simple(v_forward, autocvar_g_turrets_unit_ewheel_speed_slow, 0.4);
--       }
--        else
--        {
--            newframe = ewheel_amin_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_amin_bck_slow;
--        movelib_move_simple(v_forward * -1, autocvar_g_turrets_unit_ewheel_speed_slow, 0.4);
--    }
--    else
--    {
--        newframe = ewheel_amin_stop;
--        movelib_beak_simple(autocvar_g_turrets_unit_ewheel_speed_stop);
--    }
--
-     turrets_setframe(newframe , FALSE);
 -    turrets_setframe(newframe , false);
--
--    /*if(self.frame != newframe)
--    {
--        self.frame = newframe;
--        self.SendFlags |= TNSF_ANIM;
--        self.anim_start_time = time;
--    }*/
--}
--
--
--void ewheel_move_idle()
--{
--    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 ewheel_postthink()
--{
--    float vz;
--    vector wish_angle, real_angle;
--
-     vz = self.velocity_z;
 -    vz = self.velocity.z;
--
-     self.angles_x = anglemods(self.angles_x);
-     self.angles_y = anglemods(self.angles_y);
 -    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);
 -    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;
--}
--
--void ewheel_respawnhook()
--{
--    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)
--              return;
--
--    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 = WALKER_PATH(self.origin,e.origin);
--            self.pathgoal = e;
--#else
--            self.pathcurrent  = e;
--#endif
--        }
--    }
--}
--
--void ewheel_diehook()
--{
--    self.velocity = '0 0 0';
--
--#ifdef EWHEEL_FANCYPATH
--    if (self.pathcurrent)
--        pathlib_deletepath(self.pathcurrent.owner);
--#endif
--    self.pathcurrent = world;
--}
--
--void turret_ewheel_dinit()
--{
--    entity e;
--
--    if (self.netname == "")
--        self.netname     = "eWheel Turret";
--
--    if (self.target != "")
--    {
--        e = find(world,targetname,self.target);
--        if (!e)
--        {
--            bprint("Warning! initital waypoint for ewheel does NOT exsist!\n");
--            self.target = "";
--        }
--
--        if (e.classname != "turret_checkpoint")
--            dprint("Warning: not a turrret path\n");
--        else
--            self.goalcurrent = e;
--    }
--
--    self.ammo_flags = TFL_AMMO_ENERGY | TFL_AMMO_RECHARGE | TFL_AMMO_RECIVE;
--    self.turrcaps_flags = TFL_TURRCAPS_PLAYERKILL | TFL_TURRCAPS_MOVE | TFL_TURRCAPS_ROAM ;
--    self.turret_respawnhook = ewheel_respawnhook;
--
--    self.turret_diehook = ewheel_diehook;
--
--    if (turret_stdproc_init("ewheel_std", "models/turrets/ewheel-base2.md3", "models/turrets/ewheel-gun1.md3", TID_EWHEEL) == 0)
--    {
--        remove(self);
--        return;
--    }
--
--    self.frame = 1;
--    self.target_select_flags   = TFL_TARGETSELECT_PLAYERS | TFL_TARGETSELECT_RANGELIMTS | TFL_TARGETSELECT_TEAMCHECK | TFL_TARGETSELECT_LOS;
--    self.target_validate_flags = TFL_TARGETSELECT_PLAYERS | TFL_TARGETSELECT_RANGELIMTS | TFL_TARGETSELECT_TEAMCHECK | TFL_TARGETSELECT_LOS;
-     self.iscreature = TRUE;
 -    self.iscreature = true;
--    self.teleportable = TELEPORT_NORMAL;
-     self.damagedbycontents = TRUE;
 -    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;
--
--    setsize(self, '-32 -32 0', '32 32 48');
--
--    // Our fire routine
--    self.turret_firefunc  = ewheel_attack;
--    self.turret_postthink = ewheel_postthink;
--    self.tur_head.frame = 1;
--
--    // 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);
--
--    //setorigin(self,self.origin + '0 0 128');
--    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 = WALKER_PATH(self.origin, e.origin);
--            self.pathgoal = e;
--#else
--            self.pathcurrent = e;
--#endif
--        }
--    }
--}
--
--void spawnfunc_turret_ewheel()
--{
--    g_turrets_common_precash();
--
--    precache_model ("models/turrets/ewheel-base2.md3");
--    precache_model ("models/turrets/ewheel-gun1.md3");
--
--    self.think = turret_ewheel_dinit;
--    self.nextthink = time + 0.5;
--}
diff --cc qcsrc/server/tturrets/units/unit_flac.qc
index 3c9e55863f7698d423ede49d0664115bc7fd660c,e398a83da58f133b63ec62f7f3f049493694a6db..0000000000000000000000000000000000000000
deleted file mode 100644,100644
+++ /dev/null
@@@ -1,74 -1,74 +1,0 @@@
--void spawnfunc_turret_flac();
--void turret_flac_dinit();
--void turret_flac_attack();
--
--void turret_flac_projectile_think_explode()
--{
--    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
--    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
--    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
--    remove(self);
--}
--
--void turret_flac_attack()
--{
--    entity proj;
--
--    turret_tag_fire_update();
--
-     proj = turret_projectile("weapons/hagar_fire.wav", 5, 0, DEATH_TURRET_FLAC, PROJECTILE_HAGAR, TRUE, TRUE);
 -    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;
--
--    self.tur_head.frame = self.tur_head.frame + 1;
--    if (self.tur_head.frame >= 4)
--        self.tur_head.frame = 0;
--
--}
--
--void turret_flac_dinit()
--{
--    if (self.netname == "")
--        self.netname  = "FLAC Cannon";
--
--    self.turrcaps_flags = TFL_TURRCAPS_RADIUSDMG | TFL_TURRCAPS_FASTPROJ | TFL_TURRCAPS_MISSILEKILL;
--    self.ammo_flags     = TFL_AMMO_ROCKETS | TFL_AMMO_RECHARGE;
--    self.aim_flags      = TFL_AIM_LEAD | TFL_AIM_SHOTTIMECOMPENSATE;
--
--    if (turret_stdproc_init("flac_std", "models/turrets/base.md3", "models/turrets/flac.md3", TID_FLAC) == 0)
--    {
--        remove(self);
--        return;
--    }
--    setsize(self.tur_head,'-32 -32 0','32 32 64');
--
--    self.damage_flags |= TFL_DMG_HEADSHAKE;
--    self.target_select_flags |= TFL_TARGETSELECT_NOTURRETS | TFL_TARGETSELECT_MISSILESONLY;
--
--    // Our fire routine
--    self.turret_firefunc  = turret_flac_attack;
--
--}
--/*QUAKED turret_flac (0 .5 .8) ?
--*/
--
--void spawnfunc_turret_flac()
--{
--    precache_model ("models/turrets/base.md3");
--    precache_model ("models/turrets/flac.md3");
--
--    self.think = turret_flac_dinit;
--    self.nextthink = time + 0.5;
--}
--
diff --cc qcsrc/server/tturrets/units/unit_machinegun.qc
index d235dfb32787124cdaf946b6bd59ff5178549db4,d235dfb32787124cdaf946b6bd59ff5178549db4..0000000000000000000000000000000000000000
deleted file mode 100644,100644
+++ /dev/null
@@@ -1,52 -1,52 +1,0 @@@
--void spawnfunc_turret_machinegun();
--void turret_machinegun_std_init();
--void turret_machinegun_attack();
--
--//.float bulletcounter;
--void turret_machinegun_attack()
--{
--    fireBullet (self.tur_shotorg, self.tur_shotdir_updated,self.shot_spread, 0, self.shot_dmg, self.shot_force, DEATH_TURRET_MACHINEGUN, 0);
--
--    W_MachineGun_MuzzleFlash(); // WEAPONTODO
--    setattachment(self.muzzle_flash, self.tur_head, "tag_fire");
--}
--
--
--void turret_machinegun_std_init()
--{
--    if (self.netname == "")      self.netname     = "Machinegun Turret";
--
--    self.ammo_flags = TFL_AMMO_BULLETS | TFL_AMMO_RECHARGE | TFL_AMMO_RECIVE;
--    self.turrcaps_flags = TFL_TURRCAPS_PLAYERKILL;
--    self.aim_flags = TFL_AIM_LEAD | TFL_AIM_SHOTTIMECOMPENSATE;
--
--    self.turrcaps_flags |= TFL_TURRCAPS_HITSCAN;
--
--    if (turret_stdproc_init("machinegun_std", "models/turrets/base.md3", "models/turrets/machinegun.md3", TID_MACHINEGUN) == 0)
--    {
--        remove(self);
--        return;
--    }
--
--    self.damage_flags |= TFL_DMG_HEADSHAKE;
--      self.target_select_flags = TFL_TARGETSELECT_PLAYERS | TFL_TARGETSELECT_RANGELIMTS | TFL_TARGETSELECT_TEAMCHECK;
--
--    // Our fire routine
--    self.turret_firefunc  = turret_machinegun_attack;
--
--}
--
--
--/*QUAKED turret_machinegun (0 .5 .8) ?
--* machinegun turret. does what you'd expect
--*/
--void spawnfunc_turret_machinegun()
--{
--    precache_model ("models/turrets/machinegun.md3");
--    precache_model ("models/turrets/base.md3");
--    precache_sound ("weapons/uzi_fire.wav");
--
--    self.think = turret_machinegun_std_init;
--    self.nextthink = time + 0.5;
--}
--
diff --cc qcsrc/server/tturrets/units/unit_plasma.qc
index 26a3dc04e42992eae003a698465b5659e525665e,1bfd8ac34d3ab278111b065c2e1cd702ab7552f0..0000000000000000000000000000000000000000
deleted file mode 100644,100644
+++ /dev/null
@@@ -1,173 -1,173 +1,0 @@@
--void spawnfunc_turret_plasma();
--void spawnfunc_turret_plasma_dual();
--
--void turret_plasma_std_init();
--void turret_plasma_dual_init();
--
--void turret_plasma_attack();
--
--
--void turret_plasma_postthink()
--{
--    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;
--}
--
--void turret_plasma_dual_postthink()
--{
--    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;
--}
--
--void turret_plasma_minsta_attack (void)
--{
--      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;
--      v = WarpZone_UnTransformOrigin(WarpZone_trace_transform, trace_endpos);
--      if(teamplay)
--      {
--          switch(self.team)
--          {
--            case NUM_TEAM_1:   // Red
--                    WarpZone_TrailParticles(world, particleeffectnum("TE_TEI_G3RED"), self.tur_shotorg, v);
--                break;
--            case NUM_TEAM_2:   // Blue
--                    WarpZone_TrailParticles(world, particleeffectnum("TE_TEI_G3BLUE"), self.tur_shotorg, v);
--                break;
--            case NUM_TEAM_3:   // Yellow
--                    WarpZone_TrailParticles(world, particleeffectnum("TE_TEI_G3YELLOW"), self.tur_shotorg, v);
--                break;
--            case NUM_TEAM_4:   // Pink
--                    WarpZone_TrailParticles(world, particleeffectnum("TE_TEI_G3PINK"), self.tur_shotorg, v);
--                break;
--          }
--      }
--      else
--        WarpZone_TrailParticles(world, particleeffectnum("TE_TEI_G3"), self.tur_shotorg, v);
--    if (self.tur_head.frame == 0)
--        self.tur_head.frame = 1;
--}
--
--void turret_plasma_attack()
--{
-     entity missile = turret_projectile("weapons/hagar_fire.wav", 1, 0, DEATH_TURRET_PLASMA, PROJECTILE_ELECTRO_BEAM, TRUE, TRUE);
 -    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;
--}
--
--void turret_plasma_dual_attack()
--{
-     entity missile = turret_projectile("weapons/hagar_fire.wav", 1, 0, DEATH_TURRET_PLASMA, PROJECTILE_ELECTRO_BEAM, TRUE, TRUE);
 -    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;
--}
--
--void turret_plasma_std_init()
--{
--    if (self.netname == "")      self.netname     = "Plasma Cannon";
--
--    // What ammo to use
--    self.ammo_flags = TFL_AMMO_ENERGY | TFL_AMMO_RECHARGE | TFL_AMMO_RECIVE;
--
--    // How to aim
--    self.aim_flags      = TFL_AIM_LEAD | TFL_AIM_SHOTTIMECOMPENSATE | TFL_AIM_GROUNDGROUND;
--    self.turrcaps_flags = TFL_TURRCAPS_RADIUSDMG | TFL_TURRCAPS_MEDPROJ | TFL_TURRCAPS_PLAYERKILL;
--
--    if (turret_stdproc_init("plasma_std", "models/turrets/base.md3", "models/turrets/plasma.md3", TID_PLASMA) == 0)
--    {
--        remove(self);
--        return;
--    }
--
--    self.damage_flags    |= TFL_DMG_HEADSHAKE;
--    self.firecheck_flags |= TFL_FIRECHECK_AFF;
--
--    // Our fireing routine
--    if(g_instagib)
--        self.turret_firefunc  = turret_plasma_minsta_attack;
--    else
--        self.turret_firefunc  = turret_plasma_attack;
--
--    // Custom per turret frame stuff. usualy animation.
--    self.turret_postthink = turret_plasma_postthink;
--    turret_do_updates(self);
--}
--
--
--void turret_plasma_dual_init()
--{
--    if (self.netname == "")      self.netname     = "Dual Plasma Cannon";
--
--    // What ammo to use
--    self.ammo_flags = TFL_AMMO_ENERGY | TFL_AMMO_RECHARGE | TFL_AMMO_RECIVE;
--
--    // How to aim at targets
--    self.aim_flags      = TFL_AIM_LEAD | TFL_AIM_SHOTTIMECOMPENSATE  | TFL_AIM_GROUNDGROUND ;
--    self.turrcaps_flags = TFL_TURRCAPS_RADIUSDMG | TFL_TURRCAPS_MEDPROJ | TFL_TURRCAPS_PLAYERKILL;
--
--    if (turret_stdproc_init("plasma_dual", "models/turrets/base.md3", "models/turrets/plasmad.md3", TID_PLASMA_DUAL) == 0)
--    {
--        remove(self);
--        return;
--    }
--
--    self.damage_flags    |= TFL_DMG_HEADSHAKE;
--    self.firecheck_flags |= TFL_FIRECHECK_AFF;
--
--    // Our fireing routine
--    self.turret_firefunc  = turret_plasma_dual_attack;
--
--    // Custom per turret frame stuff. usualy animation.
--    self.turret_postthink = turret_plasma_dual_postthink;
--}
--
--
--/*
--* Basic moderate (std) or fast (dual) fireing, short-mid range energy cannon.
--* Not too mutch of a therat on its own, but can be rather dangerous in groups.
--* Regenerates ammo slowly, support with a fusionreactor(s) to do some real damage.
--*/
--
--/*QUAKED turret_plasma (0 .5 .8) ?
--*/
--void spawnfunc_turret_plasma()
--{
--    g_turrets_common_precash();
--    precache_model ("models/turrets/plasma.md3");
--    precache_model ("models/turrets/base.md3");
--
--    self.think = turret_plasma_std_init;
--    self.nextthink = time + 0.5;
--}
--
--/*QUAKED turret_plasma_dual (0 .5 .8) ?
--*/
--void spawnfunc_turret_plasma_dual()
--{
--
--    precache_model ("models/turrets/plasmad.md3");
--    precache_model ("models/turrets/base.md3");
--
--    self.think = turret_plasma_dual_init;
--    self.nextthink = time + 0.5;
--}
--
diff --cc qcsrc/server/tturrets/units/unit_walker.qc
index a91daa190194c04cc7526a8a544c6beb1f41045d,4b1c44c1541ca24b8f3da79738db8c1113731e09..0000000000000000000000000000000000000000
deleted file mode 100644,100644
+++ /dev/null
@@@ -1,643 -1,643 +1,0 @@@
- #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_MEELE      9
- #define ANIM_SWIM       10
- #define ANIM_ROAM       11
 -const float ANIM_NO         = 0;
 -const float ANIM_TURN       = 1;
 -const float ANIM_WALK       = 2;
 -const float ANIM_RUN        = 3;
 -const float ANIM_STRAFE_L   = 4;
 -const float ANIM_STRAFE_R   = 5;
 -const float ANIM_JUMP       = 6;
 -const float ANIM_LAND       = 7;
 -const float ANIM_PAIN       = 8;
 -const float ANIM_MEELE      = 9;
 -const float ANIM_SWIM       = 10;
 -const float ANIM_ROAM       = 11;
--.float animflag;
--
- #define WALKER_MIN '-70 -70 0'
- #define WALKER_MAX '70 70 95'
 -const vector WALKER_MIN = '-70 -70 0';
 -const vector WALKER_MAX = '70 70 95';
--
--#define WALKER_PATH(s,e) pathlib_astar(s,e)
--
--float walker_firecheck()
--{
--    if (self.animflag == ANIM_MEELE)
--        return 0;
--
--    return turret_stdproc_firecheck();
--}
--
--void walker_meele_do_dmg()
--{
--    vector where;
--    entity e;
--
--    makevectors(self.angles);
--    where = self.origin + v_forward * 128;
--
--    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_std_meele_dmg, DEATH_TURRET_WALK_MEELE, '0 0 0', v_forward * autocvar_g_turrets_unit_walker_std_meele_force);
--
--        e = e.chain;
--    }
--}
--
--void walker_setnoanim()
--{
-     turrets_setframe(ANIM_NO, FALSE);
 -    turrets_setframe(ANIM_NO, false);
--    self.animflag = self.frame;
--}
--void walker_rocket_explode()
--{
--    RadiusDamage (self, self.owner, autocvar_g_turrets_unit_walker_std_rocket_dmg, 0, autocvar_g_turrets_unit_walker_std_rocket_radius, self, world, autocvar_g_turrets_unit_walker_std_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)
--{
--    self.health = self.health - damage;
--    self.velocity = self.velocity + vforce;
--
--    if (self.health <= 0)
--        W_PrepareExplosionByDamage(self.owner, walker_rocket_explode);
--}
--
--#define WALKER_ROCKET_MOVE movelib_move_simple(newdir, autocvar_g_turrets_unit_walker_std_rocket_speed, autocvar_g_turrets_unit_walker_std_rocket_turnrate); UpdateCSQCProjectile(self)
--void walker_rocket_loop();
--void walker_rocket_think()
--{
--    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.tur_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()
--{
--    vector newdir;
--    self.nextthink = time;
--
--    if (self.tur_health < time)
--    {
--        self.think = walker_rocket_explode;
--        return;
--    }
--
--    if (vlen(self.origin - self.tur_shotorg) < 100 )
--    {
--        self.think = walker_rocket_think;
--        return;
--    }
--
--    newdir = steerlib_pull(self.tur_shotorg);
--    WALKER_ROCKET_MOVE;
--
--    self.angles = vectoangles(self.velocity);
--}
--
--void walker_rocket_loop2()
--{
--    vector newdir;
--
--    self.nextthink = time;
--
--    if (self.tur_health < time)
--    {
--        self.think = walker_rocket_explode;
--        return;
--    }
--
--    if (vlen(self.origin - self.tur_shotorg) < 100 )
--    {
--        self.tur_shotorg = self.origin - '0 0 200';
--        self.think = walker_rocket_loop3;
--        return;
--    }
--
--    newdir = steerlib_pull(self.tur_shotorg);
--    WALKER_ROCKET_MOVE;
--}
--
--void walker_rocket_loop()
--{
--    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)
--{
--    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_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_std_rocket_speed;
--    rocket.angles             = vectoangles(rocket.velocity);
--    rocket.touch              = walker_rocket_explode;
--    rocket.flags              = FL_PROJECTILE;
--    rocket.solid              = SOLID_BBOX;
--    rocket.tur_health         = time + 9;
--    rocket.missile_flags = MIF_SPLASH | MIF_PROXY | MIF_GUIDED_HEAT;
--
-     CSQCProjectile(rocket, FALSE, PROJECTILE_ROCKET, FALSE); // no culling, has fly sound
 -    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)
--{
--    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
--    // 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 (vlen(self.origin - self.pathcurrent.origin) < 64)
--        self.pathcurrent = self.pathcurrent.enemy;
--
--    if(!self.pathcurrent)
--        return;
--
--    self.moveto = self.pathcurrent.origin;
--    self.steerto = steerlib_attract2(self.moveto, 0.5, 500, 0.95);
--    walker_move_to(self.moveto, 0);
--#endif
--}
--
--.float idletime;
--void walker_postthink()
--{
--    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;
 -                    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_std_meele_range && self.animflag != ANIM_MEELE)
--        {
--            vector wish_angle;
--
--            wish_angle = angleofs(self, self.enemy);
--            if (self.animflag != ANIM_SWIM)
-             if (fabs(wish_angle_y) < 15)
 -            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_MEELE;
--            }
--        }
--        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_std_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_std_rockets_range_min)
--                if (self.tur_dist_enemy < autocvar_g_turrets_unit_walker_std_rockets_range)
--                    self.tur_head.shot_volly = 4;
--            }
--        }
--        else
--        {
--            if (self.animflag != ANIM_MEELE)
--                walker_move_to(self.enemy.origin, self.tur_dist_enemy);
--        }
--    }
--
--    //if(self.animflag != ANIM_NO)
--    {
--        vector real_angle;
--        float turny = 0, turnx = 0;
--        float  vz;
--
--        real_angle = vectoangles(self.steerto) - self.angles;
-         vz         = self.velocity_z;
 -        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_MEELE:
--                if(self.frame != ANIM_MEELE)
--                {
--                    defer(0.41, walker_setnoanim);
--                    defer(0.21, walker_meele_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);
 -                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 );
 -            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 );
 -            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);
 -    turrets_setframe(self.animflag, false);
--}
--
--void walker_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);
--}
--
--
--void walker_respawnhook()
--{
--    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)
--              return;
--
--    setorigin(self, self.pos1);
--    self.angles = self.pos2;
--
--    if (self.target != "")
--    {
--        e = find(world, targetname, self.target);
--        if (!e)
--        {
--            dprint("Warning! initital waypoint for Walker does NOT exsist!\n");
--            self.target = "";
--        }
--
--        if (e.classname != "turret_checkpoint")
--            dprint("Warning: not a turrret path\n");
--        else
--        {
-- #ifdef WALKER_FANCYPATHING
--            self.pathcurrent = WALKER_PATH(self.origin, e.origin);
--            self.pathgoal = e;
--#else
--            self.pathcurrent = e;
--#endif
--        }
--    }
--}
--
--void walker_diehook()
--{
--#ifdef WALKER_FANCYPATHING
--    if (self.pathcurrent)
--        pathlib_deletepath(self.pathcurrent.owner);
--#endif
--    self.pathcurrent = world;
--}
--
--void turret_walker_dinit()
--{
--    entity e;
--
--    if (self.netname == "")      self.netname     = "Walker Turret";
--
--    self.ammo_flags = TFL_AMMO_BULLETS | TFL_AMMO_RECHARGE | TFL_AMMO_RECIVE;
--    self.turrcaps_flags = TFL_TURRCAPS_PLAYERKILL | TFL_TURRCAPS_MOVE ;
--    self.aim_flags = TFL_AIM_LEAD;
--
--    self.turrcaps_flags |= TFL_TURRCAPS_HITSCAN;
--
--
--    self.turret_respawnhook = walker_respawnhook;
--    self.turret_diehook = walker_diehook;
--
--    self.ticrate = 0.05;
--    if (turret_stdproc_init("walker_std", "models/turrets/walker_body.md3", "models/turrets/walker_head_minigun.md3", TID_WALKER) == 0)
--    {
--        remove(self);
--        return;
--    }
--    setsize(self, WALKER_MIN, WALKER_MAX);
--    self.target_select_flags   = TFL_TARGETSELECT_PLAYERS | TFL_TARGETSELECT_RANGELIMTS | TFL_TARGETSELECT_TEAMCHECK | TFL_TARGETSELECT_LOS;
--    self.target_validate_flags = TFL_TARGETSELECT_PLAYERS | TFL_TARGETSELECT_RANGELIMTS | TFL_TARGETSELECT_TEAMCHECK | TFL_TARGETSELECT_LOS;
-     self.iscreature = TRUE;
 -    self.iscreature = true;
--    self.teleportable = TELEPORT_NORMAL;
-     self.damagedbycontents = TRUE;
 -    self.damagedbycontents = true;
--    self.movetype   = MOVETYPE_WALK;
--    self.solid      = SOLID_SLIDEBOX;
--    self.takedamage = DAMAGE_AIM;
--    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.idle_aim = '0 0 0';
--    self.turret_firecheckfunc = walker_firecheck;
--    self.turret_firefunc      = walker_attack;
--    self.turret_postthink     = walker_postthink;
--
--    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 = WALKER_PATH(self.origin, e.origin);
--            self.pathgoal = e;
--#else
--            self.pathcurrent = e;
--#endif
--        }
--    }
--}
--
--
--void spawnfunc_turret_walker()
--{
--    g_turrets_common_precash();
--
--    precache_model ("models/turrets/walker_head_minigun.md3");
--    precache_model ("models/turrets/walker_body.md3");
--    precache_model ( "models/turrets/rocket.md3");
--    precache_sound ( "weapons/rocket_impact.wav" );
--
--    self.think = turret_walker_dinit;
--    self.nextthink = time + 0.5;
--}
Simple merge
index fc9cee8657f97e58af04c999e87f3d80e6358052,87dfe52a7e55f2d0a8b94dadbbb4dcacca51653a..45c3713af7f2260e3b6ed190fd77528f5194b5d6
@@@ -1,7 -1,7 +1,9 @@@
- #define RACER_MIN '-120 -120 -40'
- #define RACER_MAX '120 120 40'
+ const vector RACER_MIN = '-120 -120 -40';
+ const vector RACER_MAX = '120 120 40';
  
  #ifdef SVQC
++#include "../../common/turrets/util.qh"
++
  void racer_exit(float eject);
  void racer_enter();
  
index 94656c2f4787541d13973dee90cfd70841a9adc4,96d54e3de7bfa832da6a1d6ba8458031389deed8..695e3db750b45672afe50f3671a76b415756dcc7
@@@ -1,3 -1,3 +1,5 @@@
++#include "../../common/turrets/util.qh"
++
  float autocvar_g_vehicles_crush_dmg;
  float autocvar_g_vehicles_crush_force;
  float autocvar_g_vehicles_delayspawn;
index 5b82788d165b73ba390bdfe23426fdb9e51566ba,080f891f4ece6ca1f76bb93c97aef426decba311..ca40a93e8d9415a5984ce96d59b70fb532adca78
@@@ -1,3 -1,8 +1,6 @@@
 -#include "../tturrets/include/turrets_early.qh"
 -
+ #ifndef VEHICLES_DEF_H
+ #define VEHICLES_DEF_H
  // #define VEHICLES_USE_ODE
  #define VEHICLES_ENABLED
  #ifdef VEHICLES_ENABLED