Cleanup vehicle #includes
authorTimePath <andrew.hardaker1995@gmail.com>
Sun, 3 May 2015 05:00:21 +0000 (15:00 +1000)
committerTimePath <andrew.hardaker1995@gmail.com>
Sun, 3 May 2015 05:00:21 +0000 (15:00 +1000)
34 files changed:
qcsrc/Makefile
qcsrc/common/command/generic.qc
qcsrc/common/monsters/sv_monsters.qc
qcsrc/common/weapons/all.inc [new file with mode: 0644]
qcsrc/common/weapons/all.qh [deleted file]
qcsrc/common/weapons/weapons.qc
qcsrc/common/weapons/weapons.qh
qcsrc/server/antilag.qc
qcsrc/server/cl_client.qc
qcsrc/server/cl_impulse.qc
qcsrc/server/command/cmd.qc
qcsrc/server/g_damage.qc
qcsrc/server/g_damage.qh
qcsrc/server/g_hook.qc
qcsrc/server/miscfunctions.qc
qcsrc/server/mutators/gamemode_ctf.qc
qcsrc/server/mutators/mutators_include.qc
qcsrc/server/progs.src
qcsrc/server/sv_main.qc
qcsrc/server/t_halflife.qc
qcsrc/server/t_items.qh
qcsrc/server/t_teleporters.qc
qcsrc/server/vehicles/all.qc [new file with mode: 0644]
qcsrc/server/vehicles/all.qh [new file with mode: 0644]
qcsrc/server/vehicles/bumblebee.qc
qcsrc/server/vehicles/racer.qc
qcsrc/server/vehicles/raptor.qc
qcsrc/server/vehicles/spiderbot.qc
qcsrc/server/vehicles/vehicle.qc [new file with mode: 0644]
qcsrc/server/vehicles/vehicle.qh [new file with mode: 0644]
qcsrc/server/vehicles/vehicles.qc [deleted file]
qcsrc/server/vehicles/vehicles.qh [deleted file]
qcsrc/server/vehicles/vehicles_def.qh [deleted file]
qcsrc/test/compilationunit.sh

index abbd25f..f53707e 100644 (file)
@@ -15,8 +15,13 @@ QCCFLAGS ?= \
        -Werror -fno-bail-on-werror -Wall \
        -fftepp -fftepp-predefs -Wcpp -futf8 \
        $(QCCFLAGS_WTFS) \
+       $(QCCFLAGS_FEATURES) \
        $(QCCFLAGS_EXTRA) $(QCCFLAGS_WATERMARK)
 
+QCCFLAGS_FEATURES ?= \
+       -DVEHICLES_ENABLED=1 \
+       -DVEHICLES_USE_ODE=0
+
 # xonotic build system overrides this by command line argument to turn off the update-cvarcount step
 XON_BUILDSYSTEM =
 
index dac268d..f0b6d0d 100644 (file)
@@ -20,6 +20,8 @@
        #include "../../server/command/cmd.qh"
        #include "../../server/command/common.qh"
        #include "../../server/command/sv_cmd.qh"
+
+       #include "../../common/weapons/config.qh"
 #endif
 
 // =========================================================
index 225c00f..3ff926b 100644 (file)
@@ -15,7 +15,7 @@
     #include "../deathtypes.qh"
     #include "../../server/mutators/mutators_include.qh"
     #include "../../server/tturrets/include/turrets_early.qh"
-    #include "../../server/vehicles/vehicles_def.qh"
+    #include "../../server/vehicles/vehicle.qh"
     #include "../../server/campaign.qh"
     #include "../../server/command/common.qh"
     #include "../../server/command/cmd.qh"
diff --git a/qcsrc/common/weapons/all.inc b/qcsrc/common/weapons/all.inc
new file mode 100644 (file)
index 0000000..4f4cd2b
--- /dev/null
@@ -0,0 +1,29 @@
+// ONLY EVER ADD NEW WEAPONS AT THE END. IF YOU REMOVE ONE, PUT THE LAST ONE ON
+// ITS PLACE. THIS IS TO AVOID UNNECESSARY RENUMBERING OF WEAPON IMPULSES.
+// IF YOU DISREGARD THIS NOTICE, I'LL KILL YOU WITH THE @!#%'N TUBA
+
+// core weapons
+#include "w_blaster.qc"
+#include "w_shotgun.qc"
+#include "w_machinegun.qc"
+#include "w_mortar.qc"
+#include "w_minelayer.qc"
+#include "w_electro.qc"
+#include "w_crylink.qc"
+#include "w_vortex.qc"
+#include "w_hagar.qc"
+#include "w_devastator.qc"
+
+// other weapons
+#include "w_porto.qc"
+#include "w_vaporizer.qc"
+#include "w_hook.qc"
+#include "w_hlac.qc"
+#include "w_tuba.qc"
+#include "w_rifle.qc"
+#include "w_fireball.qc"
+#include "w_seeker.qc"
+#include "w_shockwave.qc"
+#include "w_arc.qc"
+#include "w_hmg.qc"
+#include "w_rpc.qc"
diff --git a/qcsrc/common/weapons/all.qh b/qcsrc/common/weapons/all.qh
deleted file mode 100644 (file)
index b4ee1e2..0000000
+++ /dev/null
@@ -1,42 +0,0 @@
-// TODO: include once
-//#ifndef WEAPONS_ALL_H
-//#define WEAPONS_ALL_H
-
-#include "../util.qh"
-
-#ifdef SVQC
-#   include "config.qh"
-#   include "../../server/bot/aim.qh"
-#endif
-
-// ONLY EVER ADD NEW WEAPONS AT THE END. IF YOU REMOVE ONE, PUT THE LAST ONE ON
-// ITS PLACE. THIS IS TO AVOID UNNECESSARY RENUMBERING OF WEAPON IMPULSES.
-// IF YOU DISREGARD THIS NOTICE, I'LL KILL YOU WITH THE @!#%'N TUBA
-
-// core weapons
-#include "w_blaster.qc"
-#include "w_shotgun.qc"
-#include "w_machinegun.qc"
-#include "w_mortar.qc"
-#include "w_minelayer.qc"
-#include "w_electro.qc"
-#include "w_crylink.qc"
-#include "w_vortex.qc"
-#include "w_hagar.qc"
-#include "w_devastator.qc"
-
-// other weapons
-#include "w_porto.qc"
-#include "w_vaporizer.qc"
-#include "w_hook.qc"
-#include "w_hlac.qc"
-#include "w_tuba.qc"
-#include "w_rifle.qc"
-#include "w_fireball.qc"
-#include "w_seeker.qc"
-#include "w_shockwave.qc"
-#include "w_arc.qc"
-#include "w_hmg.qc"
-#include "w_rpc.qc"
-
-//#endif
index 3ab584f..58fdbae 100644 (file)
@@ -54,7 +54,7 @@
 #ifndef MENUQC
 #include "calculations.qc"
 #endif
-#include "all.qh"
+#include "all.inc"
 
 // WEAPON PLUGIN SYSTEM
 entity weapon_info[WEP_MAXCOUNT];
index 593a40e..5f17ccb 100644 (file)
@@ -5,6 +5,10 @@
 #include "calculations.qh"
 #endif
 
+#include "../util.qh"
+#ifdef SVQC
+#include "../../server/bot/aim.qh"
+#endif
 const int MAX_SHOT_DISTANCE = 32768;
 
 // weapon pickup ratings for bot logic
@@ -199,7 +203,7 @@ void register_weapons_done();
        REGISTER_WEAPON_2(WEP_##id,WEPSET_##id,function,ammotype,impulse,flags,rating,color,modelname,simplemdl,crosshair,wepimg,refname,wepname)
 #endif
 
-#include "all.qh"
+#include "all.inc"
 
 #undef WEP_ADD_CVAR_MO_PRI
 #undef WEP_ADD_CVAR_MO_SEC
index f982996..f4fe205 100644 (file)
@@ -3,7 +3,7 @@
 #elif defined(SVQC)
        #include "../dpdefs/progsdefs.qh"
     #include "../dpdefs/dpextensions.qh"
-    #include "vehicles/vehicles_def.qh"
+    #include "vehicles/vehicle.qh"
     #include "antilag.qh"
 #endif
 
index 61565b7..259b7e2 100644 (file)
@@ -28,7 +28,7 @@
 #include "bot/bot.qh"
 #include "bot/navigation.qh"
 
-#include "vehicles/vehicles_def.qh"
+#include "vehicles/vehicle.qh"
 
 #include "weapons/hitplot.qh"
 #include "weapons/weaponsystem.qh"
index 8b40f9c..2169139 100644 (file)
@@ -10,7 +10,7 @@
 #include "weapons/selection.qh"
 #include "weapons/tracing.qh"
 #include "weapons/weaponsystem.qh"
-#include "vehicles/vehicles_def.qh"
+#include "vehicles/vehicle.qh"
 #include "waypointsprites.qh"
 
 #include "../common/weapons/weapons.qh"
index 13bf15e..eadb8ec 100644 (file)
@@ -16,7 +16,9 @@
 
 #include "../mutators/mutators_include.qh"
 
-#include "../vehicles/vehicles_def.qh"
+#ifdef SVQC
+       #include "../vehicles/vehicle.qh"
+#endif
 
 #include "../../common/constants.qh"
 #include "../../common/deathtypes.qh"
index beed2e1..42bce3e 100644 (file)
@@ -8,7 +8,7 @@
 #include "spawnpoints.qh"
 #include "tturrets/include/turrets_early.qh"
 #include "t_items.qh"
-#include "vehicles/vehicles_def.qh"
+#include "vehicles/vehicle.qh"
 #include "weapons/accuracy.qh"
 #include "weapons/csqcprojectile.qh"
 #include "weapons/selection.qh"
index b98693d..49f495b 100644 (file)
@@ -22,7 +22,7 @@
     #include "../common/deathtypes.qh"
     #include "mutators/mutators_include.qh"
     #include "tturrets/include/turrets_early.qh"
-    #include "vehicles/vehicles_def.qh"
+    #include "vehicles/vehicle.qh"
     #include "../csqcmodellib/sv_model.qh"
     #include "../common/playerstats.qh"
     #include "g_hook.qh"
index 1c6c3a7..3445b65 100644 (file)
@@ -9,7 +9,7 @@
 #include "t_teleporters.qh"
 #include "command/common.qh"
 #include "round_handler.qh"
-#include "vehicles/vehicles_def.qh"
+#include "vehicles/vehicle.qh"
 #include "../common/constants.qh"
 #include "../common/util.qh"
 #include "../common/weapons/weapons.qh"
index 4a01390..970c051 100644 (file)
@@ -4,6 +4,7 @@
 #include "antilag.qh"
 #include "command/common.qh"
 #include "constants.qh"
+#include "g_hook.qh"
 #include "ipban.qh"
 #include "mutators/mutators_include.qh"
 #include "tturrets/include/turrets_early.qh"
@@ -1461,7 +1462,6 @@ float SUB_NoImpactCheck()
 
 #define SUB_OwnerCheck() (other && (other == self.owner))
 
-void RemoveGrapplingHook(entity pl);
 void W_Crylink_Dequeue(entity e);
 float WarpZone_Projectile_Touch_ImpactFilter_Callback()
 {
index d40263f..99a85d1 100644 (file)
@@ -3,7 +3,9 @@
 
 #include "gamemode.qh"
 
-#include "../vehicles/vehicles_def.qh"
+#ifdef SVQC
+#include "../vehicles/vehicle.qh"
+#endif
 
 #include "../../warpzonelib/common.qh"
 #include "../../warpzonelib/mathlib.qh"
index 350f10a..4c59144 100644 (file)
@@ -46,7 +46,7 @@
     #include "../../common/deathtypes.qh"
     #include "mutators_include.qh"
     #include "../tturrets/include/turrets_early.qh"
-    #include "../vehicles/vehicles_def.qh"
+    #include "../vehicles/vehicle.qh"
     #include "../campaign.qh"
     #include "../../common/campaign_common.qh"
     #include "../../common/mapinfo.qh"
@@ -77,7 +77,7 @@
     #include "../secret.qh"
     #include "../pathlib/pathlib.qh"
     #include "../tturrets/include/turrets.qh"
-    #include "../vehicles/vehicles.qh"
+    #include "../vehicles/all.qh"
 #endif
 
 #include "base.qc"
index 6b93a92..9d86a37 100644 (file)
@@ -83,6 +83,8 @@ pathlib/movenode.qc
 pathlib/path_waypoint.qc
 pathlib/utility.qc
 
+vehicles/all.qc
+
 weapons/accuracy.qc
 weapons/common.qc
 weapons/csqcprojectile.qc // TODO
index 5779a51..b52c2d7 100644 (file)
@@ -10,7 +10,7 @@
 #include "command/common.qh"
 
 #include "mutators/mutators_include.qh"
-#include "vehicles/vehicles_def.qh"
+#include "vehicles/vehicle.qh"
 #include "weapons/csqcprojectile.qh"
 
 #include "../common/constants.qh"
index 754c52b..299db79 100644 (file)
@@ -1,7 +1,7 @@
 #include "_.qh"
 
 #include "../warpzonelib/util_server.qh"
-#include "vehicles/vehicles_def.qh"
+#include "vehicles/vehicle.qh"
 
 .float  ladder_time;
 .entity ladder_entity;
index 143395b..ef5813c 100644 (file)
@@ -63,13 +63,6 @@ const int ISF_SIZE                           = 128;
 
 .int ItemStatus;
 
-void spawnfunc_item_strength();
-void spawnfunc_item_invincible();
-void spawnfunc_item_armor_small();
-void spawnfunc_item_shells();
-void spawnfunc_item_bullets();
-void spawnfunc_item_rockets();
-
 #ifdef CSQC
 
 float  autocvar_cl_animate_items = 1;
@@ -91,6 +84,13 @@ void ItemRead(float _IsNew);
 
 #endif
 #ifdef SVQC
+void spawnfunc_item_strength();
+void spawnfunc_item_invincible();
+void spawnfunc_item_armor_small();
+void spawnfunc_item_shells();
+void spawnfunc_item_bullets();
+void spawnfunc_item_rockets();
+
 float autocvar_sv_simple_items;
 bool ItemSend(entity to, int sf);
 
index b3266f3..e9f381d 100644 (file)
@@ -6,7 +6,7 @@
 #include "g_hook.qh"
 #include "bot/waypoints.qh"
 #include "tturrets/include/turrets_early.qh"
-#include "vehicles/vehicles_def.qh"
+#include "vehicles/vehicle.qh"
 #include "weapons/csqcprojectile.qh"
 #include "../common/constants.qh"
 #include "../common/deathtypes.qh"
diff --git a/qcsrc/server/vehicles/all.qc b/qcsrc/server/vehicles/all.qc
new file mode 100644 (file)
index 0000000..33e0c71
--- /dev/null
@@ -0,0 +1,11 @@
+#if VEHICLES_ENABLED
+#   include "vehicle.qc"
+
+#   include "racer.qc"
+#   include "raptor.qc"
+#   include "spiderbot.qc"
+
+#   ifndef VEHICLES_NO_UNSTABLE
+#       include "bumblebee.qc"
+#   endif
+#endif
diff --git a/qcsrc/server/vehicles/all.qh b/qcsrc/server/vehicles/all.qh
new file mode 100644 (file)
index 0000000..c675c9c
--- /dev/null
@@ -0,0 +1,14 @@
+#ifndef VEHICLES_H
+#define VEHICLES_H
+
+#if VEHICLES_ENABLED
+#   include "racer.qh"
+#   include "raptor.qh"
+#   include "spiderbot.qh"
+
+#   ifndef VEHICLES_NO_UNSTABLE
+#       include "bumblebee.qh"
+#   endif
+#endif
+
+#endif
index dfbcd4c..3fd45ee 100644 (file)
@@ -1,3 +1,4 @@
+#include "vehicle.qh"
 #include "bumblebee.qh"
 
 #ifdef SVQC
index 49cebfc..545e309 100644 (file)
@@ -1,3 +1,4 @@
+#include "vehicle.qh"
 #include "racer.qh"
 
 #ifdef SVQC
index 74d3c7a..5c14fb7 100644 (file)
@@ -1,3 +1,4 @@
+#include "vehicle.qh"
 #include "raptor.qh"
 
 #ifdef SVQC
index 10ab353..c2a59fd 100644 (file)
@@ -1,3 +1,4 @@
+#include "vehicle.qh"
 #include "spiderbot.qh"
 
 #ifdef SVQC
diff --git a/qcsrc/server/vehicles/vehicle.qc b/qcsrc/server/vehicles/vehicle.qc
new file mode 100644 (file)
index 0000000..b7ec768
--- /dev/null
@@ -0,0 +1,1434 @@
+#include "vehicle.qh"
+
+#include "../_.qh"
+#include "../cl_player.qh"
+#include "../../common/constants.qh"
+#include "../waypointsprites.qh"
+
+#include "../bot/waypoints.qh"
+
+float autocvar_g_vehicles_crush_dmg;
+float autocvar_g_vehicles_crush_force;
+float autocvar_g_vehicles_delayspawn;
+float autocvar_g_vehicles_delayspawn_jitter;
+
+float autocvar_g_vehicles_vortex_damagerate = 0.5;
+float autocvar_g_vehicles_machinegun_damagerate = 0.5;
+float autocvar_g_vehicles_rifle_damagerate = 0.75;
+float autocvar_g_vehicles_vaporizer_damagerate = 0.001;
+float autocvar_g_vehicles_tag_damagerate = 5;
+
+float autocvar_g_vehicles;
+
+void vehicles_damage(entity inflictor, entity attacker, float damage, int deathtype, vector hitloc, vector force);
+void vehicles_return();
+void vehicles_enter();
+void vehicles_reset_colors();
+void vehicles_clearreturn();
+void vehicles_setreturn();
+
+
+/** AuxiliaryXhair*
+    Send additional points of interest to be drawn, to vehicle owner
+**/
+const float MAX_AXH = 4;
+.entity AuxiliaryXhair[MAX_AXH];
+
+float SendAuxiliaryXhair(entity to, int sf)
+{
+
+       WriteByte(MSG_ENTITY, ENT_CLIENT_AUXILIARYXHAIR);
+
+       WriteByte(MSG_ENTITY, self.cnt);
+
+       WriteCoord(MSG_ENTITY, self.origin.x);
+       WriteCoord(MSG_ENTITY, self.origin.y);
+       WriteCoord(MSG_ENTITY, self.origin.z);
+
+    WriteByte(MSG_ENTITY, rint(self.colormod.x * 255));
+    WriteByte(MSG_ENTITY, rint(self.colormod.y * 255));
+    WriteByte(MSG_ENTITY, rint(self.colormod.z * 255));
+
+    return true;
+}
+
+void UpdateAuxiliaryXhair(entity own, vector loc, vector clr, int axh_id)
+{
+    if (!IS_REAL_CLIENT(own))
+        return;
+
+    entity axh;
+
+    axh_id = bound(0, axh_id, MAX_AXH);
+    axh = own.(AuxiliaryXhair[axh_id]);
+
+    if(axh == world || wasfreed(axh))  // MADNESS? THIS IS QQQQCCCCCCCCC (wasfreed, why do you exsist?)
+    {
+        axh                     = spawn();
+        axh.cnt                 = axh_id;
+        axh.drawonlytoclient    = own;
+        axh.owner               = own;
+        Net_LinkEntity(axh, false, 0, SendAuxiliaryXhair);
+    }
+
+    setorigin(axh, loc);
+    axh.colormod            = clr;
+    axh.SendFlags           = 0x01;
+    own.(AuxiliaryXhair[axh_id]) = axh;
+}
+
+/*
+// SVC_TEMPENTITY based, horrible with even 50 ping. hm.
+// WriteByte(MSG_ONE, SVC_TEMPENTITY) uses reliable messagess, never use for thinsg that need continous updates.
+void SendAuxiliaryXhair2(entity own, vector loc, vector clr, float axh_id)
+{
+       msgexntity = own;
+
+       WriteByte(MSG_ONE, SVC_TEMPENTITY);
+       WriteByte(MSG_ONE, TE_CSQC_AUXILIARYXHAIR);
+
+       WriteByte(MSG_ONE, axh_id);
+
+       WriteCoord(MSG_ONE, loc_x);
+       WriteCoord(MSG_ONE, loc_y);
+       WriteCoord(MSG_ONE, loc_z);
+
+    WriteByte(MSG_ONE, rint(clr_x * 255));
+    WriteByte(MSG_ONE, rint(clr_y * 255));
+    WriteByte(MSG_ONE, rint(clr_z * 255));
+
+}
+*/
+// End AuxiliaryXhair
+
+/**
+    Notifies the client that he enterd a vehicle, and sends
+    realavent data.
+
+    only sends vehicle_id atm (wich is a HUD_* constant, ex. HUD_SPIDERBOT)
+**/
+void CSQCVehicleSetup(entity own, float vehicle_id)
+{
+    if (!IS_REAL_CLIENT(own))
+        return;
+
+       msg_entity = own;
+
+       WriteByte(MSG_ONE, SVC_TEMPENTITY);
+       WriteByte(MSG_ONE, TE_CSQC_VEHICLESETUP);
+       if(vehicle_id != 0)
+           WriteByte(MSG_ONE, vehicle_id);
+       else
+        WriteByte(MSG_ONE, 1 + own.vehicle.vehicle_weapon2mode + HUD_VEHICLE_LAST);
+}
+
+
+const float    DAMAGE_TARGETDRONE = 10;
+
+vector targetdrone_getnewspot()
+{
+
+       vector spot;
+       float i;
+       for(i = 0; i < 100; ++i)
+       {
+               spot = self.origin + randomvec() * 1024;
+               tracebox(spot, self.mins, self.maxs, spot, MOVE_NORMAL, self);
+               if(trace_fraction == 1.0 && trace_startsolid == 0 && trace_allsolid == 0)
+                       return spot;
+       }
+       return self.origin;
+}
+
+#if 0
+void targetdrone_think();
+void targetdrone_damage(entity inflictor, entity attacker, float damage, int deathtype, vector hitloc, vector force);
+void targetdrone_renwe()
+{
+       self.think = targetdrone_think;
+       self.nextthink = time + 0.1;
+       setorigin(self, targetdrone_getnewspot());
+       self.health = 200;
+       self.takedamage = DAMAGE_TARGETDRONE;
+       self.event_damage = targetdrone_damage;
+       self.solid = SOLID_BBOX;
+       setmodel(self, "models/runematch/rune.mdl");
+       self.effects = EF_LOWPRECISION;
+       self.scale = 10;
+       self.movetype = MOVETYPE_BOUNCEMISSILE;
+       setsize(self, '-100 -100 -100', '100 100 100');
+
+}
+void targetdrone_damage(entity inflictor, entity attacker, float damage, int deathtype, vector hitloc, vector force)
+{
+       self.health -= damage;
+       if(self.health <= 0)
+       {
+               pointparticles(particleeffectnum("explosion_medium"), self.origin, '0 0 0', 1);
+
+               if(!self.cnt)
+                       remove(self);
+               else
+               {
+                       self.think = targetdrone_renwe;
+                       self.nextthink = time + 1 + random() * 2;
+                       self.solid = SOLID_NOT;
+                       setmodel(self, "");
+               }
+       }
+}
+entity targetdrone_getfear()
+{
+       entity fear;
+       float i;
+
+       for(i = 64; i <= 1024; i += 64)
+       {
+               fear = findradius(self.origin, i);
+               while(fear)
+               {
+                       if(fear.bot_dodge)
+                               return fear;
+
+                       fear = fear.chain;
+               }
+       }
+
+       return world;
+}
+void targetdrone_think()
+{
+       self.nextthink = time + 0.1;
+
+       if(self.wp00)
+       if(self.wp00.deadflag != DEAD_NO)
+               self.wp00 = targetdrone_getfear();
+
+       if(!self.wp00)
+               self.wp00 = targetdrone_getfear();
+
+       vector newdir;
+
+       if(self.wp00)
+               newdir = steerlib_push(self.wp00.origin) + randomvec() * 0.75;
+       else
+               newdir = randomvec() * 0.75;
+
+       newdir = newdir * 0.5 + normalize(self.velocity) * 0.5;
+
+       if(self.wp00)
+               self.velocity = normalize(newdir) * (500 + (1024 / min(vlen(self.wp00.origin - self.origin), 1024)) * 700);
+       else
+               self.velocity = normalize(newdir) * 750;
+
+       tracebox(self.origin, self.mins, self.maxs, self.origin + self.velocity * 2, MOVE_NORMAL, self);
+       if(trace_fraction != 1.0)
+               self.velocity = self.velocity * -1;
+
+       //normalize((normalize(self.velocity) * 0.5 + newdir * 0.5)) * 750;
+}
+
+void targetdrone_spawn(vector _where, float _autorenew)
+{
+       entity drone = spawn();
+       setorigin(drone, _where);
+       drone.think = targetdrone_renwe;
+       drone.nextthink = time + 0.1;
+       drone.cnt = _autorenew;
+}
+#endif
+
+void vehicles_locktarget(float incr, float decr, float _lock_time)
+{
+    if(self.lock_target && self.lock_target.deadflag != DEAD_NO)
+    {
+        self.lock_target    = world;
+        self.lock_strength  = 0;
+        self.lock_time      = 0;
+    }
+
+    if(self.lock_time > time)
+    {
+        if(self.lock_target)
+        if(self.lock_soundtime < time)
+        {
+            self.lock_soundtime = time + 0.5;
+            play2(self.owner, "vehicles/locked.wav");
+        }
+
+        return;
+    }
+
+    if(trace_ent != world)
+    {
+        if(teamplay && trace_ent.team == self.team)
+            trace_ent = world;
+
+        if(trace_ent.deadflag != DEAD_NO)
+            trace_ent = world;
+        if(!(
+            (trace_ent.vehicle_flags & VHF_ISVEHICLE) || 
+            (trace_ent.turrcaps_flags & TFL_TURRCAPS_ISTURRET) || 
+            (trace_ent.takedamage == DAMAGE_TARGETDRONE)
+            )) { trace_ent = world; }
+    }
+
+    if(self.lock_target == world && trace_ent != world)
+        self.lock_target = trace_ent;
+
+    if(self.lock_target && trace_ent == self.lock_target)
+    {
+        if(self.lock_strength != 1 && self.lock_strength + incr >= 1)
+        {
+            play2(self.owner, "vehicles/lock.wav");
+            self.lock_soundtime = time + 0.8;
+        }
+        else if (self.lock_strength != 1 && self.lock_soundtime < time)
+        {
+            play2(self.owner, "vehicles/locking.wav");
+            self.lock_soundtime = time + 0.3;
+        }
+
+    }
+
+    // Have a locking target
+    // Trace hit current target
+    if(trace_ent == self.lock_target && trace_ent != world)
+    {
+        self.lock_strength = min(self.lock_strength + incr, 1);
+        if(self.lock_strength == 1)
+            self.lock_time = time + _lock_time;
+    }
+    else
+    {
+        if(trace_ent)
+            self.lock_strength = max(self.lock_strength - decr * 2, 0);
+        else
+            self.lock_strength = max(self.lock_strength - decr, 0);
+
+        if(self.lock_strength == 0)
+            self.lock_target = world;
+    }
+}
+
+
+#define vehicles_sweap_collision(orig,vel,dt,acm,mult) \
+traceline(orig, orig + vel * dt, MOVE_NORMAL, self); \
+if(trace_fraction != 1) \
+    acm += normalize(self.origin - trace_endpos) * (vlen(vel) * mult)
+
+// Hover movement support
+float  force_fromtag_power;
+vector force_fromtag_origin;
+vector vehicles_force_fromtag_hover(string tag_name, float spring_length, float max_power)
+{
+    force_fromtag_origin = gettaginfo(self, gettagindex(self, tag_name));
+    v_forward  = normalize(v_forward) * -1;
+    traceline(force_fromtag_origin, force_fromtag_origin - (v_forward  * spring_length), MOVE_NORMAL, self);
+
+    force_fromtag_power = (1 - trace_fraction) * max_power;
+    force_fromtag_normpower = force_fromtag_power / max_power;
+
+    return v_forward  * force_fromtag_power;
+}
+
+// Experimental hovermode wich uses attraction/repulstion from surface insted of gravity/repulsion
+// Can possibly be use to move abt any surface (inclusing walls/celings)
+vector vehicles_force_fromtag_maglev(string tag_name, float spring_length, float max_power)
+{
+
+    force_fromtag_origin = gettaginfo(self, gettagindex(self, tag_name));
+    v_forward  = normalize(v_forward) * -1;
+    traceline(force_fromtag_origin, force_fromtag_origin - (v_forward  * spring_length), MOVE_NORMAL, self);
+
+    // TODO - this may NOT be compatible with wall/celing movement, unhardcode 0.25 (engine count multiplier)
+    if(trace_fraction == 1.0)
+    {
+        force_fromtag_normpower = -0.25;
+        return '0 0 -200';
+    }
+
+    force_fromtag_power = ((1 - trace_fraction) - trace_fraction) * max_power;
+    force_fromtag_normpower = force_fromtag_power / max_power;
+
+    return v_forward  * force_fromtag_power;
+}
+
+// Generic vehile projectile system
+void vehicles_projectile_damage(entity inflictor, entity attacker, float damage, int deathtype, vector hitloc, vector force)
+{
+    // Ignore damage from oterh projectiles from my owner (dont mess up volly's)
+    if(inflictor.owner == self.owner)
+        return;
+
+    self.health -= damage;
+    self.velocity += force;
+    if(self.health < 1)
+    {
+        self.takedamage = DAMAGE_NO;
+        self.event_damage = func_null;
+        self.think = self.use;
+        self.nextthink = time;
+    }
+}
+
+void vehicles_projectile_explode()
+{
+    if(self.owner && other != world)
+    {
+        if(other == self.owner.vehicle)
+            return;
+
+        if(other == self.owner.vehicle.tur_head)
+            return;
+    }
+
+       PROJECTILE_TOUCH;
+
+       self.event_damage = func_null;
+    RadiusDamage (self, self.realowner, self.shot_dmg, 0, self.shot_radius, self, world, self.shot_force, self.totalfrags, other);
+
+    remove (self);
+}
+
+entity vehicles_projectile(string _mzlfx, string _mzlsound,
+                           vector _org, vector _vel,
+                           float _dmg, float _radi, float _force,  float _size,
+                           float _deahtype, float _projtype, float _health,
+                           float _cull, float _clianim, entity _owner)
+{
+    entity proj;
+
+    proj = spawn();
+
+    PROJECTILE_MAKETRIGGER(proj);
+    setorigin(proj, _org);
+
+    proj.shot_dmg         = _dmg;
+    proj.shot_radius      = _radi;
+    proj.shot_force       = _force;
+    proj.totalfrags       = _deahtype;
+    proj.solid            = SOLID_BBOX;
+    proj.movetype         = MOVETYPE_FLYMISSILE;
+    proj.flags            = FL_PROJECTILE;
+    proj.bot_dodge        = true;
+    proj.bot_dodgerating  = _dmg;
+    proj.velocity         = _vel;
+    proj.touch            = vehicles_projectile_explode;
+    proj.use              = vehicles_projectile_explode;
+    proj.owner            = self;
+    proj.realowner        = _owner;
+    proj.think            = SUB_Remove;
+    proj.nextthink        = time + 30;
+
+    if(_health)
+    {
+        proj.takedamage       = DAMAGE_AIM;
+        proj.event_damage     = vehicles_projectile_damage;
+        proj.health           = _health;
+    }
+    else
+        proj.flags           = FL_PROJECTILE | FL_NOTARGET;
+
+    if(_mzlsound)
+        sound (self, CH_WEAPON_A, _mzlsound, VOL_BASE, ATTEN_NORM);
+
+    if(_mzlfx)
+        pointparticles(particleeffectnum(_mzlfx), proj.origin, proj.velocity, 1);
+
+
+    setsize (proj, '-1 -1 -1' * _size, '1 1 1' * _size);
+
+    CSQCProjectile(proj, _clianim, _projtype, _cull);
+
+    return proj;
+}
+// End generic vehile projectile system
+
+void vehicles_reset()
+{
+       if(self.owner)
+       {
+               entity oldself = self;
+               self = self.owner;
+               vehicles_exit(VHEF_RELESE);
+               self = oldself;
+       }
+       self.alpha      = -1;
+       self.movetype   = MOVETYPE_NONE;
+       self.effects    = EF_NODRAW;
+       self.colormod  = '0 0 0';
+       self.avelocity = '0 0 0';
+       self.velocity  = '0 0 0';
+       self.event_damage = func_null;
+       self.solid = SOLID_NOT;
+       self.deadflag = DEAD_NO;
+
+       self.touch = func_null;
+       self.nextthink = 0;
+       vehicles_setreturn();
+}
+
+/** vehicles_spawn
+    Exetuted for all vehicles on (re)spawn.
+    Sets defaults for newly spawned units.
+**/
+void vehicles_spawn()
+{
+    dprint("Spawning vehicle: ", self.netname, "\n");
+
+    // De-own & reset
+    self.vehicle_hudmodel.viewmodelforclient = self;
+
+    self.owner              = world;
+    self.touch              = vehicles_touch;
+    self.event_damage       = vehicles_damage;
+    self.reset              = vehicles_reset;
+    self.iscreature         = true;
+    self.teleportable       = false; // no teleporting for vehicles, too buggy
+    self.damagedbycontents     = true;
+    self.movetype           = MOVETYPE_WALK;
+    self.solid              = SOLID_SLIDEBOX;
+    self.takedamage         = DAMAGE_AIM;
+       self.deadflag           = DEAD_NO;
+    self.bot_attack         = true;
+    self.flags              = FL_NOTARGET;
+    self.avelocity          = '0 0 0';
+    self.velocity           = '0 0 0';
+
+    // Reset locking
+    self.lock_strength      = 0;
+    self.lock_target        = world;
+    self.misc_bulletcounter = 0;
+
+    // Return to spawn
+    self.angles             = self.pos2;
+    setorigin(self, self.pos1 + '0 0 0');
+    // Show it
+    pointparticles(particleeffectnum("teleport"), self.origin + '0 0 64', '0 0 0', 1);
+
+    if(self.vehicle_controller)
+        self.team = self.vehicle_controller.team;
+
+    vehicles_reset_colors();
+    self.vehicle_spawn(VHSF_NORMAL);
+}
+
+// Better way of determening whats crushable needed! (fl_crushable?)
+float vehicles_crushable(entity e)
+{
+    if(IS_PLAYER(e))
+        return true;
+
+    if(e.flags & FL_MONSTER)
+        return true;
+
+    return false;
+}
+
+void vehicles_impact(float _minspeed, float _speedfac, float _maxpain)
+{
+    if (trace_dphitq3surfaceflags & Q3SURFACEFLAG_NOIMPACT)
+        return;
+
+    if(self.play_time < time)
+    {
+        float wc = vlen(self.velocity - self.oldvelocity);
+        //dprint("oldvel: ", vtos(self.oldvelocity), "\n");
+        //dprint("vel: ", vtos(self.velocity), "\n");
+        if(_minspeed < wc)
+        {
+            float take = min(_speedfac * wc, _maxpain);
+            Damage (self, world, world, take, DEATH_FALL, self.origin, '0 0 0');
+            self.play_time = time + 0.25;
+
+            //dprint("wc: ", ftos(wc), "\n");
+            //dprint("take: ", ftos(take), "\n");
+        }
+    }
+}
+
+void vehicles_touch()
+{
+       if(MUTATOR_CALLHOOK(VehicleTouch))
+               return;
+
+    // Vehicle currently in use
+    if(self.owner)
+    {
+        if(other != world)
+        if(vehicles_crushable(other))
+        {
+            if(vlen(self.velocity) != 0)
+                Damage(other, self, self.owner, autocvar_g_vehicles_crush_dmg, DEATH_VH_CRUSH, '0 0 0', normalize(other.origin - self.origin) * autocvar_g_vehicles_crush_force);
+
+            return; // Dont do selfdamage when hitting "soft targets".
+        }
+
+        if(self.play_time < time)
+        if(self.vehicle_impact)
+            self.vehicle_impact();
+
+        return;
+    }
+
+    if (!IS_PLAYER(other))
+        return;
+
+    if(other.deadflag != DEAD_NO)
+        return;
+
+    if(other.vehicle != world)
+        return;
+
+    vehicles_enter();
+}
+.float monster_attack;
+void vehicles_enter()
+{
+   // Remove this when bots know how to use vehicles
+
+    if (IS_BOT_CLIENT(other))
+        if (autocvar_g_vehicles_allow_bots)
+            dprint("Bot enters vehicle\n"); // This is where we need to disconnect (some, all?) normal bot AI and hand over to vehicle's _aiframe()
+        else
+            return;
+
+    if(self.phase > time)
+        return;
+    if(other.frozen)
+        return;
+    if(other.vehicle)
+        return;
+    if(other.deadflag != DEAD_NO)
+        return;
+
+    if(teamplay)
+    if(self.team)
+    if(self.team != other.team)
+        return;
+
+    RemoveGrapplingHook(other);
+
+    self.vehicle_ammo1   = 0;
+    self.vehicle_ammo2   = 0;
+    self.vehicle_reload1 = 0;
+    self.vehicle_reload2 = 0;
+    self.vehicle_energy  = 0;
+
+    self.owner          = other;
+    self.switchweapon   = other.switchweapon;
+
+    // .viewmodelforclient works better.
+    //self.vehicle_hudmodel.drawonlytoclient = self.owner;
+
+    self.vehicle_hudmodel.viewmodelforclient = self.owner;
+
+    self.event_damage         = vehicles_damage;
+    self.nextthink            = 0;
+    self.owner.angles         = self.angles;
+    self.owner.takedamage     = DAMAGE_NO;
+    self.owner.solid          = SOLID_NOT;
+    self.owner.movetype       = MOVETYPE_NOCLIP;
+    self.owner.alpha          = -1;
+    self.owner.vehicle        = self;
+    self.owner.event_damage   = func_null;
+    self.owner.view_ofs       = '0 0 0';
+    self.colormap             = self.owner.colormap;
+    if(self.tur_head)
+        self.tur_head.colormap    = self.owner.colormap;
+
+    self.owner.hud            = self.hud;
+    self.owner.PlayerPhysplug = self.PlayerPhysplug;
+
+    self.owner.vehicle_ammo1    = self.vehicle_ammo1;
+    self.owner.vehicle_ammo2    = self.vehicle_ammo2;
+    self.owner.vehicle_reload1  = self.vehicle_reload1;
+    self.owner.vehicle_reload2  = self.vehicle_reload2;
+
+    // Cant do this, hides attached objects too.
+    //self.exteriormodeltoclient = self.owner;
+    //self.tur_head.exteriormodeltoclient = self.owner;
+
+    other.flags &= ~FL_ONGROUND;
+    self.flags  &= ~FL_ONGROUND;
+
+    self.team                 = self.owner.team;
+    self.flags               -= FL_NOTARGET;
+    self.monster_attack       = true;
+
+    if (IS_REAL_CLIENT(other))
+    {
+        msg_entity = other;
+        WriteByte (MSG_ONE, SVC_SETVIEWPORT);
+        WriteEntity(MSG_ONE, self.vehicle_viewport);
+
+        WriteByte (MSG_ONE, SVC_SETVIEWANGLES);
+        if(self.tur_head)
+        {
+            WriteAngle(MSG_ONE, self.tur_head.angles.x + self.angles.x); // tilt
+            WriteAngle(MSG_ONE, self.tur_head.angles.y + self.angles.y); // yaw
+            WriteAngle(MSG_ONE, 0);                                      // roll
+        }
+        else
+        {
+            WriteAngle(MSG_ONE,  self.angles.x * -1); // tilt
+            WriteAngle(MSG_ONE,  self.angles.y);      // yaw
+            WriteAngle(MSG_ONE,  0);                  // roll
+        }
+    }
+
+    vehicles_clearreturn();
+
+    CSQCVehicleSetup(self.owner, self.hud);
+
+    vh_player = other;
+    vh_vehicle = self;
+    MUTATOR_CALLHOOK(VehicleEnter);
+    other = vh_player;
+    self = vh_vehicle;
+
+    self.vehicle_enter();
+    antilag_clear(other);
+}
+
+/** vehicles_findgoodexit
+    Locates a valid location for the player to exit the vehicle.
+    Will first try prefer_spot, then up 100 random spots arround the vehicle
+    wich are in direct line of sight and empty enougth to hold a players bbox
+**/
+vector vehicles_findgoodexit(vector prefer_spot)
+{
+    //vector exitspot;
+    float mysize;
+
+    tracebox(self.origin + '0 0 32', PL_MIN, PL_MAX, prefer_spot, MOVE_NORMAL, self.owner);
+    if(trace_fraction == 1.0 && !trace_startsolid && !trace_allsolid)
+        return prefer_spot;
+
+    mysize = 1.5 * vlen(self.maxs - self.mins);
+    float i;
+    vector v, v2;
+    v2 = 0.5 * (self.absmin + self.absmax);
+    for(i = 0; i < 100; ++i)
+    {
+        v = randomvec();
+        v.z = 0;
+        v = v2 + normalize(v) * mysize;
+        tracebox(v2, PL_MIN, PL_MAX, v, MOVE_NORMAL, self.owner);
+        if(trace_fraction == 1.0 && !trace_startsolid && !trace_allsolid)
+            return v;
+    }
+
+    /*
+    exitspot = (self.origin + '0 0 48') + v_forward * mysize;
+    tracebox(self.origin + '0 0 32', PL_MIN, PL_MAX, exitspot, MOVE_NORMAL, self.owner);
+    if(trace_fraction == 1.0 && !trace_startsolid && !trace_allsolid)
+        return exitspot;
+
+    exitspot = (self.origin + '0 0 48') - v_forward * mysize;
+    tracebox(self.origin + '0 0 32', PL_MIN, PL_MAX, exitspot, MOVE_NORMAL, self.owner);
+    if(trace_fraction == 1.0 && !trace_startsolid && !trace_allsolid)
+        return exitspot;
+
+    exitspot = (self.origin + '0 0 48') + v_right * mysize;
+    tracebox(self.origin + '0 0 32', PL_MIN, PL_MAX, exitspot, MOVE_NORMAL, self.owner);
+    if(trace_fraction == 1.0 && !trace_startsolid && !trace_allsolid)
+        return exitspot;
+
+    exitspot = (self.origin + '0 0 48') - v_right * mysize;
+    tracebox(self.origin + '0 0 32', PL_MIN, PL_MAX, exitspot, MOVE_NORMAL, self.owner);
+    if(trace_fraction == 1.0 && !trace_startsolid && !trace_allsolid)
+        return exitspot;
+    */
+
+    return self.origin;
+}
+
+/** vehicles_exit
+    Standarrd vehicle release fucntion.
+    custom code goes in self.vehicle_exit
+**/
+float vehicles_exit_running;
+void vehicles_exit(float eject)
+{
+    entity _vehicle;
+    entity _player;
+    entity _oldself = self;
+
+    if(vehicles_exit_running)
+    {
+        dprint("^1vehicles_exit allready running! this is not good..\n");
+        return;
+    }
+
+    vehicles_exit_running = true;
+    if(IS_CLIENT(self))
+    {
+        _vehicle = self.vehicle;
+
+        if (_vehicle.vehicle_flags & VHF_PLAYERSLOT)
+        {
+            _vehicle.vehicle_exit(eject);
+            self = _oldself;
+            vehicles_exit_running = false;
+            return;
+        }
+    }
+    else
+        _vehicle = self;
+
+    _player = _vehicle.owner;
+
+    self = _vehicle;
+
+    if (_player)
+    {
+        if (IS_REAL_CLIENT(_player))
+        {
+            msg_entity = _player;
+            WriteByte (MSG_ONE, SVC_SETVIEWPORT);
+            WriteEntity( MSG_ONE, _player);
+
+            WriteByte (MSG_ONE, SVC_SETVIEWANGLES);
+            WriteAngle(MSG_ONE, 0);
+            WriteAngle(MSG_ONE, _vehicle.angles.y);
+            WriteAngle(MSG_ONE, 0);
+        }
+
+        setsize(_player, PL_MIN,PL_MAX);
+
+        _player.takedamage     = DAMAGE_AIM;
+        _player.solid          = SOLID_SLIDEBOX;
+        _player.movetype       = MOVETYPE_WALK;
+        _player.effects        &= ~EF_NODRAW;
+        _player.alpha          = 1;
+        _player.PlayerPhysplug = func_null;
+        _player.vehicle        = world;
+        _player.view_ofs       = PL_VIEW_OFS;
+        _player.event_damage   = PlayerDamage;
+        _player.hud            = HUD_NORMAL;
+        _player.switchweapon   = _vehicle.switchweapon;
+
+        CSQCVehicleSetup(_player, HUD_NORMAL);
+    }
+    _vehicle.flags |= FL_NOTARGET;
+
+    if(_vehicle.deadflag == DEAD_NO)
+        _vehicle.avelocity          = '0 0 0';
+
+    _vehicle.tur_head.nodrawtoclient             = world;
+
+    if(!teamplay)
+        _vehicle.team = 0;
+
+    vh_player = _player;
+    vh_vehicle = _vehicle;
+    MUTATOR_CALLHOOK(VehicleExit);
+    _player = vh_player;
+    _vehicle = vh_vehicle;
+
+    _vehicle.team = _vehicle.tur_head.team;
+
+    sound (_vehicle, CH_TRIGGER_SINGLE, "misc/null.wav", 1, ATTEN_NORM);
+    _vehicle.vehicle_hudmodel.viewmodelforclient = _vehicle;
+    _vehicle.phase = time + 1;
+    _vehicle.monster_attack = false;
+
+    _vehicle.vehicle_exit(eject);
+
+    vehicles_setreturn();
+    vehicles_reset_colors();
+    _vehicle.owner = world;
+    self = _oldself;
+
+    vehicles_exit_running = false;
+}
+
+
+void vehicles_regen(float timer, .float regen_field, float field_max, float rpause, float regen, float delta_time, float _healthscale)
+{
+    if (self.(regen_field) < field_max)
+    if (timer + rpause < time)
+    {
+        if (_healthscale)
+            regen = regen * (self.vehicle_health / self.tur_health);
+
+        self.(regen_field) = min(self.(regen_field) + regen * delta_time, field_max);
+
+        if (self.owner)
+            self.owner.(regen_field) = (self.(regen_field) / field_max) * 100;
+    }
+}
+
+void shieldhit_think()
+{
+    self.alpha -= 0.1;
+    if (self.alpha <= 0)
+    {
+        //setmodel(self, "");
+        self.alpha = -1;
+        self.effects |= EF_NODRAW;
+    }
+    else
+    {
+        self.nextthink = time + 0.1;
+    }
+}
+
+void vehicles_painframe()
+{
+    if(self.owner.vehicle_health <= 50)
+    if(self.pain_frame < time)
+    {
+        float _ftmp;
+        _ftmp = self.owner.vehicle_health / 50;
+        self.pain_frame = time + 0.1 + (random() * 0.5 * _ftmp);
+        pointparticles(particleeffectnum("smoke_small"), (self.origin + (randomvec() * 80)), '0 0 0', 1);
+
+        if(self.vehicle_flags & VHF_DMGSHAKE)
+            self.velocity += randomvec() * 30;
+
+        if(self.vehicle_flags & VHF_DMGROLL)
+            if(self.vehicle_flags & VHF_DMGHEADROLL)
+                self.tur_head.angles += randomvec();
+            else
+                self.angles += randomvec();
+
+    }
+}
+
+void vehicles_damage(entity inflictor, entity attacker, float damage, int deathtype, vector hitloc, vector force)
+{
+    self.dmg_time = time;
+
+       // WEAPONTODO
+    if(DEATH_ISWEAPON(deathtype, WEP_VORTEX))
+        damage *= autocvar_g_vehicles_vortex_damagerate;
+
+    if(DEATH_ISWEAPON(deathtype, WEP_MACHINEGUN))
+        damage *= autocvar_g_vehicles_machinegun_damagerate;
+
+    if(DEATH_ISWEAPON(deathtype, WEP_RIFLE))
+        damage *= autocvar_g_vehicles_rifle_damagerate;
+
+    if(DEATH_ISWEAPON(deathtype, WEP_VAPORIZER))
+        damage *= autocvar_g_vehicles_vaporizer_damagerate;
+
+    if(DEATH_ISWEAPON(deathtype, WEP_SEEKER))
+        damage *= autocvar_g_vehicles_tag_damagerate;
+
+    self.enemy = attacker;
+
+    if((self.vehicle_flags & VHF_HASSHIELD) && (self.vehicle_shield > 0))
+    {
+        if (wasfreed(self.vehicle_shieldent) || self.vehicle_shieldent == world)
+        {
+            self.vehicle_shieldent = spawn();
+            self.vehicle_shieldent.effects = EF_LOWPRECISION;
+
+            setmodel(self.vehicle_shieldent, "models/vhshield.md3");
+            setattachment(self.vehicle_shieldent, self, "");
+            setorigin(self.vehicle_shieldent, real_origin(self) - self.origin);
+            self.vehicle_shieldent.scale       = 256 / vlen(self.maxs - self.mins);
+            self.vehicle_shieldent.think       = shieldhit_think;
+        }
+
+        self.vehicle_shieldent.colormod    = '1 1 1';
+        self.vehicle_shieldent.alpha       = 0.45;
+        self.vehicle_shieldent.angles      = vectoangles(normalize(hitloc - (self.origin + self.vehicle_shieldent.origin))) - self.angles;
+        self.vehicle_shieldent.nextthink   = time;
+        self.vehicle_shieldent.effects &= ~EF_NODRAW;
+
+        self.vehicle_shield -= damage;
+
+        if(self.vehicle_shield < 0)
+        {
+            self.vehicle_health            -= fabs(self.vehicle_shield);
+            self.vehicle_shieldent.colormod = '2 0 0';
+            self.vehicle_shield             = 0;
+            self.vehicle_shieldent.alpha    = 0.75;
+
+               if(sound_allowed(MSG_BROADCAST, attacker))
+                spamsound (self, CH_PAIN, "onslaught/ons_hit2.wav", VOL_BASE, ATTEN_NORM);   // FIXME: PLACEHOLDER
+        }
+        else
+               if(sound_allowed(MSG_BROADCAST, attacker))
+                spamsound (self, CH_PAIN, "onslaught/electricity_explode.wav", VOL_BASE, ATTEN_NORM);  // FIXME: PLACEHOLDER
+
+    }
+    else
+    {
+        self.vehicle_health -= damage;
+
+        if(sound_allowed(MSG_BROADCAST, attacker))
+            spamsound (self, CH_PAIN, "onslaught/ons_hit2.wav", VOL_BASE, ATTEN_NORM);  // FIXME: PLACEHOLDER
+    }
+
+       if(self.damageforcescale < 1 && self.damageforcescale > 0)
+               self.velocity += force * self.damageforcescale;
+       else
+               self.velocity += force;
+
+    if(self.vehicle_health <= 0)
+    {
+        if(self.owner)
+            if(self.vehicle_flags & VHF_DEATHEJECT)
+                vehicles_exit(VHEF_EJECT);
+            else
+                vehicles_exit(VHEF_RELESE);
+
+
+        antilag_clear(self);
+
+        self.vehicle_die();
+        vehicles_setreturn();
+    }
+}
+
+void vehicles_clearreturn()
+{
+    entity ret;
+    // Remove "return helper", if any.
+    ret = findchain(classname, "vehicle_return");
+    while(ret)
+    {
+        if(ret.wp00 == self)
+        {
+            ret.classname   = "";
+            ret.think       = SUB_Remove;
+            ret.nextthink   = time + 0.1;
+
+            if(ret.waypointsprite_attached)
+                WaypointSprite_Kill(ret.waypointsprite_attached);
+
+            return;
+        }
+        ret = ret.chain;
+    }
+}
+
+void vehicles_return()
+{
+    pointparticles(particleeffectnum("teleport"), self.wp00.origin + '0 0 64', '0 0 0', 1);
+
+    self.wp00.think     = vehicles_spawn;
+    self.wp00.nextthink = time;
+
+    if(self.waypointsprite_attached)
+        WaypointSprite_Kill(self.waypointsprite_attached);
+
+    remove(self);
+}
+
+void vehicles_showwp_goaway()
+{
+    if(self.waypointsprite_attached)
+        WaypointSprite_Kill(self.waypointsprite_attached);
+
+    remove(self);
+
+}
+
+void vehicles_showwp()
+{
+    entity oldself = world;
+    vector rgb;
+
+    if(self.cnt)
+    {
+        self.think      = vehicles_return;
+        self.nextthink  = self.cnt;
+    }
+    else
+    {
+        self.think      = vehicles_return;
+        self.nextthink  = time +1;
+
+        oldself = self;
+        self = spawn();
+        setmodel(self, "null");
+        self.team = oldself.wp00.team;
+        self.wp00 = oldself.wp00;
+        setorigin(self, oldself.wp00.pos1);
+
+        self.nextthink = time + 5;
+        self.think = vehicles_showwp_goaway;
+    }
+
+    if(teamplay && self.team)
+           rgb = Team_ColorRGB(self.team);
+    else
+           rgb = '1 1 1';
+    WaypointSprite_Spawn("vehicle", 0, 0, self, '0 0 64', world, 0, self, waypointsprite_attached, true, RADARICON_POWERUP, rgb);
+    if(self.waypointsprite_attached)
+    {
+        WaypointSprite_UpdateRule(self.waypointsprite_attached, self.wp00.team, SPRITERULE_DEFAULT);
+        if(oldself == world)
+            WaypointSprite_UpdateBuildFinished(self.waypointsprite_attached, self.nextthink);
+        WaypointSprite_Ping(self.waypointsprite_attached);
+    }
+
+    if(oldself != world)
+        self = oldself;
+}
+
+void vehicles_setreturn()
+{
+    entity ret;
+
+    vehicles_clearreturn();
+
+    ret = spawn();
+    ret.classname   = "vehicle_return";
+    ret.wp00       = self;
+    ret.team        = self.team;
+    ret.think       = vehicles_showwp;
+
+       if(self.deadflag != DEAD_NO)
+       {
+               ret.cnt = max(game_starttime, time) + self.vehicle_respawntime;
+               ret.nextthink = max(game_starttime, time) + max(0, self.vehicle_respawntime - 5);
+       }
+       else
+               ret.nextthink = max(game_starttime, time) + max(0, self.vehicle_respawntime - 1);
+
+    setmodel(ret, "null");
+    setorigin(ret, self.pos1 + '0 0 96');
+}
+
+void vehicles_reset_colors()
+{
+    entity e;
+    float _effects = 0, _colormap;
+    vector _glowmod, _colormod;
+
+    if(autocvar_g_nodepthtestplayers)
+        _effects |= EF_NODEPTHTEST;
+
+    if(autocvar_g_fullbrightplayers)
+        _effects |= EF_FULLBRIGHT;
+
+    if(self.team)
+        _colormap = 1024 + (self.team - 1) * 17;
+    else
+        _colormap = 1024;
+
+    _glowmod  = '0 0 0';
+    _colormod = '0 0 0';
+
+    // Find all ents attacked to main model and setup effects, colormod etc.
+    e = findchainentity(tag_entity, self);
+    while(e)
+    {
+        if(e != self.vehicle_shieldent)
+        {
+            e.effects   = _effects; //  | EF_LOWPRECISION;
+            e.colormod  = _colormod;
+            e.colormap  = _colormap;
+            e.alpha     = 1;
+        }
+        e = e.chain;
+    }
+
+    self.vehicle_hudmodel.effects  = self.effects  = _effects; // | EF_LOWPRECISION;
+    self.vehicle_hudmodel.colormod = self.colormod = _colormod;
+    self.vehicle_hudmodel.colormap = self.colormap = _colormap;
+    self.vehicle_viewport.effects = (EF_ADDITIVE | EF_DOUBLESIDED | EF_FULLBRIGHT | EF_NODEPTHTEST | EF_NOGUNBOB | EF_NOSHADOW | EF_LOWPRECISION | EF_SELECTABLE | EF_TELEPORT_BIT);
+
+    self.alpha     = 1;
+    self.avelocity = '0 0 0';
+    self.velocity  = '0 0 0';
+    self.effects   = _effects;
+}
+
+void vehicle_use()
+{
+    dprint("vehicle ",self.netname, " used by ", activator.classname, "\n");
+
+    self.tur_head.team = activator.team;
+
+    if(self.tur_head.team == 0)
+        self.active = ACTIVE_NOT;
+    else
+        self.active = ACTIVE_ACTIVE;
+
+    if(self.active == ACTIVE_ACTIVE && self.deadflag == DEAD_NO)
+    {
+        dprint("^3Eat shit yall!\n");
+        vehicles_setreturn();
+        vehicles_reset_colors();
+    }
+    else if(self.active == ACTIVE_NOT && self.deadflag != DEAD_NO)
+    {
+
+    }
+}
+
+float vehicle_addplayerslot(    entity _owner,
+                                entity _slot,
+                                float _hud,
+                                string _hud_model,
+                                float() _framefunc,
+                                void(float) _exitfunc)
+{
+    if (!(_owner.vehicle_flags & VHF_MULTISLOT))
+        _owner.vehicle_flags |= VHF_MULTISLOT;
+
+    _slot.PlayerPhysplug = _framefunc;
+    _slot.vehicle_exit = _exitfunc;
+    _slot.hud = _hud;
+    _slot.vehicle_flags = VHF_PLAYERSLOT;
+    _slot.vehicle_viewport = spawn();
+    _slot.vehicle_hudmodel = spawn();
+    _slot.vehicle_hudmodel.viewmodelforclient = _slot;
+    _slot.vehicle_viewport.effects = (EF_ADDITIVE | EF_DOUBLESIDED | EF_FULLBRIGHT | EF_NODEPTHTEST | EF_NOGUNBOB | EF_NOSHADOW | EF_LOWPRECISION | EF_SELECTABLE | EF_TELEPORT_BIT);
+
+    setmodel(_slot.vehicle_hudmodel, _hud_model);
+    setmodel(_slot.vehicle_viewport, "null");
+
+    setattachment(_slot.vehicle_hudmodel, _slot, "");
+    setattachment(_slot.vehicle_viewport, _slot.vehicle_hudmodel, "");
+
+    return true;
+}
+
+float vehicle_initialize(string  net_name,
+                         string  bodymodel,
+                         string  topmodel,
+                         string  hudmodel,
+                         string  toptag,
+                         string  hudtag,
+                         string  viewtag,
+                         float   vhud,
+                         vector  min_s,
+                         vector  max_s,
+                         float   nodrop,
+                         void(float _spawnflag)  spawnproc,
+                         float   _respawntime,
+                         float() physproc,
+                         void()  enterproc,
+                         void(float extflag) exitfunc,
+                         void() dieproc,
+                         void() thinkproc,
+                         float  use_csqc,
+                         float _max_health,
+                         float _max_shield)
+{
+       if(!autocvar_g_vehicles)
+               return false;
+
+    if(self.targetname)
+    {
+        self.vehicle_controller = find(world, target, self.targetname);
+        if(!self.vehicle_controller)
+        {
+            bprint("^1WARNING: ^7Vehicle with invalid .targetname\n");
+        }
+        else
+        {
+            self.team = self.vehicle_controller.team;
+            self.use = vehicle_use;
+
+            if(teamplay)
+            {
+                if(self.vehicle_controller.team == 0)
+                    self.active = ACTIVE_NOT;
+                else
+                    self.active = ACTIVE_ACTIVE;
+            }
+        }
+    }
+
+    precache_sound("onslaught/ons_hit2.wav");
+    precache_sound("onslaught/electricity_explode.wav");
+
+
+    addstat(STAT_HUD, AS_INT,  hud);
+       addstat(STAT_VEHICLESTAT_HEALTH,  AS_INT, vehicle_health);
+       addstat(STAT_VEHICLESTAT_SHIELD,  AS_INT, vehicle_shield);
+       addstat(STAT_VEHICLESTAT_ENERGY,  AS_INT, vehicle_energy);
+
+       addstat(STAT_VEHICLESTAT_AMMO1,   AS_INT, vehicle_ammo1);
+       addstat(STAT_VEHICLESTAT_RELOAD1, AS_INT, vehicle_reload1);
+
+       addstat(STAT_VEHICLESTAT_AMMO2,   AS_INT, vehicle_ammo2);
+       addstat(STAT_VEHICLESTAT_RELOAD2, AS_INT, vehicle_reload2);
+
+    if(bodymodel == "")
+        error("vehicles: missing bodymodel!");
+
+    if(hudmodel == "")
+        error("vehicles: missing hudmodel!");
+
+    if(net_name == "")
+        self.netname = self.classname;
+    else
+        self.netname = net_name;
+
+    if(self.team && !teamplay)
+        self.team = 0;
+
+    self.vehicle_flags |= VHF_ISVEHICLE;
+
+    setmodel(self, bodymodel);
+
+    self.vehicle_viewport   = spawn();
+    self.vehicle_hudmodel   = spawn();
+    self.tur_head           = spawn();
+    self.tur_head.owner     = self;
+    self.takedamage         = DAMAGE_AIM;
+    self.bot_attack         = true;
+    self.iscreature         = true;
+    self.teleportable       = false; // no teleporting for vehicles, too buggy
+    self.damagedbycontents     = true;
+    self.hud                = vhud;
+    self.tur_health          = _max_health;
+    self.tur_head.tur_health = _max_shield;
+    self.vehicle_die         = dieproc;
+    self.vehicle_exit        = exitfunc;
+    self.vehicle_enter       = enterproc;
+    self.PlayerPhysplug      = physproc;
+    self.event_damage        = func_null;
+    self.touch               = vehicles_touch;
+    self.think               = vehicles_spawn;
+    self.vehicle_spawn       = spawnproc;
+       self.vehicle_respawntime = max(0, _respawntime);
+    self.effects             = EF_NODRAW;
+       self.dphitcontentsmask   = DPCONTENTS_BODY | DPCONTENTS_SOLID;
+       if(!autocvar_g_vehicles_delayspawn || !self.vehicle_respawntime)
+               self.nextthink = time;
+       else
+               self.nextthink = max(time, game_starttime) + max(0, self.vehicle_respawntime + ((random() * 2 - 1) * autocvar_g_vehicles_delayspawn_jitter));
+
+       if(autocvar_g_playerclip_collisions)
+               self.dphitcontentsmask |= DPCONTENTS_PLAYERCLIP;
+
+    if(autocvar_g_nodepthtestplayers)
+        self.effects = self.effects | EF_NODEPTHTEST;
+
+    if(autocvar_g_fullbrightplayers)
+        self.effects = self.effects | EF_FULLBRIGHT;
+
+    setmodel(self.vehicle_hudmodel, hudmodel);
+    setmodel(self.vehicle_viewport, "null");
+
+    if(topmodel != "")
+    {
+        setmodel(self.tur_head, topmodel);
+        setattachment(self.tur_head, self, toptag);
+        setattachment(self.vehicle_hudmodel, self.tur_head, hudtag);
+        setattachment(self.vehicle_viewport, self.vehicle_hudmodel, viewtag);
+    }
+    else
+    {
+        setattachment(self.tur_head, self, "");
+        setattachment(self.vehicle_hudmodel, self, hudtag);
+        setattachment(self.vehicle_viewport, self.vehicle_hudmodel, viewtag);
+    }
+
+    setsize(self, min_s, max_s);
+    if (!nodrop)
+    {
+        setorigin(self, self.origin);
+        tracebox(self.origin + '0 0 100', min_s, max_s, self.origin - '0 0 10000', MOVE_WORLDONLY, self);
+        setorigin(self, trace_endpos);
+    }
+
+    self.pos1 = self.origin;
+    self.pos2 = self.angles;
+    self.tur_head.team = self.team;
+
+       if(MUTATOR_CALLHOOK(VehicleSpawn))
+               return false;
+
+    return true;
+}
+
+vector vehicle_aimturret(entity _vehic, vector _target, entity _turrret, string _tagname,
+                         float _pichlimit_min, float _pichlimit_max,
+                         float _rotlimit_min, float _rotlimit_max, float _aimspeed)
+{
+    vector vtmp, vtag;
+    float ftmp;
+    vtag = gettaginfo(_turrret, gettagindex(_turrret, _tagname));
+    vtmp = vectoangles(normalize(_target - vtag));
+    vtmp = AnglesTransform_ToAngles(AnglesTransform_LeftDivide(AnglesTransform_FromAngles(_vehic.angles), AnglesTransform_FromAngles(vtmp))) - _turrret.angles;
+    vtmp = AnglesTransform_Normalize(vtmp, true);
+    ftmp = _aimspeed * frametime;
+    vtmp.y = bound(-ftmp, vtmp.y, ftmp);
+    vtmp.x = bound(-ftmp, vtmp.x, ftmp);
+    _turrret.angles_y = bound(_rotlimit_min, _turrret.angles.y + vtmp.y, _rotlimit_max);
+    _turrret.angles_x = bound(_pichlimit_min, _turrret.angles.x + vtmp.x, _pichlimit_max);
+    return vtag;
+}
+
+void vehicles_gib_explode()
+{
+       sound (self, CH_SHOTS, "weapons/rocket_impact.wav", VOL_BASE, ATTEN_NORM);
+       pointparticles(particleeffectnum("explosion_small"), randomvec() * 80 + (self.origin + '0 0 100'), '0 0 0', 1);
+       remove(self);
+}
+
+void vehicles_gib_think()
+{
+       self.alpha -= 0.1;
+       if(self.cnt >= time)
+               remove(self);
+       else
+               self.nextthink = time + 0.1;
+}
+
+entity vehicle_tossgib(entity _template, vector _vel, string _tag, float _burn, float _explode, float _maxtime, vector _rot)
+{
+       entity _gib = spawn();
+       setmodel(_gib, _template.model);
+       setorigin(_gib, gettaginfo(self, gettagindex(self, _tag)));
+       _gib.velocity = _vel;
+       _gib.movetype = MOVETYPE_TOSS;
+       _gib.solid = SOLID_CORPSE;
+       _gib.colormod = '-0.5 -0.5 -0.5';
+       _gib.effects = EF_LOWPRECISION;
+       _gib.avelocity = _rot;
+
+       if(_burn)
+               _gib.effects |= EF_FLAME;
+
+       if(_explode)
+       {
+               _gib.think = vehicles_gib_explode;
+               _gib.nextthink = time + random() * _explode;
+               _gib.touch = vehicles_gib_explode;
+       }
+       else
+       {
+               _gib.cnt = time + _maxtime;
+               _gib.think = vehicles_gib_think;
+               _gib.nextthink = time + _maxtime - 1;
+               _gib.alpha = 1;
+       }
+       return _gib;
+}
+
+/*
+vector predict_target(entity _targ, vector _from, float _shot_speed)
+{
+    float i;                // loop
+    float _distance;        // How far to target
+    float _impact_time;     // How long untill projectile impacts
+    vector _predict_pos;    // Predicted enemy location
+    vector _original_origin;// Where target is before predicted
+
+     _original_origin = real_origin(_targ); // Typicaly center of target BBOX
+
+    _predict_pos = _original_origin;
+    for(i = 0; i < 4; ++i)  // Loop a few times to increase prediction accuracy (increase loop count if accuracy is to low)
+    {
+        _distance = vlen(_predict_pos - _from); // Get distance to previos predicted location
+        _impact_time = _distance / _shot_speed; // Calculate impact time
+        _predict_pos = _original_origin + _targ.velocity * _impact_time; // Calculate new predicted location
+    }
+
+    return _predict_pos;
+}
+*/
diff --git a/qcsrc/server/vehicles/vehicle.qh b/qcsrc/server/vehicles/vehicle.qh
new file mode 100644 (file)
index 0000000..3b9368b
--- /dev/null
@@ -0,0 +1,197 @@
+#ifndef VEHICLE_H
+#define VEHICLE_H
+
+#include "../_.qh"
+
+#include "../antilag.qh"
+#include "../cl_player.qh"
+#include "../g_damage.qh"
+#include "../g_hook.qh"
+#include "../g_subs.qh"
+#include "../movelib.qh"
+
+#include "../bot/bot.qh"
+
+#include "../command/common.qh"
+
+#include "../tturrets/include/turrets_early.qh"
+
+#include "../weapons/tracing.qh"
+
+#include "../../common/deathtypes.qh"
+#include "../../common/stats.qh"
+
+#include "../../warpzonelib/anglestransform.qh"
+#include "../../warpzonelib/server.qh"
+
+entity vehicles_projectile(string _mzlfx, string _mzlsound,
+                           vector _org, vector _vel,
+                           float _dmg, float _radi, float _force,  float _size,
+                           float _deahtype, float _projtype, float _health,
+                           float _cull, float _clianim, entity _owner);
+
+vector vehicles_findgoodexit(vector prefer_spot);
+
+
+
+/** vehicles_locktarget
+
+    Generic target locking.
+
+    Figure out if what target is "locked" (if any), for missile tracking as such.
+
+    after calling, "if(self.lock_target != world && self.lock_strength == 1)" mean
+    you have a locked in target.
+
+    Exspects a crosshair_trace() or equivalent to be
+    dont before calling.
+
+**/
+.entity lock_target;
+.float  lock_strength;
+.float  lock_time;
+.float  lock_soundtime;
+
+void UpdateAuxiliaryXhair(entity own, vector loc, vector clr, int axh_id);
+
+vector vehicle_aimturret(entity _vehic, vector _target, entity _turrret, string _tagname,
+                         float _pichlimit_min, float _pichlimit_max,
+                         float _rotlimit_min, float _rotlimit_max, float _aimspeed);
+
+#define VEHICLE_UPDATE_PLAYER(ply,fld,vhname) \
+ply.vehicle_##fld = (self.vehicle_##fld / autocvar_g_vehicle_##vhname##_##fld) * 100
+
+void CSQCVehicleSetup(entity own, float vehicle_id);
+
+.float() PlayerPhysplug;
+
+float autocvar_g_vehicles_allow_bots = 0;
+
+void vehicles_touch();
+
+void vehicles_regen(float timer, .float regen_field, float field_max, float rpause, float regen, float delta_time, float _healthscale);
+
+float shortangle_f(float ang1, float ang2);
+float anglemods(float v);
+
+entity vehicle_tossgib(entity _template, vector _vel, string _tag, float _burn, float _explode, float _maxtime, vector _rot);
+
+void vehicles_impact(float _minspeed, float _speedfac, float _maxpain);
+
+void shieldhit_think();
+
+float vehicle_addplayerslot(    entity _owner,
+                                entity _slot,
+                                float _hud,
+                                string _hud_model,
+                                float() _framefunc,
+                                void(float) _exitfunc);
+
+.void() vehicle_impact;
+
+float vehicle_initialize(string  net_name,
+                         string  bodymodel,
+                         string  topmodel,
+                         string  hudmodel,
+                         string  toptag,
+                         string  hudtag,
+                         string  viewtag,
+                         float   vhud,
+                         vector  min_s,
+                         vector  max_s,
+                         float   nodrop,
+                         void(float _spawnflag)  spawnproc,
+                         float   _respawntime,
+                         float() physproc,
+                         void()  enterproc,
+                         void(float extflag) exitfunc,
+                         void() dieproc,
+                         void() thinkproc,
+                         float  use_csqc,
+                         float _max_health,
+                         float _max_shield);
+
+float  force_fromtag_normpower;
+
+void vehicles_painframe();
+
+void vehicles_locktarget(float incr, float decr, float _lock_time);
+
+vector vehicles_force_fromtag_maglev(string tag_name, float spring_length, float max_power);
+
+vector vehicles_force_fromtag_hover(string tag_name, float spring_length, float max_power);
+
+void vehicles_projectile_explode();
+
+#if VEHICLES_ENABLED
+
+.int vehicle_flags;
+const int VHF_ISVEHICLE     = 2;    /// Indicates vehicle
+const int VHF_HASSHIELD     = 4;    /// Vehicle has shileding
+const int VHF_SHIELDREGEN   = 8;    /// Vehicles shield regenerates
+const int VHF_HEALTHREGEN   = 16;   /// Vehicles health regenerates
+const int VHF_ENERGYREGEN   = 32;   /// Vehicles energy regenerates
+const int VHF_DEATHEJECT    = 64;   /// Vehicle ejects pilot upon fatal damage
+const int VHF_MOVE_GROUND   = 128;  /// Vehicle moves on gound
+const int VHF_MOVE_HOVER    = 256;  /// Vehicle hover close to gound
+const int VHF_MOVE_FLY      = 512;  /// Vehicle is airborn
+const int VHF_DMGSHAKE      = 1024; /// Add random velocity each frame if health < 50%
+const int VHF_DMGROLL       = 2048; /// Add random angles each frame if health < 50%
+const int VHF_DMGHEADROLL   = 4096; /// Add random head angles each frame if health < 50%
+const int VHF_MULTISLOT     = 8192; /// Vehicle has multiple player slots
+const int VHF_PLAYERSLOT    = 16384;    /// This ent is a player slot on a multi-person vehicle
+
+.entity gun1;
+.entity gun2;
+.entity gun3;
+.entity vehicle_shieldent;  /// Entity to disply the shild effect on damage
+.entity vehicle;
+.entity vehicle_viewport;
+.entity vehicle_hudmodel;
+.entity vehicle_controller;
+
+.entity gunner1;
+.entity gunner2;
+
+.float vehicle_health;      /// If self is player this is 0..100 indicating precentage of health left on vehicle. If self is vehile, this is the real health value.
+.float vehicle_energy;      /// If self is player this is 0..100 indicating precentage of energy left on vehicle. If self is vehile, this is the real energy value.
+.float vehicle_shield;      /// If self is player this is 0..100 indicating precentage of shield left on vehicle. If self is vehile, this is the real shield value.
+
+.float vehicle_ammo1;   /// If self is player this field's use depends on the individual vehile. If self is vehile, this is the real ammo1 value.
+.float vehicle_reload1; /// If self is player this field's use depends on the individual vehile. If self is vehile, this is the real reload1 value.
+.float vehicle_ammo2;   /// If self is player this field's use depends on the individual vehile. If self is vehile, this is the real ammo2 value.
+.float vehicle_reload2; /// If self is player this field's use depends on the individual vehile. If self is vehile, this is the real reload2 value.
+
+.float sound_nexttime;
+const float VOL_VEHICLEENGINE = 1;
+
+.float hud;
+.float dmg_time;
+.float  vehicle_respawntime;
+//.void() vehicle_spawn;
+
+void vehicles_exit(float eject);
+.void(float exit_flags) vehicle_exit;
+const float VHEF_NORMAL = 0;  /// User pressed exit key
+const float VHEF_EJECT  = 1;  /// User pressed exit key 3 times fast (not implemented) or vehile is dying
+const float VHEF_RELESE = 2;  /// Release ownership, client possibly allready dissconnected / went spec / changed team / used "kill" (not implemented)
+
+const float SVC_SETVIEWPORT   = 5;   // Net.Protocol 0x05
+const float SVC_SETVIEWANGLES = 10;  // Net.Protocol 0x0A
+const float SVC_UPDATEENTITY  = 128; // Net.Protocol 0x80
+
+.void() vehicle_enter;  /// Vehicles custom funciton to be executed when owner exit it
+.void() vehicle_die;    /// Vehicles custom function to be executed when vehile die
+const float VHSF_NORMAL = 0;
+const float VHSF_FACTORY = 2;
+.void(float _spawnflag) vehicle_spawn;  /// Vehicles custom fucntion to be efecuted when vehicle (re)spawns
+.float(float _imp) vehicles_impulse;
+.float vehicle_weapon2mode;
+
+#if VEHICLES_USE_ODE
+void(entity e, float physics_enabled) physics_enable = #540; // enable or disable physics on object
+void(entity e, vector force, vector force_pos) physics_addforce = #541; // apply a force from certain origin, length of force vector is power of force
+void(entity e, vector torque) physics_addtorque = #542; // add relative torque
+#endif  // VEHICLES_USE_ODE
+#endif  // VEHICLES_ENABLED
+#endif
diff --git a/qcsrc/server/vehicles/vehicles.qc b/qcsrc/server/vehicles/vehicles.qc
deleted file mode 100644 (file)
index 3778b04..0000000
+++ /dev/null
@@ -1,1455 +0,0 @@
-#include "vehicles.qh"
-
-#include "../cl_player.qh"
-#include "../waypointsprites.qh"
-
-#include "../bot/waypoints.qh"
-
-.float() PlayerPhysplug;
-
-float autocvar_g_vehicles_crush_dmg;
-float autocvar_g_vehicles_crush_force;
-float autocvar_g_vehicles_delayspawn;
-float autocvar_g_vehicles_delayspawn_jitter;
-
-float autocvar_g_vehicles_vortex_damagerate = 0.5;
-float autocvar_g_vehicles_machinegun_damagerate = 0.5;
-float autocvar_g_vehicles_rifle_damagerate = 0.75;
-float autocvar_g_vehicles_vaporizer_damagerate = 0.001;
-float autocvar_g_vehicles_tag_damagerate = 5;
-
-float autocvar_g_vehicles;
-
-void vehicles_damage(entity inflictor, entity attacker, float damage, int deathtype, vector hitloc, vector force);
-void vehicles_return();
-void vehicles_enter();
-void vehicles_touch();
-void vehicles_reset_colors();
-void vehicles_clearreturn();
-void vehicles_setreturn();
-
-
-/** AuxiliaryXhair*
-    Send additional points of interest to be drawn, to vehicle owner
-**/
-const float MAX_AXH = 4;
-.entity AuxiliaryXhair[MAX_AXH];
-
-float SendAuxiliaryXhair(entity to, int sf)
-{
-
-       WriteByte(MSG_ENTITY, ENT_CLIENT_AUXILIARYXHAIR);
-
-       WriteByte(MSG_ENTITY, self.cnt);
-
-       WriteCoord(MSG_ENTITY, self.origin.x);
-       WriteCoord(MSG_ENTITY, self.origin.y);
-       WriteCoord(MSG_ENTITY, self.origin.z);
-
-    WriteByte(MSG_ENTITY, rint(self.colormod.x * 255));
-    WriteByte(MSG_ENTITY, rint(self.colormod.y * 255));
-    WriteByte(MSG_ENTITY, rint(self.colormod.z * 255));
-
-    return true;
-}
-
-void UpdateAuxiliaryXhair(entity own, vector loc, vector clr, int axh_id)
-{
-    if (!IS_REAL_CLIENT(own))
-        return;
-
-    entity axh;
-
-    axh_id = bound(0, axh_id, MAX_AXH);
-    axh = own.(AuxiliaryXhair[axh_id]);
-
-    if(axh == world || wasfreed(axh))  // MADNESS? THIS IS QQQQCCCCCCCCC (wasfreed, why do you exsist?)
-    {
-        axh                     = spawn();
-        axh.cnt                 = axh_id;
-        axh.drawonlytoclient    = own;
-        axh.owner               = own;
-        Net_LinkEntity(axh, false, 0, SendAuxiliaryXhair);
-    }
-
-    setorigin(axh, loc);
-    axh.colormod            = clr;
-    axh.SendFlags           = 0x01;
-    own.(AuxiliaryXhair[axh_id]) = axh;
-}
-
-/*
-// SVC_TEMPENTITY based, horrible with even 50 ping. hm.
-// WriteByte(MSG_ONE, SVC_TEMPENTITY) uses reliable messagess, never use for thinsg that need continous updates.
-void SendAuxiliaryXhair2(entity own, vector loc, vector clr, float axh_id)
-{
-       msgexntity = own;
-
-       WriteByte(MSG_ONE, SVC_TEMPENTITY);
-       WriteByte(MSG_ONE, TE_CSQC_AUXILIARYXHAIR);
-
-       WriteByte(MSG_ONE, axh_id);
-
-       WriteCoord(MSG_ONE, loc_x);
-       WriteCoord(MSG_ONE, loc_y);
-       WriteCoord(MSG_ONE, loc_z);
-
-    WriteByte(MSG_ONE, rint(clr_x * 255));
-    WriteByte(MSG_ONE, rint(clr_y * 255));
-    WriteByte(MSG_ONE, rint(clr_z * 255));
-
-}
-*/
-// End AuxiliaryXhair
-
-/**
-    Notifies the client that he enterd a vehicle, and sends
-    realavent data.
-
-    only sends vehicle_id atm (wich is a HUD_* constant, ex. HUD_SPIDERBOT)
-**/
-void CSQCVehicleSetup(entity own, float vehicle_id)
-{
-    if (!IS_REAL_CLIENT(own))
-        return;
-
-       msg_entity = own;
-
-       WriteByte(MSG_ONE, SVC_TEMPENTITY);
-       WriteByte(MSG_ONE, TE_CSQC_VEHICLESETUP);
-       if(vehicle_id != 0)
-           WriteByte(MSG_ONE, vehicle_id);
-       else
-        WriteByte(MSG_ONE, 1 + own.vehicle.vehicle_weapon2mode + HUD_VEHICLE_LAST);
-}
-
-/** vehicles_locktarget
-
-    Generic target locking.
-
-    Figure out if what target is "locked" (if any), for missile tracking as such.
-
-    after calling, "if(self.lock_target != world && self.lock_strength == 1)" mean
-    you have a locked in target.
-
-    Exspects a crosshair_trace() or equivalent to be
-    dont before calling.
-
-**/
-.entity lock_target;
-.float  lock_strength;
-.float  lock_time;
-.float  lock_soundtime;
-const float    DAMAGE_TARGETDRONE = 10;
-
-vector targetdrone_getnewspot()
-{
-
-       vector spot;
-       float i;
-       for(i = 0; i < 100; ++i)
-       {
-               spot = self.origin + randomvec() * 1024;
-               tracebox(spot, self.mins, self.maxs, spot, MOVE_NORMAL, self);
-               if(trace_fraction == 1.0 && trace_startsolid == 0 && trace_allsolid == 0)
-                       return spot;
-       }
-       return self.origin;
-}
-
-#if 0
-void targetdrone_think();
-void targetdrone_damage(entity inflictor, entity attacker, float damage, int deathtype, vector hitloc, vector force);
-void targetdrone_renwe()
-{
-       self.think = targetdrone_think;
-       self.nextthink = time + 0.1;
-       setorigin(self, targetdrone_getnewspot());
-       self.health = 200;
-       self.takedamage = DAMAGE_TARGETDRONE;
-       self.event_damage = targetdrone_damage;
-       self.solid = SOLID_BBOX;
-       setmodel(self, "models/runematch/rune.mdl");
-       self.effects = EF_LOWPRECISION;
-       self.scale = 10;
-       self.movetype = MOVETYPE_BOUNCEMISSILE;
-       setsize(self, '-100 -100 -100', '100 100 100');
-
-}
-void targetdrone_damage(entity inflictor, entity attacker, float damage, int deathtype, vector hitloc, vector force)
-{
-       self.health -= damage;
-       if(self.health <= 0)
-       {
-               pointparticles(particleeffectnum("explosion_medium"), self.origin, '0 0 0', 1);
-
-               if(!self.cnt)
-                       remove(self);
-               else
-               {
-                       self.think = targetdrone_renwe;
-                       self.nextthink = time + 1 + random() * 2;
-                       self.solid = SOLID_NOT;
-                       setmodel(self, "");
-               }
-       }
-}
-entity targetdrone_getfear()
-{
-       entity fear;
-       float i;
-
-       for(i = 64; i <= 1024; i += 64)
-       {
-               fear = findradius(self.origin, i);
-               while(fear)
-               {
-                       if(fear.bot_dodge)
-                               return fear;
-
-                       fear = fear.chain;
-               }
-       }
-
-       return world;
-}
-void targetdrone_think()
-{
-       self.nextthink = time + 0.1;
-
-       if(self.wp00)
-       if(self.wp00.deadflag != DEAD_NO)
-               self.wp00 = targetdrone_getfear();
-
-       if(!self.wp00)
-               self.wp00 = targetdrone_getfear();
-
-       vector newdir;
-
-       if(self.wp00)
-               newdir = steerlib_push(self.wp00.origin) + randomvec() * 0.75;
-       else
-               newdir = randomvec() * 0.75;
-
-       newdir = newdir * 0.5 + normalize(self.velocity) * 0.5;
-
-       if(self.wp00)
-               self.velocity = normalize(newdir) * (500 + (1024 / min(vlen(self.wp00.origin - self.origin), 1024)) * 700);
-       else
-               self.velocity = normalize(newdir) * 750;
-
-       tracebox(self.origin, self.mins, self.maxs, self.origin + self.velocity * 2, MOVE_NORMAL, self);
-       if(trace_fraction != 1.0)
-               self.velocity = self.velocity * -1;
-
-       //normalize((normalize(self.velocity) * 0.5 + newdir * 0.5)) * 750;
-}
-
-void targetdrone_spawn(vector _where, float _autorenew)
-{
-       entity drone = spawn();
-       setorigin(drone, _where);
-       drone.think = targetdrone_renwe;
-       drone.nextthink = time + 0.1;
-       drone.cnt = _autorenew;
-}
-#endif
-
-void vehicles_locktarget(float incr, float decr, float _lock_time)
-{
-    if(self.lock_target && self.lock_target.deadflag != DEAD_NO)
-    {
-        self.lock_target    = world;
-        self.lock_strength  = 0;
-        self.lock_time      = 0;
-    }
-
-    if(self.lock_time > time)
-    {
-        if(self.lock_target)
-        if(self.lock_soundtime < time)
-        {
-            self.lock_soundtime = time + 0.5;
-            play2(self.owner, "vehicles/locked.wav");
-        }
-
-        return;
-    }
-
-    if(trace_ent != world)
-    {
-        if(teamplay && trace_ent.team == self.team)
-            trace_ent = world;
-
-        if(trace_ent.deadflag != DEAD_NO)
-            trace_ent = world;
-        if(!(
-            (trace_ent.vehicle_flags & VHF_ISVEHICLE) || 
-            (trace_ent.turrcaps_flags & TFL_TURRCAPS_ISTURRET) || 
-            (trace_ent.takedamage == DAMAGE_TARGETDRONE)
-            )) { trace_ent = world; }
-    }
-
-    if(self.lock_target == world && trace_ent != world)
-        self.lock_target = trace_ent;
-
-    if(self.lock_target && trace_ent == self.lock_target)
-    {
-        if(self.lock_strength != 1 && self.lock_strength + incr >= 1)
-        {
-            play2(self.owner, "vehicles/lock.wav");
-            self.lock_soundtime = time + 0.8;
-        }
-        else if (self.lock_strength != 1 && self.lock_soundtime < time)
-        {
-            play2(self.owner, "vehicles/locking.wav");
-            self.lock_soundtime = time + 0.3;
-        }
-
-    }
-
-    // Have a locking target
-    // Trace hit current target
-    if(trace_ent == self.lock_target && trace_ent != world)
-    {
-        self.lock_strength = min(self.lock_strength + incr, 1);
-        if(self.lock_strength == 1)
-            self.lock_time = time + _lock_time;
-    }
-    else
-    {
-        if(trace_ent)
-            self.lock_strength = max(self.lock_strength - decr * 2, 0);
-        else
-            self.lock_strength = max(self.lock_strength - decr, 0);
-
-        if(self.lock_strength == 0)
-            self.lock_target = world;
-    }
-}
-
-#define VEHICLE_UPDATE_PLAYER(ply,fld,vhname) \
-ply.vehicle_##fld = (self.vehicle_##fld / autocvar_g_vehicle_##vhname##_##fld) * 100
-
-#define vehicles_sweap_collision(orig,vel,dt,acm,mult) \
-traceline(orig, orig + vel * dt, MOVE_NORMAL, self); \
-if(trace_fraction != 1) \
-    acm += normalize(self.origin - trace_endpos) * (vlen(vel) * mult)
-
-// Hover movement support
-float  force_fromtag_power;
-float  force_fromtag_normpower;
-vector force_fromtag_origin;
-vector vehicles_force_fromtag_hover(string tag_name, float spring_length, float max_power)
-{
-    force_fromtag_origin = gettaginfo(self, gettagindex(self, tag_name));
-    v_forward  = normalize(v_forward) * -1;
-    traceline(force_fromtag_origin, force_fromtag_origin - (v_forward  * spring_length), MOVE_NORMAL, self);
-
-    force_fromtag_power = (1 - trace_fraction) * max_power;
-    force_fromtag_normpower = force_fromtag_power / max_power;
-
-    return v_forward  * force_fromtag_power;
-}
-
-// Experimental hovermode wich uses attraction/repulstion from surface insted of gravity/repulsion
-// Can possibly be use to move abt any surface (inclusing walls/celings)
-vector vehicles_force_fromtag_maglev(string tag_name, float spring_length, float max_power)
-{
-
-    force_fromtag_origin = gettaginfo(self, gettagindex(self, tag_name));
-    v_forward  = normalize(v_forward) * -1;
-    traceline(force_fromtag_origin, force_fromtag_origin - (v_forward  * spring_length), MOVE_NORMAL, self);
-
-    // TODO - this may NOT be compatible with wall/celing movement, unhardcode 0.25 (engine count multiplier)
-    if(trace_fraction == 1.0)
-    {
-        force_fromtag_normpower = -0.25;
-        return '0 0 -200';
-    }
-
-    force_fromtag_power = ((1 - trace_fraction) - trace_fraction) * max_power;
-    force_fromtag_normpower = force_fromtag_power / max_power;
-
-    return v_forward  * force_fromtag_power;
-}
-
-// Generic vehile projectile system
-void vehicles_projectile_damage(entity inflictor, entity attacker, float damage, int deathtype, vector hitloc, vector force)
-{
-    // Ignore damage from oterh projectiles from my owner (dont mess up volly's)
-    if(inflictor.owner == self.owner)
-        return;
-
-    self.health -= damage;
-    self.velocity += force;
-    if(self.health < 1)
-    {
-        self.takedamage = DAMAGE_NO;
-        self.event_damage = func_null;
-        self.think = self.use;
-        self.nextthink = time;
-    }
-}
-
-void vehicles_projectile_explode()
-{
-    if(self.owner && other != world)
-    {
-        if(other == self.owner.vehicle)
-            return;
-
-        if(other == self.owner.vehicle.tur_head)
-            return;
-    }
-
-       PROJECTILE_TOUCH;
-
-       self.event_damage = func_null;
-    RadiusDamage (self, self.realowner, self.shot_dmg, 0, self.shot_radius, self, world, self.shot_force, self.totalfrags, other);
-
-    remove (self);
-}
-
-entity vehicles_projectile(string _mzlfx, string _mzlsound,
-                           vector _org, vector _vel,
-                           float _dmg, float _radi, float _force,  float _size,
-                           float _deahtype, float _projtype, float _health,
-                           float _cull, float _clianim, entity _owner)
-{
-    entity proj;
-
-    proj = spawn();
-
-    PROJECTILE_MAKETRIGGER(proj);
-    setorigin(proj, _org);
-
-    proj.shot_dmg         = _dmg;
-    proj.shot_radius      = _radi;
-    proj.shot_force       = _force;
-    proj.totalfrags       = _deahtype;
-    proj.solid            = SOLID_BBOX;
-    proj.movetype         = MOVETYPE_FLYMISSILE;
-    proj.flags            = FL_PROJECTILE;
-    proj.bot_dodge        = true;
-    proj.bot_dodgerating  = _dmg;
-    proj.velocity         = _vel;
-    proj.touch            = vehicles_projectile_explode;
-    proj.use              = vehicles_projectile_explode;
-    proj.owner            = self;
-    proj.realowner        = _owner;
-    proj.think            = SUB_Remove;
-    proj.nextthink        = time + 30;
-
-    if(_health)
-    {
-        proj.takedamage       = DAMAGE_AIM;
-        proj.event_damage     = vehicles_projectile_damage;
-        proj.health           = _health;
-    }
-    else
-        proj.flags           = FL_PROJECTILE | FL_NOTARGET;
-
-    if(_mzlsound)
-        sound (self, CH_WEAPON_A, _mzlsound, VOL_BASE, ATTEN_NORM);
-
-    if(_mzlfx)
-        pointparticles(particleeffectnum(_mzlfx), proj.origin, proj.velocity, 1);
-
-
-    setsize (proj, '-1 -1 -1' * _size, '1 1 1' * _size);
-
-    CSQCProjectile(proj, _clianim, _projtype, _cull);
-
-    return proj;
-}
-// End generic vehile projectile system
-
-void vehicles_reset()
-{
-       if(self.owner)
-       {
-               entity oldself = self;
-               self = self.owner;
-               vehicles_exit(VHEF_RELESE);
-               self = oldself;
-       }
-       self.alpha      = -1;
-       self.movetype   = MOVETYPE_NONE;
-       self.effects    = EF_NODRAW;
-       self.colormod  = '0 0 0';
-       self.avelocity = '0 0 0';
-       self.velocity  = '0 0 0';
-       self.event_damage = func_null;
-       self.solid = SOLID_NOT;
-       self.deadflag = DEAD_NO;
-
-       self.touch = func_null;
-       self.nextthink = 0;
-       vehicles_setreturn();
-}
-
-/** vehicles_spawn
-    Exetuted for all vehicles on (re)spawn.
-    Sets defaults for newly spawned units.
-**/
-void vehicles_spawn()
-{
-    dprint("Spawning vehicle: ", self.netname, "\n");
-
-    // De-own & reset
-    self.vehicle_hudmodel.viewmodelforclient = self;
-
-    self.owner              = world;
-    self.touch              = vehicles_touch;
-    self.event_damage       = vehicles_damage;
-    self.reset              = vehicles_reset;
-    self.iscreature         = true;
-    self.teleportable       = false; // no teleporting for vehicles, too buggy
-    self.damagedbycontents     = true;
-    self.movetype           = MOVETYPE_WALK;
-    self.solid              = SOLID_SLIDEBOX;
-    self.takedamage         = DAMAGE_AIM;
-       self.deadflag           = DEAD_NO;
-    self.bot_attack         = true;
-    self.flags              = FL_NOTARGET;
-    self.avelocity          = '0 0 0';
-    self.velocity           = '0 0 0';
-
-    // Reset locking
-    self.lock_strength      = 0;
-    self.lock_target        = world;
-    self.misc_bulletcounter = 0;
-
-    // Return to spawn
-    self.angles             = self.pos2;
-    setorigin(self, self.pos1 + '0 0 0');
-    // Show it
-    pointparticles(particleeffectnum("teleport"), self.origin + '0 0 64', '0 0 0', 1);
-
-    if(self.vehicle_controller)
-        self.team = self.vehicle_controller.team;
-
-    vehicles_reset_colors();
-    self.vehicle_spawn(VHSF_NORMAL);
-}
-
-// Better way of determening whats crushable needed! (fl_crushable?)
-float vehicles_crushable(entity e)
-{
-    if(IS_PLAYER(e))
-        return true;
-
-    if(e.flags & FL_MONSTER)
-        return true;
-
-    return false;
-}
-
-void vehicles_impact(float _minspeed, float _speedfac, float _maxpain)
-{
-    if (trace_dphitq3surfaceflags & Q3SURFACEFLAG_NOIMPACT)
-        return;
-
-    if(self.play_time < time)
-    {
-        float wc = vlen(self.velocity - self.oldvelocity);
-        //dprint("oldvel: ", vtos(self.oldvelocity), "\n");
-        //dprint("vel: ", vtos(self.velocity), "\n");
-        if(_minspeed < wc)
-        {
-            float take = min(_speedfac * wc, _maxpain);
-            Damage (self, world, world, take, DEATH_FALL, self.origin, '0 0 0');
-            self.play_time = time + 0.25;
-
-            //dprint("wc: ", ftos(wc), "\n");
-            //dprint("take: ", ftos(take), "\n");
-        }
-    }
-}
-
-.void() vehicle_impact;
-void vehicles_touch()
-{
-       if(MUTATOR_CALLHOOK(VehicleTouch))
-               return;
-
-    // Vehicle currently in use
-    if(self.owner)
-    {
-        if(other != world)
-        if(vehicles_crushable(other))
-        {
-            if(vlen(self.velocity) != 0)
-                Damage(other, self, self.owner, autocvar_g_vehicles_crush_dmg, DEATH_VH_CRUSH, '0 0 0', normalize(other.origin - self.origin) * autocvar_g_vehicles_crush_force);
-
-            return; // Dont do selfdamage when hitting "soft targets".
-        }
-
-        if(self.play_time < time)
-        if(self.vehicle_impact)
-            self.vehicle_impact();
-
-        return;
-    }
-
-    if (!IS_PLAYER(other))
-        return;
-
-    if(other.deadflag != DEAD_NO)
-        return;
-
-    if(other.vehicle != world)
-        return;
-
-    vehicles_enter();
-}
-float autocvar_g_vehicles_allow_bots = 0;
-void vehicles_enter()
-{
-   // Remove this when bots know how to use vehicles
-
-    if (IS_BOT_CLIENT(other))
-        if (autocvar_g_vehicles_allow_bots)
-            dprint("Bot enters vehicle\n"); // This is where we need to disconnect (some, all?) normal bot AI and hand over to vehicle's _aiframe()
-        else
-            return;
-
-    if(self.phase > time)
-        return;
-    if(other.frozen)
-        return;
-    if(other.vehicle)
-        return;
-    if(other.deadflag != DEAD_NO)
-        return;
-
-    if(teamplay)
-    if(self.team)
-    if(self.team != other.team)
-        return;
-
-    RemoveGrapplingHook(other);
-
-    self.vehicle_ammo1   = 0;
-    self.vehicle_ammo2   = 0;
-    self.vehicle_reload1 = 0;
-    self.vehicle_reload2 = 0;
-    self.vehicle_energy  = 0;
-
-    self.owner          = other;
-    self.switchweapon   = other.switchweapon;
-
-    // .viewmodelforclient works better.
-    //self.vehicle_hudmodel.drawonlytoclient = self.owner;
-
-    self.vehicle_hudmodel.viewmodelforclient = self.owner;
-
-    self.event_damage         = vehicles_damage;
-    self.nextthink            = 0;
-    self.owner.angles         = self.angles;
-    self.owner.takedamage     = DAMAGE_NO;
-    self.owner.solid          = SOLID_NOT;
-    self.owner.movetype       = MOVETYPE_NOCLIP;
-    self.owner.alpha          = -1;
-    self.owner.vehicle        = self;
-    self.owner.event_damage   = func_null;
-    self.owner.view_ofs       = '0 0 0';
-    self.colormap             = self.owner.colormap;
-    if(self.tur_head)
-        self.tur_head.colormap    = self.owner.colormap;
-
-    self.owner.hud            = self.hud;
-    self.owner.PlayerPhysplug = self.PlayerPhysplug;
-
-    self.owner.vehicle_ammo1    = self.vehicle_ammo1;
-    self.owner.vehicle_ammo2    = self.vehicle_ammo2;
-    self.owner.vehicle_reload1  = self.vehicle_reload1;
-    self.owner.vehicle_reload2  = self.vehicle_reload2;
-
-    // Cant do this, hides attached objects too.
-    //self.exteriormodeltoclient = self.owner;
-    //self.tur_head.exteriormodeltoclient = self.owner;
-
-    other.flags &= ~FL_ONGROUND;
-    self.flags  &= ~FL_ONGROUND;
-
-    self.team                 = self.owner.team;
-    self.flags               -= FL_NOTARGET;
-    self.monster_attack       = true;
-
-    if (IS_REAL_CLIENT(other))
-    {
-        msg_entity = other;
-        WriteByte (MSG_ONE, SVC_SETVIEWPORT);
-        WriteEntity(MSG_ONE, self.vehicle_viewport);
-
-        WriteByte (MSG_ONE, SVC_SETVIEWANGLES);
-        if(self.tur_head)
-        {
-            WriteAngle(MSG_ONE, self.tur_head.angles.x + self.angles.x); // tilt
-            WriteAngle(MSG_ONE, self.tur_head.angles.y + self.angles.y); // yaw
-            WriteAngle(MSG_ONE, 0);                                      // roll
-        }
-        else
-        {
-            WriteAngle(MSG_ONE,  self.angles.x * -1); // tilt
-            WriteAngle(MSG_ONE,  self.angles.y);      // yaw
-            WriteAngle(MSG_ONE,  0);                  // roll
-        }
-    }
-
-    vehicles_clearreturn();
-
-    CSQCVehicleSetup(self.owner, self.hud);
-
-    vh_player = other;
-    vh_vehicle = self;
-    MUTATOR_CALLHOOK(VehicleEnter);
-    other = vh_player;
-    self = vh_vehicle;
-
-    self.vehicle_enter();
-    antilag_clear(other);
-}
-
-/** vehicles_findgoodexit
-    Locates a valid location for the player to exit the vehicle.
-    Will first try prefer_spot, then up 100 random spots arround the vehicle
-    wich are in direct line of sight and empty enougth to hold a players bbox
-**/
-vector vehicles_findgoodexit(vector prefer_spot)
-{
-    //vector exitspot;
-    float mysize;
-
-    tracebox(self.origin + '0 0 32', PL_MIN, PL_MAX, prefer_spot, MOVE_NORMAL, self.owner);
-    if(trace_fraction == 1.0 && !trace_startsolid && !trace_allsolid)
-        return prefer_spot;
-
-    mysize = 1.5 * vlen(self.maxs - self.mins);
-    float i;
-    vector v, v2;
-    v2 = 0.5 * (self.absmin + self.absmax);
-    for(i = 0; i < 100; ++i)
-    {
-        v = randomvec();
-        v.z = 0;
-        v = v2 + normalize(v) * mysize;
-        tracebox(v2, PL_MIN, PL_MAX, v, MOVE_NORMAL, self.owner);
-        if(trace_fraction == 1.0 && !trace_startsolid && !trace_allsolid)
-            return v;
-    }
-
-    /*
-    exitspot = (self.origin + '0 0 48') + v_forward * mysize;
-    tracebox(self.origin + '0 0 32', PL_MIN, PL_MAX, exitspot, MOVE_NORMAL, self.owner);
-    if(trace_fraction == 1.0 && !trace_startsolid && !trace_allsolid)
-        return exitspot;
-
-    exitspot = (self.origin + '0 0 48') - v_forward * mysize;
-    tracebox(self.origin + '0 0 32', PL_MIN, PL_MAX, exitspot, MOVE_NORMAL, self.owner);
-    if(trace_fraction == 1.0 && !trace_startsolid && !trace_allsolid)
-        return exitspot;
-
-    exitspot = (self.origin + '0 0 48') + v_right * mysize;
-    tracebox(self.origin + '0 0 32', PL_MIN, PL_MAX, exitspot, MOVE_NORMAL, self.owner);
-    if(trace_fraction == 1.0 && !trace_startsolid && !trace_allsolid)
-        return exitspot;
-
-    exitspot = (self.origin + '0 0 48') - v_right * mysize;
-    tracebox(self.origin + '0 0 32', PL_MIN, PL_MAX, exitspot, MOVE_NORMAL, self.owner);
-    if(trace_fraction == 1.0 && !trace_startsolid && !trace_allsolid)
-        return exitspot;
-    */
-
-    return self.origin;
-}
-
-/** vehicles_exit
-    Standarrd vehicle release fucntion.
-    custom code goes in self.vehicle_exit
-**/
-float vehicles_exit_running;
-void vehicles_exit(float eject)
-{
-    entity _vehicle;
-    entity _player;
-    entity _oldself = self;
-
-    if(vehicles_exit_running)
-    {
-        dprint("^1vehicles_exit allready running! this is not good..\n");
-        return;
-    }
-
-    vehicles_exit_running = true;
-    if(IS_CLIENT(self))
-    {
-        _vehicle = self.vehicle;
-
-        if (_vehicle.vehicle_flags & VHF_PLAYERSLOT)
-        {
-            _vehicle.vehicle_exit(eject);
-            self = _oldself;
-            vehicles_exit_running = false;
-            return;
-        }
-    }
-    else
-        _vehicle = self;
-
-    _player = _vehicle.owner;
-
-    self = _vehicle;
-
-    if (_player)
-    {
-        if (IS_REAL_CLIENT(_player))
-        {
-            msg_entity = _player;
-            WriteByte (MSG_ONE, SVC_SETVIEWPORT);
-            WriteEntity( MSG_ONE, _player);
-
-            WriteByte (MSG_ONE, SVC_SETVIEWANGLES);
-            WriteAngle(MSG_ONE, 0);
-            WriteAngle(MSG_ONE, _vehicle.angles.y);
-            WriteAngle(MSG_ONE, 0);
-        }
-
-        setsize(_player, PL_MIN,PL_MAX);
-
-        _player.takedamage     = DAMAGE_AIM;
-        _player.solid          = SOLID_SLIDEBOX;
-        _player.movetype       = MOVETYPE_WALK;
-        _player.effects        &= ~EF_NODRAW;
-        _player.alpha          = 1;
-        _player.PlayerPhysplug = func_null;
-        _player.vehicle        = world;
-        _player.view_ofs       = PL_VIEW_OFS;
-        _player.event_damage   = PlayerDamage;
-        _player.hud            = HUD_NORMAL;
-        _player.switchweapon   = _vehicle.switchweapon;
-
-        CSQCVehicleSetup(_player, HUD_NORMAL);
-    }
-    _vehicle.flags |= FL_NOTARGET;
-
-    if(_vehicle.deadflag == DEAD_NO)
-        _vehicle.avelocity          = '0 0 0';
-
-    _vehicle.tur_head.nodrawtoclient             = world;
-
-    if(!teamplay)
-        _vehicle.team = 0;
-
-    vh_player = _player;
-    vh_vehicle = _vehicle;
-    MUTATOR_CALLHOOK(VehicleExit);
-    _player = vh_player;
-    _vehicle = vh_vehicle;
-
-    _vehicle.team = _vehicle.tur_head.team;
-
-    sound (_vehicle, CH_TRIGGER_SINGLE, "misc/null.wav", 1, ATTEN_NORM);
-    _vehicle.vehicle_hudmodel.viewmodelforclient = _vehicle;
-    _vehicle.phase = time + 1;
-    _vehicle.monster_attack = false;
-
-    _vehicle.vehicle_exit(eject);
-
-    vehicles_setreturn();
-    vehicles_reset_colors();
-    _vehicle.owner = world;
-    self = _oldself;
-
-    vehicles_exit_running = false;
-}
-
-
-void vehicles_regen(float timer, .float regen_field, float field_max, float rpause, float regen, float delta_time, float _healthscale)
-{
-    if (self.(regen_field) < field_max)
-    if (timer + rpause < time)
-    {
-        if (_healthscale)
-            regen = regen * (self.vehicle_health / self.tur_health);
-
-        self.(regen_field) = min(self.(regen_field) + regen * delta_time, field_max);
-
-        if (self.owner)
-            self.owner.(regen_field) = (self.(regen_field) / field_max) * 100;
-    }
-}
-
-void shieldhit_think()
-{
-    self.alpha -= 0.1;
-    if (self.alpha <= 0)
-    {
-        //setmodel(self, "");
-        self.alpha = -1;
-        self.effects |= EF_NODRAW;
-    }
-    else
-    {
-        self.nextthink = time + 0.1;
-    }
-}
-
-void vehicles_painframe()
-{
-    if(self.owner.vehicle_health <= 50)
-    if(self.pain_frame < time)
-    {
-        float _ftmp;
-        _ftmp = self.owner.vehicle_health / 50;
-        self.pain_frame = time + 0.1 + (random() * 0.5 * _ftmp);
-        pointparticles(particleeffectnum("smoke_small"), (self.origin + (randomvec() * 80)), '0 0 0', 1);
-
-        if(self.vehicle_flags & VHF_DMGSHAKE)
-            self.velocity += randomvec() * 30;
-
-        if(self.vehicle_flags & VHF_DMGROLL)
-            if(self.vehicle_flags & VHF_DMGHEADROLL)
-                self.tur_head.angles += randomvec();
-            else
-                self.angles += randomvec();
-
-    }
-}
-
-void vehicles_damage(entity inflictor, entity attacker, float damage, int deathtype, vector hitloc, vector force)
-{
-    self.dmg_time = time;
-
-       // WEAPONTODO
-    if(DEATH_ISWEAPON(deathtype, WEP_VORTEX))
-        damage *= autocvar_g_vehicles_vortex_damagerate;
-
-    if(DEATH_ISWEAPON(deathtype, WEP_MACHINEGUN))
-        damage *= autocvar_g_vehicles_machinegun_damagerate;
-
-    if(DEATH_ISWEAPON(deathtype, WEP_RIFLE))
-        damage *= autocvar_g_vehicles_rifle_damagerate;
-
-    if(DEATH_ISWEAPON(deathtype, WEP_VAPORIZER))
-        damage *= autocvar_g_vehicles_vaporizer_damagerate;
-
-    if(DEATH_ISWEAPON(deathtype, WEP_SEEKER))
-        damage *= autocvar_g_vehicles_tag_damagerate;
-
-    self.enemy = attacker;
-
-    if((self.vehicle_flags & VHF_HASSHIELD) && (self.vehicle_shield > 0))
-    {
-        if (wasfreed(self.vehicle_shieldent) || self.vehicle_shieldent == world)
-        {
-            self.vehicle_shieldent = spawn();
-            self.vehicle_shieldent.effects = EF_LOWPRECISION;
-
-            setmodel(self.vehicle_shieldent, "models/vhshield.md3");
-            setattachment(self.vehicle_shieldent, self, "");
-            setorigin(self.vehicle_shieldent, real_origin(self) - self.origin);
-            self.vehicle_shieldent.scale       = 256 / vlen(self.maxs - self.mins);
-            self.vehicle_shieldent.think       = shieldhit_think;
-        }
-
-        self.vehicle_shieldent.colormod    = '1 1 1';
-        self.vehicle_shieldent.alpha       = 0.45;
-        self.vehicle_shieldent.angles      = vectoangles(normalize(hitloc - (self.origin + self.vehicle_shieldent.origin))) - self.angles;
-        self.vehicle_shieldent.nextthink   = time;
-        self.vehicle_shieldent.effects &= ~EF_NODRAW;
-
-        self.vehicle_shield -= damage;
-
-        if(self.vehicle_shield < 0)
-        {
-            self.vehicle_health            -= fabs(self.vehicle_shield);
-            self.vehicle_shieldent.colormod = '2 0 0';
-            self.vehicle_shield             = 0;
-            self.vehicle_shieldent.alpha    = 0.75;
-
-               if(sound_allowed(MSG_BROADCAST, attacker))
-                spamsound (self, CH_PAIN, "onslaught/ons_hit2.wav", VOL_BASE, ATTEN_NORM);   // FIXME: PLACEHOLDER
-        }
-        else
-               if(sound_allowed(MSG_BROADCAST, attacker))
-                spamsound (self, CH_PAIN, "onslaught/electricity_explode.wav", VOL_BASE, ATTEN_NORM);  // FIXME: PLACEHOLDER
-
-    }
-    else
-    {
-        self.vehicle_health -= damage;
-
-        if(sound_allowed(MSG_BROADCAST, attacker))
-            spamsound (self, CH_PAIN, "onslaught/ons_hit2.wav", VOL_BASE, ATTEN_NORM);  // FIXME: PLACEHOLDER
-    }
-
-       if(self.damageforcescale < 1 && self.damageforcescale > 0)
-               self.velocity += force * self.damageforcescale;
-       else
-               self.velocity += force;
-
-    if(self.vehicle_health <= 0)
-    {
-        if(self.owner)
-            if(self.vehicle_flags & VHF_DEATHEJECT)
-                vehicles_exit(VHEF_EJECT);
-            else
-                vehicles_exit(VHEF_RELESE);
-
-
-        antilag_clear(self);
-
-        self.vehicle_die();
-        vehicles_setreturn();
-    }
-}
-
-void vehicles_clearreturn()
-{
-    entity ret;
-    // Remove "return helper", if any.
-    ret = findchain(classname, "vehicle_return");
-    while(ret)
-    {
-        if(ret.wp00 == self)
-        {
-            ret.classname   = "";
-            ret.think       = SUB_Remove;
-            ret.nextthink   = time + 0.1;
-
-            if(ret.waypointsprite_attached)
-                WaypointSprite_Kill(ret.waypointsprite_attached);
-
-            return;
-        }
-        ret = ret.chain;
-    }
-}
-
-void vehicles_return()
-{
-    pointparticles(particleeffectnum("teleport"), self.wp00.origin + '0 0 64', '0 0 0', 1);
-
-    self.wp00.think     = vehicles_spawn;
-    self.wp00.nextthink = time;
-
-    if(self.waypointsprite_attached)
-        WaypointSprite_Kill(self.waypointsprite_attached);
-
-    remove(self);
-}
-
-void vehicles_showwp_goaway()
-{
-    if(self.waypointsprite_attached)
-        WaypointSprite_Kill(self.waypointsprite_attached);
-
-    remove(self);
-
-}
-
-void vehicles_showwp()
-{
-    entity oldself = world;
-    vector rgb;
-
-    if(self.cnt)
-    {
-        self.think      = vehicles_return;
-        self.nextthink  = self.cnt;
-    }
-    else
-    {
-        self.think      = vehicles_return;
-        self.nextthink  = time +1;
-
-        oldself = self;
-        self = spawn();
-        setmodel(self, "null");
-        self.team = oldself.wp00.team;
-        self.wp00 = oldself.wp00;
-        setorigin(self, oldself.wp00.pos1);
-
-        self.nextthink = time + 5;
-        self.think = vehicles_showwp_goaway;
-    }
-
-    if(teamplay && self.team)
-           rgb = Team_ColorRGB(self.team);
-    else
-           rgb = '1 1 1';
-    WaypointSprite_Spawn("vehicle", 0, 0, self, '0 0 64', world, 0, self, waypointsprite_attached, true, RADARICON_POWERUP, rgb);
-    if(self.waypointsprite_attached)
-    {
-        WaypointSprite_UpdateRule(self.waypointsprite_attached, self.wp00.team, SPRITERULE_DEFAULT);
-        if(oldself == world)
-            WaypointSprite_UpdateBuildFinished(self.waypointsprite_attached, self.nextthink);
-        WaypointSprite_Ping(self.waypointsprite_attached);
-    }
-
-    if(oldself != world)
-        self = oldself;
-}
-
-void vehicles_setreturn()
-{
-    entity ret;
-
-    vehicles_clearreturn();
-
-    ret = spawn();
-    ret.classname   = "vehicle_return";
-    ret.wp00       = self;
-    ret.team        = self.team;
-    ret.think       = vehicles_showwp;
-
-       if(self.deadflag != DEAD_NO)
-       {
-               ret.cnt = max(game_starttime, time) + self.vehicle_respawntime;
-               ret.nextthink = max(game_starttime, time) + max(0, self.vehicle_respawntime - 5);
-       }
-       else
-               ret.nextthink = max(game_starttime, time) + max(0, self.vehicle_respawntime - 1);
-
-    setmodel(ret, "null");
-    setorigin(ret, self.pos1 + '0 0 96');
-}
-
-void vehicles_reset_colors()
-{
-    entity e;
-    float _effects = 0, _colormap;
-    vector _glowmod, _colormod;
-
-    if(autocvar_g_nodepthtestplayers)
-        _effects |= EF_NODEPTHTEST;
-
-    if(autocvar_g_fullbrightplayers)
-        _effects |= EF_FULLBRIGHT;
-
-    if(self.team)
-        _colormap = 1024 + (self.team - 1) * 17;
-    else
-        _colormap = 1024;
-
-    _glowmod  = '0 0 0';
-    _colormod = '0 0 0';
-
-    // Find all ents attacked to main model and setup effects, colormod etc.
-    e = findchainentity(tag_entity, self);
-    while(e)
-    {
-        if(e != self.vehicle_shieldent)
-        {
-            e.effects   = _effects; //  | EF_LOWPRECISION;
-            e.colormod  = _colormod;
-            e.colormap  = _colormap;
-            e.alpha     = 1;
-        }
-        e = e.chain;
-    }
-
-    self.vehicle_hudmodel.effects  = self.effects  = _effects; // | EF_LOWPRECISION;
-    self.vehicle_hudmodel.colormod = self.colormod = _colormod;
-    self.vehicle_hudmodel.colormap = self.colormap = _colormap;
-    self.vehicle_viewport.effects = (EF_ADDITIVE | EF_DOUBLESIDED | EF_FULLBRIGHT | EF_NODEPTHTEST | EF_NOGUNBOB | EF_NOSHADOW | EF_LOWPRECISION | EF_SELECTABLE | EF_TELEPORT_BIT);
-
-    self.alpha     = 1;
-    self.avelocity = '0 0 0';
-    self.velocity  = '0 0 0';
-    self.effects   = _effects;
-}
-
-void vehicle_use()
-{
-    dprint("vehicle ",self.netname, " used by ", activator.classname, "\n");
-
-    self.tur_head.team = activator.team;
-
-    if(self.tur_head.team == 0)
-        self.active = ACTIVE_NOT;
-    else
-        self.active = ACTIVE_ACTIVE;
-
-    if(self.active == ACTIVE_ACTIVE && self.deadflag == DEAD_NO)
-    {
-        dprint("^3Eat shit yall!\n");
-        vehicles_setreturn();
-        vehicles_reset_colors();
-    }
-    else if(self.active == ACTIVE_NOT && self.deadflag != DEAD_NO)
-    {
-
-    }
-}
-
-float vehicle_addplayerslot(    entity _owner,
-                                entity _slot,
-                                float _hud,
-                                string _hud_model,
-                                float() _framefunc,
-                                void(float) _exitfunc)
-{
-    if (!(_owner.vehicle_flags & VHF_MULTISLOT))
-        _owner.vehicle_flags |= VHF_MULTISLOT;
-
-    _slot.PlayerPhysplug = _framefunc;
-    _slot.vehicle_exit = _exitfunc;
-    _slot.hud = _hud;
-    _slot.vehicle_flags = VHF_PLAYERSLOT;
-    _slot.vehicle_viewport = spawn();
-    _slot.vehicle_hudmodel = spawn();
-    _slot.vehicle_hudmodel.viewmodelforclient = _slot;
-    _slot.vehicle_viewport.effects = (EF_ADDITIVE | EF_DOUBLESIDED | EF_FULLBRIGHT | EF_NODEPTHTEST | EF_NOGUNBOB | EF_NOSHADOW | EF_LOWPRECISION | EF_SELECTABLE | EF_TELEPORT_BIT);
-
-    setmodel(_slot.vehicle_hudmodel, _hud_model);
-    setmodel(_slot.vehicle_viewport, "null");
-
-    setattachment(_slot.vehicle_hudmodel, _slot, "");
-    setattachment(_slot.vehicle_viewport, _slot.vehicle_hudmodel, "");
-
-    return true;
-}
-
-float vehicle_initialize(string  net_name,
-                         string  bodymodel,
-                         string  topmodel,
-                         string  hudmodel,
-                         string  toptag,
-                         string  hudtag,
-                         string  viewtag,
-                         float   vhud,
-                         vector  min_s,
-                         vector  max_s,
-                         float   nodrop,
-                         void(float _spawnflag)  spawnproc,
-                         float   _respawntime,
-                         float() physproc,
-                         void()  enterproc,
-                         void(float extflag) exitfunc,
-                         void() dieproc,
-                         void() thinkproc,
-                         float  use_csqc,
-                         float _max_health,
-                         float _max_shield)
-{
-       if(!autocvar_g_vehicles)
-               return false;
-
-    if(self.targetname)
-    {
-        self.vehicle_controller = find(world, target, self.targetname);
-        if(!self.vehicle_controller)
-        {
-            bprint("^1WARNING: ^7Vehicle with invalid .targetname\n");
-        }
-        else
-        {
-            self.team = self.vehicle_controller.team;
-            self.use = vehicle_use;
-
-            if(teamplay)
-            {
-                if(self.vehicle_controller.team == 0)
-                    self.active = ACTIVE_NOT;
-                else
-                    self.active = ACTIVE_ACTIVE;
-            }
-        }
-    }
-
-    precache_sound("onslaught/ons_hit2.wav");
-    precache_sound("onslaught/electricity_explode.wav");
-
-
-    addstat(STAT_HUD, AS_INT,  hud);
-       addstat(STAT_VEHICLESTAT_HEALTH,  AS_INT, vehicle_health);
-       addstat(STAT_VEHICLESTAT_SHIELD,  AS_INT, vehicle_shield);
-       addstat(STAT_VEHICLESTAT_ENERGY,  AS_INT, vehicle_energy);
-
-       addstat(STAT_VEHICLESTAT_AMMO1,   AS_INT, vehicle_ammo1);
-       addstat(STAT_VEHICLESTAT_RELOAD1, AS_INT, vehicle_reload1);
-
-       addstat(STAT_VEHICLESTAT_AMMO2,   AS_INT, vehicle_ammo2);
-       addstat(STAT_VEHICLESTAT_RELOAD2, AS_INT, vehicle_reload2);
-
-    if(bodymodel == "")
-        error("vehicles: missing bodymodel!");
-
-    if(hudmodel == "")
-        error("vehicles: missing hudmodel!");
-
-    if(net_name == "")
-        self.netname = self.classname;
-    else
-        self.netname = net_name;
-
-    if(self.team && !teamplay)
-        self.team = 0;
-
-    self.vehicle_flags |= VHF_ISVEHICLE;
-
-    setmodel(self, bodymodel);
-
-    self.vehicle_viewport   = spawn();
-    self.vehicle_hudmodel   = spawn();
-    self.tur_head           = spawn();
-    self.tur_head.owner     = self;
-    self.takedamage         = DAMAGE_AIM;
-    self.bot_attack         = true;
-    self.iscreature         = true;
-    self.teleportable       = false; // no teleporting for vehicles, too buggy
-    self.damagedbycontents     = true;
-    self.hud                = vhud;
-    self.tur_health          = _max_health;
-    self.tur_head.tur_health = _max_shield;
-    self.vehicle_die         = dieproc;
-    self.vehicle_exit        = exitfunc;
-    self.vehicle_enter       = enterproc;
-    self.PlayerPhysplug      = physproc;
-    self.event_damage        = func_null;
-    self.touch               = vehicles_touch;
-    self.think               = vehicles_spawn;
-    self.vehicle_spawn       = spawnproc;
-       self.vehicle_respawntime = max(0, _respawntime);
-    self.effects             = EF_NODRAW;
-       self.dphitcontentsmask   = DPCONTENTS_BODY | DPCONTENTS_SOLID;
-       if(!autocvar_g_vehicles_delayspawn || !self.vehicle_respawntime)
-               self.nextthink = time;
-       else
-               self.nextthink = max(time, game_starttime) + max(0, self.vehicle_respawntime + ((random() * 2 - 1) * autocvar_g_vehicles_delayspawn_jitter));
-
-       if(autocvar_g_playerclip_collisions)
-               self.dphitcontentsmask |= DPCONTENTS_PLAYERCLIP;
-
-    if(autocvar_g_nodepthtestplayers)
-        self.effects = self.effects | EF_NODEPTHTEST;
-
-    if(autocvar_g_fullbrightplayers)
-        self.effects = self.effects | EF_FULLBRIGHT;
-
-    setmodel(self.vehicle_hudmodel, hudmodel);
-    setmodel(self.vehicle_viewport, "null");
-
-    if(topmodel != "")
-    {
-        setmodel(self.tur_head, topmodel);
-        setattachment(self.tur_head, self, toptag);
-        setattachment(self.vehicle_hudmodel, self.tur_head, hudtag);
-        setattachment(self.vehicle_viewport, self.vehicle_hudmodel, viewtag);
-    }
-    else
-    {
-        setattachment(self.tur_head, self, "");
-        setattachment(self.vehicle_hudmodel, self, hudtag);
-        setattachment(self.vehicle_viewport, self.vehicle_hudmodel, viewtag);
-    }
-
-    setsize(self, min_s, max_s);
-    if (!nodrop)
-    {
-        setorigin(self, self.origin);
-        tracebox(self.origin + '0 0 100', min_s, max_s, self.origin - '0 0 10000', MOVE_WORLDONLY, self);
-        setorigin(self, trace_endpos);
-    }
-
-    self.pos1 = self.origin;
-    self.pos2 = self.angles;
-    self.tur_head.team = self.team;
-
-       if(MUTATOR_CALLHOOK(VehicleSpawn))
-               return false;
-
-    return true;
-}
-
-vector vehicle_aimturret(entity _vehic, vector _target, entity _turrret, string _tagname,
-                         float _pichlimit_min, float _pichlimit_max,
-                         float _rotlimit_min, float _rotlimit_max, float _aimspeed)
-{
-    vector vtmp, vtag;
-    float ftmp;
-    vtag = gettaginfo(_turrret, gettagindex(_turrret, _tagname));
-    vtmp = vectoangles(normalize(_target - vtag));
-    vtmp = AnglesTransform_ToAngles(AnglesTransform_LeftDivide(AnglesTransform_FromAngles(_vehic.angles), AnglesTransform_FromAngles(vtmp))) - _turrret.angles;
-    vtmp = AnglesTransform_Normalize(vtmp, true);
-    ftmp = _aimspeed * frametime;
-    vtmp.y = bound(-ftmp, vtmp.y, ftmp);
-    vtmp.x = bound(-ftmp, vtmp.x, ftmp);
-    _turrret.angles_y = bound(_rotlimit_min, _turrret.angles.y + vtmp.y, _rotlimit_max);
-    _turrret.angles_x = bound(_pichlimit_min, _turrret.angles.x + vtmp.x, _pichlimit_max);
-    return vtag;
-}
-
-void vehicles_gib_explode()
-{
-       sound (self, CH_SHOTS, "weapons/rocket_impact.wav", VOL_BASE, ATTEN_NORM);
-       pointparticles(particleeffectnum("explosion_small"), randomvec() * 80 + (self.origin + '0 0 100'), '0 0 0', 1);
-       remove(self);
-}
-
-void vehicles_gib_think()
-{
-       self.alpha -= 0.1;
-       if(self.cnt >= time)
-               remove(self);
-       else
-               self.nextthink = time + 0.1;
-}
-
-entity vehicle_tossgib(entity _template, vector _vel, string _tag, float _burn, float _explode, float _maxtime, vector _rot)
-{
-       entity _gib = spawn();
-       setmodel(_gib, _template.model);
-       setorigin(_gib, gettaginfo(self, gettagindex(self, _tag)));
-       _gib.velocity = _vel;
-       _gib.movetype = MOVETYPE_TOSS;
-       _gib.solid = SOLID_CORPSE;
-       _gib.colormod = '-0.5 -0.5 -0.5';
-       _gib.effects = EF_LOWPRECISION;
-       _gib.avelocity = _rot;
-
-       if(_burn)
-               _gib.effects |= EF_FLAME;
-
-       if(_explode)
-       {
-               _gib.think = vehicles_gib_explode;
-               _gib.nextthink = time + random() * _explode;
-               _gib.touch = vehicles_gib_explode;
-       }
-       else
-       {
-               _gib.cnt = time + _maxtime;
-               _gib.think = vehicles_gib_think;
-               _gib.nextthink = time + _maxtime - 1;
-               _gib.alpha = 1;
-       }
-       return _gib;
-}
-
-/*
-vector predict_target(entity _targ, vector _from, float _shot_speed)
-{
-    float i;                // loop
-    float _distance;        // How far to target
-    float _impact_time;     // How long untill projectile impacts
-    vector _predict_pos;    // Predicted enemy location
-    vector _original_origin;// Where target is before predicted
-
-     _original_origin = real_origin(_targ); // Typicaly center of target BBOX
-
-    _predict_pos = _original_origin;
-    for(i = 0; i < 4; ++i)  // Loop a few times to increase prediction accuracy (increase loop count if accuracy is to low)
-    {
-        _distance = vlen(_predict_pos - _from); // Get distance to previos predicted location
-        _impact_time = _distance / _shot_speed; // Calculate impact time
-        _predict_pos = _original_origin + _targ.velocity * _impact_time; // Calculate new predicted location
-    }
-
-    return _predict_pos;
-}
-*/
diff --git a/qcsrc/server/vehicles/vehicles.qh b/qcsrc/server/vehicles/vehicles.qh
deleted file mode 100644 (file)
index ec152d7..0000000
+++ /dev/null
@@ -1,16 +0,0 @@
-#ifndef VEHICLES_H
-#define VEHICLES_H
-
-#ifdef VEHICLES_ENABLED
-#   include "vehicles.qc"
-
-#   include "racer.qc"
-#   include "raptor.qc"
-#   include "spiderbot.qc"
-
-#   ifndef VEHICLES_NO_UNSTABLE
-#       include "bumblebee.qc"
-#   endif
-#endif
-
-#endif
diff --git a/qcsrc/server/vehicles/vehicles_def.qh b/qcsrc/server/vehicles/vehicles_def.qh
deleted file mode 100644 (file)
index 20f7ade..0000000
+++ /dev/null
@@ -1,79 +0,0 @@
-#ifndef VEHICLES_DEF_H
-#define VEHICLES_DEF_H
-
-#include "../tturrets/include/turrets_early.qh"
-
-// #define VEHICLES_USE_ODE
-#define VEHICLES_ENABLED
-#ifdef VEHICLES_ENABLED
-
-.int vehicle_flags;
-const int VHF_ISVEHICLE     = 2;    /// Indicates vehicle
-const int VHF_HASSHIELD     = 4;    /// Vehicle has shileding
-const int VHF_SHIELDREGEN   = 8;    /// Vehicles shield regenerates
-const int VHF_HEALTHREGEN   = 16;   /// Vehicles health regenerates
-const int VHF_ENERGYREGEN   = 32;   /// Vehicles energy regenerates
-const int VHF_DEATHEJECT    = 64;   /// Vehicle ejects pilot upon fatal damage
-const int VHF_MOVE_GROUND   = 128;  /// Vehicle moves on gound
-const int VHF_MOVE_HOVER    = 256;  /// Vehicle hover close to gound
-const int VHF_MOVE_FLY      = 512;  /// Vehicle is airborn
-const int VHF_DMGSHAKE      = 1024; /// Add random velocity each frame if health < 50%
-const int VHF_DMGROLL       = 2048; /// Add random angles each frame if health < 50%
-const int VHF_DMGHEADROLL   = 4096; /// Add random head angles each frame if health < 50%
-const int VHF_MULTISLOT     = 8192; /// Vehicle has multiple player slots
-const int VHF_PLAYERSLOT    = 16384;    /// This ent is a player slot on a multi-person vehicle
-
-.entity gun1;
-.entity gun2;
-.entity gun3;
-.entity vehicle_shieldent;  /// Entity to disply the shild effect on damage
-.entity vehicle;
-.entity vehicle_viewport;
-.entity vehicle_hudmodel;
-.entity vehicle_controller;
-
-.entity gunner1;
-.entity gunner2;
-
-.float vehicle_health;      /// If self is player this is 0..100 indicating precentage of health left on vehicle. If self is vehile, this is the real health value.
-.float vehicle_energy;      /// If self is player this is 0..100 indicating precentage of energy left on vehicle. If self is vehile, this is the real energy value.
-.float vehicle_shield;      /// If self is player this is 0..100 indicating precentage of shield left on vehicle. If self is vehile, this is the real shield value.
-
-.float vehicle_ammo1;   /// If self is player this field's use depends on the individual vehile. If self is vehile, this is the real ammo1 value.
-.float vehicle_reload1; /// If self is player this field's use depends on the individual vehile. If self is vehile, this is the real reload1 value.
-.float vehicle_ammo2;   /// If self is player this field's use depends on the individual vehile. If self is vehile, this is the real ammo2 value.
-.float vehicle_reload2; /// If self is player this field's use depends on the individual vehile. If self is vehile, this is the real reload2 value.
-
-.float sound_nexttime;
-const float VOL_VEHICLEENGINE = 1;
-
-.float hud;
-.float dmg_time;
-.float  vehicle_respawntime;
-//.void() vehicle_spawn;
-
-void vehicles_exit(float eject);
-.void(float exit_flags) vehicle_exit;
-const float VHEF_NORMAL = 0;  /// User pressed exit key
-const float VHEF_EJECT  = 1;  /// User pressed exit key 3 times fast (not implemented) or vehile is dying
-const float VHEF_RELESE = 2;  /// Release ownership, client possibly allready dissconnected / went spec / changed team / used "kill" (not implemented)
-
-const float SVC_SETVIEWPORT   = 5;   // Net.Protocol 0x05
-const float SVC_SETVIEWANGLES = 10;  // Net.Protocol 0x0A
-const float SVC_UPDATEENTITY  = 128; // Net.Protocol 0x80
-
-.void() vehicle_enter;  /// Vehicles custom funciton to be executed when owner exit it
-.void() vehicle_die;    /// Vehicles custom function to be executed when vehile die
-const float VHSF_NORMAL = 0;
-const float VHSF_FACTORY = 2;
-.void(float _spawnflag) vehicle_spawn;  /// Vehicles custom fucntion to be efecuted when vehicle (re)spawns
-.float(float _imp) vehicles_impulse;
-.float vehicle_weapon2mode;
-
-#ifdef VEHICLES_USE_ODE
-void(entity e, float physics_enabled) physics_enable = #540; // enable or disable physics on object
-void(entity e, vector force, vector force_pos) physics_addforce = #541; // apply a force from certain origin, length of force vector is power of force
-void(entity e, vector torque) physics_addtorque = #542; // add relative torque
-#endif  // VEHICLES_USE_ODE
-#endif  // VEHICLES_ENABLED
-#endif
index 09539c6..784784f 100755 (executable)
@@ -8,6 +8,10 @@ declare -a NOWARN=(
   '-Wno-unused-variable'
   '-Wno-implicit-function-pointer'
 )
+declare -a FEATURES=(
+  '-DVEHICLES_ENABLED=1'
+  '-DVEHICLES_USE_ODE=0'
+)
 declare QCC=../../../gmqcc/gmqcc
 
 function check() {
@@ -15,7 +19,7 @@ function check() {
   declare -la predefs=("${!2}")
   find "$base" -type f -name '*.qc' -print0 | sort -z | while IFS= read -r -d '' file; do
     echo "$file"
-    ${QCC} -std=gmqcc -fftepp -fftepp-predefs -Werror -Wall "${NOWARN[@]}" -futf8 -O3 "${predefs[@]}" "$file" >/dev/null
+    ${QCC} -std=gmqcc -fftepp -fftepp-predefs -Werror -Wall "${NOWARN[@]}" "${FEATURES[@]}" -futf8 -O3 "${predefs[@]}" "$file" >/dev/null
   done
 }