Move weapons into a folder like items, monsters, turrets, and vehicles
authorTimePath <andrew.hardaker1995@gmail.com>
Sun, 30 Aug 2015 05:55:52 +0000 (15:55 +1000)
committerTimePath <andrew.hardaker1995@gmail.com>
Sun, 30 Aug 2015 05:56:46 +0000 (15:56 +1000)
45 files changed:
qcsrc/common/weapons/all.inc
qcsrc/common/weapons/w_arc.qc [deleted file]
qcsrc/common/weapons/w_blaster.qc [deleted file]
qcsrc/common/weapons/w_crylink.qc [deleted file]
qcsrc/common/weapons/w_devastator.qc [deleted file]
qcsrc/common/weapons/w_electro.qc [deleted file]
qcsrc/common/weapons/w_fireball.qc [deleted file]
qcsrc/common/weapons/w_hagar.qc [deleted file]
qcsrc/common/weapons/w_hlac.qc [deleted file]
qcsrc/common/weapons/w_hmg.qc [deleted file]
qcsrc/common/weapons/w_hook.qc [deleted file]
qcsrc/common/weapons/w_machinegun.qc [deleted file]
qcsrc/common/weapons/w_minelayer.qc [deleted file]
qcsrc/common/weapons/w_mortar.qc [deleted file]
qcsrc/common/weapons/w_porto.qc [deleted file]
qcsrc/common/weapons/w_rifle.qc [deleted file]
qcsrc/common/weapons/w_rpc.qc [deleted file]
qcsrc/common/weapons/w_seeker.qc [deleted file]
qcsrc/common/weapons/w_shockwave.qc [deleted file]
qcsrc/common/weapons/w_shotgun.qc [deleted file]
qcsrc/common/weapons/w_tuba.qc [deleted file]
qcsrc/common/weapons/w_vaporizer.qc [deleted file]
qcsrc/common/weapons/w_vortex.qc [deleted file]
qcsrc/common/weapons/weapon/arc.qc [new file with mode: 0644]
qcsrc/common/weapons/weapon/blaster.qc [new file with mode: 0644]
qcsrc/common/weapons/weapon/crylink.qc [new file with mode: 0644]
qcsrc/common/weapons/weapon/devastator.qc [new file with mode: 0644]
qcsrc/common/weapons/weapon/electro.qc [new file with mode: 0644]
qcsrc/common/weapons/weapon/fireball.qc [new file with mode: 0644]
qcsrc/common/weapons/weapon/hagar.qc [new file with mode: 0644]
qcsrc/common/weapons/weapon/hlac.qc [new file with mode: 0644]
qcsrc/common/weapons/weapon/hmg.qc [new file with mode: 0644]
qcsrc/common/weapons/weapon/hook.qc [new file with mode: 0644]
qcsrc/common/weapons/weapon/machinegun.qc [new file with mode: 0644]
qcsrc/common/weapons/weapon/minelayer.qc [new file with mode: 0644]
qcsrc/common/weapons/weapon/mortar.qc [new file with mode: 0644]
qcsrc/common/weapons/weapon/porto.qc [new file with mode: 0644]
qcsrc/common/weapons/weapon/rifle.qc [new file with mode: 0644]
qcsrc/common/weapons/weapon/rpc.qc [new file with mode: 0644]
qcsrc/common/weapons/weapon/seeker.qc [new file with mode: 0644]
qcsrc/common/weapons/weapon/shockwave.qc [new file with mode: 0644]
qcsrc/common/weapons/weapon/shotgun.qc [new file with mode: 0644]
qcsrc/common/weapons/weapon/tuba.qc [new file with mode: 0644]
qcsrc/common/weapons/weapon/vaporizer.qc [new file with mode: 0644]
qcsrc/common/weapons/weapon/vortex.qc [new file with mode: 0644]

index 4f4cd2b..fc89a0c 100644 (file)
@@ -3,27 +3,27 @@
 // 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"
+#include "weapon/blaster.qc"
+#include "weapon/shotgun.qc"
+#include "weapon/machinegun.qc"
+#include "weapon/mortar.qc"
+#include "weapon/minelayer.qc"
+#include "weapon/electro.qc"
+#include "weapon/crylink.qc"
+#include "weapon/vortex.qc"
+#include "weapon/hagar.qc"
+#include "weapon/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"
+#include "weapon/porto.qc"
+#include "weapon/vaporizer.qc"
+#include "weapon/hook.qc"
+#include "weapon/hlac.qc"
+#include "weapon/tuba.qc"
+#include "weapon/rifle.qc"
+#include "weapon/fireball.qc"
+#include "weapon/seeker.qc"
+#include "weapon/shockwave.qc"
+#include "weapon/arc.qc"
+#include "weapon/hmg.qc"
+#include "weapon/rpc.qc"
diff --git a/qcsrc/common/weapons/w_arc.qc b/qcsrc/common/weapons/w_arc.qc
deleted file mode 100644 (file)
index c101a8c..0000000
+++ /dev/null
@@ -1,1546 +0,0 @@
-#ifndef IMPLEMENTATION
-REGISTER_WEAPON(
-/* WEP_##id  */ ARC,
-/* function  */ W_Arc,
-/* ammotype  */ ammo_cells,
-/* impulse   */ 3,
-/* flags     */ WEP_FLAG_NORMAL,
-/* rating    */ BOT_PICKUP_RATING_HIGH,
-/* color     */ '1 1 1',
-/* modelname */ "arc",
-/* simplemdl */ "foobar",
-/* crosshair */ "gfx/crosshairhlac 0.7",
-/* wepimg    */ "weaponarc",
-/* refname   */ "arc",
-/* wepname   */ _("Arc")
-);
-
-#define ARC_SETTINGS(w_cvar,w_prop) ARC_SETTINGS_LIST(w_cvar, w_prop, ARC, arc)
-#define ARC_SETTINGS_LIST(w_cvar,w_prop,id,sn) \
-       w_cvar(id, sn, NONE, beam_ammo) \
-       w_cvar(id, sn, NONE, beam_animtime) \
-       w_cvar(id, sn, NONE, beam_botaimspeed) \
-       w_cvar(id, sn, NONE, beam_botaimlifetime) \
-       w_cvar(id, sn, NONE, beam_damage) \
-       w_cvar(id, sn, NONE, beam_degreespersegment) \
-       w_cvar(id, sn, NONE, beam_distancepersegment) \
-       w_cvar(id, sn, NONE, beam_falloff_halflifedist) \
-       w_cvar(id, sn, NONE, beam_falloff_maxdist) \
-       w_cvar(id, sn, NONE, beam_falloff_mindist) \
-       w_cvar(id, sn, NONE, beam_force) \
-       w_cvar(id, sn, NONE, beam_healing_amax) \
-       w_cvar(id, sn, NONE, beam_healing_aps) \
-       w_cvar(id, sn, NONE, beam_healing_hmax) \
-       w_cvar(id, sn, NONE, beam_healing_hps) \
-       w_cvar(id, sn, NONE, beam_maxangle) \
-       w_cvar(id, sn, NONE, beam_nonplayerdamage) \
-       w_cvar(id, sn, NONE, beam_range) \
-       w_cvar(id, sn, NONE, beam_refire) \
-       w_cvar(id, sn, NONE, beam_returnspeed) \
-       w_cvar(id, sn, NONE, beam_tightness) \
-       w_cvar(id, sn, NONE, burst_ammo) \
-       w_cvar(id, sn, NONE, burst_damage) \
-       w_cvar(id, sn, NONE, burst_healing_aps) \
-       w_cvar(id, sn, NONE, burst_healing_hps) \
-       w_cvar(id, sn, NONE, overheat_max)/* maximum heat before jamming */ \
-       w_cvar(id, sn, NONE, overheat_min)/* minimum heat to wait for cooldown */ \
-       w_cvar(id, sn, NONE, beam_heat)   /* heat increase per second (primary) */ \
-       w_cvar(id, sn, NONE, burst_heat)  /* heat increase per second (secondary) */ \
-       w_cvar(id, sn, NONE, cooldown)    /* heat decrease per second when resting */ \
-       w_prop(id, sn, float,  switchdelay_raise, switchdelay_raise) \
-       w_prop(id, sn, float,  switchdelay_drop, switchdelay_drop) \
-       w_prop(id, sn, string, weaponreplace, weaponreplace) \
-       w_prop(id, sn, float,  weaponstart, weaponstart) \
-       w_prop(id, sn, float,  weaponstartoverride, weaponstartoverride) \
-       w_prop(id, sn, float,  weaponthrowable, weaponthrowable)
-
-#ifndef MENUQC
-const float ARC_MAX_SEGMENTS = 20;
-vector arc_shotorigin[4];
-.vector beam_start;
-.vector beam_dir;
-.vector beam_wantdir;
-.int beam_type;
-
-const int ARC_BT_MISS =        0x00;
-const int ARC_BT_WALL =        0x01;
-const int ARC_BT_HEAL =        0x02;
-const int ARC_BT_HIT =         0x03;
-const int ARC_BT_BURST_MISS =  0x10;
-const int ARC_BT_BURST_WALL =  0x11;
-const int ARC_BT_BURST_HEAL =  0x12;
-const int ARC_BT_BURST_HIT =   0x13;
-const int ARC_BT_BURSTMASK =   0x10;
-
-const int ARC_SF_SETTINGS =    1;
-const int ARC_SF_START =       2;
-const int ARC_SF_WANTDIR =     4;
-const int ARC_SF_BEAMDIR =     8;
-const int ARC_SF_BEAMTYPE =    16;
-const int ARC_SF_LOCALMASK =   14;
-#endif
-#ifdef SVQC
-ARC_SETTINGS(WEP_ADD_CVAR, WEP_ADD_PROP)
-.entity arc_beam;
-.float arc_BUTTON_ATCK_prev; // for better animation control
-.float beam_prev;
-.float beam_initialized;
-.float beam_bursting;
-.float beam_teleporttime;
-.float beam_heat; // (beam) amount of heat produced
-.float arc_overheat; // (dropped arc/player) time during which it's too hot
-.float arc_cooldown; // (dropped arc/player) cooling speed
-.float arc_heat_percent; // (player) arc heat in [0,1] (stat)
-.float arc_smoke_sound;
-#endif
-#ifdef CSQC
-void Ent_ReadArcBeam(float isnew);
-
-.vector beam_color;
-.float beam_alpha;
-.float beam_thickness;
-.float beam_traileffect;
-.float beam_hiteffect;
-.float beam_hitlight[4]; // 0: radius, 123: rgb
-.float beam_muzzleeffect;
-.float beam_muzzlelight[4]; // 0: radius, 123: rgb
-.string beam_image;
-
-.entity beam_muzzleentity;
-
-.float beam_degreespersegment;
-.float beam_distancepersegment;
-.float beam_usevieworigin;
-.float beam_initialized;
-.float beam_maxangle;
-.float beam_range;
-.float beam_returnspeed;
-.float beam_tightness;
-.vector beam_shotorigin;
-
-entity Draw_ArcBeam_callback_entity;
-float Draw_ArcBeam_callback_last_thickness;
-vector Draw_ArcBeam_callback_last_top; // NOTE: in same coordinate system as player.
-vector Draw_ArcBeam_callback_last_bottom; // NOTE: in same coordinate system as player.
-#endif
-#endif
-#ifdef IMPLEMENTATION
-#ifdef SVQC
-void spawnfunc_weapon_arc(void) { weapon_defaultspawnfunc(WEP_ARC.m_id); }
-
-float W_Arc_Beam_Send(entity to, int sf)
-{
-       WriteByte(MSG_ENTITY, ENT_CLIENT_ARC_BEAM);
-
-       // Truncate information when this beam is displayed to the owner client
-       // - The owner client has no use for beam start position or directions,
-       //    it always figures this information out for itself with csqc code.
-       // - Spectating the owner also truncates this information.
-       float drawlocal = ((to == self.owner) || ((to.enemy == self.owner) && IS_SPEC(to)));
-       if(drawlocal) { sf &= ~ARC_SF_LOCALMASK; }
-
-       WriteByte(MSG_ENTITY, sf);
-
-       if(sf & ARC_SF_SETTINGS) // settings information
-       {
-               WriteShort(MSG_ENTITY, WEP_CVAR(arc, beam_degreespersegment));
-               WriteShort(MSG_ENTITY, WEP_CVAR(arc, beam_distancepersegment));
-               WriteShort(MSG_ENTITY, WEP_CVAR(arc, beam_maxangle));
-               WriteCoord(MSG_ENTITY, WEP_CVAR(arc, beam_range));
-               WriteShort(MSG_ENTITY, WEP_CVAR(arc, beam_returnspeed));
-               WriteByte(MSG_ENTITY, WEP_CVAR(arc, beam_tightness) * 10);
-
-               WriteByte(MSG_ENTITY, drawlocal);
-       }
-       if(sf & ARC_SF_START) // starting location
-       {
-               WriteCoord(MSG_ENTITY, self.beam_start.x);
-               WriteCoord(MSG_ENTITY, self.beam_start.y);
-               WriteCoord(MSG_ENTITY, self.beam_start.z);
-       }
-       if(sf & ARC_SF_WANTDIR) // want/aim direction
-       {
-               WriteCoord(MSG_ENTITY, self.beam_wantdir.x);
-               WriteCoord(MSG_ENTITY, self.beam_wantdir.y);
-               WriteCoord(MSG_ENTITY, self.beam_wantdir.z);
-       }
-       if(sf & ARC_SF_BEAMDIR) // beam direction
-       {
-               WriteCoord(MSG_ENTITY, self.beam_dir.x);
-               WriteCoord(MSG_ENTITY, self.beam_dir.y);
-               WriteCoord(MSG_ENTITY, self.beam_dir.z);
-       }
-       if(sf & ARC_SF_BEAMTYPE) // beam type
-       {
-               WriteByte(MSG_ENTITY, self.beam_type);
-       }
-
-       return true;
-}
-
-void Reset_ArcBeam(entity player, vector forward)
-{
-       if (!player.arc_beam) {
-               return;
-       }
-       player.arc_beam.beam_dir = forward;
-       player.arc_beam.beam_teleporttime = time;
-}
-
-float Arc_GetHeat_Percent(entity player)
-{
-       if ( WEP_CVAR(arc, overheat_max) <= 0 ||  WEP_CVAR(arc, overheat_max) <= 0 )
-       {
-               player.arc_overheat = 0;
-               return 0;
-       }
-
-       if ( player.arc_beam )
-               return player.arc_beam.beam_heat/WEP_CVAR(arc, overheat_max);
-
-       if ( player.arc_overheat > time )
-       {
-               return (player.arc_overheat-time) / WEP_CVAR(arc, overheat_max)
-                       * player.arc_cooldown;
-       }
-
-       return 0;
-}
-void Arc_Player_SetHeat(entity player)
-{
-       player.arc_heat_percent = Arc_GetHeat_Percent(player);
-       //dprint("Heat: ",ftos(player.arc_heat_percent*100),"%\n");
-}
-
-void W_Arc_Beam_Think(void)
-{
-       if(self != self.owner.arc_beam)
-       {
-               remove(self);
-               return;
-       }
-
-
-       float burst = 0;
-       if( self.owner.BUTTON_ATCK2 || self.beam_bursting)
-       {
-               if(!self.beam_bursting)
-                       self.beam_bursting = true;
-               burst = ARC_BT_BURSTMASK;
-       }
-
-       if(
-               !IS_PLAYER(self.owner)
-               ||
-               (self.owner.WEP_AMMO(ARC) <= 0 && !(self.owner.items & IT_UNLIMITED_WEAPON_AMMO))
-               ||
-               self.owner.deadflag != DEAD_NO
-               ||
-               (!self.owner.BUTTON_ATCK && !burst )
-               ||
-               self.owner.frozen
-               ||
-               self.owner.vehicle
-               ||
-               (WEP_CVAR(arc, overheat_max) > 0 && self.beam_heat >= WEP_CVAR(arc, overheat_max))
-       )
-       {
-               if ( WEP_CVAR(arc, cooldown) > 0 )
-               {
-                       float cooldown_speed = 0;
-                       if ( self.beam_heat > WEP_CVAR(arc, overheat_min) && WEP_CVAR(arc, cooldown) > 0 )
-                       {
-                               cooldown_speed = WEP_CVAR(arc, cooldown);
-                       }
-                       else if ( !burst )
-                       {
-                               cooldown_speed = self.beam_heat / WEP_CVAR(arc, beam_refire);
-                       }
-
-                       if ( cooldown_speed )
-                       {
-                               self.owner.arc_overheat = time + self.beam_heat / cooldown_speed;
-                               self.owner.arc_cooldown = cooldown_speed;
-                       }
-
-                       if ( WEP_CVAR(arc, overheat_max) > 0 && self.beam_heat >= WEP_CVAR(arc, overheat_max) )
-                       {
-                               Send_Effect_("arc_overheat",
-                                       self.beam_start, self.beam_wantdir, 1 );
-                               sound(self, CH_WEAPON_A, W_Sound("arc_stop"), VOL_BASE, ATTN_NORM);
-                       }
-               }
-
-               if(self == self.owner.arc_beam) { self.owner.arc_beam = world; }
-               entity oldself = self;
-               self = self.owner;
-               if(!WEP_ACTION(WEP_ARC.m_id, WR_CHECKAMMO1) && !WEP_ACTION(WEP_ARC.m_id, WR_CHECKAMMO2))
-               if(!(self.items & IT_UNLIMITED_WEAPON_AMMO))
-               {
-                       // note: this doesn't force the switch
-                       W_SwitchToOtherWeapon(self);
-               }
-               self = oldself;
-               remove(self);
-               return;
-       }
-
-       // decrease ammo
-       float coefficient = frametime;
-       if(!(self.owner.items & IT_UNLIMITED_WEAPON_AMMO))
-       {
-               float rootammo;
-               if(burst)
-                       { rootammo = WEP_CVAR(arc, burst_ammo); }
-               else
-                       { rootammo = WEP_CVAR(arc, beam_ammo); }
-
-               if(rootammo)
-               {
-                       coefficient = min(coefficient, self.owner.WEP_AMMO(ARC) / rootammo);
-                       self.owner.WEP_AMMO(ARC) = max(0, self.owner.WEP_AMMO(ARC) - (rootammo * frametime));
-               }
-       }
-       float heat_speed = burst ? WEP_CVAR(arc, burst_heat) : WEP_CVAR(arc, beam_heat);
-       self.beam_heat = min( WEP_CVAR(arc, overheat_max), self.beam_heat + heat_speed*frametime );
-
-       makevectors(self.owner.v_angle);
-
-       W_SetupShot_Range(
-               self.owner,
-               true,
-               0,
-               "",
-               0,
-               WEP_CVAR(arc, beam_damage) * coefficient,
-               WEP_CVAR(arc, beam_range)
-       );
-
-       // After teleport, "lock" the beam until the teleport is confirmed.
-       if (time < self.beam_teleporttime + ANTILAG_LATENCY(self.owner)) {
-               w_shotdir = self.beam_dir;
-       }
-
-       // network information: shot origin and want/aim direction
-       if(self.beam_start != w_shotorg)
-       {
-               self.SendFlags |= ARC_SF_START;
-               self.beam_start = w_shotorg;
-       }
-       if(self.beam_wantdir != w_shotdir)
-       {
-               self.SendFlags |= ARC_SF_WANTDIR;
-               self.beam_wantdir = w_shotdir;
-       }
-
-       if(!self.beam_initialized)
-       {
-               self.beam_dir = w_shotdir;
-               self.beam_initialized = true;
-       }
-
-       // WEAPONTODO: Detect player velocity so that the beam curves when moving too
-       // idea: blend together self.beam_dir with the inverted direction the player is moving in
-       // might have to make some special accomodation so that it only uses view_right and view_up
-
-       // note that if we do this, it'll always be corrected to a maximum angle by beam_maxangle handling
-
-       float segments;
-       if(self.beam_dir != w_shotdir)
-       {
-               // calculate how much we're going to move the end of the beam to the want position
-               // WEAPONTODO (server and client):
-               // blendfactor never actually becomes 0 in this situation, which is a problem
-               // regarding precision... this means that self.beam_dir and w_shotdir approach
-               // eachother, however they never actually become the same value with this method.
-               // Perhaps we should do some form of rounding/snapping?
-               float angle = vlen(w_shotdir - self.beam_dir) * RAD2DEG;
-               if(angle && (angle > WEP_CVAR(arc, beam_maxangle)))
-               {
-                       // if the angle is greater than maxangle, force the blendfactor to make this the maximum factor
-                       float blendfactor = bound(
-                               0,
-                               (1 - (WEP_CVAR(arc, beam_returnspeed) * frametime)),
-                               min(WEP_CVAR(arc, beam_maxangle) / angle, 1)
-                       );
-                       self.beam_dir = normalize((w_shotdir * (1 - blendfactor)) + (self.beam_dir * blendfactor));
-               }
-               else
-               {
-                       // the radius is not too far yet, no worries :D
-                       float blendfactor = bound(
-                               0,
-                               (1 - (WEP_CVAR(arc, beam_returnspeed) * frametime)),
-                               1
-                       );
-                       self.beam_dir = normalize((w_shotdir * (1 - blendfactor)) + (self.beam_dir * blendfactor));
-               }
-
-               // network information: beam direction
-               self.SendFlags |= ARC_SF_BEAMDIR;
-
-               // calculate how many segments are needed
-               float max_allowed_segments;
-
-               if(WEP_CVAR(arc, beam_distancepersegment))
-               {
-                       max_allowed_segments = min(
-                               ARC_MAX_SEGMENTS,
-                               1 + (vlen(w_shotdir / WEP_CVAR(arc, beam_distancepersegment)))
-                       );
-               }
-               else { max_allowed_segments = ARC_MAX_SEGMENTS; }
-
-               if(WEP_CVAR(arc, beam_degreespersegment))
-               {
-                       segments = bound(
-                               1,
-                               (
-                                       min(
-                                               angle,
-                                               WEP_CVAR(arc, beam_maxangle)
-                                       )
-                                       /
-                                       WEP_CVAR(arc, beam_degreespersegment)
-                               ),
-                               max_allowed_segments
-                       );
-               }
-               else { segments = 1; }
-       }
-       else { segments = 1; }
-
-       vector beam_endpos = (w_shotorg + (self.beam_dir * WEP_CVAR(arc, beam_range)));
-       vector beam_controlpoint = w_shotorg + w_shotdir * (WEP_CVAR(arc, beam_range) * (1 - WEP_CVAR(arc, beam_tightness)));
-
-       float i;
-       float new_beam_type = 0;
-       vector last_origin = w_shotorg;
-       for(i = 1; i <= segments; ++i)
-       {
-               // WEAPONTODO (client):
-               // In order to do nice fading and pointing on the starting segment, we must always
-               // have that drawn as a separate triangle... However, that is difficult to do when
-               // keeping in mind the above problems and also optimizing the amount of segments
-               // drawn on screen at any given time. (Automatic beam quality scaling, essentially)
-
-               vector new_origin = bezier_quadratic_getpoint(
-                       w_shotorg,
-                       beam_controlpoint,
-                       beam_endpos,
-                       i / segments);
-               vector new_dir = normalize(new_origin - last_origin);
-
-               WarpZone_traceline_antilag(
-                       self.owner,
-                       last_origin,
-                       new_origin,
-                       MOVE_NORMAL,
-                       self.owner,
-                       ANTILAG_LATENCY(self.owner)
-               );
-
-               // Do all the transforms for warpzones right now, as we already
-               // "are" in the post-trace system (if we hit a player, that's
-               // always BEHIND the last passed wz).
-               last_origin = trace_endpos;
-               w_shotorg = WarpZone_TransformOrigin(WarpZone_trace_transform, w_shotorg);
-               beam_controlpoint = WarpZone_TransformOrigin(WarpZone_trace_transform, beam_controlpoint);
-               beam_endpos = WarpZone_TransformOrigin(WarpZone_trace_transform, beam_endpos);
-               new_dir = WarpZone_TransformVelocity(WarpZone_trace_transform, new_dir);
-
-               float is_player = (
-                       IS_PLAYER(trace_ent)
-                       ||
-                       trace_ent.classname == "body"
-                       ||
-                       IS_MONSTER(trace_ent)
-               );
-
-               if(trace_ent && trace_ent.takedamage && (is_player || WEP_CVAR(arc, beam_nonplayerdamage)))
-               {
-                       // calculate our own hit origin as trace_endpos tends to jump around annoyingly (to player origin?)
-                       // NO. trace_endpos should be just fine. If not,
-                       // that's an engine bug that needs proper debugging.
-                       vector hitorigin = trace_endpos;
-
-                       float falloff = ExponentialFalloff(
-                               WEP_CVAR(arc, beam_falloff_mindist),
-                               WEP_CVAR(arc, beam_falloff_maxdist),
-                               WEP_CVAR(arc, beam_falloff_halflifedist),
-                               vlen(WarpZone_UnTransformOrigin(WarpZone_trace_transform, hitorigin) - w_shotorg)
-                       );
-
-                       if(is_player && SAME_TEAM(self.owner, trace_ent))
-                       {
-                               float roothealth, rootarmor;
-                               if(burst)
-                               {
-                                       roothealth = WEP_CVAR(arc, burst_healing_hps);
-                                       rootarmor = WEP_CVAR(arc, burst_healing_aps);
-                               }
-                               else
-                               {
-                                       roothealth = WEP_CVAR(arc, beam_healing_hps);
-                                       rootarmor = WEP_CVAR(arc, beam_healing_aps);
-                               }
-
-                               if(trace_ent.health <= WEP_CVAR(arc, beam_healing_hmax) && roothealth)
-                               {
-                                       trace_ent.health = min(
-                                               trace_ent.health + (roothealth * coefficient),
-                                               WEP_CVAR(arc, beam_healing_hmax)
-                                       );
-                               }
-                               if(trace_ent.armorvalue <= WEP_CVAR(arc, beam_healing_amax) && rootarmor)
-                               {
-                                       trace_ent.armorvalue = min(
-                                               trace_ent.armorvalue + (rootarmor * coefficient),
-                                               WEP_CVAR(arc, beam_healing_amax)
-                                       );
-                               }
-
-                               // stop rot, set visual effect
-                               if(roothealth || rootarmor)
-                               {
-                                       trace_ent.pauserothealth_finished = max(
-                                               trace_ent.pauserothealth_finished,
-                                               time + autocvar_g_balance_pause_health_rot
-                                       );
-                                       trace_ent.pauserotarmor_finished = max(
-                                               trace_ent.pauserotarmor_finished,
-                                               time + autocvar_g_balance_pause_armor_rot
-                                       );
-                                       new_beam_type = ARC_BT_HEAL;
-                               }
-                       }
-                       else
-                       {
-                               float rootdamage;
-                               if(is_player)
-                               {
-                                       if(burst)
-                                               { rootdamage = WEP_CVAR(arc, burst_damage); }
-                                       else
-                                               { rootdamage = WEP_CVAR(arc, beam_damage); }
-                               }
-                               else
-                                       { rootdamage = WEP_CVAR(arc, beam_nonplayerdamage); }
-
-                               if(accuracy_isgooddamage(self.owner, trace_ent))
-                               {
-                                       accuracy_add(
-                                               self.owner,
-                                               WEP_ARC.m_id,
-                                               0,
-                                               rootdamage * coefficient * falloff
-                                       );
-                               }
-
-                               Damage(
-                                       trace_ent,
-                                       self.owner,
-                                       self.owner,
-                                       rootdamage * coefficient * falloff,
-                                       WEP_ARC.m_id,
-                                       hitorigin,
-                                       WEP_CVAR(arc, beam_force) * new_dir * coefficient * falloff
-                               );
-
-                               new_beam_type = ARC_BT_HIT;
-                       }
-                       break;
-               }
-               else if(trace_fraction != 1)
-               {
-                       // we collided with geometry
-                       new_beam_type = ARC_BT_WALL;
-                       break;
-               }
-       }
-
-       // te_explosion(trace_endpos);
-
-       // if we're bursting, use burst visual effects
-       new_beam_type |= burst;
-
-       // network information: beam type
-       if(new_beam_type != self.beam_type)
-       {
-               self.SendFlags |= ARC_SF_BEAMTYPE;
-               self.beam_type = new_beam_type;
-       }
-
-       self.owner.beam_prev = time;
-       self.nextthink = time;
-}
-
-void W_Arc_Beam(float burst)
-{
-
-       // only play fire sound if 1 sec has passed since player let go the fire button
-       if(time - self.beam_prev > 1)
-               sound(self, CH_WEAPON_A, W_Sound("arc_fire"), VOL_BASE, ATTN_NORM);
-
-       entity beam = self.arc_beam = spawn();
-       beam.classname = "W_Arc_Beam";
-       beam.solid = SOLID_NOT;
-       beam.think = W_Arc_Beam_Think;
-       beam.owner = self;
-       beam.movetype = MOVETYPE_NONE;
-       beam.bot_dodge = true;
-       beam.bot_dodgerating = WEP_CVAR(arc, beam_damage);
-       beam.beam_bursting = burst;
-       Net_LinkEntity(beam, false, 0, W_Arc_Beam_Send);
-
-       entity oldself = self;
-       self = beam;
-       self.think();
-       self = oldself;
-}
-
-void Arc_Smoke()
-{
-       makevectors(self.v_angle);
-       W_SetupShot_Range(self,true,0,"",0,0,0);
-
-       vector smoke_origin = w_shotorg + self.velocity*frametime;
-       if ( self.arc_overheat > time )
-       {
-               if ( random() < self.arc_heat_percent )
-                       Send_Effect_("arc_smoke", smoke_origin, '0 0 0', 1 );
-               if ( self.BUTTON_ATCK || self.BUTTON_ATCK2 )
-               {
-                       Send_Effect_("arc_overheat_fire", smoke_origin, w_shotdir, 1 );
-                       if ( !self.arc_smoke_sound )
-                       {
-                               self.arc_smoke_sound = 1;
-                               sound(self, CH_SHOTS_SINGLE, W_Sound("arc_loop_overheat"), VOL_BASE, ATTN_NORM);
-                       }
-               }
-       }
-       else if ( self.arc_beam && WEP_CVAR(arc, overheat_max) > 0 &&
-                       self.arc_beam.beam_heat > WEP_CVAR(arc, overheat_min) )
-       {
-               if ( random() < (self.arc_beam.beam_heat-WEP_CVAR(arc, overheat_min)) /
-                               ( WEP_CVAR(arc, overheat_max)-WEP_CVAR(arc, overheat_min) ) )
-                       Send_Effect_("arc_smoke", smoke_origin, '0 0 0', 1 );
-       }
-
-       if (  self.arc_smoke_sound && ( self.arc_overheat <= time ||
-               !( self.BUTTON_ATCK || self.BUTTON_ATCK2 ) ) || self.switchweapon != WEP_ARC.m_id )
-       {
-               self.arc_smoke_sound = 0;
-               sound(self, CH_SHOTS_SINGLE, "misc/null.wav", VOL_BASE, ATTEN_NORM);
-       }
-}
-
-bool W_Arc(int req)
-{
-       switch(req)
-       {
-               case WR_AIM:
-               {
-                       if(WEP_CVAR(arc, beam_botaimspeed))
-                       {
-                               self.BUTTON_ATCK = bot_aim(
-                                       WEP_CVAR(arc, beam_botaimspeed),
-                                       0,
-                                       WEP_CVAR(arc, beam_botaimlifetime),
-                                       false
-                               );
-                       }
-                       else
-                       {
-                               self.BUTTON_ATCK = bot_aim(
-                                       1000000,
-                                       0,
-                                       0.001,
-                                       false
-                               );
-                       }
-                       return true;
-               }
-               case WR_THINK:
-               {
-                       Arc_Player_SetHeat(self);
-                       Arc_Smoke();
-
-                       if ( self.arc_overheat <= time )
-                       if(self.BUTTON_ATCK || self.BUTTON_ATCK2 || self.arc_beam.beam_bursting )
-                       {
-
-                               if(self.arc_BUTTON_ATCK_prev)
-                               {
-                                       #if 0
-                                       if(self.animstate_startframe == self.anim_shoot.x && self.animstate_numframes == self.anim_shoot.y)
-                                               weapon_thinkf(WFRAME_DONTCHANGE, autocvar_g_balance_arc_primary_animtime, w_ready);
-                                       else
-                                       #endif
-                                               weapon_thinkf(WFRAME_FIRE1, WEP_CVAR(arc, beam_animtime), w_ready);
-                               }
-
-                               if((!self.arc_beam) || wasfreed(self.arc_beam))
-                               {
-                                       if(weapon_prepareattack(!!self.BUTTON_ATCK2, 0))
-                                       {
-                                               W_Arc_Beam(!!self.BUTTON_ATCK2);
-
-                                               if(!self.arc_BUTTON_ATCK_prev)
-                                               {
-                                                       weapon_thinkf(WFRAME_FIRE1, WEP_CVAR(arc, beam_animtime), w_ready);
-                                                       self.arc_BUTTON_ATCK_prev = 1;
-                                               }
-                                       }
-                               }
-
-                               return true;
-                       }
-
-                       if(self.arc_BUTTON_ATCK_prev != 0)
-                       {
-                               sound(self, CH_WEAPON_A, W_Sound("arc_stop"), VOL_BASE, ATTN_NORM);
-                               weapon_thinkf(WFRAME_FIRE1, WEP_CVAR(arc, beam_animtime), w_ready);
-                               ATTACK_FINISHED(self) = time + WEP_CVAR(arc, beam_refire) * W_WeaponRateFactor();
-                       }
-                       self.arc_BUTTON_ATCK_prev = 0;
-
-                       #if 0
-                       if(self.BUTTON_ATCK2)
-                       if(weapon_prepareattack(1, autocvar_g_balance_arc_secondary_refire))
-                       {
-                               W_Arc_Attack2();
-                               self.arc_count = autocvar_g_balance_arc_secondary_count;
-                               weapon_thinkf(WFRAME_FIRE2, autocvar_g_balance_arc_secondary_animtime, w_arc_checkattack);
-                               self.arc_secondarytime = time + autocvar_g_balance_arc_secondary_refire2 * W_WeaponRateFactor();
-                       }
-                       #endif
-
-                       return true;
-               }
-               case WR_INIT:
-               {
-                       precache_model(W_Model("g_arc.md3"));
-                       precache_model(W_Model("v_arc.md3"));
-                       precache_model(W_Model("h_arc.iqm"));
-                       precache_sound(W_Sound("arc_fire"));
-                       precache_sound(W_Sound("arc_loop"));
-                       precache_sound(W_Sound("arc_stop"));
-                       precache_sound(W_Sound("arc_loop_overheat"));
-                       if(!arc_shotorigin[0])
-                       {
-                               arc_shotorigin[0] = shotorg_adjust_values(CL_Weapon_GetShotOrg(WEP_ARC.m_id), false, false, 1);
-                               arc_shotorigin[1] = shotorg_adjust_values(CL_Weapon_GetShotOrg(WEP_ARC.m_id), false, false, 2);
-                               arc_shotorigin[2] = shotorg_adjust_values(CL_Weapon_GetShotOrg(WEP_ARC.m_id), false, false, 3);
-                               arc_shotorigin[3] = shotorg_adjust_values(CL_Weapon_GetShotOrg(WEP_ARC.m_id), false, false, 4);
-                       }
-                       ARC_SETTINGS(WEP_SKIP_CVAR, WEP_SET_PROP);
-                       return true;
-               }
-               case WR_CHECKAMMO1:
-               {
-                       return ((!WEP_CVAR(arc, beam_ammo)) || (self.WEP_AMMO(ARC) > 0));
-               }
-               case WR_CHECKAMMO2:
-               {
-                       return WEP_CVAR(arc, overheat_max) > 0 &&
-                               ((!WEP_CVAR(arc, burst_ammo)) || (self.WEP_AMMO(ARC) > 0));
-               }
-               case WR_CONFIG:
-               {
-                       ARC_SETTINGS(WEP_CONFIG_WRITE_CVARS, WEP_CONFIG_WRITE_PROPS);
-                       return true;
-               }
-               case WR_KILLMESSAGE:
-               {
-                       return WEAPON_ARC_MURDER;
-               }
-               case WR_DROP:
-               {
-                       weapon_dropevent_item.arc_overheat = self.arc_overheat;
-                       weapon_dropevent_item.arc_cooldown = self.arc_cooldown;
-                       self.arc_overheat = 0;
-                       self.arc_cooldown = 0;
-                       return true;
-               }
-               case WR_PICKUP:
-               {
-                       if ( !client_hasweapon(self, WEP_ARC.m_id, false, false) &&
-                               weapon_dropevent_item.arc_overheat > time )
-                       {
-                               self.arc_overheat = weapon_dropevent_item.arc_overheat;
-                               self.arc_cooldown = weapon_dropevent_item.arc_cooldown;
-                       }
-                       return true;
-               }
-       }
-       return false;
-}
-#endif
-#ifdef CSQC
-void Draw_ArcBeam_callback(vector start, vector hit, vector end)
-{
-       entity beam = Draw_ArcBeam_callback_entity;
-       vector transformed_view_org;
-       transformed_view_org = WarpZone_TransformOrigin(WarpZone_trace_transform, view_origin);
-
-       // Thickdir shall be perpendicular to the beam and to the view-to-beam direction (WEAPONTODO: WHY)
-       // WEAPONTODO: Wouldn't it be better to be perpendicular to the beam and to the view FORWARD direction?
-       vector thickdir = normalize(cross(normalize(start - hit), transformed_view_org - start));
-
-       vector hitorigin;
-
-       // draw segment
-       #if 0
-       if(trace_fraction != 1)
-       {
-               // calculate our own hit origin as trace_endpos tends to jump around annoyingly (to player origin?)
-               hitorigin = start + (Draw_ArcBeam_callback_new_dir * Draw_ArcBeam_callback_segmentdist * trace_fraction);
-               hitorigin = WarpZone_TransformOrigin(WarpZone_trace_transform, hitorigin);
-       }
-       else
-       {
-               hitorigin = hit;
-       }
-       #else
-       hitorigin = hit;
-       #endif
-
-       // decide upon thickness
-       float thickness = beam.beam_thickness;
-
-       // draw primary beam render
-       vector top    = hitorigin + (thickdir * thickness);
-       vector bottom = hitorigin - (thickdir * thickness);
-
-       vector last_top = WarpZone_TransformOrigin(WarpZone_trace_transform, Draw_ArcBeam_callback_last_top);
-       vector last_bottom = WarpZone_TransformOrigin(WarpZone_trace_transform, Draw_ArcBeam_callback_last_bottom);
-
-       R_BeginPolygon(beam.beam_image, DRAWFLAG_NORMAL); // DRAWFLAG_ADDITIVE
-       R_PolygonVertex(
-               top,
-               '0 0.5 0' + ('0 0.5 0' * (thickness / beam.beam_thickness)),
-               beam.beam_color,
-               beam.beam_alpha
-       );
-       R_PolygonVertex(
-               last_top,
-               '0 0.5 0' + ('0 0.5 0' * (Draw_ArcBeam_callback_last_thickness / beam.beam_thickness)),
-               beam.beam_color,
-               beam.beam_alpha
-       );
-       R_PolygonVertex(
-               last_bottom,
-               '0 0.5 0' * (1 - (Draw_ArcBeam_callback_last_thickness / beam.beam_thickness)),
-               beam.beam_color,
-               beam.beam_alpha
-       );
-       R_PolygonVertex(
-               bottom,
-               '0 0.5 0' * (1 - (thickness / beam.beam_thickness)),
-               beam.beam_color,
-               beam.beam_alpha
-       );
-       R_EndPolygon();
-
-       // draw trailing particles
-       // NOTES:
-       //  - Don't use spammy particle counts here, use a FEW small particles around the beam
-       //  - We're not using WarpZone_TrailParticles here because we will handle warpzones ourselves.
-       if(beam.beam_traileffect)
-       {
-               trailparticles(beam, beam.beam_traileffect, start, hitorigin);
-       }
-
-       // set up for the next
-       Draw_ArcBeam_callback_last_thickness = thickness;
-       Draw_ArcBeam_callback_last_top = WarpZone_UnTransformOrigin(WarpZone_trace_transform, top);
-       Draw_ArcBeam_callback_last_bottom = WarpZone_UnTransformOrigin(WarpZone_trace_transform, bottom);
-}
-
-void Reset_ArcBeam(void)
-{
-       entity e;
-       for (e = world; (e = findfloat(e, beam_usevieworigin, 1)); ) {
-               e.beam_initialized = false;
-       }
-       for (e = world; (e = findfloat(e, beam_usevieworigin, 2)); ) {
-               e.beam_initialized = false;
-       }
-}
-
-void Draw_ArcBeam(void)
-{
-       float dt = time - self.move_time;
-       self.move_time = time;
-       if(dt <= 0) { return; }
-
-       if(!self.beam_usevieworigin)
-       {
-               InterpolateOrigin_Do();
-       }
-
-       // origin = beam starting origin
-       // v_angle = wanted/aim direction
-       // angles = current direction of beam
-
-       vector start_pos;
-       vector wantdir; //= view_forward;
-       vector beamdir; //= self.beam_dir;
-
-       float segments;
-       if(self.beam_usevieworigin)
-       {
-               // WEAPONTODO:
-               // Currently we have to replicate nearly the same method of figuring
-               // out the shotdir that the server does... Ideally in the future we
-               // should be able to acquire this from a generalized function built
-               // into a weapon system for client code.
-
-               // find where we are aiming
-               makevectors(warpzone_save_view_angles);
-               vector forward = v_forward;
-               vector right = v_right;
-               vector up = v_up;
-
-               // decide upon start position
-               if(self.beam_usevieworigin == 2)
-                       { start_pos = warpzone_save_view_origin; }
-               else
-                       { start_pos = self.origin; }
-
-               // trace forward with an estimation
-               WarpZone_TraceLine(
-                       start_pos,
-                       start_pos + forward * self.beam_range,
-                       MOVE_NOMONSTERS,
-                       self
-               );
-
-               // untransform in case our trace went through a warpzone
-               vector end_pos = WarpZone_UnTransformOrigin(WarpZone_trace_transform, trace_endpos);
-
-               // un-adjust trueaim if shotend is too close
-               if(vlen(end_pos - start_pos) < g_trueaim_minrange)
-                       end_pos = start_pos + (forward * g_trueaim_minrange);
-
-               // move shot origin to the actual gun muzzle origin
-               vector origin_offset =
-                         right * -self.beam_shotorigin.y
-                       + up * self.beam_shotorigin.z;
-
-               start_pos = start_pos + origin_offset;
-
-               // Move it also forward, but only as far as possible without hitting anything. Don't poke into walls!
-               traceline(start_pos, start_pos + forward * self.beam_shotorigin.x, MOVE_NORMAL, self);
-               start_pos = trace_endpos;
-
-               // calculate the aim direction now
-               wantdir = normalize(end_pos - start_pos);
-
-               if(!self.beam_initialized)
-               {
-                       self.beam_dir = wantdir;
-                       self.beam_initialized = true;
-               }
-
-               if(self.beam_dir != wantdir)
-               {
-                       // calculate how much we're going to move the end of the beam to the want position
-                       // WEAPONTODO (server and client):
-                       // blendfactor never actually becomes 0 in this situation, which is a problem
-                       // regarding precision... this means that self.beam_dir and w_shotdir approach
-                       // eachother, however they never actually become the same value with this method.
-                       // Perhaps we should do some form of rounding/snapping?
-                       float angle = vlen(wantdir - self.beam_dir) * RAD2DEG;
-                       if(angle && (angle > self.beam_maxangle))
-                       {
-                               // if the angle is greater than maxangle, force the blendfactor to make this the maximum factor
-                               float blendfactor = bound(
-                                       0,
-                                       (1 - (self.beam_returnspeed * frametime)),
-                                       min(self.beam_maxangle / angle, 1)
-                               );
-                               self.beam_dir = normalize((wantdir * (1 - blendfactor)) + (self.beam_dir * blendfactor));
-                       }
-                       else
-                       {
-                               // the radius is not too far yet, no worries :D
-                               float blendfactor = bound(
-                                       0,
-                                       (1 - (self.beam_returnspeed * frametime)),
-                                       1
-                               );
-                               self.beam_dir = normalize((wantdir * (1 - blendfactor)) + (self.beam_dir * blendfactor));
-                       }
-
-                       // calculate how many segments are needed
-                       float max_allowed_segments;
-
-                       if(self.beam_distancepersegment)
-                       {
-                               max_allowed_segments = min(
-                                       ARC_MAX_SEGMENTS,
-                                       1 + (vlen(wantdir / self.beam_distancepersegment))
-                               );
-                       }
-                       else { max_allowed_segments = ARC_MAX_SEGMENTS; }
-
-                       if(self.beam_degreespersegment)
-                       {
-                               segments = bound(
-                                       1,
-                                       (
-                                               min(
-                                                       angle,
-                                                       self.beam_maxangle
-                                               )
-                                               /
-                                               self.beam_degreespersegment
-                                       ),
-                                       max_allowed_segments
-                               );
-                       }
-                       else { segments = 1; }
-               }
-               else { segments = 1; }
-
-               // set the beam direction which the rest of the code will refer to
-               beamdir = self.beam_dir;
-
-               // finally, set self.angles to the proper direction so that muzzle attachment points in proper direction
-               self.angles = fixedvectoangles2(forward, up); // TODO(Samual): is this == warpzone_save_view_angles?
-       }
-       else
-       {
-               // set the values from the provided info from the networked entity
-               start_pos = self.origin;
-               wantdir = self.v_angle;
-               beamdir = self.angles;
-
-               if(beamdir != wantdir)
-               {
-                       float angle = vlen(wantdir - beamdir) * RAD2DEG;
-
-                       // calculate how many segments are needed
-                       float max_allowed_segments;
-
-                       if(self.beam_distancepersegment)
-                       {
-                               max_allowed_segments = min(
-                                       ARC_MAX_SEGMENTS,
-                                       1 + (vlen(wantdir / self.beam_distancepersegment))
-                               );
-                       }
-                       else { max_allowed_segments = ARC_MAX_SEGMENTS; }
-
-                       if(self.beam_degreespersegment)
-                       {
-                               segments = bound(
-                                       1,
-                                       (
-                                               min(
-                                                       angle,
-                                                       self.beam_maxangle
-                                               )
-                                               /
-                                               self.beam_degreespersegment
-                                       ),
-                                       max_allowed_segments
-                               );
-                       }
-                       else { segments = 1; }
-               }
-               else { segments = 1; }
-       }
-
-       setorigin(self, start_pos);
-       self.beam_muzzleentity.angles_z = random() * 360; // WEAPONTODO: use avelocity instead?
-
-       vector beam_endpos = (start_pos + (beamdir * self.beam_range));
-       vector beam_controlpoint = start_pos + wantdir * (self.beam_range * (1 - self.beam_tightness));
-
-       Draw_ArcBeam_callback_entity = self;
-       Draw_ArcBeam_callback_last_thickness = 0;
-       Draw_ArcBeam_callback_last_top = start_pos;
-       Draw_ArcBeam_callback_last_bottom = start_pos;
-
-       vector last_origin = start_pos;
-       vector original_start_pos = start_pos;
-
-       float i;
-       for(i = 1; i <= segments; ++i)
-       {
-               // WEAPONTODO (client):
-               // In order to do nice fading and pointing on the starting segment, we must always
-               // have that drawn as a separate triangle... However, that is difficult to do when
-               // keeping in mind the above problems and also optimizing the amount of segments
-               // drawn on screen at any given time. (Automatic beam quality scaling, essentially)
-
-               vector new_origin = bezier_quadratic_getpoint(
-                       start_pos,
-                       beam_controlpoint,
-                       beam_endpos,
-                       i / segments);
-
-               WarpZone_TraceBox_ThroughZone(
-                       last_origin,
-                       '0 0 0',
-                       '0 0 0',
-                       new_origin,
-                       MOVE_NORMAL,
-                       world,
-                       world,
-                       Draw_ArcBeam_callback
-               );
-
-               // Do all the transforms for warpzones right now, as we already "are" in the post-trace
-               // system (if we hit a player, that's always BEHIND the last passed wz).
-               last_origin = trace_endpos;
-               start_pos = WarpZone_TransformOrigin(WarpZone_trace_transform, start_pos);
-               beam_controlpoint = WarpZone_TransformOrigin(WarpZone_trace_transform, beam_controlpoint);
-               beam_endpos = WarpZone_TransformOrigin(WarpZone_trace_transform, beam_endpos);
-               beamdir = WarpZone_TransformVelocity(WarpZone_trace_transform, beamdir);
-               Draw_ArcBeam_callback_last_top = WarpZone_TransformOrigin(WarpZone_trace_transform, Draw_ArcBeam_callback_last_top);
-               Draw_ArcBeam_callback_last_bottom = WarpZone_TransformOrigin(WarpZone_trace_transform, Draw_ArcBeam_callback_last_bottom);
-
-               if(trace_fraction < 1) { break; }
-       }
-
-       // visual effects for startpoint and endpoint
-       if(self.beam_hiteffect)
-       {
-               // FIXME we really should do this on the server so it actually
-               // matches gameplay. What this client side stuff is doing is no
-               // more than guesswork.
-               if((trace_ent || trace_fraction < 1) && !(trace_dphitq3surfaceflags & Q3SURFACEFLAG_NOIMPACT))
-               pointparticles(
-                       self.beam_hiteffect,
-                       last_origin,
-                       beamdir * -1,
-                       frametime * 2
-               );
-       }
-       if(self.beam_hitlight[0])
-       {
-               adddynamiclight(
-                       last_origin,
-                       self.beam_hitlight[0],
-                       vec3(
-                               self.beam_hitlight[1],
-                               self.beam_hitlight[2],
-                               self.beam_hitlight[3]
-                       )
-               );
-       }
-       if(self.beam_muzzleeffect)
-       {
-               pointparticles(
-                       self.beam_muzzleeffect,
-                       original_start_pos + wantdir * 20,
-                       wantdir * 1000,
-                       frametime * 0.1
-               );
-       }
-       if(self.beam_muzzlelight[0])
-       {
-               adddynamiclight(
-                       original_start_pos + wantdir * 20,
-                       self.beam_muzzlelight[0],
-                       vec3(
-                               self.beam_muzzlelight[1],
-                               self.beam_muzzlelight[2],
-                               self.beam_muzzlelight[3]
-                       )
-               );
-       }
-
-       // cleanup
-       Draw_ArcBeam_callback_entity = world;
-       Draw_ArcBeam_callback_last_thickness = 0;
-       Draw_ArcBeam_callback_last_top = '0 0 0';
-       Draw_ArcBeam_callback_last_bottom = '0 0 0';
-}
-
-void Remove_ArcBeam(void)
-{
-       remove(self.beam_muzzleentity);
-       sound(self, CH_SHOTS_SINGLE, "misc/null.wav", VOL_BASE, ATTEN_NORM);
-}
-
-void Ent_ReadArcBeam(float isnew)
-{
-       int sf = ReadByte();
-       entity flash;
-
-       if(isnew)
-       {
-               // calculate shot origin offset from gun alignment
-               int gunalign = autocvar_cl_gunalign;
-               if(gunalign != 1 && gunalign != 2 && gunalign != 4)
-                       gunalign = 3; // default value
-               --gunalign;
-
-               self.beam_shotorigin = arc_shotorigin[gunalign];
-
-               // set other main attributes of the beam
-               self.draw = Draw_ArcBeam;
-               self.entremove = Remove_ArcBeam;
-               self.move_time = time;
-               loopsound(self, CH_SHOTS_SINGLE, W_Sound("arc_loop"), VOL_BASE, ATTEN_NORM);
-
-               flash = spawn();
-               flash.owner = self;
-               flash.effects = EF_ADDITIVE | EF_FULLBRIGHT;
-               flash.drawmask = MASK_NORMAL;
-               flash.solid = SOLID_NOT;
-               flash.avelocity_z = 5000;
-               setattachment(flash, self, "");
-               setorigin(flash, '0 0 0');
-
-               self.beam_muzzleentity = flash;
-       }
-       else
-       {
-               flash = self.beam_muzzleentity;
-       }
-
-       if(sf & ARC_SF_SETTINGS) // settings information
-       {
-               self.beam_degreespersegment = ReadShort();
-               self.beam_distancepersegment = ReadShort();
-               self.beam_maxangle = ReadShort();
-               self.beam_range = ReadCoord();
-               self.beam_returnspeed = ReadShort();
-               self.beam_tightness = (ReadByte() / 10);
-
-               if(ReadByte())
-               {
-                       if(autocvar_chase_active)
-                               { self.beam_usevieworigin = 1; }
-                       else // use view origin
-                               { self.beam_usevieworigin = 2; }
-               }
-               else
-               {
-                       self.beam_usevieworigin = 0;
-               }
-       }
-
-       if(!self.beam_usevieworigin)
-       {
-               // self.iflags = IFLAG_ORIGIN | IFLAG_ANGLES | IFLAG_V_ANGLE; // why doesn't this work?
-               self.iflags = IFLAG_ORIGIN;
-
-               InterpolateOrigin_Undo();
-       }
-
-       if(sf & ARC_SF_START) // starting location
-       {
-               self.origin_x = ReadCoord();
-               self.origin_y = ReadCoord();
-               self.origin_z = ReadCoord();
-       }
-       else if(self.beam_usevieworigin) // infer the location from player location
-       {
-               if(self.beam_usevieworigin == 2)
-               {
-                       // use view origin
-                       self.origin = view_origin;
-               }
-               else
-               {
-                       // use player origin so that third person display still works
-                       self.origin = getplayerorigin(player_localnum) + ('0 0 1' * getstati(STAT_VIEWHEIGHT));
-               }
-       }
-
-       setorigin(self, self.origin);
-
-       if(sf & ARC_SF_WANTDIR) // want/aim direction
-       {
-               self.v_angle_x = ReadCoord();
-               self.v_angle_y = ReadCoord();
-               self.v_angle_z = ReadCoord();
-       }
-
-       if(sf & ARC_SF_BEAMDIR) // beam direction
-       {
-               self.angles_x = ReadCoord();
-               self.angles_y = ReadCoord();
-               self.angles_z = ReadCoord();
-       }
-
-       if(sf & ARC_SF_BEAMTYPE) // beam type
-       {
-               self.beam_type = ReadByte();
-               switch(self.beam_type)
-               {
-                       case ARC_BT_MISS:
-                       {
-                               self.beam_color = '1 1 1';
-                               self.beam_alpha = 0.5;
-                               self.beam_thickness = 8;
-                               self.beam_traileffect = particleeffectnum(EFFECT_ARC_BEAM);
-                               self.beam_hiteffect = particleeffectnum(EFFECT_ARC_LIGHTNING);
-                               self.beam_hitlight[0] = 0;
-                               self.beam_hitlight[1] = 1;
-                               self.beam_hitlight[2] = 1;
-                               self.beam_hitlight[3] = 1;
-                               self.beam_muzzleeffect = -1; //particleeffectnum(EFFECT_VORTEX_MUZZLEFLASH);
-                               self.beam_muzzlelight[0] = 0;
-                               self.beam_muzzlelight[1] = 1;
-                               self.beam_muzzlelight[2] = 1;
-                               self.beam_muzzlelight[3] = 1;
-                               if(self.beam_muzzleeffect >= 0)
-                               {
-                                       setmodel(flash, "models/flash.md3");
-                                       flash.alpha = self.beam_alpha;
-                                       flash.colormod = self.beam_color;
-                                       flash.scale = 0.5;
-                               }
-                               break;
-                       }
-                       case ARC_BT_WALL: // grenadelauncher_muzzleflash healray_muzzleflash
-                       {
-                               self.beam_color = '1 1 1';
-                               self.beam_alpha = 0.5;
-                               self.beam_thickness = 8;
-                               self.beam_traileffect = particleeffectnum(EFFECT_ARC_BEAM);
-                               self.beam_hiteffect = particleeffectnum(EFFECT_ARC_LIGHTNING);
-                               self.beam_hitlight[0] = 0;
-                               self.beam_hitlight[1] = 1;
-                               self.beam_hitlight[2] = 1;
-                               self.beam_hitlight[3] = 1;
-                               self.beam_muzzleeffect = -1; // particleeffectnum(EFFECT_GRENADE_MUZZLEFLASH);
-                               self.beam_muzzlelight[0] = 0;
-                               self.beam_muzzlelight[1] = 1;
-                               self.beam_muzzlelight[2] = 1;
-                               self.beam_muzzlelight[3] = 1;
-                               self.beam_image = "particles/lgbeam";
-                               if(self.beam_muzzleeffect >= 0)
-                               {
-                                       setmodel(flash, "models/flash.md3");
-                                       flash.alpha = self.beam_alpha;
-                                       flash.colormod = self.beam_color;
-                                       flash.scale = 0.5;
-                               }
-                               break;
-                       }
-                       case ARC_BT_HEAL:
-                       {
-                               self.beam_color = '1 1 1';
-                               self.beam_alpha = 0.5;
-                               self.beam_thickness = 8;
-                               self.beam_traileffect = particleeffectnum(EFFECT_ARC_BEAM_HEAL);
-                               self.beam_hiteffect = particleeffectnum(EFFECT_ARC_BEAM_HEAL_IMPACT);
-                               self.beam_hitlight[0] = 0;
-                               self.beam_hitlight[1] = 1;
-                               self.beam_hitlight[2] = 1;
-                               self.beam_hitlight[3] = 1;
-                               self.beam_muzzleeffect = -1; //particleeffectnum(EFFECT_VORTEX_MUZZLEFLASH);
-                               self.beam_muzzlelight[0] = 0;
-                               self.beam_muzzlelight[1] = 1;
-                               self.beam_muzzlelight[2] = 1;
-                               self.beam_muzzlelight[3] = 1;
-                               self.beam_image = "particles/lgbeam";
-                               if(self.beam_muzzleeffect >= 0)
-                               {
-                                       setmodel(flash, "models/flash.md3");
-                                       flash.alpha = self.beam_alpha;
-                                       flash.colormod = self.beam_color;
-                                       flash.scale = 0.5;
-                               }
-                               break;
-                       }
-                       case ARC_BT_HIT:
-                       {
-                               self.beam_color = '1 1 1';
-                               self.beam_alpha = 0.5;
-                               self.beam_thickness = 8;
-                               self.beam_traileffect = particleeffectnum(EFFECT_ARC_BEAM);
-                               self.beam_hiteffect = particleeffectnum(EFFECT_ARC_LIGHTNING);
-                               self.beam_hitlight[0] = 20;
-                               self.beam_hitlight[1] = 1;
-                               self.beam_hitlight[2] = 0;
-                               self.beam_hitlight[3] = 0;
-                               self.beam_muzzleeffect = -1; //particleeffectnum(EFFECT_VORTEX_MUZZLEFLASH);
-                               self.beam_muzzlelight[0] = 50;
-                               self.beam_muzzlelight[1] = 1;
-                               self.beam_muzzlelight[2] = 0;
-                               self.beam_muzzlelight[3] = 0;
-                               self.beam_image = "particles/lgbeam";
-                               if(self.beam_muzzleeffect >= 0)
-                               {
-                                       setmodel(flash, "models/flash.md3");
-                                       flash.alpha = self.beam_alpha;
-                                       flash.colormod = self.beam_color;
-                                       flash.scale = 0.5;
-                               }
-                               break;
-                       }
-                       case ARC_BT_BURST_MISS:
-                       {
-                               self.beam_color = '1 1 1';
-                               self.beam_alpha = 0.5;
-                               self.beam_thickness = 14;
-                               self.beam_traileffect = particleeffectnum(EFFECT_ARC_BEAM);
-                               self.beam_hiteffect = particleeffectnum(EFFECT_ARC_LIGHTNING);
-                               self.beam_hitlight[0] = 0;
-                               self.beam_hitlight[1] = 1;
-                               self.beam_hitlight[2] = 1;
-                               self.beam_hitlight[3] = 1;
-                               self.beam_muzzleeffect = -1; //particleeffectnum(EFFECT_VORTEX_MUZZLEFLASH);
-                               self.beam_muzzlelight[0] = 0;
-                               self.beam_muzzlelight[1] = 1;
-                               self.beam_muzzlelight[2] = 1;
-                               self.beam_muzzlelight[3] = 1;
-                               self.beam_image = "particles/lgbeam";
-                               if(self.beam_muzzleeffect >= 0)
-                               {
-                                       setmodel(flash, "models/flash.md3");
-                                       flash.alpha = self.beam_alpha;
-                                       flash.colormod = self.beam_color;
-                                       flash.scale = 0.5;
-                               }
-                               break;
-                       }
-                       case ARC_BT_BURST_WALL:
-                       {
-                               self.beam_color = '1 1 1';
-                               self.beam_alpha = 0.5;
-                               self.beam_thickness = 14;
-                               self.beam_traileffect = particleeffectnum(EFFECT_ARC_BEAM);
-                               self.beam_hiteffect = particleeffectnum(EFFECT_ARC_LIGHTNING);
-                               self.beam_hitlight[0] = 0;
-                               self.beam_hitlight[1] = 1;
-                               self.beam_hitlight[2] = 1;
-                               self.beam_hitlight[3] = 1;
-                               self.beam_muzzleeffect = -1; //particleeffectnum(EFFECT_VORTEX_MUZZLEFLASH);
-                               self.beam_muzzlelight[0] = 0;
-                               self.beam_muzzlelight[1] = 1;
-                               self.beam_muzzlelight[2] = 1;
-                               self.beam_muzzlelight[3] = 1;
-                               self.beam_image = "particles/lgbeam";
-                               if(self.beam_muzzleeffect >= 0)
-                               {
-                                       setmodel(flash, "models/flash.md3");
-                                       flash.alpha = self.beam_alpha;
-                                       flash.colormod = self.beam_color;
-                                       flash.scale = 0.5;
-                               }
-                               break;
-                       }
-                       case ARC_BT_BURST_HEAL:
-                       {
-                               self.beam_color = '1 1 1';
-                               self.beam_alpha = 0.5;
-                               self.beam_thickness = 14;
-                               self.beam_traileffect = particleeffectnum(EFFECT_ARC_BEAM_HEAL);
-                               self.beam_hiteffect = particleeffectnum(EFFECT_ARC_BEAM_HEAL_IMPACT2);
-                               self.beam_hitlight[0] = 0;
-                               self.beam_hitlight[1] = 1;
-                               self.beam_hitlight[2] = 1;
-                               self.beam_hitlight[3] = 1;
-                               self.beam_muzzleeffect = -1; //particleeffectnum(EFFECT_VORTEX_MUZZLEFLASH);
-                               self.beam_muzzlelight[0] = 0;
-                               self.beam_muzzlelight[1] = 1;
-                               self.beam_muzzlelight[2] = 1;
-                               self.beam_muzzlelight[3] = 1;
-                               self.beam_image = "particles/lgbeam";
-                               if(self.beam_muzzleeffect >= 0)
-                               {
-                                       setmodel(flash, "models/flash.md3");
-                                       flash.alpha = self.beam_alpha;
-                                       flash.colormod = self.beam_color;
-                                       flash.scale = 0.5;
-                               }
-                               break;
-                       }
-                       case ARC_BT_BURST_HIT:
-                       {
-                               self.beam_color = '1 1 1';
-                               self.beam_alpha = 0.5;
-                               self.beam_thickness = 14;
-                               self.beam_traileffect = particleeffectnum(EFFECT_ARC_BEAM);
-                               self.beam_hiteffect = particleeffectnum(EFFECT_ARC_LIGHTNING);
-                               self.beam_hitlight[0] = 0;
-                               self.beam_hitlight[1] = 1;
-                               self.beam_hitlight[2] = 1;
-                               self.beam_hitlight[3] = 1;
-                               self.beam_muzzleeffect = -1; //particleeffectnum(EFFECT_VORTEX_MUZZLEFLASH);
-                               self.beam_muzzlelight[0] = 0;
-                               self.beam_muzzlelight[1] = 1;
-                               self.beam_muzzlelight[2] = 1;
-                               self.beam_muzzlelight[3] = 1;
-                               self.beam_image = "particles/lgbeam";
-                               if(self.beam_muzzleeffect >= 0)
-                               {
-                                       setmodel(flash, "models/flash.md3");
-                                       flash.alpha = self.beam_alpha;
-                                       flash.colormod = self.beam_color;
-                                       flash.scale = 0.5;
-                               }
-                               break;
-                       }
-
-                       // shouldn't be possible, but lets make it colorful if it does :D
-                       default:
-                       {
-                               self.beam_color = randomvec();
-                               self.beam_alpha = 1;
-                               self.beam_thickness = 8;
-                               self.beam_traileffect = false;
-                               self.beam_hiteffect = false;
-                               self.beam_hitlight[0] = 0;
-                               self.beam_hitlight[1] = 1;
-                               self.beam_hitlight[2] = 1;
-                               self.beam_hitlight[3] = 1;
-                               self.beam_muzzleeffect = -1; //particleeffectnum(EFFECT_VORTEX_MUZZLEFLASH);
-                               self.beam_muzzlelight[0] = 0;
-                               self.beam_muzzlelight[1] = 1;
-                               self.beam_muzzlelight[2] = 1;
-                               self.beam_muzzlelight[3] = 1;
-                               self.beam_image = "particles/lgbeam";
-                               if(self.beam_muzzleeffect >= 0)
-                               {
-                                       setmodel(flash, "models/flash.md3");
-                                       flash.alpha = self.beam_alpha;
-                                       flash.colormod = self.beam_color;
-                                       flash.scale = 0.5;
-                               }
-                               break;
-                       }
-               }
-       }
-
-       if(!self.beam_usevieworigin)
-       {
-               InterpolateOrigin_Note();
-       }
-}
-
-bool W_Arc(int req)
-{
-       switch(req)
-       {
-               case WR_IMPACTEFFECT:
-               {
-                       // todo
-                       return true;
-               }
-               case WR_INIT:
-               {
-                       precache_sound(W_Sound("arc_loop"));
-                       return true;
-               }
-               case WR_ZOOMRETICLE:
-               {
-                       // no weapon specific image for this weapon
-                       return false;
-               }
-       }
-       return false;
-}
-#endif
-#endif
diff --git a/qcsrc/common/weapons/w_blaster.qc b/qcsrc/common/weapons/w_blaster.qc
deleted file mode 100644 (file)
index 6234f4a..0000000
+++ /dev/null
@@ -1,297 +0,0 @@
-#ifndef IMPLEMENTATION
-REGISTER_WEAPON(
-/* WEP_##id  */ BLASTER,
-/* function  */ W_Blaster,
-/* ammotype  */ ammo_none,
-/* impulse   */ 1,
-/* flags     */ WEP_FLAG_NORMAL | WEP_FLAG_CANCLIMB | WEP_TYPE_SPLASH,
-/* rating    */ 0,
-/* color     */ '1 0.5 0.5',
-/* modelname */ "laser",
-/* simplemdl */ "foobar",
-/* crosshair */ "gfx/crosshairlaser 0.5",
-/* wepimg    */ "weaponlaser",
-/* refname   */ "blaster",
-/* wepname   */ _("Blaster")
-);
-
-#define BLASTER_SETTINGS(w_cvar,w_prop) BLASTER_SETTINGS_LIST(w_cvar, w_prop, BLASTER, blaster)
-#define BLASTER_SETTINGS_LIST(w_cvar,w_prop,id,sn) \
-       w_cvar(id, sn, BOTH, animtime) \
-       w_cvar(id, sn, BOTH, damage) \
-       w_cvar(id, sn, BOTH, delay) \
-       w_cvar(id, sn, BOTH, edgedamage) \
-       w_cvar(id, sn, BOTH, force) \
-       w_cvar(id, sn, BOTH, force_zscale) \
-       w_cvar(id, sn, BOTH, lifetime) \
-       w_cvar(id, sn, BOTH, radius) \
-       w_cvar(id, sn, BOTH, refire) \
-       w_cvar(id, sn, BOTH, shotangle) \
-       w_cvar(id, sn, BOTH, speed) \
-       w_cvar(id, sn, BOTH, spread) \
-       w_cvar(id, sn, NONE, secondary) \
-       w_prop(id, sn, float,  switchdelay_raise, switchdelay_raise) \
-       w_prop(id, sn, float,  switchdelay_drop, switchdelay_drop) \
-       w_prop(id, sn, string, weaponreplace, weaponreplace) \
-       w_prop(id, sn, float,  weaponstart, weaponstart) \
-       w_prop(id, sn, float,  weaponstartoverride, weaponstartoverride) \
-       w_prop(id, sn, float,  weaponthrowable, weaponthrowable)
-
-#ifdef SVQC
-BLASTER_SETTINGS(WEP_ADD_CVAR, WEP_ADD_PROP)
-.float blaster_damage;
-.float blaster_edgedamage;
-.float blaster_radius;
-.float blaster_force;
-.float blaster_lifetime;
-#endif
-#endif
-#ifdef IMPLEMENTATION
-#ifdef SVQC
-void spawnfunc_weapon_blaster(void) { weapon_defaultspawnfunc(WEP_BLASTER.m_id); }
-void spawnfunc_weapon_laser(void) { spawnfunc_weapon_blaster(); }
-
-void W_Blaster_Touch(void)
-{
-       PROJECTILE_TOUCH;
-
-       self.event_damage = func_null;
-
-       RadiusDamage(
-               self,
-               self.realowner,
-               self.blaster_damage,
-               self.blaster_edgedamage,
-               self.blaster_radius,
-               world,
-               world,
-               self.blaster_force,
-               self.projectiledeathtype,
-               other
-       );
-
-       remove(self);
-}
-
-void W_Blaster_Think(void)
-{
-       self.movetype = MOVETYPE_FLY;
-       self.think = SUB_Remove;
-       self.nextthink = time + self.blaster_lifetime;
-       CSQCProjectile(self, true, PROJECTILE_BLASTER, true);
-}
-
-void W_Blaster_Attack(
-       float atk_deathtype,
-       float atk_shotangle,
-       float atk_damage,
-       float atk_edgedamage,
-       float atk_radius,
-       float atk_force,
-       float atk_speed,
-       float atk_spread,
-       float atk_delay,
-       float atk_lifetime)
-{
-       vector s_forward = v_forward * cos(atk_shotangle * DEG2RAD) + v_up * sin(atk_shotangle * DEG2RAD);
-
-       W_SetupShot_Dir(self, s_forward, false, 3, W_Sound("lasergun_fire"), CH_WEAPON_B, atk_damage);
-       Send_Effect(EFFECT_BLASTER_MUZZLEFLASH, w_shotorg, w_shotdir * 1000, 1);
-
-       entity missile = spawn();
-       missile.owner = missile.realowner = self;
-       missile.classname = "blasterbolt";
-       missile.bot_dodge = true;
-       missile.bot_dodgerating = atk_damage;
-       PROJECTILE_MAKETRIGGER(missile);
-
-       missile.blaster_damage = atk_damage;
-       missile.blaster_edgedamage = atk_edgedamage;
-       missile.blaster_radius = atk_radius;
-       missile.blaster_force = atk_force;
-       missile.blaster_lifetime = atk_lifetime;
-
-       setorigin(missile, w_shotorg);
-       setsize(missile, '0 0 0', '0 0 0');
-
-       W_SetupProjVelocity_Explicit(
-               missile,
-               w_shotdir,
-               v_up,
-               atk_speed,
-               0,
-               0,
-               atk_spread,
-               false
-       );
-
-       missile.angles = vectoangles(missile.velocity);
-
-       //missile.glow_color = 250; // 244, 250
-       //missile.glow_size = 120;
-
-       missile.touch = W_Blaster_Touch;
-       missile.flags = FL_PROJECTILE;
-       missile.missile_flags = MIF_SPLASH;
-       missile.projectiledeathtype = atk_deathtype;
-       missile.think = W_Blaster_Think;
-       missile.nextthink = time + atk_delay;
-
-       MUTATOR_CALLHOOK(EditProjectile, self, missile);
-
-       if(time >= missile.nextthink)
-       {
-               entity oldself;
-               oldself = self;
-               self = missile;
-               self.think();
-               self = oldself;
-       }
-}
-bool W_Blaster(int request)
-{
-       switch(request)
-       {
-               case WR_AIM:
-               {
-                       if(WEP_CVAR(blaster, secondary))
-                       {
-                               if((random() * (WEP_CVAR_PRI(blaster, damage) + WEP_CVAR_SEC(blaster, damage))) > WEP_CVAR_PRI(blaster, damage))
-                                       { self.BUTTON_ATCK2 = bot_aim(WEP_CVAR_SEC(blaster, speed), 0, WEP_CVAR_SEC(blaster, lifetime), false); }
-                               else
-                                       { self.BUTTON_ATCK = bot_aim(WEP_CVAR_PRI(blaster, speed), 0, WEP_CVAR_PRI(blaster, lifetime), false); }
-                       }
-                       else
-                               { self.BUTTON_ATCK = bot_aim(WEP_CVAR_PRI(blaster, speed), 0, WEP_CVAR_PRI(blaster, lifetime), false); }
-
-                       return true;
-               }
-
-               case WR_THINK:
-               {
-                       if(self.BUTTON_ATCK)
-                       {
-                               if(weapon_prepareattack(0, WEP_CVAR_PRI(blaster, refire)))
-                               {
-                                       W_Blaster_Attack(
-                                               WEP_BLASTER.m_id,
-                                               WEP_CVAR_PRI(blaster, shotangle),
-                                               WEP_CVAR_PRI(blaster, damage),
-                                               WEP_CVAR_PRI(blaster, edgedamage),
-                                               WEP_CVAR_PRI(blaster, radius),
-                                               WEP_CVAR_PRI(blaster, force),
-                                               WEP_CVAR_PRI(blaster, speed),
-                                               WEP_CVAR_PRI(blaster, spread),
-                                               WEP_CVAR_PRI(blaster, delay),
-                                               WEP_CVAR_PRI(blaster, lifetime)
-                                       );
-                                       weapon_thinkf(WFRAME_FIRE1, WEP_CVAR_PRI(blaster, animtime), w_ready);
-                               }
-                       }
-                       else if(self.BUTTON_ATCK2)
-                       {
-                               switch(WEP_CVAR(blaster, secondary))
-                               {
-                                       case 0: // switch to last used weapon
-                                       {
-                                               if(self.switchweapon == WEP_BLASTER.m_id) // don't do this if already switching
-                                                       W_LastWeapon();
-                                               break;
-                                       }
-
-                                       case 1: // normal projectile secondary
-                                       {
-                                               if(weapon_prepareattack(1, WEP_CVAR_SEC(blaster, refire)))
-                                               {
-                                                       W_Blaster_Attack(
-                                                               WEP_BLASTER.m_id | HITTYPE_SECONDARY,
-                                                               WEP_CVAR_SEC(blaster, shotangle),
-                                                               WEP_CVAR_SEC(blaster, damage),
-                                                               WEP_CVAR_SEC(blaster, edgedamage),
-                                                               WEP_CVAR_SEC(blaster, radius),
-                                                               WEP_CVAR_SEC(blaster, force),
-                                                               WEP_CVAR_SEC(blaster, speed),
-                                                               WEP_CVAR_SEC(blaster, spread),
-                                                               WEP_CVAR_SEC(blaster, delay),
-                                                               WEP_CVAR_SEC(blaster, lifetime)
-                                                       );
-                                                       weapon_thinkf(WFRAME_FIRE2, WEP_CVAR_SEC(blaster, animtime), w_ready);
-                                               }
-
-                                               break;
-                                       }
-                               }
-                       }
-                       return true;
-               }
-
-               case WR_INIT:
-               {
-                       precache_model(W_Model("g_laser.md3"));
-                       precache_model(W_Model("v_laser.md3"));
-                       precache_model(W_Model("h_laser.iqm"));
-                       precache_sound(W_Sound("lasergun_fire"));
-                       BLASTER_SETTINGS(WEP_SKIP_CVAR, WEP_SET_PROP);
-                       return true;
-               }
-
-               case WR_SETUP:
-               {
-                       self.ammo_field = ammo_none;
-                       return true;
-               }
-
-               case WR_CHECKAMMO1:
-               case WR_CHECKAMMO2:
-               {
-                       return true; // laser has infinite ammo
-               }
-
-               case WR_CONFIG:
-               {
-                       BLASTER_SETTINGS(WEP_CONFIG_WRITE_CVARS, WEP_CONFIG_WRITE_PROPS);
-                       return true;
-               }
-
-               case WR_SUICIDEMESSAGE:
-               {
-                       return WEAPON_BLASTER_SUICIDE;
-               }
-
-               case WR_KILLMESSAGE:
-               {
-                       return WEAPON_BLASTER_MURDER;
-               }
-       }
-       return false;
-}
-#endif
-#ifdef CSQC
-bool W_Blaster(int request)
-{
-       switch(request)
-       {
-               case WR_IMPACTEFFECT:
-               {
-                       vector org2;
-                       org2 = w_org + w_backoff * 6;
-                       pointparticles(particleeffectnum(EFFECT_BLASTER_IMPACT), org2, w_backoff * 1000, 1);
-                       if(!w_issilent) { sound(self, CH_SHOTS, W_Sound("laserimpact"), VOL_BASE, ATTN_NORM); }
-                       return true;
-               }
-
-               case WR_INIT:
-               {
-                       precache_sound(W_Sound("laserimpact"));
-                       return true;
-               }
-               case WR_ZOOMRETICLE:
-               {
-                       // no weapon specific image for this weapon
-                       return false;
-               }
-       }
-       return false;
-}
-#endif
-#endif
diff --git a/qcsrc/common/weapons/w_crylink.qc b/qcsrc/common/weapons/w_crylink.qc
deleted file mode 100644 (file)
index 08deaf7..0000000
+++ /dev/null
@@ -1,731 +0,0 @@
-#ifndef IMPLEMENTATION
-REGISTER_WEAPON(
-/* WEP_##id  */ CRYLINK,
-/* function  */ W_Crylink,
-/* ammotype  */ ammo_cells,
-/* impulse   */ 6,
-/* flags     */ WEP_FLAG_NORMAL | WEP_FLAG_RELOADABLE | WEP_TYPE_SPLASH,
-/* rating    */ BOT_PICKUP_RATING_MID,
-/* color     */ '1 0.5 1',
-/* modelname */ "crylink",
-/* simplemdl */ "foobar",
-/* crosshair */ "gfx/crosshaircrylink 0.5",
-/* wepimg    */ "weaponcrylink",
-/* refname   */ "crylink",
-/* wepname   */ _("Crylink")
-);
-
-#define CRYLINK_SETTINGS(w_cvar,w_prop) CRYLINK_SETTINGS_LIST(w_cvar, w_prop, CRYLINK, crylink)
-#define CRYLINK_SETTINGS_LIST(w_cvar,w_prop,id,sn) \
-       w_cvar(id, sn, BOTH, ammo) \
-       w_cvar(id, sn, BOTH, animtime) \
-       w_cvar(id, sn, BOTH, damage) \
-       w_cvar(id, sn, BOTH, edgedamage) \
-       w_cvar(id, sn, BOTH, radius) \
-       w_cvar(id, sn, BOTH, force) \
-       w_cvar(id, sn, BOTH, spread) \
-       w_cvar(id, sn, BOTH, refire) \
-       w_cvar(id, sn, BOTH, speed) \
-       w_cvar(id, sn, BOTH, shots) \
-       w_cvar(id, sn, BOTH, bounces) \
-       w_cvar(id, sn, BOTH, bouncedamagefactor) \
-       w_cvar(id, sn, BOTH, middle_lifetime) \
-       w_cvar(id, sn, BOTH, middle_fadetime) \
-       w_cvar(id, sn, BOTH, other_lifetime) \
-       w_cvar(id, sn, BOTH, other_fadetime) \
-       w_cvar(id, sn, BOTH, linkexplode) \
-       w_cvar(id, sn, BOTH, joindelay) \
-       w_cvar(id, sn, BOTH, joinspread) \
-       w_cvar(id, sn, BOTH, joinexplode) \
-       w_cvar(id, sn, BOTH, joinexplode_damage) \
-       w_cvar(id, sn, BOTH, joinexplode_edgedamage) \
-       w_cvar(id, sn, BOTH, joinexplode_radius) \
-       w_cvar(id, sn, BOTH, joinexplode_force) \
-       w_cvar(id, sn, SEC,  spreadtype) \
-       w_cvar(id, sn, NONE, secondary) \
-       w_prop(id, sn, float,  reloading_ammo, reload_ammo) \
-       w_prop(id, sn, float,  reloading_time, reload_time) \
-       w_prop(id, sn, float,  switchdelay_raise, switchdelay_raise) \
-       w_prop(id, sn, float,  switchdelay_drop, switchdelay_drop) \
-       w_prop(id, sn, string, weaponreplace, weaponreplace) \
-       w_prop(id, sn, float,  weaponstart, weaponstart) \
-       w_prop(id, sn, float,  weaponstartoverride, weaponstartoverride) \
-       w_prop(id, sn, float,  weaponthrowable, weaponthrowable)
-
-#ifdef SVQC
-CRYLINK_SETTINGS(WEP_ADD_CVAR, WEP_ADD_PROP)
-.float gravity;
-.float crylink_waitrelease;
-.entity crylink_lastgroup;
-
-.entity queuenext;
-.entity queueprev;
-#endif
-#endif
-#ifdef IMPLEMENTATION
-#ifdef SVQC
-void spawnfunc_weapon_crylink(void) { weapon_defaultspawnfunc(WEP_CRYLINK.m_id); }
-
-void W_Crylink_CheckLinks(entity e)
-{
-       float i;
-       entity p;
-
-       if(e == world)
-               error("W_Crylink_CheckLinks: entity is world");
-       if(e.classname != "spike" || wasfreed(e))
-               error(sprintf("W_Crylink_CheckLinks: entity is not a spike but a %s (freed: %d)", e.classname, wasfreed(e)));
-
-       p = e;
-       for(i = 0; i < 1000; ++i)
-       {
-               if(p.queuenext.queueprev != p || p.queueprev.queuenext != p)
-                       error("W_Crylink_CheckLinks: queue is inconsistent");
-               p = p.queuenext;
-               if(p == e)
-                       break;
-       }
-       if(i >= 1000)
-               error("W_Crylink_CheckLinks: infinite chain");
-}
-
-void W_Crylink_Dequeue_Raw(entity own, entity prev, entity me, entity next)
-{
-       W_Crylink_CheckLinks(next);
-       if(me == own.crylink_lastgroup)
-               own.crylink_lastgroup = ((me == next) ? world : next);
-       prev.queuenext = next;
-       next.queueprev = prev;
-       me.classname = "spike_oktoremove";
-       if(me != next)
-               W_Crylink_CheckLinks(next);
-}
-
-void W_Crylink_Dequeue(entity e)
-{
-       W_Crylink_Dequeue_Raw(e.realowner, e.queueprev, e, e.queuenext);
-}
-
-void W_Crylink_Reset(void)
-{
-       W_Crylink_Dequeue(self);
-       remove(self);
-}
-
-// force projectile to explode
-void W_Crylink_LinkExplode(entity e, entity e2)
-{
-       float a;
-
-       if(e == e2)
-               return;
-
-       a = bound(0, 1 - (time - e.fade_time) * e.fade_rate, 1);
-
-       if(e == e.realowner.crylink_lastgroup)
-               e.realowner.crylink_lastgroup = world;
-
-       float isprimary = !(e.projectiledeathtype & HITTYPE_SECONDARY);
-
-       RadiusDamage(e, e.realowner, WEP_CVAR_BOTH(crylink, isprimary, damage) * a, WEP_CVAR_BOTH(crylink, isprimary, edgedamage) * a, WEP_CVAR_BOTH(crylink, isprimary, radius), world, world, WEP_CVAR_BOTH(crylink, isprimary, force) * a, e.projectiledeathtype, other);
-
-       W_Crylink_LinkExplode(e.queuenext, e2);
-
-       e.classname = "spike_oktoremove";
-       remove(e);
-}
-
-// adjust towards center
-// returns the origin where they will meet... and the time till the meeting is
-// stored in w_crylink_linkjoin_time.
-// could possibly network this origin and time, and display a special particle
-// effect when projectiles meet there :P
-// jspeed: joining speed (calculate this as join spread * initial speed)
-float w_crylink_linkjoin_time;
-vector W_Crylink_LinkJoin(entity e, float jspeed)
-{
-       vector avg_origin, avg_velocity;
-       vector targ_origin;
-       float avg_dist, n;
-       entity p;
-
-       // FIXME remove this debug code
-       W_Crylink_CheckLinks(e);
-
-       w_crylink_linkjoin_time = 0;
-
-       avg_origin = e.origin;
-       avg_velocity = e.velocity;
-       n = 1;
-       for(p = e; (p = p.queuenext) != e; )
-       {
-               avg_origin += WarpZone_RefSys_TransformOrigin(p, e, p.origin);
-               avg_velocity += WarpZone_RefSys_TransformVelocity(p, e, p.velocity);
-               ++n;
-       }
-       avg_origin *= (1.0 / n);
-       avg_velocity *= (1.0 / n);
-
-       if(n < 2)
-               return avg_origin; // nothing to do
-
-       // yes, mathematically we can do this in ONE step, but beware of 32bit floats...
-       avg_dist = pow(vlen(e.origin - avg_origin), 2);
-       for(p = e; (p = p.queuenext) != e; )
-               avg_dist += pow(vlen(WarpZone_RefSys_TransformOrigin(p, e, p.origin) - avg_origin), 2);
-       avg_dist *= (1.0 / n);
-       avg_dist = sqrt(avg_dist);
-
-       if(avg_dist == 0)
-               return avg_origin; // no change needed
-
-       if(jspeed == 0)
-       {
-               e.velocity = avg_velocity;
-               UpdateCSQCProjectile(e);
-               for(p = e; (p = p.queuenext) != e; )
-               {
-                       p.velocity = WarpZone_RefSys_TransformVelocity(e, p, avg_velocity);
-                       UpdateCSQCProjectile(p);
-               }
-               targ_origin = avg_origin + 1000000000 * normalize(avg_velocity); // HUUUUUUGE
-       }
-       else
-       {
-               w_crylink_linkjoin_time = avg_dist / jspeed;
-               targ_origin = avg_origin + w_crylink_linkjoin_time * avg_velocity;
-
-               e.velocity = (targ_origin - e.origin) * (1.0 / w_crylink_linkjoin_time);
-               UpdateCSQCProjectile(e);
-               for(p = e; (p = p.queuenext) != e; )
-               {
-                       p.velocity = WarpZone_RefSys_TransformVelocity(e, p, (targ_origin - WarpZone_RefSys_TransformOrigin(p, e, p.origin)) * (1.0 / w_crylink_linkjoin_time));
-                       UpdateCSQCProjectile(p);
-               }
-
-               // analysis:
-               //   jspeed -> +infinity:
-               //      w_crylink_linkjoin_time -> +0
-               //      targ_origin -> avg_origin
-               //      p->velocity -> HUEG towards center
-               //   jspeed -> 0:
-               //      w_crylink_linkjoin_time -> +/- infinity
-               //      targ_origin -> avg_velocity * +/- infinity
-               //      p->velocity -> avg_velocity
-               //   jspeed -> -infinity:
-               //      w_crylink_linkjoin_time -> -0
-               //      targ_origin -> avg_origin
-               //      p->velocity -> HUEG away from center
-       }
-
-       W_Crylink_CheckLinks(e);
-
-       return targ_origin;
-}
-
-void W_Crylink_LinkJoinEffect_Think(void)
-{
-       // is there at least 2 projectiles very close?
-       entity e, p;
-       float n;
-       e = self.owner.crylink_lastgroup;
-       n = 0;
-       if(e)
-       {
-               if(vlen(e.origin - self.origin) < vlen(e.velocity) * frametime)
-                       ++n;
-               for(p = e; (p = p.queuenext) != e; )
-               {
-                       if(vlen(p.origin - self.origin) < vlen(p.velocity) * frametime)
-                               ++n;
-               }
-               if(n >= 2)
-               {
-                       float isprimary = !(e.projectiledeathtype & HITTYPE_SECONDARY);
-
-                       if(WEP_CVAR_BOTH(crylink, isprimary, joinexplode))
-                       {
-                               n /= WEP_CVAR_BOTH(crylink, isprimary, shots);
-                               RadiusDamage(
-                                       e,
-                                       e.realowner,
-                                       WEP_CVAR_BOTH(crylink, isprimary, joinexplode_damage) * n,
-                                       WEP_CVAR_BOTH(crylink, isprimary, joinexplode_edgedamage) * n,
-                                       WEP_CVAR_BOTH(crylink, isprimary, joinexplode_radius) * n,
-                                       e.realowner,
-                                       world,
-                                       WEP_CVAR_BOTH(crylink, isprimary, joinexplode_force) * n,
-                                       e.projectiledeathtype,
-                                       other
-                               );
-                               Send_Effect(EFFECT_CRYLINK_JOINEXPLODE, self.origin, '0 0 0', n);
-                       }
-               }
-       }
-       remove(self);
-}
-
-float W_Crylink_Touch_WouldHitFriendly(entity projectile, float rad)
-{
-       entity head = WarpZone_FindRadius((projectile.origin + (projectile.mins + projectile.maxs) * 0.5), rad + MAX_DAMAGEEXTRARADIUS, false);
-       float hit_friendly = 0;
-       float hit_enemy = 0;
-
-       while(head)
-       {
-               if((head.takedamage != DAMAGE_NO) && (head.deadflag == DEAD_NO))
-               {
-                       if(SAME_TEAM(head, projectile.realowner))
-                               ++hit_friendly;
-                       else
-                               ++hit_enemy;
-               }
-
-               head = head.chain;
-       }
-
-       return (hit_enemy ? false : hit_friendly);
-}
-
-// NO bounce protection, as bounces are limited!
-void W_Crylink_Touch(void)
-{
-       float finalhit;
-       float f;
-       float isprimary = !(self.projectiledeathtype & HITTYPE_SECONDARY);
-       PROJECTILE_TOUCH;
-
-       float a;
-       a = bound(0, 1 - (time - self.fade_time) * self.fade_rate, 1);
-
-       finalhit = ((self.cnt <= 0) || (other.takedamage != DAMAGE_NO));
-       if(finalhit)
-               f = 1;
-       else
-               f = WEP_CVAR_BOTH(crylink, isprimary, bouncedamagefactor);
-       if(a)
-               f *= a;
-
-       float totaldamage = RadiusDamage(self, self.realowner, WEP_CVAR_BOTH(crylink, isprimary, damage) * f, WEP_CVAR_BOTH(crylink, isprimary, edgedamage) * f, WEP_CVAR_BOTH(crylink, isprimary, radius), world, world, WEP_CVAR_BOTH(crylink, isprimary, force) * f, self.projectiledeathtype, other);
-
-       if(totaldamage && ((WEP_CVAR_BOTH(crylink, isprimary, linkexplode) == 2) || ((WEP_CVAR_BOTH(crylink, isprimary, linkexplode) == 1) && !W_Crylink_Touch_WouldHitFriendly(self, WEP_CVAR_BOTH(crylink, isprimary, radius)))))
-       {
-               if(self == self.realowner.crylink_lastgroup)
-                       self.realowner.crylink_lastgroup = world;
-               W_Crylink_LinkExplode(self.queuenext, self);
-               self.classname = "spike_oktoremove";
-               remove(self);
-               return;
-       }
-       else if(finalhit)
-       {
-               // just unlink
-               W_Crylink_Dequeue(self);
-               remove(self);
-               return;
-       }
-       self.cnt = self.cnt - 1;
-       self.angles = vectoangles(self.velocity);
-       self.owner = world;
-       self.projectiledeathtype |= HITTYPE_BOUNCE;
-       // commented out as it causes a little hitch...
-       //if(proj.cnt == 0)
-       //      CSQCProjectile(proj, true, PROJECTILE_CRYLINK, true);
-}
-
-void W_Crylink_Fadethink(void)
-{
-       W_Crylink_Dequeue(self);
-       remove(self);
-}
-
-void W_Crylink_Attack(void)
-{
-       float counter, shots;
-       entity proj, prevproj, firstproj;
-       vector s;
-       vector forward, right, up;
-       float maxdmg;
-
-       W_DecreaseAmmo(WEP_CVAR_PRI(crylink, ammo));
-
-       maxdmg = WEP_CVAR_PRI(crylink, damage) * WEP_CVAR_PRI(crylink, shots);
-       maxdmg *= 1 + WEP_CVAR_PRI(crylink, bouncedamagefactor) * WEP_CVAR_PRI(crylink, bounces);
-       if(WEP_CVAR_PRI(crylink, joinexplode))
-               maxdmg += WEP_CVAR_PRI(crylink, joinexplode_damage);
-
-       W_SetupShot(self, false, 2, W_Sound("crylink_fire"), CH_WEAPON_A, maxdmg);
-       forward = v_forward;
-       right = v_right;
-       up = v_up;
-
-       shots = WEP_CVAR_PRI(crylink, shots);
-       Send_Effect(EFFECT_CRYLINK_MUZZLEFLASH, w_shotorg, w_shotdir * 1000, shots);
-       proj = prevproj = firstproj = world;
-       for(counter = 0; counter < shots; ++counter)
-       {
-               proj = spawn();
-               proj.reset = W_Crylink_Reset;
-               proj.realowner = proj.owner = self;
-               proj.classname = "spike";
-               proj.bot_dodge = true;
-               proj.bot_dodgerating = WEP_CVAR_PRI(crylink, damage);
-               if(shots == 1) {
-                       proj.queuenext = proj;
-                       proj.queueprev = proj;
-               }
-               else if(counter == 0) { // first projectile, store in firstproj for now
-                       firstproj = proj;
-               }
-               else if(counter == shots - 1) { // last projectile, link up with first projectile
-                       prevproj.queuenext = proj;
-                       firstproj.queueprev = proj;
-                       proj.queuenext = firstproj;
-                       proj.queueprev = prevproj;
-               }
-               else { // else link up with previous projectile
-                       prevproj.queuenext = proj;
-                       proj.queueprev = prevproj;
-               }
-
-               prevproj = proj;
-
-               proj.movetype = MOVETYPE_BOUNCEMISSILE;
-               PROJECTILE_MAKETRIGGER(proj);
-               proj.projectiledeathtype = WEP_CRYLINK.m_id;
-               //proj.gravity = 0.001;
-
-               setorigin(proj, w_shotorg);
-               setsize(proj, '0 0 0', '0 0 0');
-
-
-               s = '0 0 0';
-               if(counter == 0)
-                       s = '0 0 0';
-               else
-               {
-                       makevectors('0 360 0' * (0.75 + (counter - 0.5) / (shots - 1)));
-                       s.y = v_forward.x;
-                       s.z = v_forward.y;
-               }
-               s = s * WEP_CVAR_PRI(crylink, spread) * g_weaponspreadfactor;
-               W_SetupProjVelocity_Explicit(proj, w_shotdir + right * s.y + up * s.z, v_up, WEP_CVAR_PRI(crylink, speed), 0, 0, 0, false);
-               proj.touch = W_Crylink_Touch;
-
-               proj.think = W_Crylink_Fadethink;
-               if(counter == 0)
-               {
-                       proj.fade_time = time + WEP_CVAR_PRI(crylink, middle_lifetime);
-                       proj.fade_rate = 1 / WEP_CVAR_PRI(crylink, middle_fadetime);
-                       proj.nextthink = time + WEP_CVAR_PRI(crylink, middle_lifetime) + WEP_CVAR_PRI(crylink, middle_fadetime);
-               }
-               else
-               {
-                       proj.fade_time = time + WEP_CVAR_PRI(crylink, other_lifetime);
-                       proj.fade_rate = 1 / WEP_CVAR_PRI(crylink, other_fadetime);
-                       proj.nextthink = time + WEP_CVAR_PRI(crylink, other_lifetime) + WEP_CVAR_PRI(crylink, other_fadetime);
-               }
-               proj.teleport_time = time + WEP_CVAR_PRI(crylink, joindelay);
-               proj.cnt = WEP_CVAR_PRI(crylink, bounces);
-               //proj.scale = 1 + 1 * proj.cnt;
-
-               proj.angles = vectoangles(proj.velocity);
-
-               //proj.glow_size = 20;
-
-               proj.flags = FL_PROJECTILE;
-               proj.missile_flags = MIF_SPLASH;
-
-               CSQCProjectile(proj, true, (proj.cnt ? PROJECTILE_CRYLINK_BOUNCING : PROJECTILE_CRYLINK), true);
-
-               MUTATOR_CALLHOOK(EditProjectile, self, proj);
-       }
-       if(WEP_CVAR_PRI(crylink, joinspread) != 0)
-       {
-               self.crylink_lastgroup = proj;
-               W_Crylink_CheckLinks(proj);
-               self.crylink_waitrelease = 1;
-       }
-}
-
-void W_Crylink_Attack2(void)
-{
-       float counter, shots;
-       entity proj, prevproj, firstproj;
-       vector s;
-       vector forward, right, up;
-       float maxdmg;
-
-       W_DecreaseAmmo(WEP_CVAR_SEC(crylink, ammo));
-
-       maxdmg = WEP_CVAR_SEC(crylink, damage) * WEP_CVAR_SEC(crylink, shots);
-       maxdmg *= 1 + WEP_CVAR_SEC(crylink, bouncedamagefactor) * WEP_CVAR_SEC(crylink, bounces);
-       if(WEP_CVAR_SEC(crylink, joinexplode))
-               maxdmg += WEP_CVAR_SEC(crylink, joinexplode_damage);
-
-       W_SetupShot(self, false, 2, W_Sound("crylink_fire2"), CH_WEAPON_A, maxdmg);
-       forward = v_forward;
-       right = v_right;
-       up = v_up;
-
-       shots = WEP_CVAR_SEC(crylink, shots);
-       Send_Effect(EFFECT_CRYLINK_MUZZLEFLASH, w_shotorg, w_shotdir * 1000, shots);
-       proj = prevproj = firstproj = world;
-       for(counter = 0; counter < shots; ++counter)
-       {
-               proj = spawn();
-               proj.reset = W_Crylink_Reset;
-               proj.realowner = proj.owner = self;
-               proj.classname = "spike";
-               proj.bot_dodge = true;
-               proj.bot_dodgerating = WEP_CVAR_SEC(crylink, damage);
-               if(shots == 1) {
-                       proj.queuenext = proj;
-                       proj.queueprev = proj;
-               }
-               else if(counter == 0) { // first projectile, store in firstproj for now
-                       firstproj = proj;
-               }
-               else if(counter == shots - 1) { // last projectile, link up with first projectile
-                       prevproj.queuenext = proj;
-                       firstproj.queueprev = proj;
-                       proj.queuenext = firstproj;
-                       proj.queueprev = prevproj;
-               }
-               else { // else link up with previous projectile
-                       prevproj.queuenext = proj;
-                       proj.queueprev = prevproj;
-               }
-
-               prevproj = proj;
-
-               proj.movetype = MOVETYPE_BOUNCEMISSILE;
-               PROJECTILE_MAKETRIGGER(proj);
-               proj.projectiledeathtype = WEP_CRYLINK.m_id | HITTYPE_SECONDARY;
-               //proj.gravity = 0.001;
-
-               setorigin(proj, w_shotorg);
-               setsize(proj, '0 0 0', '0 0 0');
-
-               if(WEP_CVAR_SEC(crylink, spreadtype) == 1)
-               {
-                       s = '0 0 0';
-                       if(counter == 0)
-                               s = '0 0 0';
-                       else
-                       {
-                               makevectors('0 360 0' * (0.75 + (counter - 0.5) / (shots - 1)));
-                               s.y = v_forward.x;
-                               s.z = v_forward.y;
-                       }
-                       s = s * WEP_CVAR_SEC(crylink, spread) * g_weaponspreadfactor;
-                       s = w_shotdir + right * s.y + up * s.z;
-               }
-               else
-               {
-                       s = (w_shotdir + (((counter + 0.5) / shots) * 2 - 1) * v_right * WEP_CVAR_SEC(crylink, spread) * g_weaponspreadfactor);
-               }
-
-               W_SetupProjVelocity_Explicit(proj, s, v_up, WEP_CVAR_SEC(crylink, speed), 0, 0, 0, false);
-               proj.touch = W_Crylink_Touch;
-               proj.think = W_Crylink_Fadethink;
-               if(counter == (shots - 1) / 2)
-               {
-                       proj.fade_time = time + WEP_CVAR_SEC(crylink, middle_lifetime);
-                       proj.fade_rate = 1 / WEP_CVAR_SEC(crylink, middle_fadetime);
-                       proj.nextthink = time + WEP_CVAR_SEC(crylink, middle_lifetime) + WEP_CVAR_SEC(crylink, middle_fadetime);
-               }
-               else
-               {
-                       proj.fade_time = time + WEP_CVAR_SEC(crylink, other_lifetime);
-                       proj.fade_rate = 1 / WEP_CVAR_SEC(crylink, other_fadetime);
-                       proj.nextthink = time + WEP_CVAR_SEC(crylink, other_lifetime) + WEP_CVAR_SEC(crylink, other_fadetime);
-               }
-               proj.teleport_time = time + WEP_CVAR_SEC(crylink, joindelay);
-               proj.cnt = WEP_CVAR_SEC(crylink, bounces);
-               //proj.scale = 1 + 1 * proj.cnt;
-
-               proj.angles = vectoangles(proj.velocity);
-
-               //proj.glow_size = 20;
-
-               proj.flags = FL_PROJECTILE;
-        proj.missile_flags = MIF_SPLASH;
-
-               CSQCProjectile(proj, true, (proj.cnt ? PROJECTILE_CRYLINK_BOUNCING : PROJECTILE_CRYLINK), true);
-
-               MUTATOR_CALLHOOK(EditProjectile, self, proj);
-       }
-       if(WEP_CVAR_SEC(crylink, joinspread) != 0)
-       {
-               self.crylink_lastgroup = proj;
-               W_Crylink_CheckLinks(proj);
-               self.crylink_waitrelease = 2;
-       }
-}
-
-bool W_Crylink(int req)
-{
-       float ammo_amount;
-       switch(req)
-       {
-               case WR_AIM:
-               {
-                       if(random() < 0.10)
-                               self.BUTTON_ATCK = bot_aim(WEP_CVAR_PRI(crylink, speed), 0, WEP_CVAR_PRI(crylink, middle_lifetime), false);
-                       else
-                               self.BUTTON_ATCK2 = bot_aim(WEP_CVAR_SEC(crylink, speed), 0, WEP_CVAR_SEC(crylink, middle_lifetime), false);
-
-                       return true;
-               }
-               case WR_THINK:
-               {
-                       if(autocvar_g_balance_crylink_reload_ammo && self.clip_load < min(WEP_CVAR_PRI(crylink, ammo), WEP_CVAR_SEC(crylink, ammo))) // forced reload
-                               WEP_ACTION(self.weapon, WR_RELOAD);
-
-                       if(self.BUTTON_ATCK)
-                       {
-                               if(self.crylink_waitrelease != 1)
-                               if(weapon_prepareattack(0, WEP_CVAR_PRI(crylink, refire)))
-                               {
-                                       W_Crylink_Attack();
-                                       weapon_thinkf(WFRAME_FIRE1, WEP_CVAR_PRI(crylink, animtime), w_ready);
-                               }
-                       }
-
-                       if(self.BUTTON_ATCK2 && autocvar_g_balance_crylink_secondary)
-                       {
-                               if(self.crylink_waitrelease != 2)
-                               if(weapon_prepareattack(1, WEP_CVAR_SEC(crylink, refire)))
-                               {
-                                       W_Crylink_Attack2();
-                                       weapon_thinkf(WFRAME_FIRE2, WEP_CVAR_SEC(crylink, animtime), w_ready);
-                               }
-                       }
-
-                       if((self.crylink_waitrelease == 1 && !self.BUTTON_ATCK) || (self.crylink_waitrelease == 2 && !self.BUTTON_ATCK2))
-                       {
-                               if(!self.crylink_lastgroup || time > self.crylink_lastgroup.teleport_time)
-                               {
-                                       // fired and released now!
-                                       if(self.crylink_lastgroup)
-                                       {
-                                               vector pos;
-                                               entity linkjoineffect;
-                                               float isprimary = (self.crylink_waitrelease == 1);
-
-                                               pos = W_Crylink_LinkJoin(self.crylink_lastgroup, WEP_CVAR_BOTH(crylink, isprimary, joinspread) * WEP_CVAR_BOTH(crylink, isprimary, speed));
-
-                                               linkjoineffect = spawn();
-                                               linkjoineffect.think = W_Crylink_LinkJoinEffect_Think;
-                                               linkjoineffect.classname = "linkjoineffect";
-                                               linkjoineffect.nextthink = time + w_crylink_linkjoin_time;
-                                               linkjoineffect.owner = self;
-                                               setorigin(linkjoineffect, pos);
-                                       }
-                                       self.crylink_waitrelease = 0;
-                                       if(!W_Crylink(WR_CHECKAMMO1) && !W_Crylink(WR_CHECKAMMO2))
-                                       if(!(self.items & IT_UNLIMITED_WEAPON_AMMO))
-                                       {
-                                               // ran out of ammo!
-                                               self.cnt = WEP_CRYLINK.m_id;
-                                               self.switchweapon = w_getbestweapon(self);
-                                       }
-                               }
-                       }
-
-                       return true;
-               }
-               case WR_INIT:
-               {
-                       precache_model(W_Model("g_crylink.md3"));
-                       precache_model(W_Model("v_crylink.md3"));
-                       precache_model(W_Model("h_crylink.iqm"));
-                       precache_sound(W_Sound("crylink_fire"));
-                       precache_sound(W_Sound("crylink_fire2"));
-                       precache_sound(W_Sound("crylink_linkjoin"));
-                       CRYLINK_SETTINGS(WEP_SKIP_CVAR, WEP_SET_PROP);
-                       return true;
-               }
-               case WR_CHECKAMMO1:
-               {
-                       // don't "run out of ammo" and switch weapons while waiting for release
-                       if(self.crylink_lastgroup && self.crylink_waitrelease)
-                               return true;
-
-                       ammo_amount = self.WEP_AMMO(CRYLINK) >= WEP_CVAR_PRI(crylink, ammo);
-                       ammo_amount += self.(weapon_load[WEP_CRYLINK.m_id]) >= WEP_CVAR_PRI(crylink, ammo);
-                       return ammo_amount;
-               }
-               case WR_CHECKAMMO2:
-               {
-                       // don't "run out of ammo" and switch weapons while waiting for release
-                       if(self.crylink_lastgroup && self.crylink_waitrelease)
-                               return true;
-
-                       ammo_amount = self.WEP_AMMO(CRYLINK) >= WEP_CVAR_SEC(crylink, ammo);
-                       ammo_amount += self.(weapon_load[WEP_CRYLINK.m_id]) >= WEP_CVAR_SEC(crylink, ammo);
-                       return ammo_amount;
-               }
-               case WR_CONFIG:
-               {
-                       CRYLINK_SETTINGS(WEP_CONFIG_WRITE_CVARS, WEP_CONFIG_WRITE_PROPS);
-                       return true;
-               }
-               case WR_RELOAD:
-               {
-                       W_Reload(min(WEP_CVAR_PRI(crylink, ammo), WEP_CVAR_SEC(crylink, ammo)), W_Sound("reload"));
-                       return true;
-               }
-               case WR_SUICIDEMESSAGE:
-               {
-                       return WEAPON_CRYLINK_SUICIDE;
-               }
-               case WR_KILLMESSAGE:
-               {
-                       return WEAPON_CRYLINK_MURDER;
-               }
-       }
-       return false;
-}
-#endif
-#ifdef CSQC
-bool W_Crylink(int req)
-{
-       switch(req)
-       {
-               case WR_IMPACTEFFECT:
-               {
-                       vector org2;
-                       org2 = w_org + w_backoff * 2;
-                       if(w_deathtype & HITTYPE_SECONDARY)
-                       {
-                               pointparticles(particleeffectnum(EFFECT_CRYLINK_IMPACT2), org2, '0 0 0', 1);
-                               if(!w_issilent)
-                                       sound(self, CH_SHOTS, W_Sound("crylink_impact2"), VOL_BASE, ATTN_NORM);
-                       }
-                       else
-                       {
-                               pointparticles(particleeffectnum(EFFECT_CRYLINK_IMPACT), org2, '0 0 0', 1);
-                               if(!w_issilent)
-                                       sound(self, CH_SHOTS, W_Sound("crylink_impact"), VOL_BASE, ATTN_NORM);
-                       }
-
-                       return true;
-               }
-               case WR_INIT:
-               {
-                       precache_sound(W_Sound("crylink_impact2"));
-                       precache_sound(W_Sound("crylink_impact"));
-                       return true;
-               }
-               case WR_ZOOMRETICLE:
-               {
-                       // no weapon specific image for this weapon
-                       return false;
-               }
-       }
-       return false;
-}
-#endif
-#endif
diff --git a/qcsrc/common/weapons/w_devastator.qc b/qcsrc/common/weapons/w_devastator.qc
deleted file mode 100644 (file)
index 9a235bf..0000000
+++ /dev/null
@@ -1,687 +0,0 @@
-#ifndef IMPLEMENTATION
-REGISTER_WEAPON(
-/* WEP_##id  */ DEVASTATOR,
-/* function  */ W_Devastator,
-/* ammotype  */ ammo_rockets,
-/* impulse   */ 9,
-/* flags     */ WEP_FLAG_NORMAL | WEP_FLAG_RELOADABLE | WEP_FLAG_CANCLIMB | WEP_TYPE_SPLASH,
-/* rating    */ BOT_PICKUP_RATING_HIGH,
-/* color     */ '1 1 0',
-/* modelname */ "rl",
-/* simplemdl */ "foobar",
-/* crosshair */ "gfx/crosshairrocketlauncher 0.7",
-/* wepimg    */ "weaponrocketlauncher",
-/* refname   */ "devastator",
-/* wepname   */ _("Devastator")
-);
-
-#define DEVASTATOR_SETTINGS(w_cvar,w_prop) DEVASTATOR_SETTINGS_LIST(w_cvar, w_prop, DEVASTATOR, devastator)
-#define DEVASTATOR_SETTINGS_LIST(w_cvar,w_prop,id,sn) \
-       w_cvar(id, sn, NONE, ammo) \
-       w_cvar(id, sn, NONE, animtime) \
-       w_cvar(id, sn, NONE, damage) \
-       w_cvar(id, sn, NONE, damageforcescale) \
-       w_cvar(id, sn, NONE, detonatedelay) \
-       w_cvar(id, sn, NONE, edgedamage) \
-       w_cvar(id, sn, NONE, force) \
-       w_cvar(id, sn, NONE, guidedelay) \
-       w_cvar(id, sn, NONE, guidegoal) \
-       w_cvar(id, sn, NONE, guiderate) \
-       w_cvar(id, sn, NONE, guideratedelay) \
-       w_cvar(id, sn, NONE, guidestop) \
-       w_cvar(id, sn, NONE, health) \
-       w_cvar(id, sn, NONE, lifetime) \
-       w_cvar(id, sn, NONE, radius) \
-       w_cvar(id, sn, NONE, refire) \
-       w_cvar(id, sn, NONE, remote_damage) \
-       w_cvar(id, sn, NONE, remote_edgedamage) \
-       w_cvar(id, sn, NONE, remote_force) \
-       w_cvar(id, sn, NONE, remote_jump_damage) \
-       w_cvar(id, sn, NONE, remote_jump_radius) \
-       w_cvar(id, sn, NONE, remote_jump_velocity_z_add) \
-       w_cvar(id, sn, NONE, remote_jump_velocity_z_max) \
-       w_cvar(id, sn, NONE, remote_jump_velocity_z_min) \
-       w_cvar(id, sn, NONE, remote_radius) \
-       w_cvar(id, sn, NONE, speed) \
-       w_cvar(id, sn, NONE, speedaccel) \
-       w_cvar(id, sn, NONE, speedstart) \
-       w_prop(id, sn, float,  reloading_ammo, reload_ammo) \
-       w_prop(id, sn, float,  reloading_time, reload_time) \
-       w_prop(id, sn, float,  switchdelay_raise, switchdelay_raise) \
-       w_prop(id, sn, float,  switchdelay_drop, switchdelay_drop) \
-       w_prop(id, sn, string, weaponreplace, weaponreplace) \
-       w_prop(id, sn, float,  weaponstart, weaponstart) \
-       w_prop(id, sn, float,  weaponstartoverride, weaponstartoverride) \
-       w_prop(id, sn, float,  weaponthrowable, weaponthrowable)
-
-#ifdef SVQC
-DEVASTATOR_SETTINGS(WEP_ADD_CVAR, WEP_ADD_PROP)
-.float rl_release;
-.float rl_detonate_later;
-#endif
-#endif
-#ifdef IMPLEMENTATION
-#ifdef SVQC
-void spawnfunc_weapon_devastator(void) { weapon_defaultspawnfunc(WEP_DEVASTATOR.m_id); }
-void spawnfunc_weapon_rocketlauncher(void) { spawnfunc_weapon_devastator(); }
-
-void W_Devastator_Unregister(void)
-{
-       if(self.realowner && self.realowner.lastrocket == self)
-       {
-               self.realowner.lastrocket = world;
-               // self.realowner.rl_release = 1;
-       }
-}
-
-void W_Devastator_Explode(void)
-{
-       W_Devastator_Unregister();
-
-       if(other.takedamage == DAMAGE_AIM)
-               if(IS_PLAYER(other))
-                       if(DIFF_TEAM(self.realowner, other))
-                               if(other.deadflag == DEAD_NO)
-                                       if(IsFlying(other))
-                                               Send_Notification(NOTIF_ONE, self.realowner, MSG_ANNCE, ANNCE_ACHIEVEMENT_AIRSHOT);
-
-       self.event_damage = func_null;
-       self.takedamage = DAMAGE_NO;
-
-       RadiusDamage(
-               self,
-               self.realowner,
-               WEP_CVAR(devastator, damage),
-               WEP_CVAR(devastator, edgedamage),
-               WEP_CVAR(devastator, radius),
-               world,
-               world,
-               WEP_CVAR(devastator, force),
-               self.projectiledeathtype,
-               other
-       );
-
-       if(self.realowner.weapon == WEP_DEVASTATOR.m_id)
-       {
-               if(self.realowner.WEP_AMMO(DEVASTATOR) < WEP_CVAR(devastator, ammo))
-               if(!(self.realowner.items & IT_UNLIMITED_WEAPON_AMMO))
-               {
-                       self.realowner.cnt = WEP_DEVASTATOR.m_id;
-                       ATTACK_FINISHED(self.realowner) = time;
-                       self.realowner.switchweapon = w_getbestweapon(self.realowner);
-               }
-       }
-       remove(self);
-}
-
-void W_Devastator_DoRemoteExplode(void)
-{
-       W_Devastator_Unregister();
-
-       self.event_damage = func_null;
-       self.takedamage = DAMAGE_NO;
-
-       float handled_as_rocketjump = false;
-
-       entity head = WarpZone_FindRadius(
-               self.origin,
-               WEP_CVAR(devastator, remote_jump_radius),
-               false
-       );
-
-       while(head)
-       {
-               if(head.takedamage && (head == self.realowner))
-               {
-                       float distance_to_head = vlen(self.origin - head.WarpZone_findradius_nearest);
-                       if(distance_to_head <= WEP_CVAR(devastator, remote_jump_radius))
-                       {
-                               // we handled this as a rocketjump :)
-                               handled_as_rocketjump = true;
-
-                               // modify velocity
-                               head.velocity_x *= 0.9;
-                               head.velocity_y *= 0.9;
-                               head.velocity_z = bound(
-                                       WEP_CVAR(devastator, remote_jump_velocity_z_min),
-                                       head.velocity.z + WEP_CVAR(devastator, remote_jump_velocity_z_add),
-                                       WEP_CVAR(devastator, remote_jump_velocity_z_max)
-                               );
-
-                               // now do the damage
-                               RadiusDamage(
-                                       self,
-                                       head,
-                                       WEP_CVAR(devastator, remote_jump_damage),
-                                       WEP_CVAR(devastator, remote_jump_damage),
-                                       WEP_CVAR(devastator, remote_jump_radius),
-                                       world,
-                                       head,
-                                       0,
-                                       self.projectiledeathtype | HITTYPE_BOUNCE,
-                                       world
-                               );
-                               break;
-                       }
-               }
-               head = head.chain;
-       }
-
-       RadiusDamage(
-               self,
-               self.realowner,
-               WEP_CVAR(devastator, remote_damage),
-               WEP_CVAR(devastator, remote_edgedamage),
-               WEP_CVAR(devastator, remote_radius),
-               (handled_as_rocketjump ? head : world),
-               world,
-               WEP_CVAR(devastator, remote_force),
-               self.projectiledeathtype | HITTYPE_BOUNCE,
-               world
-       );
-
-       if(self.realowner.weapon == WEP_DEVASTATOR.m_id)
-       {
-               if(self.realowner.WEP_AMMO(DEVASTATOR) < WEP_CVAR(devastator, ammo))
-               if(!(self.realowner.items & IT_UNLIMITED_WEAPON_AMMO))
-               {
-                       self.realowner.cnt = WEP_DEVASTATOR.m_id;
-                       ATTACK_FINISHED(self.realowner) = time;
-                       self.realowner.switchweapon = w_getbestweapon(self.realowner);
-               }
-       }
-       remove(self);
-}
-
-void W_Devastator_RemoteExplode(void)
-{
-       if(self.realowner.deadflag == DEAD_NO)
-       if(self.realowner.lastrocket)
-       {
-               if((self.spawnshieldtime >= 0)
-                       ? (time >= self.spawnshieldtime) // timer
-                       : (vlen(NearestPointOnBox(self.realowner, self.origin) - self.origin) > WEP_CVAR(devastator, remote_radius)) // safety device
-               )
-               {
-                       W_Devastator_DoRemoteExplode();
-               }
-       }
-}
-
-vector W_Devastator_SteerTo(vector thisdir, vector goaldir, float maxturn_cos)
-{
-       if(thisdir * goaldir > maxturn_cos)
-               return goaldir;
-       if(thisdir * goaldir < -0.9998) // less than 1 degree and opposite
-               return thisdir; // refuse to guide (better than letting a numerical error happen)
-       float f, m2;
-       vector v;
-       // solve:
-       //   g = normalize(thisdir + goaldir * X)
-       //   thisdir * g = maxturn
-       //
-       //   gg = thisdir + goaldir * X
-       //   (thisdir * gg)^2 = maxturn^2 * (gg * gg)
-       //
-       //   (1 + (thisdir * goaldir) * X)^2 = maxturn^2 * (1 + X*X + 2 * X * thisdir * goaldir)
-       f = thisdir * goaldir;
-       //   (1 + f * X)^2 = maxturn^2 * (1 + X*X + 2 * X * f)
-       //   0 = (m^2 - f^2) * x^2 + (2 * f * (m^2 - 1)) * x + (m^2 - 1)
-       m2 = maxturn_cos * maxturn_cos;
-       v = solve_quadratic(m2 - f * f, 2 * f * (m2 - 1), m2 - 1);
-       return normalize(thisdir + goaldir * v.y); // the larger solution!
-}
-// assume thisdir == -goaldir:
-//   f == -1
-//   v = solve_qadratic(m2 - 1, -2 * (m2 - 1), m2 - 1)
-//   (m2 - 1) x^2 - 2 * (m2 - 1) * x + (m2 - 1) = 0
-//   x^2 - 2 * x + 1 = 0
-//   (x - 1)^2 = 0
-//   x = 1
-//   normalize(thisdir + goaldir)
-//   normalize(0)
-
-void W_Devastator_Think(void)
-{
-       vector desireddir, olddir, newdir, desiredorigin, goal;
-       float velspeed, f;
-       self.nextthink = time;
-       if(time > self.cnt)
-       {
-               other = world;
-               self.projectiledeathtype |= HITTYPE_BOUNCE;
-               W_Devastator_Explode();
-               return;
-       }
-
-       // accelerate
-       makevectors(self.angles.x * '-1 0 0' + self.angles.y * '0 1 0');
-       velspeed = WEP_CVAR(devastator, speed) * W_WeaponSpeedFactor() - (self.velocity * v_forward);
-       if(velspeed > 0)
-               self.velocity = self.velocity + v_forward * min(WEP_CVAR(devastator, speedaccel) * W_WeaponSpeedFactor() * frametime, velspeed);
-
-       // laser guided, or remote detonation
-       if(self.realowner.weapon == WEP_DEVASTATOR.m_id)
-       {
-               if(self == self.realowner.lastrocket)
-               if(!self.realowner.rl_release)
-               if(!self.BUTTON_ATCK2)
-               if(WEP_CVAR(devastator, guiderate))
-               if(time > self.pushltime)
-               if(self.realowner.deadflag == DEAD_NO)
-               {
-                       f = WEP_CVAR(devastator, guideratedelay);
-                       if(f)
-                               f = bound(0, (time - self.pushltime) / f, 1);
-                       else
-                               f = 1;
-
-                       velspeed = vlen(self.velocity);
-
-                       makevectors(self.realowner.v_angle);
-                       desireddir = WarpZone_RefSys_TransformVelocity(self.realowner, self, v_forward);
-                       desiredorigin = WarpZone_RefSys_TransformOrigin(self.realowner, self, self.realowner.origin + self.realowner.view_ofs);
-                       olddir = normalize(self.velocity);
-
-                       // now it gets tricky... we want to move like some curve to approximate the target direction
-                       // but we are limiting the rate at which we can turn!
-                       goal = desiredorigin + ((self.origin - desiredorigin) * desireddir + WEP_CVAR(devastator, guidegoal)) * desireddir;
-                       newdir = W_Devastator_SteerTo(olddir, normalize(goal - self.origin), cos(WEP_CVAR(devastator, guiderate) * f * frametime * DEG2RAD));
-
-                       self.velocity = newdir * velspeed;
-                       self.angles = vectoangles(self.velocity);
-
-                       if(!self.count)
-                       {
-                               Send_Effect(EFFECT_ROCKET_GUIDE, self.origin, self.velocity, 1);
-                               // TODO add a better sound here
-                               sound(self.realowner, CH_WEAPON_B, W_Sound("rocket_mode"), VOL_BASE, ATTN_NORM);
-                               self.count = 1;
-                       }
-               }
-
-               if(self.rl_detonate_later)
-                       W_Devastator_RemoteExplode();
-       }
-
-       if(self.csqcprojectile_clientanimate == 0)
-               UpdateCSQCProjectile(self);
-}
-
-void W_Devastator_Touch(void)
-{
-       if(WarpZone_Projectile_Touch())
-       {
-               if(wasfreed(self))
-                       W_Devastator_Unregister();
-               return;
-       }
-       W_Devastator_Unregister();
-       W_Devastator_Explode();
-}
-
-void W_Devastator_Damage(entity inflictor, entity attacker, float damage, int deathtype, vector hitloc, vector force)
-{
-       if(self.health <= 0)
-               return;
-
-       if(!W_CheckProjectileDamage(inflictor.realowner, self.realowner, deathtype, -1)) // no exceptions
-               return; // g_projectiles_damage says to halt
-
-       self.health = self.health - damage;
-       self.angles = vectoangles(self.velocity);
-
-       if(self.health <= 0)
-               W_PrepareExplosionByDamage(attacker, W_Devastator_Explode);
-}
-
-void W_Devastator_Attack(void)
-{
-       entity missile;
-       entity flash;
-
-       W_DecreaseAmmo(WEP_CVAR(devastator, ammo));
-
-       W_SetupShot_ProjectileSize(self, '-3 -3 -3', '3 3 3', false, 5, W_Sound("rocket_fire"), CH_WEAPON_A, WEP_CVAR(devastator, damage));
-       Send_Effect(EFFECT_ROCKET_MUZZLEFLASH, w_shotorg, w_shotdir * 1000, 1);
-
-       missile = WarpZone_RefSys_SpawnSameRefSys(self);
-       missile.owner = missile.realowner = self;
-       self.lastrocket = missile;
-       if(WEP_CVAR(devastator, detonatedelay) >= 0)
-               missile.spawnshieldtime = time + WEP_CVAR(devastator, detonatedelay);
-       else
-               missile.spawnshieldtime = -1;
-       missile.pushltime = time + WEP_CVAR(devastator, guidedelay);
-       missile.classname = "rocket";
-       missile.bot_dodge = true;
-       missile.bot_dodgerating = WEP_CVAR(devastator, damage) * 2; // * 2 because it can be detonated inflight which makes it even more dangerous
-
-       missile.takedamage = DAMAGE_YES;
-       missile.damageforcescale = WEP_CVAR(devastator, damageforcescale);
-       missile.health = WEP_CVAR(devastator, health);
-       missile.event_damage = W_Devastator_Damage;
-       missile.damagedbycontents = true;
-
-       missile.movetype = MOVETYPE_FLY;
-       PROJECTILE_MAKETRIGGER(missile);
-       missile.projectiledeathtype = WEP_DEVASTATOR.m_id;
-       setsize(missile, '-3 -3 -3', '3 3 3'); // give it some size so it can be shot
-
-       setorigin(missile, w_shotorg - v_forward * 3); // move it back so it hits the wall at the right point
-       W_SetupProjVelocity_Basic(missile, WEP_CVAR(devastator, speedstart), 0);
-       missile.angles = vectoangles(missile.velocity);
-
-       missile.touch = W_Devastator_Touch;
-       missile.think = W_Devastator_Think;
-       missile.nextthink = time;
-       missile.cnt = time + WEP_CVAR(devastator, lifetime);
-       missile.flags = FL_PROJECTILE;
-       missile.missile_flags = MIF_SPLASH;
-
-       CSQCProjectile(missile, WEP_CVAR(devastator, guiderate) == 0 && WEP_CVAR(devastator, speedaccel) == 0, PROJECTILE_ROCKET, false); // because of fly sound
-
-       // muzzle flash for 1st person view
-       flash = spawn();
-       setmodel(flash, "models/flash.md3"); // precision set below
-       SUB_SetFade(flash, time, 0.1);
-       flash.effects = EF_ADDITIVE | EF_FULLBRIGHT | EF_LOWPRECISION;
-       W_AttachToShotorg(flash, '5 0 0');
-
-       // common properties
-       MUTATOR_CALLHOOK(EditProjectile, self, missile);
-}
-
-bool W_Devastator(int req)
-{
-       entity rock;
-       float rockfound;
-       float ammo_amount;
-       switch(req)
-       {
-               #if 0
-               case WR_AIM:
-               {
-                       // aim and decide to fire if appropriate
-                       self.BUTTON_ATCK = bot_aim(WEP_CVAR(devastator, speed), 0, WEP_CVAR(devastator, lifetime), false);
-                       if(skill >= 2) // skill 0 and 1 bots won't detonate rockets!
-                       {
-                               // decide whether to detonate rockets
-                               entity missile, targetlist, targ;
-                               targetlist = findchainfloat(bot_attack, true);
-                               for(missile = world; (missile = find(missile, classname, "rocket")); ) if(missile.realowner == self)
-                               {
-                                       targ = targetlist;
-                                       while(targ)
-                                       {
-                                               if(targ != missile.realowner && vlen(targ.origin - missile.origin) < WEP_CVAR(devastator, radius))
-                                               {
-                                                       self.BUTTON_ATCK2 = true;
-                                                       break;
-                                               }
-                                               targ = targ.chain;
-                                       }
-                               }
-
-                               if(self.BUTTON_ATCK2) self.BUTTON_ATCK = false;
-                       }
-
-                       return true;
-               }
-               #else
-               case WR_AIM:
-               {
-                       // aim and decide to fire if appropriate
-                       self.BUTTON_ATCK = bot_aim(WEP_CVAR(devastator, speed), 0, WEP_CVAR(devastator, lifetime), false);
-                       if(skill >= 2) // skill 0 and 1 bots won't detonate rockets!
-                       {
-                               // decide whether to detonate rockets
-                               entity missile, targetlist, targ;
-                               float edgedamage, coredamage, edgeradius, recipricoledgeradius, d;
-                               float selfdamage, teamdamage, enemydamage;
-                               edgedamage = WEP_CVAR(devastator, edgedamage);
-                               coredamage = WEP_CVAR(devastator, damage);
-                               edgeradius = WEP_CVAR(devastator, radius);
-                               recipricoledgeradius = 1 / edgeradius;
-                               selfdamage = 0;
-                               teamdamage = 0;
-                               enemydamage = 0;
-                               targetlist = findchainfloat(bot_attack, true);
-                               missile = find(world, classname, "rocket");
-                               while(missile)
-                               {
-                                       if(missile.realowner != self)
-                                       {
-                                               missile = find(missile, classname, "rocket");
-                                               continue;
-                                       }
-                                       targ = targetlist;
-                                       while(targ)
-                                       {
-                                               d = vlen(targ.origin + (targ.mins + targ.maxs) * 0.5 - missile.origin);
-                                               d = bound(0, edgedamage + (coredamage - edgedamage) * sqrt(1 - d * recipricoledgeradius), 10000);
-                                               // count potential damage according to type of target
-                                               if(targ == self)
-                                                       selfdamage = selfdamage + d;
-                                               else if(targ.team == self.team && teamplay)
-                                                       teamdamage = teamdamage + d;
-                                               else if(bot_shouldattack(targ))
-                                                       enemydamage = enemydamage + d;
-                                               targ = targ.chain;
-                                       }
-                                       missile = find(missile, classname, "rocket");
-                               }
-                               float desirabledamage;
-                               desirabledamage = enemydamage;
-                               if(time > self.invincible_finished && time > self.spawnshieldtime)
-                                       desirabledamage = desirabledamage - selfdamage * autocvar_g_balance_selfdamagepercent;
-                               if(teamplay && self.team)
-                                       desirabledamage = desirabledamage - teamdamage;
-
-                               missile = find(world, classname, "rocket");
-                               while(missile)
-                               {
-                                       if(missile.realowner != self)
-                                       {
-                                               missile = find(missile, classname, "rocket");
-                                               continue;
-                                       }
-                                       makevectors(missile.v_angle);
-                                       targ = targetlist;
-                                       if(skill > 9) // normal players only do this for the target they are tracking
-                                       {
-                                               targ = targetlist;
-                                               while(targ)
-                                               {
-                                                       if(
-                                                               (v_forward * normalize(missile.origin - targ.origin)< 0.1)
-                                                               && desirabledamage > 0.1*coredamage
-                                                       )self.BUTTON_ATCK2 = true;
-                                                       targ = targ.chain;
-                                               }
-                                       }else{
-                                               float distance; distance= bound(300,vlen(self.origin-self.enemy.origin),30000);
-                                               //As the distance gets larger, a correct detonation gets near imposible
-                                               //Bots are assumed to use the rocket spawnfunc_light to see if the rocket gets near a player
-                                               if(v_forward * normalize(missile.origin - self.enemy.origin)< 0.1)
-                                                       if(IS_PLAYER(self.enemy))
-                                                               if(desirabledamage >= 0.1*coredamage)
-                                                                       if(random()/distance*300 > frametime*bound(0,(10-skill)*0.2,1))
-                                                                               self.BUTTON_ATCK2 = true;
-                                       //      dprint(ftos(random()/distance*300),">");dprint(ftos(frametime*bound(0,(10-skill)*0.2,1)),"\n");
-                                       }
-
-                                       missile = find(missile, classname, "rocket");
-                               }
-                               // if we would be doing at X percent of the core damage, detonate it
-                               // but don't fire a new shot at the same time!
-                               if(desirabledamage >= 0.75 * coredamage) //this should do group damage in rare fortunate events
-                                       self.BUTTON_ATCK2 = true;
-                               if((skill > 6.5) && (selfdamage > self.health))
-                                       self.BUTTON_ATCK2 = false;
-                               //if(self.BUTTON_ATCK2 == true)
-                               //      dprint(ftos(desirabledamage),"\n");
-                               if(self.BUTTON_ATCK2 == true) self.BUTTON_ATCK = false;
-                       }
-
-                       return true;
-               }
-               #endif
-               case WR_THINK:
-               {
-                       if(WEP_CVAR(devastator, reload_ammo) && self.clip_load < WEP_CVAR(devastator, ammo)) // forced reload
-                               WEP_ACTION(self.weapon, WR_RELOAD);
-                       else
-                       {
-                               if(self.BUTTON_ATCK)
-                               {
-                                       if(self.rl_release || WEP_CVAR(devastator, guidestop))
-                                       if(weapon_prepareattack(0, WEP_CVAR(devastator, refire)))
-                                       {
-                                               W_Devastator_Attack();
-                                               weapon_thinkf(WFRAME_FIRE1, WEP_CVAR(devastator, animtime), w_ready);
-                                               self.rl_release = 0;
-                                       }
-                               }
-                               else
-                                       self.rl_release = 1;
-
-                               if(self.BUTTON_ATCK2)
-                               if(self.switchweapon == WEP_DEVASTATOR.m_id)
-                               {
-                                       rockfound = 0;
-                                       for(rock = world; (rock = find(rock, classname, "rocket")); ) if(rock.realowner == self)
-                                       {
-                                               if(!rock.rl_detonate_later)
-                                               {
-                                                       rock.rl_detonate_later = true;
-                                                       rockfound = 1;
-                                               }
-                                       }
-                                       if(rockfound)
-                                               sound(self, CH_WEAPON_B, W_Sound("rocket_det"), VOL_BASE, ATTN_NORM);
-                               }
-                       }
-
-                       return true;
-               }
-               case WR_INIT:
-               {
-                       //if(autocvar_sv_precacheweapons)
-                       //{
-                               precache_model("models/flash.md3");
-                               precache_model(W_Model("g_rl.md3"));
-                               precache_model(W_Model("v_rl.md3"));
-                               precache_model(W_Model("h_rl.iqm"));
-                               precache_sound(W_Sound("rocket_det"));
-                               precache_sound(W_Sound("rocket_fire"));
-                               precache_sound(W_Sound("rocket_mode"));
-                       //}
-                       DEVASTATOR_SETTINGS(WEP_SKIP_CVAR, WEP_SET_PROP);
-                       return true;
-               }
-               case WR_SETUP:
-               {
-                       self.rl_release = 1;
-                       return true;
-               }
-               case WR_CHECKAMMO1:
-               {
-                       #if 0
-                       // don't switch while guiding a missile
-                       if(ATTACK_FINISHED(self) <= time || self.weapon != WEP_DEVASTATOR.m_id)
-                       {
-                               ammo_amount = false;
-                               if(WEP_CVAR(devastator, reload_ammo))
-                               {
-                                       if(self.WEP_AMMO(DEVASTATOR) < WEP_CVAR(devastator, ammo) && self.(weapon_load[WEP_DEVASTATOR.m_id]) < WEP_CVAR(devastator, ammo))
-                                               ammo_amount = true;
-                               }
-                               else if(self.WEP_AMMO(DEVASTATOR) < WEP_CVAR(devastator, ammo))
-                                       ammo_amount = true;
-                               return !ammo_amount;
-                       }
-                       #endif
-                       #if 0
-                       if(self.rl_release == 0)
-                       {
-                               LOG_INFOF("W_Devastator(WR_CHECKAMMO1): %d, %.2f, %d: TRUE\n", self.rl_release, self.WEP_AMMO(DEVASTATOR), WEP_CVAR(devastator, ammo));
-                               return true;
-                       }
-                       else
-                       {
-                               ammo_amount = self.WEP_AMMO(DEVASTATOR) >= WEP_CVAR(devastator, ammo);
-                               ammo_amount += self.(weapon_load[WEP_DEVASTATOR.m_id]) >= WEP_CVAR(devastator, ammo);
-                               LOG_INFOF("W_Devastator(WR_CHECKAMMO1): %d, %.2f, %d: %s\n", self.rl_release, self.WEP_AMMO(DEVASTATOR), WEP_CVAR(devastator, ammo), (ammo_amount ? "TRUE" : "FALSE"));
-                               return ammo_amount;
-                       }
-                       #else
-                       ammo_amount = self.WEP_AMMO(DEVASTATOR) >= WEP_CVAR(devastator, ammo);
-                       ammo_amount += self.(weapon_load[WEP_DEVASTATOR.m_id]) >= WEP_CVAR(devastator, ammo);
-                       return ammo_amount;
-                       #endif
-               }
-               case WR_CHECKAMMO2:
-               {
-                       return false;
-               }
-               case WR_CONFIG:
-               {
-                       DEVASTATOR_SETTINGS(WEP_CONFIG_WRITE_CVARS, WEP_CONFIG_WRITE_PROPS);
-                       return true;
-               }
-               case WR_RESETPLAYER:
-               {
-                       self.rl_release = 0;
-                       return true;
-               }
-               case WR_RELOAD:
-               {
-                       W_Reload(WEP_CVAR(devastator, ammo), W_Sound("reload"));
-                       return true;
-               }
-               case WR_SUICIDEMESSAGE:
-               {
-                       return WEAPON_DEVASTATOR_SUICIDE;
-               }
-               case WR_KILLMESSAGE:
-               {
-                       if((w_deathtype & HITTYPE_BOUNCE) || (w_deathtype & HITTYPE_SPLASH))
-                               return WEAPON_DEVASTATOR_MURDER_SPLASH;
-                       else
-                               return WEAPON_DEVASTATOR_MURDER_DIRECT;
-               }
-       }
-       return false;
-}
-#endif
-#ifdef CSQC
-bool W_Devastator(int req)
-{
-       switch(req)
-       {
-               case WR_IMPACTEFFECT:
-               {
-                       vector org2;
-                       org2 = w_org + w_backoff * 12;
-                       pointparticles(particleeffectnum(EFFECT_ROCKET_EXPLODE), org2, '0 0 0', 1);
-                       if(!w_issilent)
-                               sound(self, CH_SHOTS, W_Sound("rocket_impact"), VOL_BASE, ATTN_NORM);
-
-                       return true;
-               }
-               case WR_INIT:
-               {
-                       precache_sound(W_Sound("rocket_impact"));
-                       return true;
-               }
-               case WR_ZOOMRETICLE:
-               {
-                       // no weapon specific image for this weapon
-                       return false;
-               }
-       }
-       return false;
-}
-#endif
-#endif
diff --git a/qcsrc/common/weapons/w_electro.qc b/qcsrc/common/weapons/w_electro.qc
deleted file mode 100644 (file)
index 0f60fd2..0000000
+++ /dev/null
@@ -1,621 +0,0 @@
-#ifndef IMPLEMENTATION
-REGISTER_WEAPON(
-/* WEP_##id  */ ELECTRO,
-/* function  */ W_Electro,
-/* ammotype  */ ammo_cells,
-/* impulse   */ 5,
-/* flags     */ WEP_FLAG_NORMAL | WEP_FLAG_RELOADABLE | WEP_FLAG_CANCLIMB | WEP_TYPE_SPLASH,
-/* rating    */ BOT_PICKUP_RATING_MID,
-/* color     */ '0 0.5 1',
-/* modelname */ "electro",
-/* simplemdl */ "foobar",
-/* crosshair */ "gfx/crosshairelectro 0.6",
-/* wepimg    */ "weaponelectro",
-/* refname   */ "electro",
-/* wepname   */ _("Electro")
-);
-
-#define ELECTRO_SETTINGS(w_cvar,w_prop) ELECTRO_SETTINGS_LIST(w_cvar, w_prop, ELECTRO, electro)
-#define ELECTRO_SETTINGS_LIST(w_cvar,w_prop,id,sn) \
-       w_cvar(id, sn, BOTH, ammo) \
-       w_cvar(id, sn, BOTH, animtime) \
-       w_cvar(id, sn, BOTH, damage) \
-       w_cvar(id, sn, BOTH, edgedamage) \
-       w_cvar(id, sn, BOTH, force) \
-       w_cvar(id, sn, BOTH, radius) \
-       w_cvar(id, sn, BOTH, refire) \
-       w_cvar(id, sn, BOTH, speed) \
-       w_cvar(id, sn, BOTH, spread) \
-       w_cvar(id, sn, BOTH, lifetime) \
-       w_cvar(id, sn, PRI,  comboradius) \
-       w_cvar(id, sn, PRI,  midaircombo_explode) \
-       w_cvar(id, sn, PRI,  midaircombo_interval) \
-       w_cvar(id, sn, PRI,  midaircombo_radius) \
-       w_cvar(id, sn, SEC,  bouncefactor) \
-       w_cvar(id, sn, SEC,  bouncestop) \
-       w_cvar(id, sn, SEC,  count) \
-       w_cvar(id, sn, SEC,  damageforcescale) \
-       w_cvar(id, sn, SEC,  damagedbycontents) \
-       w_cvar(id, sn, SEC,  health) \
-       w_cvar(id, sn, SEC,  refire2) \
-       w_cvar(id, sn, SEC,  speed_up) \
-       w_cvar(id, sn, SEC,  speed_z) \
-       w_cvar(id, sn, SEC,  touchexplode) \
-       w_cvar(id, sn, NONE, combo_comboradius) \
-       w_cvar(id, sn, NONE, combo_comboradius_thruwall) \
-       w_cvar(id, sn, NONE, combo_damage) \
-       w_cvar(id, sn, NONE, combo_edgedamage) \
-       w_cvar(id, sn, NONE, combo_force) \
-       w_cvar(id, sn, NONE, combo_radius) \
-       w_cvar(id, sn, NONE, combo_speed) \
-       w_cvar(id, sn, NONE, combo_safeammocheck) \
-       w_prop(id, sn, float,  reloading_ammo, reload_ammo) \
-       w_prop(id, sn, float,  reloading_time, reload_time) \
-       w_prop(id, sn, float,  switchdelay_raise, switchdelay_raise) \
-       w_prop(id, sn, float,  switchdelay_drop, switchdelay_drop) \
-       w_prop(id, sn, string, weaponreplace, weaponreplace) \
-       w_prop(id, sn, float,  weaponstart, weaponstart) \
-       w_prop(id, sn, float,  weaponstartoverride, weaponstartoverride) \
-       w_prop(id, sn, float,  weaponthrowable, weaponthrowable)
-
-#ifdef SVQC
-ELECTRO_SETTINGS(WEP_ADD_CVAR, WEP_ADD_PROP)
-.float electro_count;
-.float electro_secondarytime;
-void W_Electro_ExplodeCombo(void);
-#endif
-#endif
-#ifdef IMPLEMENTATION
-#ifdef SVQC
-void spawnfunc_weapon_electro(void) { weapon_defaultspawnfunc(WEP_ELECTRO.m_id); }
-
-void W_Electro_TriggerCombo(vector org, float rad, entity own)
-{
-       entity e = WarpZone_FindRadius(org, rad, !WEP_CVAR(electro, combo_comboradius_thruwall));
-       while(e)
-       {
-               if(e.classname == "electro_orb")
-               {
-                       // do we allow thruwall triggering?
-                       if(WEP_CVAR(electro, combo_comboradius_thruwall))
-                       {
-                               // if distance is greater than thruwall distance, check to make sure it's not through a wall
-                               if(vlen(e.WarpZone_findradius_dist) > WEP_CVAR(electro, combo_comboradius_thruwall))
-                               {
-                                       WarpZone_TraceLine(org, e.origin, MOVE_NOMONSTERS, e);
-                                       if(trace_fraction != 1)
-                                       {
-                                               // trigger is through a wall and outside of thruwall range, abort
-                                               e = e.chain;
-                                               continue;
-                                       }
-                               }
-                       }
-
-                       // change owner to whoever caused the combo explosion
-                       e.realowner = own;
-                       e.takedamage = DAMAGE_NO;
-                       e.classname = "electro_orb_chain";
-
-                       // now set the next one to trigger as well
-                       e.think = W_Electro_ExplodeCombo;
-
-                       // delay combo chains, looks cooler
-                       e.nextthink =
-                               (
-                                       time
-                                       +
-                                       (WEP_CVAR(electro, combo_speed) ?
-                                               (vlen(e.WarpZone_findradius_dist) / WEP_CVAR(electro, combo_speed))
-                                               :
-                                               0
-                                       )
-                               );
-               }
-               e = e.chain;
-       }
-}
-
-void W_Electro_ExplodeCombo(void)
-{
-       W_Electro_TriggerCombo(self.origin, WEP_CVAR(electro, combo_comboradius), self.realowner);
-
-       self.event_damage = func_null;
-
-       RadiusDamage(
-               self,
-               self.realowner,
-               WEP_CVAR(electro, combo_damage),
-               WEP_CVAR(electro, combo_edgedamage),
-               WEP_CVAR(electro, combo_radius),
-               world,
-               world,
-               WEP_CVAR(electro, combo_force),
-               WEP_ELECTRO.m_id | HITTYPE_BOUNCE, // use THIS type for a combo because primary can't bounce
-               world
-       );
-
-       remove(self);
-}
-
-void W_Electro_Explode(void)
-{
-       if(other.takedamage == DAMAGE_AIM)
-               if(IS_PLAYER(other))
-                       if(DIFF_TEAM(self.realowner, other))
-                               if(other.deadflag == DEAD_NO)
-                                       if(IsFlying(other))
-                                               Send_Notification(NOTIF_ONE, self.realowner, MSG_ANNCE, ANNCE_ACHIEVEMENT_ELECTROBITCH);
-
-       self.event_damage = func_null;
-       self.takedamage = DAMAGE_NO;
-
-       if(self.movetype == MOVETYPE_BOUNCE)
-       {
-               RadiusDamage(
-                       self,
-                       self.realowner,
-                       WEP_CVAR_SEC(electro, damage),
-                       WEP_CVAR_SEC(electro, edgedamage),
-                       WEP_CVAR_SEC(electro, radius),
-                       world,
-                       world,
-                       WEP_CVAR_SEC(electro, force),
-                       self.projectiledeathtype,
-                       other
-               );
-       }
-       else
-       {
-               W_Electro_TriggerCombo(self.origin, WEP_CVAR_PRI(electro, comboradius), self.realowner);
-               RadiusDamage(
-                       self,
-                       self.realowner,
-                       WEP_CVAR_PRI(electro, damage),
-                       WEP_CVAR_PRI(electro, edgedamage),
-                       WEP_CVAR_PRI(electro, radius),
-                       world,
-                       world,
-                       WEP_CVAR_PRI(electro, force),
-                       self.projectiledeathtype,
-                       other
-               );
-       }
-
-       remove(self);
-}
-
-void W_Electro_TouchExplode(void)
-{
-       PROJECTILE_TOUCH;
-       W_Electro_Explode();
-}
-
-void W_Electro_Bolt_Think(void)
-{
-       if(time >= self.ltime)
-       {
-               self.use();
-               return;
-       }
-
-       if(WEP_CVAR_PRI(electro, midaircombo_radius))
-       {
-               float found = 0;
-               entity e = WarpZone_FindRadius(self.origin, WEP_CVAR_PRI(electro, midaircombo_radius), true);
-
-               // loop through nearby orbs and trigger them
-               while(e)
-               {
-                       if(e.classname == "electro_orb")
-                       {
-                               // change owner to whoever caused the combo explosion
-                               e.realowner = self.realowner;
-                               e.takedamage = DAMAGE_NO;
-                               e.classname = "electro_orb_chain";
-
-                               // now set the next one to trigger as well
-                               e.think = W_Electro_ExplodeCombo;
-
-                               // delay combo chains, looks cooler
-                               e.nextthink =
-                                       (
-                                               time
-                                               +
-                                               (WEP_CVAR(electro, combo_speed) ?
-                                                       (vlen(e.WarpZone_findradius_dist) / WEP_CVAR(electro, combo_speed))
-                                                       :
-                                                       0
-                                               )
-                                       );
-
-                               ++found;
-                       }
-                       e = e.chain;
-               }
-
-               // if we triggered an orb, should we explode? if not, lets try again next time
-               if(found && WEP_CVAR_PRI(electro, midaircombo_explode))
-                       { self.use(); }
-               else
-                       { self.nextthink = min(time + WEP_CVAR_PRI(electro, midaircombo_interval), self.ltime); }
-       }
-       else { self.nextthink = self.ltime; }
-}
-
-void W_Electro_Attack_Bolt(void)
-{
-       entity proj;
-
-       W_DecreaseAmmo(WEP_CVAR_PRI(electro, ammo));
-
-       W_SetupShot_ProjectileSize(
-               self,
-               '0 0 -3',
-               '0 0 -3',
-               false,
-               2,
-               W_Sound("electro_fire"),
-               CH_WEAPON_A,
-               WEP_CVAR_PRI(electro, damage)
-       );
-
-       Send_Effect(EFFECT_ELECTRO_MUZZLEFLASH, w_shotorg, w_shotdir * 1000, 1);
-
-       proj = spawn();
-       proj.classname = "electro_bolt";
-       proj.owner = proj.realowner = self;
-       proj.bot_dodge = true;
-       proj.bot_dodgerating = WEP_CVAR_PRI(electro, damage);
-       proj.use = W_Electro_Explode;
-       proj.think = W_Electro_Bolt_Think;
-       proj.nextthink = time;
-       proj.ltime = time + WEP_CVAR_PRI(electro, lifetime);
-       PROJECTILE_MAKETRIGGER(proj);
-       proj.projectiledeathtype = WEP_ELECTRO.m_id;
-       setorigin(proj, w_shotorg);
-
-       proj.movetype = MOVETYPE_FLY;
-       W_SetupProjVelocity_PRI(proj, electro);
-       proj.angles = vectoangles(proj.velocity);
-       proj.touch = W_Electro_TouchExplode;
-       setsize(proj, '0 0 -3', '0 0 -3');
-       proj.flags = FL_PROJECTILE;
-       proj.missile_flags = MIF_SPLASH;
-
-       CSQCProjectile(proj, true, PROJECTILE_ELECTRO_BEAM, true);
-
-       MUTATOR_CALLHOOK(EditProjectile, self, proj);
-}
-
-void W_Electro_Orb_Touch(void)
-{
-       PROJECTILE_TOUCH;
-       if(other.takedamage == DAMAGE_AIM)
-               { if(WEP_CVAR_SEC(electro, touchexplode)) { W_Electro_Explode(); } }
-       else
-       {
-               //UpdateCSQCProjectile(self);
-               spamsound(self, CH_SHOTS, W_Sound("electro_bounce"), VOL_BASE, ATTEN_NORM);
-               self.projectiledeathtype |= HITTYPE_BOUNCE;
-       }
-}
-
-void W_Electro_Orb_Damage(entity inflictor, entity attacker, float damage, int deathtype, vector hitloc, vector force)
-{
-       if(self.health <= 0)
-               return;
-
-       // note: combos are usually triggered by W_Electro_TriggerCombo, not damage
-       float is_combo = (inflictor.classname == "electro_orb_chain" || inflictor.classname == "electro_bolt");
-
-       if(!W_CheckProjectileDamage(inflictor.realowner, self.realowner, deathtype, (is_combo ? 1 : -1)))
-               return; // g_projectiles_damage says to halt
-
-       self.health = self.health - damage;
-       if(self.health <= 0)
-       {
-               self.takedamage = DAMAGE_NO;
-               self.nextthink = time;
-               if(is_combo)
-               {
-                       // change owner to whoever caused the combo explosion
-                       self.realowner = inflictor.realowner;
-                       self.classname = "electro_orb_chain";
-                       self.think = W_Electro_ExplodeCombo;
-                       self.nextthink = time +
-                               (
-                                       // bound the length, inflictor may be in a galaxy far far away (warpzones)
-                                       min(
-                                               WEP_CVAR(electro, combo_radius),
-                                               vlen(self.origin - inflictor.origin)
-                                       )
-                                       /
-                                       // delay combo chains, looks cooler
-                                       WEP_CVAR(electro, combo_speed)
-                               );
-               }
-               else
-               {
-                       self.use = W_Electro_Explode;
-                       self.think = adaptor_think2use; // not _hittype_splash, as this runs "immediately"
-               }
-       }
-}
-
-void W_Electro_Attack_Orb(void)
-{
-       W_DecreaseAmmo(WEP_CVAR_SEC(electro, ammo));
-
-       W_SetupShot_ProjectileSize(
-               self,
-               '0 0 -4',
-               '0 0 -4',
-               false,
-               2,
-               W_Sound("electro_fire2"),
-               CH_WEAPON_A,
-               WEP_CVAR_SEC(electro, damage)
-       );
-
-       w_shotdir = v_forward; // no TrueAim for grenades please
-
-       Send_Effect(EFFECT_ELECTRO_MUZZLEFLASH, w_shotorg, w_shotdir * 1000, 1);
-
-       entity proj = spawn();
-       proj.classname = "electro_orb";
-       proj.owner = proj.realowner = self;
-       proj.use = W_Electro_Explode;
-       proj.think = adaptor_think2use_hittype_splash;
-       proj.bot_dodge = true;
-       proj.bot_dodgerating = WEP_CVAR_SEC(electro, damage);
-       proj.nextthink = time + WEP_CVAR_SEC(electro, lifetime);
-       PROJECTILE_MAKETRIGGER(proj);
-       proj.projectiledeathtype = WEP_ELECTRO.m_id | HITTYPE_SECONDARY;
-       setorigin(proj, w_shotorg);
-
-       //proj.glow_size = 50;
-       //proj.glow_color = 45;
-       proj.movetype = MOVETYPE_BOUNCE;
-       W_SetupProjVelocity_UP_SEC(proj, electro);
-       proj.touch = W_Electro_Orb_Touch;
-       setsize(proj, '0 0 -4', '0 0 -4');
-       proj.takedamage = DAMAGE_YES;
-       proj.damageforcescale = WEP_CVAR_SEC(electro, damageforcescale);
-       proj.health = WEP_CVAR_SEC(electro, health);
-       proj.event_damage = W_Electro_Orb_Damage;
-       proj.flags = FL_PROJECTILE;
-       proj.damagedbycontents = (WEP_CVAR_SEC(electro, damagedbycontents));
-
-       proj.bouncefactor = WEP_CVAR_SEC(electro, bouncefactor);
-       proj.bouncestop = WEP_CVAR_SEC(electro, bouncestop);
-       proj.missile_flags = MIF_SPLASH | MIF_ARC;
-
-#if 0
-       entity p2;
-       p2 = spawn();
-       copyentity(proj, p2);
-       setmodel(p2, "models/ebomb.mdl");
-       setsize(p2, proj.mins, proj.maxs);
-#endif
-
-       CSQCProjectile(proj, true, PROJECTILE_ELECTRO, false); // no culling, it has sound
-
-       MUTATOR_CALLHOOK(EditProjectile, self, proj);
-}
-
-void W_Electro_CheckAttack(void)
-{
-       if(self.electro_count > 1)
-       if(self.BUTTON_ATCK2)
-       if(weapon_prepareattack(1, -1))
-       {
-               W_Electro_Attack_Orb();
-               self.electro_count -= 1;
-               weapon_thinkf(WFRAME_FIRE2, WEP_CVAR_SEC(electro, animtime), W_Electro_CheckAttack);
-               return;
-       }
-       // WEAPONTODO: when the player releases the button, cut down the length of refire2?
-       w_ready();
-}
-
-.float bot_secondary_electromooth;
-bool W_Electro(int req)
-{
-       float ammo_amount;
-       switch(req)
-       {
-               case WR_AIM:
-               {
-                       self.BUTTON_ATCK = self.BUTTON_ATCK2 = false;
-                       if(vlen(self.origin-self.enemy.origin) > 1000) { self.bot_secondary_electromooth = 0; }
-                       if(self.bot_secondary_electromooth == 0)
-                       {
-                               float shoot;
-
-                               if(WEP_CVAR_PRI(electro, speed))
-                                       shoot = bot_aim(WEP_CVAR_PRI(electro, speed), 0, WEP_CVAR_PRI(electro, lifetime), false);
-                               else
-                                       shoot = bot_aim(1000000, 0, 0.001, false);
-
-                               if(shoot)
-                               {
-                                       self.BUTTON_ATCK = true;
-                                       if(random() < 0.01) self.bot_secondary_electromooth = 1;
-                               }
-                       }
-                       else
-                       {
-                               if(bot_aim(WEP_CVAR_SEC(electro, speed), WEP_CVAR_SEC(electro, speed_up), WEP_CVAR_SEC(electro, lifetime), true))
-                               {
-                                       self.BUTTON_ATCK2 = true;
-                                       if(random() < 0.03) self.bot_secondary_electromooth = 0;
-                               }
-                       }
-
-                       return true;
-               }
-               case WR_THINK:
-               {
-                       if(autocvar_g_balance_electro_reload_ammo) // forced reload // WEAPONTODO
-                       {
-                               ammo_amount = 0;
-                               if(self.clip_load >= WEP_CVAR_PRI(electro, ammo))
-                                       ammo_amount = 1;
-                               if(self.clip_load >= WEP_CVAR_SEC(electro, ammo))
-                                       ammo_amount += 1;
-
-                               if(!ammo_amount)
-                               {
-                                       WEP_ACTION(self.weapon, WR_RELOAD);
-                                       return false;
-                               }
-
-                               return true;
-                       }
-
-                       if(self.BUTTON_ATCK)
-                       {
-                               if(weapon_prepareattack(0, WEP_CVAR_PRI(electro, refire)))
-                               {
-                                               W_Electro_Attack_Bolt();
-                                               weapon_thinkf(WFRAME_FIRE1, WEP_CVAR_PRI(electro, animtime), w_ready);
-                               }
-                       }
-                       else if(self.BUTTON_ATCK2)
-                       {
-                               if(time >= self.electro_secondarytime)
-                               if(weapon_prepareattack(1, WEP_CVAR_SEC(electro, refire)))
-                               {
-                                       W_Electro_Attack_Orb();
-                                       self.electro_count = WEP_CVAR_SEC(electro, count);
-                                       weapon_thinkf(WFRAME_FIRE2, WEP_CVAR_SEC(electro, animtime), W_Electro_CheckAttack);
-                                       self.electro_secondarytime = time + WEP_CVAR_SEC(electro, refire2) * W_WeaponRateFactor();
-                               }
-                       }
-
-                       return true;
-               }
-               case WR_INIT:
-               {
-                       precache_model(W_Model("g_electro.md3"));
-                       precache_model(W_Model("v_electro.md3"));
-                       precache_model(W_Model("h_electro.iqm"));
-                       precache_sound(W_Sound("electro_bounce"));
-                       precache_sound(W_Sound("electro_fire"));
-                       precache_sound(W_Sound("electro_fire2"));
-                       precache_sound(W_Sound("electro_impact"));
-                       precache_sound(W_Sound("electro_impact_combo"));
-                       ELECTRO_SETTINGS(WEP_SKIP_CVAR, WEP_SET_PROP);
-                       return true;
-               }
-               case WR_CHECKAMMO1:
-               {
-                       ammo_amount = self.WEP_AMMO(ELECTRO) >= WEP_CVAR_PRI(electro, ammo);
-                       ammo_amount += self.(weapon_load[WEP_ELECTRO.m_id]) >= WEP_CVAR_PRI(electro, ammo);
-                       return ammo_amount;
-               }
-               case WR_CHECKAMMO2:
-               {
-                       if(WEP_CVAR(electro, combo_safeammocheck)) // true if you can fire at least one secondary blob AND one primary shot after it, otherwise false.
-                       {
-                               ammo_amount = self.WEP_AMMO(ELECTRO) >= WEP_CVAR_SEC(electro, ammo) + WEP_CVAR_PRI(electro, ammo);
-                               ammo_amount += self.(weapon_load[WEP_ELECTRO.m_id]) >= WEP_CVAR_SEC(electro, ammo) + WEP_CVAR_PRI(electro, ammo);
-                       }
-                       else
-                       {
-                               ammo_amount = self.WEP_AMMO(ELECTRO) >= WEP_CVAR_SEC(electro, ammo);
-                               ammo_amount += self.(weapon_load[WEP_ELECTRO.m_id]) >= WEP_CVAR_SEC(electro, ammo);
-                       }
-                       return ammo_amount;
-               }
-               case WR_CONFIG:
-               {
-                       ELECTRO_SETTINGS(WEP_CONFIG_WRITE_CVARS, WEP_CONFIG_WRITE_PROPS);
-                       return true;
-               }
-               case WR_RESETPLAYER:
-               {
-                       self.electro_secondarytime = time;
-                       return true;
-               }
-               case WR_RELOAD:
-               {
-                       W_Reload(min(WEP_CVAR_PRI(electro, ammo), WEP_CVAR_SEC(electro, ammo)), W_Sound("reload"));
-                       return true;
-               }
-               case WR_SUICIDEMESSAGE:
-               {
-                       if(w_deathtype & HITTYPE_SECONDARY)
-                               return WEAPON_ELECTRO_SUICIDE_ORBS;
-                       else
-                               return WEAPON_ELECTRO_SUICIDE_BOLT;
-               }
-               case WR_KILLMESSAGE:
-               {
-                       if(w_deathtype & HITTYPE_SECONDARY)
-                       {
-                               return WEAPON_ELECTRO_MURDER_ORBS;
-                       }
-                       else
-                       {
-                               if(w_deathtype & HITTYPE_BOUNCE)
-                                       return WEAPON_ELECTRO_MURDER_COMBO;
-                               else
-                                       return WEAPON_ELECTRO_MURDER_BOLT;
-                       }
-               }
-       }
-       return false;
-}
-#endif
-#ifdef CSQC
-bool W_Electro(int req)
-{
-       switch(req)
-       {
-               case WR_IMPACTEFFECT:
-               {
-                       vector org2;
-                       org2 = w_org + w_backoff * 6;
-                       if(w_deathtype & HITTYPE_SECONDARY)
-                       {
-                               pointparticles(particleeffectnum(EFFECT_ELECTRO_BALLEXPLODE), org2, '0 0 0', 1);
-                               if(!w_issilent)
-                                       sound(self, CH_SHOTS, W_Sound("electro_impact"), VOL_BASE, ATTEN_NORM);
-                       }
-                       else
-                       {
-                               if(w_deathtype & HITTYPE_BOUNCE)
-                               {
-                                       // this is sent as "primary (w_deathtype & HITTYPE_BOUNCE)" to distinguish it from (w_deathtype & HITTYPE_SECONDARY) bounced balls
-                                       pointparticles(particleeffectnum(EFFECT_ELECTRO_COMBO), org2, '0 0 0', 1);
-                                       if(!w_issilent)
-                                               sound(self, CH_SHOTS, W_Sound("electro_impact_combo"), VOL_BASE, ATTEN_NORM);
-                               }
-                               else
-                               {
-                                       pointparticles(particleeffectnum(EFFECT_ELECTRO_IMPACT), org2, '0 0 0', 1);
-                                       if(!w_issilent)
-                                               sound(self, CH_SHOTS, W_Sound("electro_impact"), VOL_BASE, ATTEN_NORM);
-                               }
-                       }
-
-                       return true;
-               }
-               case WR_INIT:
-               {
-                       precache_sound(W_Sound("electro_impact"));
-                       precache_sound(W_Sound("electro_impact_combo"));
-                       return true;
-               }
-               case WR_ZOOMRETICLE:
-               {
-                       // no weapon specific image for this weapon
-                       return false;
-               }
-       }
-       return false;
-}
-#endif
-#endif
diff --git a/qcsrc/common/weapons/w_fireball.qc b/qcsrc/common/weapons/w_fireball.qc
deleted file mode 100644 (file)
index 4f8f378..0000000
+++ /dev/null
@@ -1,486 +0,0 @@
-#ifndef IMPLEMENTATION
-REGISTER_WEAPON(
-/* WEP_##id  */ FIREBALL,
-/* function  */ W_Fireball,
-/* ammotype  */ ammo_none,
-/* impulse   */ 9,
-/* flags     */ WEP_FLAG_SUPERWEAPON | WEP_TYPE_SPLASH,
-/* rating    */ BOT_PICKUP_RATING_MID,
-/* color     */ '1 0.5 0',
-/* modelname */ "fireball",
-/* simplemdl */ "foobar",
-/* crosshair */ "gfx/crosshairfireball",
-/* wepimg    */ "weaponfireball",
-/* refname   */ "fireball",
-/* wepname   */ _("Fireball")
-);
-
-#define FIREBALL_SETTINGS(w_cvar,w_prop) FIREBALL_SETTINGS_LIST(w_cvar, w_prop, FIREBALL, fireball)
-#define FIREBALL_SETTINGS_LIST(w_cvar,w_prop,id,sn) \
-       w_cvar(id, sn, BOTH, animtime) \
-       w_cvar(id, sn, BOTH, refire) \
-       w_cvar(id, sn, BOTH, damage) \
-       w_cvar(id, sn, BOTH, damageforcescale) \
-       w_cvar(id, sn, BOTH, speed) \
-       w_cvar(id, sn, BOTH, spread) \
-       w_cvar(id, sn, BOTH, lifetime) \
-       w_cvar(id, sn, BOTH, laserburntime) \
-       w_cvar(id, sn, BOTH, laserdamage) \
-       w_cvar(id, sn, BOTH, laseredgedamage) \
-       w_cvar(id, sn, BOTH, laserradius) \
-       w_cvar(id, sn, PRI,  edgedamage) \
-       w_cvar(id, sn, PRI,  force) \
-       w_cvar(id, sn, PRI,  radius) \
-       w_cvar(id, sn, PRI,  health) \
-       w_cvar(id, sn, PRI,  refire2) \
-       w_cvar(id, sn, PRI,  bfgdamage) \
-       w_cvar(id, sn, PRI,  bfgforce) \
-       w_cvar(id, sn, PRI,  bfgradius) \
-       w_cvar(id, sn, SEC,  damagetime) \
-       w_cvar(id, sn, SEC,  speed_up) \
-       w_cvar(id, sn, SEC,  speed_z) \
-       w_prop(id, sn, float,  switchdelay_raise, switchdelay_raise) \
-       w_prop(id, sn, float,  switchdelay_drop, switchdelay_drop) \
-       w_prop(id, sn, string, weaponreplace, weaponreplace) \
-       w_prop(id, sn, float,  weaponstart, weaponstart) \
-       w_prop(id, sn, float,  weaponstartoverride, weaponstartoverride) \
-       w_prop(id, sn, float,  weaponthrowable, weaponthrowable)
-
-#ifdef SVQC
-FIREBALL_SETTINGS(WEP_ADD_CVAR, WEP_ADD_PROP)
-.float bot_primary_fireballmooth; // whatever a mooth is
-.vector fireball_impactvec;
-.float fireball_primarytime;
-#endif
-#endif
-#ifdef IMPLEMENTATION
-#ifdef SVQC
-void spawnfunc_weapon_fireball(void) { weapon_defaultspawnfunc(WEP_FIREBALL.m_id); }
-
-void W_Fireball_Explode(void)
-{
-       entity e;
-       float dist;
-       float points;
-       vector dir;
-       float d;
-
-       self.event_damage = func_null;
-       self.takedamage = DAMAGE_NO;
-
-       // 1. dist damage
-       d = (self.realowner.health + self.realowner.armorvalue);
-       RadiusDamage(self, self.realowner, WEP_CVAR_PRI(fireball, damage), WEP_CVAR_PRI(fireball, edgedamage), WEP_CVAR_PRI(fireball, radius), world, world, WEP_CVAR_PRI(fireball, force), self.projectiledeathtype, other);
-       if(self.realowner.health + self.realowner.armorvalue >= d)
-       if(!self.cnt)
-       {
-               modeleffect_spawn("models/sphere/sphere.md3", 0, 0, self.origin, '0 0 0', '0 0 0', '0 0 0', 0, WEP_CVAR_PRI(fireball, bfgradius), 0.2, 0.05, 0.25);
-
-               // 2. bfg effect
-               // NOTE: this cannot be made warpzone aware by design. So, better intentionally ignore warpzones here.
-               for(e = findradius(self.origin, WEP_CVAR_PRI(fireball, bfgradius)); e; e = e.chain)
-               if(e != self.realowner) if(e.takedamage == DAMAGE_AIM) if(!IS_PLAYER(e) || !self.realowner || DIFF_TEAM(e, self))
-               {
-                       // can we see fireball?
-                       traceline(e.origin + e.view_ofs, self.origin, MOVE_NORMAL, e);
-                       if(/* trace_startsolid || */ trace_fraction != 1) // startsolid should be never happening anyway
-                               continue;
-                       // can we see player who shot fireball?
-                       traceline(e.origin + e.view_ofs, self.realowner.origin + self.realowner.view_ofs, MOVE_NORMAL, e);
-                       if(trace_ent != self.realowner)
-                       if(/* trace_startsolid || */ trace_fraction != 1)
-                               continue;
-                       dist = vlen(self.origin - e.origin - e.view_ofs);
-                       points = (1 - sqrt(dist / WEP_CVAR_PRI(fireball, bfgradius)));
-                       if(points <= 0)
-                               continue;
-                       dir = normalize(e.origin + e.view_ofs - self.origin);
-
-                       if(accuracy_isgooddamage(self.realowner, e))
-                               accuracy_add(self.realowner, WEP_FIREBALL.m_id, 0, WEP_CVAR_PRI(fireball, bfgdamage) * points);
-
-                       Damage(e, self, self.realowner, WEP_CVAR_PRI(fireball, bfgdamage) * points, self.projectiledeathtype | HITTYPE_BOUNCE | HITTYPE_SPLASH, e.origin + e.view_ofs, WEP_CVAR_PRI(fireball, bfgforce) * dir);
-                       Send_Effect(EFFECT_FIREBALL_BFGDAMAGE, e.origin, -1 * dir, 1);
-               }
-       }
-
-       remove(self);
-}
-
-void W_Fireball_TouchExplode(void)
-{
-       PROJECTILE_TOUCH;
-       W_Fireball_Explode();
-}
-
-void W_Fireball_LaserPlay(float dt, float dist, float damage, float edgedamage, float burntime)
-{
-       entity e;
-       float d;
-       vector p;
-
-       if(damage <= 0)
-               return;
-
-       RandomSelection_Init();
-       for(e = WarpZone_FindRadius(self.origin, dist, true); e; e = e.chain)
-       if(e != self.realowner) if(e.takedamage == DAMAGE_AIM) if(!IS_PLAYER(e) || !self.realowner || DIFF_TEAM(e, self))
-       {
-               p = e.origin;
-               p.x += e.mins.x + random() * (e.maxs.x - e.mins.x);
-               p.y += e.mins.y + random() * (e.maxs.y - e.mins.y);
-               p.z += e.mins.z + random() * (e.maxs.z - e.mins.z);
-               d = vlen(WarpZone_UnTransformOrigin(e, self.origin) - p);
-               if(d < dist)
-               {
-                       e.fireball_impactvec = p;
-                       RandomSelection_Add(e, 0, string_null, 1 / (1 + d), !Fire_IsBurning(e));
-               }
-       }
-       if(RandomSelection_chosen_ent)
-       {
-               d = vlen(WarpZone_UnTransformOrigin(RandomSelection_chosen_ent, self.origin) - RandomSelection_chosen_ent.fireball_impactvec);
-               d = damage + (edgedamage - damage) * (d / dist);
-               Fire_AddDamage(RandomSelection_chosen_ent, self.realowner, d * burntime, burntime, self.projectiledeathtype | HITTYPE_BOUNCE);
-               //trailparticles(self, particleeffectnum(EFFECT_FIREBALL_LASER), self.origin, RandomSelection_chosen_ent.fireball_impactvec);
-               Send_Effect(EFFECT_FIREBALL_LASER, self.origin, RandomSelection_chosen_ent.fireball_impactvec - self.origin, 1);
-       }
-}
-
-void W_Fireball_Think(void)
-{
-       if(time > self.pushltime)
-       {
-               self.cnt = 1;
-               self.projectiledeathtype |= HITTYPE_SPLASH;
-               W_Fireball_Explode();
-               return;
-       }
-
-       W_Fireball_LaserPlay(0.1, WEP_CVAR_PRI(fireball, laserradius), WEP_CVAR_PRI(fireball, laserdamage), WEP_CVAR_PRI(fireball, laseredgedamage), WEP_CVAR_PRI(fireball, laserburntime));
-
-       self.nextthink = time + 0.1;
-}
-
-void W_Fireball_Damage(entity inflictor, entity attacker, float damage, int deathtype, vector hitloc, vector force)
-{
-       if(self.health <= 0)
-               return;
-
-       if(!W_CheckProjectileDamage(inflictor.realowner, self.realowner, deathtype, -1)) // no exceptions
-               return; // g_projectiles_damage says to halt
-
-       self.health = self.health - damage;
-       if(self.health <= 0)
-       {
-               self.cnt = 1;
-               W_PrepareExplosionByDamage(attacker, W_Fireball_Explode);
-       }
-}
-
-void W_Fireball_Attack1(void)
-{
-       entity proj;
-
-       W_SetupShot_ProjectileSize(self, '-16 -16 -16', '16 16 16', false, 2, W_Sound("fireball_fire2"), CH_WEAPON_A, WEP_CVAR_PRI(fireball, damage) + WEP_CVAR_PRI(fireball, bfgdamage));
-
-       Send_Effect(EFFECT_FIREBALL_MUZZLEFLASH, w_shotorg, w_shotdir * 1000, 1);
-
-       proj = spawn();
-       proj.classname = "plasma_prim";
-       proj.owner = proj.realowner = self;
-       proj.bot_dodge = true;
-       proj.bot_dodgerating = WEP_CVAR_PRI(fireball, damage);
-       proj.pushltime = time + WEP_CVAR_PRI(fireball, lifetime);
-       proj.use = W_Fireball_Explode;
-       proj.think = W_Fireball_Think;
-       proj.nextthink = time;
-       proj.health = WEP_CVAR_PRI(fireball, health);
-       proj.team = self.team;
-       proj.event_damage = W_Fireball_Damage;
-       proj.takedamage = DAMAGE_YES;
-       proj.damageforcescale = WEP_CVAR_PRI(fireball, damageforcescale);
-       PROJECTILE_MAKETRIGGER(proj);
-       proj.projectiledeathtype = WEP_FIREBALL.m_id;
-       setorigin(proj, w_shotorg);
-
-       proj.movetype = MOVETYPE_FLY;
-       W_SetupProjVelocity_PRI(proj, fireball);
-       proj.angles = vectoangles(proj.velocity);
-       proj.touch = W_Fireball_TouchExplode;
-       setsize(proj, '-16 -16 -16', '16 16 16');
-       proj.flags = FL_PROJECTILE;
-    proj.missile_flags = MIF_SPLASH | MIF_PROXY;
-
-       CSQCProjectile(proj, true, PROJECTILE_FIREBALL, true);
-
-       MUTATOR_CALLHOOK(EditProjectile, self, proj);
-}
-
-void W_Fireball_AttackEffect(float i, vector f_diff)
-{
-       W_SetupShot_ProjectileSize(self, '-16 -16 -16', '16 16 16', false, 0, "", 0, 0);
-       w_shotorg += f_diff.x * v_up + f_diff.y * v_right;
-       Send_Effect(EFFECT_FIREBALL_PRE_MUZZLEFLASH, w_shotorg, w_shotdir * 1000, 1);
-}
-
-void W_Fireball_Attack1_Frame4(void)
-{
-       W_Fireball_Attack1();
-       weapon_thinkf(WFRAME_FIRE1, WEP_CVAR_PRI(fireball, animtime), w_ready);
-}
-
-void W_Fireball_Attack1_Frame3(void)
-{
-       W_Fireball_AttackEffect(0, '+1.25 +3.75 0');
-       weapon_thinkf(WFRAME_FIRE1, WEP_CVAR_PRI(fireball, animtime), W_Fireball_Attack1_Frame4);
-}
-
-void W_Fireball_Attack1_Frame2(void)
-{
-       W_Fireball_AttackEffect(0, '-1.25 +3.75 0');
-       weapon_thinkf(WFRAME_FIRE1, WEP_CVAR_PRI(fireball, animtime), W_Fireball_Attack1_Frame3);
-}
-
-void W_Fireball_Attack1_Frame1(void)
-{
-       W_Fireball_AttackEffect(1, '+1.25 -3.75 0');
-       weapon_thinkf(WFRAME_FIRE1, WEP_CVAR_PRI(fireball, animtime), W_Fireball_Attack1_Frame2);
-}
-
-void W_Fireball_Attack1_Frame0(void)
-{
-       W_Fireball_AttackEffect(0, '-1.25 -3.75 0');
-       sound(self, CH_WEAPON_SINGLE, W_Sound("fireball_prefire2"), VOL_BASE, ATTEN_NORM);
-       weapon_thinkf(WFRAME_FIRE1, WEP_CVAR_PRI(fireball, animtime), W_Fireball_Attack1_Frame1);
-}
-
-void W_Fireball_Firemine_Think(void)
-{
-       if(time > self.pushltime)
-       {
-               remove(self);
-               return;
-       }
-
-       // make it "hot" once it leaves its owner
-       if(self.owner)
-       {
-               if(vlen(self.origin - self.owner.origin - self.owner.view_ofs) > WEP_CVAR_SEC(fireball, laserradius))
-               {
-                       self.cnt += 1;
-                       if(self.cnt == 3)
-                               self.owner = world;
-               }
-               else
-                       self.cnt = 0;
-       }
-
-       W_Fireball_LaserPlay(0.1, WEP_CVAR_SEC(fireball, laserradius), WEP_CVAR_SEC(fireball, laserdamage), WEP_CVAR_SEC(fireball, laseredgedamage), WEP_CVAR_SEC(fireball, laserburntime));
-
-       self.nextthink = time + 0.1;
-}
-
-void W_Fireball_Firemine_Touch(void)
-{
-       PROJECTILE_TOUCH;
-       if(other.takedamage == DAMAGE_AIM)
-       if(Fire_AddDamage(other, self.realowner, WEP_CVAR_SEC(fireball, damage), WEP_CVAR_SEC(fireball, damagetime), self.projectiledeathtype) >= 0)
-       {
-               remove(self);
-               return;
-       }
-       self.projectiledeathtype |= HITTYPE_BOUNCE;
-}
-
-void W_Fireball_Attack2(void)
-{
-       entity proj;
-       vector f_diff;
-       float c;
-
-       c = self.bulletcounter % 4;
-       switch(c)
-       {
-               case 0:
-                       f_diff = '-1.25 -3.75 0';
-                       break;
-               case 1:
-                       f_diff = '+1.25 -3.75 0';
-                       break;
-               case 2:
-                       f_diff = '-1.25 +3.75 0';
-                       break;
-               case 3:
-               default:
-                       f_diff = '+1.25 +3.75 0';
-                       break;
-       }
-       W_SetupShot_ProjectileSize(self, '-4 -4 -4', '4 4 4', false, 2, W_Sound("fireball_fire"), CH_WEAPON_A, WEP_CVAR_SEC(fireball, damage));
-       traceline(w_shotorg, w_shotorg + f_diff_x * v_up + f_diff_y * v_right, MOVE_NORMAL, self);
-       w_shotorg = trace_endpos;
-
-       Send_Effect(EFFECT_FIREBALL_MUZZLEFLASH, w_shotorg, w_shotdir * 1000, 1);
-
-       proj = spawn();
-       proj.owner = proj.realowner = self;
-       proj.classname = "grenade";
-       proj.bot_dodge = true;
-       proj.bot_dodgerating = WEP_CVAR_SEC(fireball, damage);
-       proj.movetype = MOVETYPE_BOUNCE;
-       proj.projectiledeathtype = WEP_FIREBALL.m_id | HITTYPE_SECONDARY;
-       proj.touch = W_Fireball_Firemine_Touch;
-       PROJECTILE_MAKETRIGGER(proj);
-       setsize(proj, '-4 -4 -4', '4 4 4');
-       setorigin(proj, w_shotorg);
-       proj.think = W_Fireball_Firemine_Think;
-       proj.nextthink = time;
-       proj.damageforcescale = WEP_CVAR_SEC(fireball, damageforcescale);
-       proj.pushltime = time + WEP_CVAR_SEC(fireball, lifetime);
-       W_SetupProjVelocity_UP_SEC(proj, fireball);
-
-       proj.angles = vectoangles(proj.velocity);
-       proj.flags = FL_PROJECTILE;
-    proj.missile_flags = MIF_SPLASH | MIF_PROXY | MIF_ARC;
-
-       CSQCProjectile(proj, true, PROJECTILE_FIREMINE, true);
-
-       MUTATOR_CALLHOOK(EditProjectile, self, proj);
-}
-
-bool W_Fireball(int req)
-{
-       switch(req)
-       {
-               case WR_AIM:
-               {
-                       self.BUTTON_ATCK = false;
-                       self.BUTTON_ATCK2 = false;
-                       if(self.bot_primary_fireballmooth == 0)
-                       {
-                               if(bot_aim(WEP_CVAR_PRI(fireball, speed), 0, WEP_CVAR_PRI(fireball, lifetime), false))
-                               {
-                                       self.BUTTON_ATCK = true;
-                                       if(random() < 0.02) self.bot_primary_fireballmooth = 0;
-                               }
-                       }
-                       else
-                       {
-                               if(bot_aim(WEP_CVAR_SEC(fireball, speed), WEP_CVAR_SEC(fireball, speed_up), WEP_CVAR_SEC(fireball, lifetime), true))
-                               {
-                                       self.BUTTON_ATCK2 = true;
-                                       if(random() < 0.01) self.bot_primary_fireballmooth = 1;
-                               }
-                       }
-
-                       return true;
-               }
-               case WR_THINK:
-               {
-                       if(self.BUTTON_ATCK)
-                       {
-                               if(time >= self.fireball_primarytime)
-                               if(weapon_prepareattack(0, WEP_CVAR_PRI(fireball, refire)))
-                               {
-                                       W_Fireball_Attack1_Frame0();
-                                       self.fireball_primarytime = time + WEP_CVAR_PRI(fireball, refire2) * W_WeaponRateFactor();
-                               }
-                       }
-                       else if(self.BUTTON_ATCK2)
-                       {
-                               if(weapon_prepareattack(1, WEP_CVAR_SEC(fireball, refire)))
-                               {
-                                       W_Fireball_Attack2();
-                                       weapon_thinkf(WFRAME_FIRE2, WEP_CVAR_SEC(fireball, animtime), w_ready);
-                               }
-                       }
-
-                       return true;
-               }
-               case WR_INIT:
-               {
-                       precache_model(W_Model("g_fireball.md3"));
-                       precache_model(W_Model("v_fireball.md3"));
-                       precache_model(W_Model("h_fireball.iqm"));
-                       precache_model("models/sphere/sphere.md3");
-                       precache_sound(W_Sound("fireball_fire"));
-                       precache_sound(W_Sound("fireball_fire2"));
-                       precache_sound(W_Sound("fireball_prefire2"));
-                       FIREBALL_SETTINGS(WEP_SKIP_CVAR, WEP_SET_PROP);
-                       return true;
-               }
-               case WR_SETUP:
-               {
-                       self.ammo_field = ammo_none;
-                       return true;
-               }
-               case WR_CHECKAMMO1:
-               case WR_CHECKAMMO2:
-               {
-                       return true; // fireball has infinite ammo
-               }
-               case WR_CONFIG:
-               {
-                       FIREBALL_SETTINGS(WEP_CONFIG_WRITE_CVARS, WEP_CONFIG_WRITE_PROPS);
-                       return true;
-               }
-               case WR_RESETPLAYER:
-               {
-                       self.fireball_primarytime = time;
-                       return true;
-               }
-               case WR_SUICIDEMESSAGE:
-               {
-                       if(w_deathtype & HITTYPE_SECONDARY)
-                               return WEAPON_FIREBALL_SUICIDE_FIREMINE;
-                       else
-                               return WEAPON_FIREBALL_SUICIDE_BLAST;
-               }
-               case WR_KILLMESSAGE:
-               {
-                       if(w_deathtype & HITTYPE_SECONDARY)
-                               return WEAPON_FIREBALL_MURDER_FIREMINE;
-                       else
-                               return WEAPON_FIREBALL_MURDER_BLAST;
-               }
-       }
-       return false;
-}
-#endif
-#ifdef CSQC
-bool W_Fireball(int req)
-{
-       switch(req)
-       {
-               case WR_IMPACTEFFECT:
-               {
-                       vector org2;
-                       if(w_deathtype & HITTYPE_SECONDARY)
-                       {
-                               // firemine goes out silently
-                       }
-                       else
-                       {
-                               org2 = w_org + w_backoff * 16;
-                               pointparticles(particleeffectnum(EFFECT_FIREBALL_EXPLODE), org2, '0 0 0', 1);
-                               if(!w_issilent)
-                                       sound(self, CH_SHOTS, W_Sound("fireball_impact2"), VOL_BASE, ATTEN_NORM * 0.25); // long range boom
-                       }
-
-                       return true;
-               }
-               case WR_INIT:
-               {
-                       precache_sound(W_Sound("fireball_impact2"));
-                       return true;
-               }
-               case WR_ZOOMRETICLE:
-               {
-                       // no weapon specific image for this weapon
-                       return false;
-               }
-       }
-       return false;
-}
-#endif
-#endif
diff --git a/qcsrc/common/weapons/w_hagar.qc b/qcsrc/common/weapons/w_hagar.qc
deleted file mode 100644 (file)
index 4f1b905..0000000
+++ /dev/null
@@ -1,565 +0,0 @@
-#ifndef IMPLEMENTATION
-REGISTER_WEAPON(
-/* WEP_##id  */ HAGAR,
-/* function  */ W_Hagar,
-/* ammotype  */ ammo_rockets,
-/* impulse   */ 8,
-/* flags     */ WEP_FLAG_NORMAL | WEP_FLAG_RELOADABLE | WEP_FLAG_CANCLIMB | WEP_TYPE_SPLASH,
-/* rating    */ BOT_PICKUP_RATING_MID,
-/* color     */ '1 1 0.5',
-/* modelname */ "hagar",
-/* simplemdl */ "foobar",
-/* crosshair */ "gfx/crosshairhagar 0.8",
-/* wepimg    */ "weaponhagar",
-/* refname   */ "hagar",
-/* wepname   */ _("Hagar")
-);
-
-#define HAGAR_SETTINGS(w_cvar,w_prop) HAGAR_SETTINGS_LIST(w_cvar, w_prop, HAGAR, hagar)
-#define HAGAR_SETTINGS_LIST(w_cvar,w_prop,id,sn) \
-       w_cvar(id, sn, BOTH, ammo) \
-       w_cvar(id, sn, BOTH, damage) \
-       w_cvar(id, sn, BOTH, edgedamage) \
-       w_cvar(id, sn, BOTH, force) \
-       w_cvar(id, sn, BOTH, radius) \
-       w_cvar(id, sn, BOTH, refire) \
-       w_cvar(id, sn, BOTH, speed) \
-       w_cvar(id, sn, BOTH, spread) \
-       w_cvar(id, sn, BOTH, damageforcescale) \
-       w_cvar(id, sn, BOTH, health) \
-       w_cvar(id, sn, PRI,  lifetime) \
-       w_cvar(id, sn, SEC,  load) \
-       w_cvar(id, sn, SEC,  load_max) \
-       w_cvar(id, sn, SEC,  load_abort) \
-       w_cvar(id, sn, SEC,  load_animtime) \
-       w_cvar(id, sn, SEC,  load_hold) \
-       w_cvar(id, sn, SEC,  load_speed) \
-       w_cvar(id, sn, SEC,  load_releasedeath) \
-       w_cvar(id, sn, SEC,  load_spread) \
-       w_cvar(id, sn, SEC,  load_spread_bias) \
-       w_cvar(id, sn, SEC,  load_linkexplode) \
-       w_cvar(id, sn, SEC,  lifetime_min) \
-       w_cvar(id, sn, SEC,  lifetime_rand) \
-       w_cvar(id, sn, NONE, secondary) \
-       w_prop(id, sn, float,  reloading_ammo, reload_ammo) \
-       w_prop(id, sn, float,  reloading_time, reload_time) \
-       w_prop(id, sn, float,  switchdelay_raise, switchdelay_raise) \
-       w_prop(id, sn, float,  switchdelay_drop, switchdelay_drop) \
-       w_prop(id, sn, string, weaponreplace, weaponreplace) \
-       w_prop(id, sn, float,  weaponstart, weaponstart) \
-       w_prop(id, sn, float,  weaponstartoverride, weaponstartoverride) \
-       w_prop(id, sn, float,  weaponthrowable, weaponthrowable)
-
-#ifdef SVQC
-HAGAR_SETTINGS(WEP_ADD_CVAR, WEP_ADD_PROP)
-#endif
-#endif
-#ifdef IMPLEMENTATION
-#ifdef SVQC
-void spawnfunc_weapon_hagar(void) { weapon_defaultspawnfunc(WEP_HAGAR.m_id); }
-
-// NO bounce protection, as bounces are limited!
-
-void W_Hagar_Explode(void)
-{
-       self.event_damage = func_null;
-       RadiusDamage(self, self.realowner, WEP_CVAR_PRI(hagar, damage), WEP_CVAR_PRI(hagar, edgedamage), WEP_CVAR_PRI(hagar, radius), world, world, WEP_CVAR_PRI(hagar, force), self.projectiledeathtype, other);
-
-       remove(self);
-}
-
-void W_Hagar_Explode2(void)
-{
-       self.event_damage = func_null;
-       RadiusDamage(self, self.realowner, WEP_CVAR_SEC(hagar, damage), WEP_CVAR_SEC(hagar, edgedamage), WEP_CVAR_SEC(hagar, radius), world, world, WEP_CVAR_SEC(hagar, force), self.projectiledeathtype, other);
-
-       remove(self);
-}
-
-void W_Hagar_Damage(entity inflictor, entity attacker, float damage, int deathtype, vector hitloc, vector force)
-{
-       if(self.health <= 0)
-               return;
-
-       float is_linkexplode = ( ((inflictor.owner != world) ? (inflictor.owner == self.owner) : true)
-               && (inflictor.projectiledeathtype & HITTYPE_SECONDARY)
-               && (self.projectiledeathtype & HITTYPE_SECONDARY));
-
-       if(is_linkexplode)
-               is_linkexplode = (is_linkexplode && WEP_CVAR_SEC(hagar, load_linkexplode));
-       else
-               is_linkexplode = -1; // not secondary load, so continue as normal without exception.
-
-       if(!W_CheckProjectileDamage(inflictor.realowner, self.realowner, deathtype, is_linkexplode))
-               return; // g_projectiles_damage says to halt
-
-       self.health = self.health - damage;
-       self.angles = vectoangles(self.velocity);
-
-       if(self.health <= 0)
-               W_PrepareExplosionByDamage(attacker, self.think);
-}
-
-void W_Hagar_Touch(void)
-{
-       PROJECTILE_TOUCH;
-       self.use();
-}
-
-void W_Hagar_Touch2(void)
-{
-       PROJECTILE_TOUCH;
-
-       if(self.cnt > 0 || other.takedamage == DAMAGE_AIM) {
-               self.use();
-       } else {
-               self.cnt++;
-               Send_Effect(EFFECT_HAGAR_BOUNCE, self.origin, self.velocity, 1);
-               self.angles = vectoangles(self.velocity);
-               self.owner = world;
-               self.projectiledeathtype |= HITTYPE_BOUNCE;
-       }
-}
-
-void W_Hagar_Attack(void)
-{
-       entity missile;
-
-       W_DecreaseAmmo(WEP_CVAR_PRI(hagar, ammo));
-
-       W_SetupShot(self, false, 2, W_Sound("hagar_fire"), CH_WEAPON_A, WEP_CVAR_PRI(hagar, damage));
-
-       Send_Effect(EFFECT_HAGAR_MUZZLEFLASH, w_shotorg, w_shotdir * 1000, 1);
-
-       missile = spawn();
-       missile.owner = missile.realowner = self;
-       missile.classname = "missile";
-       missile.bot_dodge = true;
-       missile.bot_dodgerating = WEP_CVAR_PRI(hagar, damage);
-
-       missile.takedamage = DAMAGE_YES;
-       missile.health = WEP_CVAR_PRI(hagar, health);
-       missile.damageforcescale = WEP_CVAR_PRI(hagar, damageforcescale);
-       missile.event_damage = W_Hagar_Damage;
-       missile.damagedbycontents = true;
-
-       missile.touch = W_Hagar_Touch;
-       missile.use = W_Hagar_Explode;
-       missile.think = adaptor_think2use_hittype_splash;
-       missile.nextthink = time + WEP_CVAR_PRI(hagar, lifetime);
-       PROJECTILE_MAKETRIGGER(missile);
-       missile.projectiledeathtype = WEP_HAGAR.m_id;
-       setorigin(missile, w_shotorg);
-       setsize(missile, '0 0 0', '0 0 0');
-
-       missile.movetype = MOVETYPE_FLY;
-       W_SetupProjVelocity_PRI(missile, hagar);
-
-       missile.angles = vectoangles(missile.velocity);
-       missile.flags = FL_PROJECTILE;
-       missile.missile_flags = MIF_SPLASH;
-
-       CSQCProjectile(missile, true, PROJECTILE_HAGAR, true);
-
-       MUTATOR_CALLHOOK(EditProjectile, self, missile);
-}
-
-void W_Hagar_Attack2(void)
-{
-       entity missile;
-
-       W_DecreaseAmmo(WEP_CVAR_SEC(hagar, ammo));
-
-       W_SetupShot(self, false, 2, W_Sound("hagar_fire"), CH_WEAPON_A, WEP_CVAR_SEC(hagar, damage));
-
-       Send_Effect(EFFECT_HAGAR_MUZZLEFLASH, w_shotorg, w_shotdir * 1000, 1);
-
-       missile = spawn();
-       missile.owner = missile.realowner = self;
-       missile.classname = "missile";
-       missile.bot_dodge = true;
-       missile.bot_dodgerating = WEP_CVAR_SEC(hagar, damage);
-
-       missile.takedamage = DAMAGE_YES;
-       missile.health = WEP_CVAR_SEC(hagar, health);
-       missile.damageforcescale = WEP_CVAR_SEC(hagar, damageforcescale);
-       missile.event_damage = W_Hagar_Damage;
-       missile.damagedbycontents = true;
-
-       missile.touch = W_Hagar_Touch2;
-       missile.cnt = 0;
-       missile.use = W_Hagar_Explode2;
-       missile.think = adaptor_think2use_hittype_splash;
-       missile.nextthink = time + WEP_CVAR_SEC(hagar, lifetime_min) + random() * WEP_CVAR_SEC(hagar, lifetime_rand);
-       PROJECTILE_MAKETRIGGER(missile);
-       missile.projectiledeathtype = WEP_HAGAR.m_id | HITTYPE_SECONDARY;
-       setorigin(missile, w_shotorg);
-       setsize(missile, '0 0 0', '0 0 0');
-
-       missile.movetype = MOVETYPE_BOUNCEMISSILE;
-       W_SetupProjVelocity_SEC(missile, hagar);
-
-       missile.angles = vectoangles(missile.velocity);
-       missile.flags = FL_PROJECTILE;
-       missile.missile_flags = MIF_SPLASH;
-
-       CSQCProjectile(missile, true, PROJECTILE_HAGAR_BOUNCING, true);
-
-       MUTATOR_CALLHOOK(EditProjectile, self, missile);
-}
-
-.float hagar_loadstep, hagar_loadblock, hagar_loadbeep, hagar_warning;
-void W_Hagar_Attack2_Load_Release(void)
-{
-       // time to release the rockets we've loaded
-
-       entity missile;
-       float counter, shots, spread_pershot;
-       vector s;
-       vector forward, right, up;
-
-       if(!self.hagar_load)
-               return;
-
-       weapon_prepareattack_do(1, WEP_CVAR_SEC(hagar, refire));
-
-       W_SetupShot(self, false, 2, W_Sound("hagar_fire"), CH_WEAPON_A, WEP_CVAR_SEC(hagar, damage));
-       Send_Effect(EFFECT_HAGAR_MUZZLEFLASH, w_shotorg, w_shotdir * 1000, 1);
-
-       forward = v_forward;
-       right = v_right;
-       up = v_up;
-
-       shots = self.hagar_load;
-       missile = world;
-       for(counter = 0; counter < shots; ++counter)
-       {
-               missile = spawn();
-               missile.owner = missile.realowner = self;
-               missile.classname = "missile";
-               missile.bot_dodge = true;
-               missile.bot_dodgerating = WEP_CVAR_SEC(hagar, damage);
-
-               missile.takedamage = DAMAGE_YES;
-               missile.health = WEP_CVAR_SEC(hagar, health);
-               missile.damageforcescale = WEP_CVAR_SEC(hagar, damageforcescale);
-               missile.event_damage = W_Hagar_Damage;
-               missile.damagedbycontents = true;
-
-               missile.touch = W_Hagar_Touch; // not bouncy
-               missile.use = W_Hagar_Explode2;
-               missile.think = adaptor_think2use_hittype_splash;
-               missile.nextthink = time + WEP_CVAR_SEC(hagar, lifetime_min) + random() * WEP_CVAR_SEC(hagar, lifetime_rand);
-               PROJECTILE_MAKETRIGGER(missile);
-               missile.projectiledeathtype = WEP_HAGAR.m_id | HITTYPE_SECONDARY;
-               setorigin(missile, w_shotorg);
-               setsize(missile, '0 0 0', '0 0 0');
-               missile.movetype = MOVETYPE_FLY;
-               missile.missile_flags = MIF_SPLASH;
-
-               // per-shot spread calculation: the more shots there are, the less spread is applied (based on the bias cvar)
-               spread_pershot = ((shots - 1) / (WEP_CVAR_SEC(hagar, load_max) - 1));
-               spread_pershot = (1 - (spread_pershot * WEP_CVAR_SEC(hagar, load_spread_bias)));
-               spread_pershot = (WEP_CVAR_SEC(hagar, spread) * spread_pershot * g_weaponspreadfactor);
-
-               // pattern spread calculation
-               s = '0 0 0';
-               if(counter == 0)
-                       s = '0 0 0';
-               else
-               {
-                       makevectors('0 360 0' * (0.75 + (counter - 0.5) / (shots - 1)));
-                       s.y = v_forward.x;
-                       s.z = v_forward.y;
-               }
-               s = s * WEP_CVAR_SEC(hagar, load_spread) * g_weaponspreadfactor;
-
-               W_SetupProjVelocity_Explicit(missile, w_shotdir + right * s.y + up * s.z, v_up, WEP_CVAR_SEC(hagar, speed), 0, 0, spread_pershot, false);
-
-               missile.angles = vectoangles(missile.velocity);
-               missile.flags = FL_PROJECTILE;
-
-               CSQCProjectile(missile, true, PROJECTILE_HAGAR, true);
-
-               MUTATOR_CALLHOOK(EditProjectile, self, missile);
-       }
-
-       weapon_thinkf(WFRAME_FIRE2, WEP_CVAR_SEC(hagar, load_animtime), w_ready);
-       self.hagar_loadstep = time + WEP_CVAR_SEC(hagar, refire) * W_WeaponRateFactor();
-       self.hagar_load = 0;
-}
-
-void W_Hagar_Attack2_Load(void)
-{
-       // loadable hagar secondary attack, must always run each frame
-
-       if(time < game_starttime)
-               return;
-
-       bool loaded = self.hagar_load >= WEP_CVAR_SEC(hagar, load_max);
-
-       // this is different than WR_CHECKAMMO when it comes to reloading
-       bool enough_ammo;
-       if(self.items & IT_UNLIMITED_WEAPON_AMMO)
-               enough_ammo = true;
-       else if(autocvar_g_balance_hagar_reload_ammo)
-               enough_ammo = self.(weapon_load[WEP_HAGAR.m_id]) >= WEP_CVAR_SEC(hagar, ammo);
-       else
-               enough_ammo = self.WEP_AMMO(HAGAR) >= WEP_CVAR_SEC(hagar, ammo);
-
-       bool stopped = loaded || !enough_ammo;
-
-       if(self.BUTTON_ATCK2)
-       {
-               if(self.BUTTON_ATCK && WEP_CVAR_SEC(hagar, load_abort))
-               {
-                       if(self.hagar_load)
-                       {
-                               // if we pressed primary fire while loading, unload all rockets and abort
-                               self.weaponentity.state = WS_READY;
-                               W_DecreaseAmmo(WEP_CVAR_SEC(hagar, ammo) * self.hagar_load * -1); // give back ammo
-                               self.hagar_load = 0;
-                               sound(self, CH_WEAPON_A, W_Sound("hagar_beep"), VOL_BASE, ATTN_NORM);
-
-                               // pause until we can load rockets again, once we re-press the alt fire button
-                               self.hagar_loadstep = time + WEP_CVAR_SEC(hagar, load_speed) * W_WeaponRateFactor();
-
-                               // require letting go of the alt fire button before we can load again
-                               self.hagar_loadblock = true;
-                       }
-               }
-               else
-               {
-                       // check if we can attempt to load another rocket
-                       if(!stopped)
-                       {
-                               if(!self.hagar_loadblock && self.hagar_loadstep < time)
-                               {
-                                       W_DecreaseAmmo(WEP_CVAR_SEC(hagar, ammo));
-                                       self.weaponentity.state = WS_INUSE;
-                                       self.hagar_load += 1;
-                                       sound(self, CH_WEAPON_B, W_Sound("hagar_load"), VOL_BASE * 0.8, ATTN_NORM); // sound is too loud according to most
-
-                                       if(self.hagar_load >= WEP_CVAR_SEC(hagar, load_max))
-                                               stopped = true;
-                                       else
-                                               self.hagar_loadstep = time + WEP_CVAR_SEC(hagar, load_speed) * W_WeaponRateFactor();
-                               }
-                       }
-                       if(stopped && !self.hagar_loadbeep && self.hagar_load) // prevents the beep from playing each frame
-                       {
-                               // if this is the last rocket we can load, play a beep sound to notify the player
-                               sound(self, CH_WEAPON_A, W_Sound("hagar_beep"), VOL_BASE, ATTN_NORM);
-                               self.hagar_loadbeep = true;
-                               self.hagar_loadstep = time + WEP_CVAR_SEC(hagar, load_hold) * W_WeaponRateFactor();
-                       }
-               }
-       }
-       else if(self.hagar_loadblock)
-       {
-               // the alt fire button has been released, so re-enable loading if blocked
-               self.hagar_loadblock = false;
-       }
-
-       if(self.hagar_load)
-       {
-               // play warning sound if we're about to release
-               if(stopped && self.hagar_loadstep - 0.5 < time && WEP_CVAR_SEC(hagar, load_hold) >= 0)
-               {
-                       if(!self.hagar_warning) // prevents the beep from playing each frame
-                       {
-                               // we're about to automatically release after holding time, play a beep sound to notify the player
-                               sound(self, CH_WEAPON_A, W_Sound("hagar_beep"), VOL_BASE, ATTN_NORM);
-                               self.hagar_warning = true;
-                       }
-               }
-
-               // release if player let go of button or if they've held it in too long
-               if(!self.BUTTON_ATCK2 || (stopped && self.hagar_loadstep < time && WEP_CVAR_SEC(hagar, load_hold) >= 0))
-               {
-                       self.weaponentity.state = WS_READY;
-                       W_Hagar_Attack2_Load_Release();
-               }
-       }
-       else
-       {
-               self.hagar_loadbeep = false;
-               self.hagar_warning = false;
-
-               // we aren't checking ammo during an attack, so we must do it here
-               if(!(WEP_ACTION(self.weapon, WR_CHECKAMMO1) + WEP_ACTION(self.weapon, WR_CHECKAMMO2)))
-               if(!(self.items & IT_UNLIMITED_WEAPON_AMMO))
-               {
-                       // note: this doesn't force the switch
-                       W_SwitchToOtherWeapon(self);
-                       return;
-               }
-       }
-}
-
-bool W_Hagar(int req)
-{
-       float ammo_amount;
-       switch(req)
-       {
-               case WR_AIM:
-               {
-                       if(random()>0.15)
-                               self.BUTTON_ATCK = bot_aim(WEP_CVAR_PRI(hagar, speed), 0, WEP_CVAR_PRI(hagar, lifetime), false);
-                       else // not using secondary_speed since these are only 15% and should cause some ricochets without re-aiming
-                               self.BUTTON_ATCK2 = bot_aim(WEP_CVAR_PRI(hagar, speed), 0, WEP_CVAR_PRI(hagar, lifetime), false);
-
-                       return true;
-               }
-               case WR_THINK:
-               {
-                       float loadable_secondary;
-                       loadable_secondary = (WEP_CVAR_SEC(hagar, load) && WEP_CVAR(hagar, secondary));
-
-                       if(loadable_secondary)
-                               W_Hagar_Attack2_Load(); // must always run each frame
-                       if(autocvar_g_balance_hagar_reload_ammo && self.clip_load < min(WEP_CVAR_PRI(hagar, ammo), WEP_CVAR_SEC(hagar, ammo))) // forced reload
-                               WEP_ACTION(self.weapon, WR_RELOAD);
-                       else if(self.BUTTON_ATCK && !self.hagar_load && !self.hagar_loadblock) // not while secondary is loaded or awaiting reset
-                       {
-                               if(weapon_prepareattack(0, WEP_CVAR_PRI(hagar, refire)))
-                               {
-                                       W_Hagar_Attack();
-                                       weapon_thinkf(WFRAME_FIRE1, WEP_CVAR_PRI(hagar, refire), w_ready);
-                               }
-                       }
-                       else if(self.BUTTON_ATCK2 && !loadable_secondary && WEP_CVAR(hagar, secondary))
-                       {
-                               if(weapon_prepareattack(1, WEP_CVAR_SEC(hagar, refire)))
-                               {
-                                       W_Hagar_Attack2();
-                                       weapon_thinkf(WFRAME_FIRE2, WEP_CVAR_SEC(hagar, refire), w_ready);
-                               }
-                       }
-                       return true;
-               }
-               case WR_GONETHINK:
-               {
-                       // we lost the weapon and want to prepare switching away
-                       if(self.hagar_load)
-                       {
-                               self.weaponentity.state = WS_READY;
-                               W_Hagar_Attack2_Load_Release();
-                       }
-
-                       return true;
-               }
-               case WR_INIT:
-               {
-                       precache_model(W_Model("g_hagar.md3"));
-                       precache_model(W_Model("v_hagar.md3"));
-                       precache_model(W_Model("h_hagar.iqm"));
-                       precache_sound(W_Sound("hagar_fire"));
-                       precache_sound(W_Sound("hagar_load"));
-                       precache_sound(W_Sound("hagar_beep"));
-                       HAGAR_SETTINGS(WEP_SKIP_CVAR, WEP_SET_PROP);
-                       return true;
-               }
-               case WR_SETUP:
-               {
-                       self.hagar_loadblock = false;
-
-                       if(self.hagar_load)
-                       {
-                               W_DecreaseAmmo(WEP_CVAR_SEC(hagar, ammo) * self.hagar_load * -1); // give back ammo if necessary
-                               self.hagar_load = 0;
-                       }
-
-                       return true;
-               }
-               case WR_CHECKAMMO1:
-               {
-                       ammo_amount = self.WEP_AMMO(HAGAR) >= WEP_CVAR_PRI(hagar, ammo);
-                       ammo_amount += self.(weapon_load[WEP_HAGAR.m_id]) >= WEP_CVAR_PRI(hagar, ammo);
-                       return ammo_amount;
-               }
-               case WR_CHECKAMMO2:
-               {
-                       ammo_amount = self.WEP_AMMO(HAGAR) >= WEP_CVAR_SEC(hagar, ammo);
-                       ammo_amount += self.(weapon_load[WEP_HAGAR.m_id]) >= WEP_CVAR_SEC(hagar, ammo);
-                       return ammo_amount;
-               }
-               case WR_CONFIG:
-               {
-                       HAGAR_SETTINGS(WEP_CONFIG_WRITE_CVARS, WEP_CONFIG_WRITE_PROPS);
-                       return true;
-               }
-               case WR_RESETPLAYER:
-               {
-                       self.hagar_load = 0;
-                       return true;
-               }
-               case WR_PLAYERDEATH:
-               {
-                       // if we have any rockets loaded when we die, release them
-                       if(self.hagar_load && WEP_CVAR_SEC(hagar, load_releasedeath))
-                               W_Hagar_Attack2_Load_Release();
-
-                       return true;
-               }
-               case WR_RELOAD:
-               {
-                       if(!self.hagar_load) // require releasing loaded rockets first
-                               W_Reload(min(WEP_CVAR_PRI(hagar, ammo), WEP_CVAR_SEC(hagar, ammo)), W_Sound("reload"));
-
-                       return true;
-               }
-               case WR_SUICIDEMESSAGE:
-               {
-                       return WEAPON_HAGAR_SUICIDE;
-               }
-               case WR_KILLMESSAGE:
-               {
-                       if(w_deathtype & HITTYPE_SECONDARY)
-                               return WEAPON_HAGAR_MURDER_BURST;
-                       else
-                               return WEAPON_HAGAR_MURDER_SPRAY;
-               }
-       }
-       return false;
-}
-#endif
-#ifdef CSQC
-bool W_Hagar(int req)
-{
-       switch(req)
-       {
-               case WR_IMPACTEFFECT:
-               {
-                       vector org2;
-                       org2 = w_org + w_backoff * 6;
-                       pointparticles(particleeffectnum(EFFECT_HAGAR_EXPLODE), org2, '0 0 0', 1);
-                       if(!w_issilent)
-                       {
-                               if(w_random<0.15)
-                                       sound(self, CH_SHOTS, W_Sound("hagexp1"), VOL_BASE, ATTN_NORM);
-                               else if(w_random<0.7)
-                                       sound(self, CH_SHOTS, W_Sound("hagexp2"), VOL_BASE, ATTN_NORM);
-                               else
-                                       sound(self, CH_SHOTS, W_Sound("hagexp3"), VOL_BASE, ATTN_NORM);
-                       }
-
-                       return true;
-               }
-               case WR_INIT:
-               {
-                       precache_sound(W_Sound("hagexp1"));
-                       precache_sound(W_Sound("hagexp2"));
-                       precache_sound(W_Sound("hagexp3"));
-                       return true;
-               }
-               case WR_ZOOMRETICLE:
-               {
-                       // no weapon specific image for this weapon
-                       return false;
-               }
-       }
-       return false;
-}
-#endif
-#endif
diff --git a/qcsrc/common/weapons/w_hlac.qc b/qcsrc/common/weapons/w_hlac.qc
deleted file mode 100644 (file)
index 4968529..0000000
+++ /dev/null
@@ -1,314 +0,0 @@
-#ifndef IMPLEMENTATION
-REGISTER_WEAPON(
-/* WEP_##id  */ HLAC,
-/* function  */ W_HLAC,
-/* ammotype  */ ammo_cells,
-/* impulse   */ 6,
-/* flags     */ WEP_FLAG_MUTATORBLOCKED | WEP_FLAG_RELOADABLE | WEP_TYPE_SPLASH,
-/* rating    */ BOT_PICKUP_RATING_MID,
-/* color     */ '0 1 0',
-/* modelname */ "hlac",
-/* simplemdl */ "foobar",
-/* crosshair */ "gfx/crosshairhlac 0.6",
-/* wepimg    */ "weaponhlac",
-/* refname   */ "hlac",
-/* wepname   */ _("Heavy Laser Assault Cannon")
-);
-
-#define HLAC_SETTINGS(w_cvar,w_prop) HLAC_SETTINGS_LIST(w_cvar, w_prop, HLAC, hlac)
-#define HLAC_SETTINGS_LIST(w_cvar,w_prop,id,sn) \
-       w_cvar(id, sn, BOTH, ammo) \
-       w_cvar(id, sn, BOTH, animtime) \
-       w_cvar(id, sn, BOTH, damage) \
-       w_cvar(id, sn, BOTH, edgedamage) \
-       w_cvar(id, sn, BOTH, force) \
-       w_cvar(id, sn, BOTH, lifetime) \
-       w_cvar(id, sn, BOTH, radius) \
-       w_cvar(id, sn, BOTH, refire) \
-       w_cvar(id, sn, BOTH, speed) \
-       w_cvar(id, sn, BOTH, spread_crouchmod) \
-       w_cvar(id, sn, PRI,  spread_add) \
-       w_cvar(id, sn, PRI,  spread_max) \
-       w_cvar(id, sn, PRI,  spread_min) \
-       w_cvar(id, sn, NONE, secondary) \
-       w_cvar(id, sn, SEC,  shots) \
-       w_cvar(id, sn, SEC,  spread) \
-       w_prop(id, sn, float,  reloading_ammo, reload_ammo) \
-       w_prop(id, sn, float,  reloading_time, reload_time) \
-       w_prop(id, sn, float,  switchdelay_raise, switchdelay_raise) \
-       w_prop(id, sn, float,  switchdelay_drop, switchdelay_drop) \
-       w_prop(id, sn, string, weaponreplace, weaponreplace) \
-       w_prop(id, sn, float,  weaponstart, weaponstart) \
-       w_prop(id, sn, float,  weaponstartoverride, weaponstartoverride) \
-       w_prop(id, sn, float,  weaponthrowable, weaponthrowable)
-
-#ifdef SVQC
-HLAC_SETTINGS(WEP_ADD_CVAR, WEP_ADD_PROP)
-#endif
-#endif
-#ifdef IMPLEMENTATION
-#ifdef SVQC
-void spawnfunc_weapon_hlac(void) { weapon_defaultspawnfunc(WEP_HLAC.m_id); }
-
-void W_HLAC_Touch(void)
-{
-       float isprimary;
-
-       PROJECTILE_TOUCH;
-
-       self.event_damage = func_null;
-
-       isprimary = !(self.projectiledeathtype & HITTYPE_SECONDARY);
-
-       RadiusDamage(self, self.realowner, WEP_CVAR_BOTH(hlac, isprimary, damage), WEP_CVAR_BOTH(hlac, isprimary, edgedamage), WEP_CVAR_BOTH(hlac, isprimary, radius), world, world, WEP_CVAR_BOTH(hlac, isprimary, force), self.projectiledeathtype, other);
-
-       remove(self);
-}
-
-void W_HLAC_Attack(void)
-{
-       entity missile;
-    float spread;
-
-       W_DecreaseAmmo(WEP_CVAR_PRI(hlac, ammo));
-
-    spread = WEP_CVAR_PRI(hlac, spread_min) + (WEP_CVAR_PRI(hlac, spread_add) * self.misc_bulletcounter);
-    spread = min(spread,WEP_CVAR_PRI(hlac, spread_max));
-    if(self.crouch)
-        spread = spread * WEP_CVAR_PRI(hlac, spread_crouchmod);
-
-       W_SetupShot(self, false, 3, W_Sound("lasergun_fire"), CH_WEAPON_A, WEP_CVAR_PRI(hlac, damage));
-       Send_Effect(EFFECT_BLASTER_MUZZLEFLASH, w_shotorg, w_shotdir * 1000, 1);
-       if(!autocvar_g_norecoil)
-       {
-               self.punchangle_x = random() - 0.5;
-               self.punchangle_y = random() - 0.5;
-       }
-
-       missile = spawn();
-       missile.owner = missile.realowner = self;
-       missile.classname = "hlacbolt";
-       missile.bot_dodge = true;
-
-    missile.bot_dodgerating = WEP_CVAR_PRI(hlac, damage);
-
-       missile.movetype = MOVETYPE_FLY;
-       PROJECTILE_MAKETRIGGER(missile);
-
-       setorigin(missile, w_shotorg);
-       setsize(missile, '0 0 0', '0 0 0');
-
-       W_SetupProjVelocity_Basic(missile, WEP_CVAR_PRI(hlac, speed), spread);
-       //missile.angles = vectoangles(missile.velocity); // csqc
-
-       missile.touch = W_HLAC_Touch;
-       missile.think = SUB_Remove;
-
-    missile.nextthink = time + WEP_CVAR_PRI(hlac, lifetime);
-
-       missile.flags = FL_PROJECTILE;
-       missile.projectiledeathtype = WEP_HLAC.m_id;
-
-       CSQCProjectile(missile, true, PROJECTILE_HLAC, true);
-
-       MUTATOR_CALLHOOK(EditProjectile, self, missile);
-}
-
-void W_HLAC_Attack2(void)
-{
-       entity missile;
-    float spread;
-
-    spread = WEP_CVAR_SEC(hlac, spread);
-
-
-    if(self.crouch)
-        spread = spread * WEP_CVAR_SEC(hlac, spread_crouchmod);
-
-       W_SetupShot(self, false, 3, W_Sound("lasergun_fire"), CH_WEAPON_A, WEP_CVAR_SEC(hlac, damage));
-       Send_Effect(EFFECT_BLASTER_MUZZLEFLASH, w_shotorg, w_shotdir * 1000, 1);
-
-       missile = spawn();
-       missile.owner = missile.realowner = self;
-       missile.classname = "hlacbolt";
-       missile.bot_dodge = true;
-
-    missile.bot_dodgerating = WEP_CVAR_SEC(hlac, damage);
-
-       missile.movetype = MOVETYPE_FLY;
-       PROJECTILE_MAKETRIGGER(missile);
-
-       setorigin(missile, w_shotorg);
-       setsize(missile, '0 0 0', '0 0 0');
-
-       W_SetupProjVelocity_Basic(missile, WEP_CVAR_SEC(hlac, speed), spread);
-       //missile.angles = vectoangles(missile.velocity); // csqc
-
-       missile.touch = W_HLAC_Touch;
-       missile.think = SUB_Remove;
-
-    missile.nextthink = time + WEP_CVAR_SEC(hlac, lifetime);
-
-       missile.flags = FL_PROJECTILE;
-       missile.missile_flags = MIF_SPLASH;
-       missile.projectiledeathtype = WEP_HLAC.m_id | HITTYPE_SECONDARY;
-
-       CSQCProjectile(missile, true, PROJECTILE_HLAC, true);
-
-       MUTATOR_CALLHOOK(EditProjectile, self, missile);
-}
-
-// weapon frames
-void W_HLAC_Attack_Frame(void)
-{
-       if(self.weapon != self.switchweapon) // abort immediately if switching
-       {
-               w_ready();
-               return;
-       }
-
-       if(self.BUTTON_ATCK)
-       {
-               if(!WEP_ACTION(self.weapon, WR_CHECKAMMO1))
-               if(!(self.items & IT_UNLIMITED_WEAPON_AMMO))
-               {
-                       W_SwitchWeapon_Force(self, w_getbestweapon(self));
-                       w_ready();
-                       return;
-               }
-
-               ATTACK_FINISHED(self) = time + WEP_CVAR_PRI(hlac, refire) * W_WeaponRateFactor();
-               W_HLAC_Attack();
-               self.misc_bulletcounter = self.misc_bulletcounter + 1;
-        weapon_thinkf(WFRAME_FIRE1, WEP_CVAR_PRI(hlac, refire), W_HLAC_Attack_Frame);
-       }
-       else
-       {
-               weapon_thinkf(WFRAME_FIRE1, WEP_CVAR_PRI(hlac, animtime), w_ready);
-       }
-}
-
-void W_HLAC_Attack2_Frame(void)
-{
-    float i;
-
-       W_DecreaseAmmo(WEP_CVAR_SEC(hlac, ammo));
-
-    for(i=WEP_CVAR_SEC(hlac, shots);i>0;--i)
-        W_HLAC_Attack2();
-
-       if(!autocvar_g_norecoil)
-       {
-               self.punchangle_x = random() - 0.5;
-               self.punchangle_y = random() - 0.5;
-       }
-}
-
-bool W_HLAC(int req)
-{
-       float ammo_amount;
-       switch(req)
-       {
-               case WR_AIM:
-               {
-                       self.BUTTON_ATCK = bot_aim(WEP_CVAR_PRI(hlac, speed), 0, WEP_CVAR_PRI(hlac, lifetime), false);
-                       return true;
-               }
-               case WR_THINK:
-               {
-                       if(autocvar_g_balance_hlac_reload_ammo && self.clip_load < min(WEP_CVAR_PRI(hlac, ammo), WEP_CVAR_SEC(hlac, ammo))) // forced reload
-                               WEP_ACTION(self.weapon, WR_RELOAD);
-                       else if(self.BUTTON_ATCK)
-                       {
-                               if(weapon_prepareattack(0, WEP_CVAR_PRI(hlac, refire)))
-                               {
-                                       self.misc_bulletcounter = 0;
-                                       W_HLAC_Attack();
-                                       weapon_thinkf(WFRAME_FIRE1, WEP_CVAR_PRI(hlac, refire), W_HLAC_Attack_Frame);
-                               }
-                       }
-
-                       else if(self.BUTTON_ATCK2 && WEP_CVAR(hlac, secondary))
-                       {
-                               if(weapon_prepareattack(1, WEP_CVAR_SEC(hlac, refire)))
-                               {
-                                       W_HLAC_Attack2_Frame();
-                                       weapon_thinkf(WFRAME_FIRE2, WEP_CVAR_SEC(hlac, animtime), w_ready);
-                               }
-                       }
-
-                       return true;
-               }
-               case WR_INIT:
-               {
-                       precache_model(W_Model("g_hlac.md3"));
-                       precache_model(W_Model("v_hlac.md3"));
-                       precache_model(W_Model("h_hlac.iqm"));
-                       precache_sound(W_Sound("lasergun_fire"));
-                       HLAC_SETTINGS(WEP_SKIP_CVAR, WEP_SET_PROP);
-                       return true;
-               }
-               case WR_CHECKAMMO1:
-               {
-                       ammo_amount = self.WEP_AMMO(HLAC) >= WEP_CVAR_PRI(hlac, ammo);
-                       ammo_amount += self.(weapon_load[WEP_HLAC.m_id]) >= WEP_CVAR_PRI(hlac, ammo);
-                       return ammo_amount;
-               }
-               case WR_CHECKAMMO2:
-               {
-                       ammo_amount = self.WEP_AMMO(HLAC) >= WEP_CVAR_SEC(hlac, ammo);
-                       ammo_amount += self.(weapon_load[WEP_HLAC.m_id]) >= WEP_CVAR_SEC(hlac, ammo);
-                       return ammo_amount;
-               }
-               case WR_CONFIG:
-               {
-                       HLAC_SETTINGS(WEP_CONFIG_WRITE_CVARS, WEP_CONFIG_WRITE_PROPS);
-                       return true;
-               }
-               case WR_RELOAD:
-               {
-                       W_Reload(min(WEP_CVAR_PRI(hlac, ammo), WEP_CVAR_SEC(hlac, ammo)), W_Sound("reload"));
-                       return true;
-               }
-               case WR_SUICIDEMESSAGE:
-               {
-                       return WEAPON_HLAC_SUICIDE;
-               }
-               case WR_KILLMESSAGE:
-               {
-                       return WEAPON_HLAC_MURDER;
-               }
-       }
-       return false;
-}
-#endif
-#ifdef CSQC
-bool W_HLAC(int req)
-{
-       switch(req)
-       {
-               case WR_IMPACTEFFECT:
-               {
-                       vector org2;
-                       org2 = w_org + w_backoff * 6;
-                       pointparticles(particleeffectnum(EFFECT_BLASTER_IMPACT), org2, w_backoff * 1000, 1);
-                       if(!w_issilent)
-                               sound(self, CH_SHOTS, W_Sound("laserimpact"), VOL_BASE, ATTN_NORM);
-
-                       return true;
-               }
-               case WR_INIT:
-               {
-                       precache_sound(W_Sound("laserimpact"));
-                       return true;
-               }
-               case WR_ZOOMRETICLE:
-               {
-                       // no weapon specific image for this weapon
-                       return false;
-               }
-       }
-       return false;
-}
-#endif
-#endif
diff --git a/qcsrc/common/weapons/w_hmg.qc b/qcsrc/common/weapons/w_hmg.qc
deleted file mode 100644 (file)
index 52b60e8..0000000
+++ /dev/null
@@ -1,208 +0,0 @@
-#ifndef IMPLEMENTATION
-REGISTER_WEAPON(
-/* WEP_##id     */ HMG,
-/* function     */ W_HeavyMachineGun,
-/* ammotype     */ ammo_nails,
-/* impulse      */ 3,
-/* flags        */ WEP_FLAG_MUTATORBLOCKED | WEP_FLAG_HIDDEN | WEP_FLAG_NORMAL | WEP_FLAG_RELOADABLE | WEP_TYPE_HITSCAN | WEP_FLAG_SUPERWEAPON,
-/* rating       */ BOT_PICKUP_RATING_HIGH,
-/* color     */ '0.5 0.5 0',
-/* modelname */ "ok_hmg",
-/* simplemdl */ "foobar",
-/* crosshair */ "gfx/crosshairuzi 0.6",
-/* wepimg    */ "weaponhmg",
-/* refname   */ "hmg",
-/* wepname   */ _("Heavy Machine Gun")
-);
-
-#define HMG_SETTINGS(w_cvar,w_prop) HMG_SETTINGS_LIST(w_cvar, w_prop, HMG, hmg)
-#define HMG_SETTINGS_LIST(w_cvar,w_prop,id,sn) \
-       w_cvar(id, sn, NONE, spread_min) \
-       w_cvar(id, sn, NONE, spread_max) \
-       w_cvar(id, sn, NONE, spread_add) \
-       w_cvar(id, sn, NONE, solidpenetration) \
-       w_cvar(id, sn, NONE, damage) \
-       w_cvar(id, sn, NONE, force) \
-       w_cvar(id, sn, NONE, refire) \
-       w_cvar(id, sn, NONE, ammo) \
-       w_prop(id, sn, float,  reloading_ammo, reload_ammo) \
-       w_prop(id, sn, float,  reloading_time, reload_time) \
-       w_prop(id, sn, float,  switchdelay_raise, switchdelay_raise) \
-       w_prop(id, sn, float,  switchdelay_drop, switchdelay_drop) \
-       w_prop(id, sn, string, weaponreplace, weaponreplace) \
-       w_prop(id, sn, float,  weaponstart, weaponstart) \
-       w_prop(id, sn, float,  weaponstartoverride, weaponstartoverride) \
-       w_prop(id, sn, float,  weaponthrowable, weaponthrowable)
-
-#ifdef SVQC
-HMG_SETTINGS(WEP_ADD_CVAR, WEP_ADD_PROP)
-#endif
-#endif
-#ifdef IMPLEMENTATION
-#ifdef SVQC
-
-void spawnfunc_weapon_hmg() { weapon_defaultspawnfunc(WEP_HMG.m_id); }
-
-void W_HeavyMachineGun_Attack_Auto()
-{
-       if (!self.BUTTON_ATCK)
-       {
-               w_ready();
-               return;
-       }
-
-       if(!WEP_ACTION(self.weapon, WR_CHECKAMMO1))
-       if(!(self.items & IT_UNLIMITED_WEAPON_AMMO))
-       {
-               W_SwitchWeapon_Force(self, w_getbestweapon(self));
-               w_ready();
-               return;
-       }
-
-       W_DecreaseAmmo(WEP_CVAR(hmg, ammo));
-
-       W_SetupShot (self, true, 0, W_Sound("uzi_fire"), CH_WEAPON_A, WEP_CVAR(hmg, damage));
-
-       if(!autocvar_g_norecoil)
-       {
-               self.punchangle_x = random () - 0.5;
-               self.punchangle_y = random () - 0.5;
-       }
-
-       float hmg_spread = bound(WEP_CVAR(hmg, spread_min), WEP_CVAR(hmg, spread_min) + (WEP_CVAR(hmg, spread_add) * self.misc_bulletcounter), WEP_CVAR(hmg, spread_max));
-       fireBullet(w_shotorg, w_shotdir, hmg_spread, WEP_CVAR(hmg, solidpenetration), WEP_CVAR(hmg, damage), WEP_CVAR(hmg, force), WEP_HMG.m_id, 0);
-
-       self.misc_bulletcounter = self.misc_bulletcounter + 1;
-
-       Send_Effect(EFFECT_MACHINEGUN_MUZZLEFLASH, w_shotorg, w_shotdir * 1000, 1);
-
-       W_MachineGun_MuzzleFlash();
-       W_AttachToShotorg(self.muzzle_flash, '5 0 0');
-
-       if (autocvar_g_casings >= 2) // casing code
-               SpawnCasing (((random () * 50 + 50) * v_right) - (v_forward * (random () * 25 + 25)) - ((random () * 5 - 70) * v_up), 2, vectoangles(v_forward),'0 250 0', 100, 3, self);
-
-       ATTACK_FINISHED(self) = time + WEP_CVAR(hmg, refire) * W_WeaponRateFactor();
-       weapon_thinkf(WFRAME_FIRE1, WEP_CVAR(hmg, refire), W_HeavyMachineGun_Attack_Auto);
-}
-
-bool W_HeavyMachineGun(int req)
-{
-       float ammo_amount;
-       switch(req)
-       {
-               case WR_AIM:
-               {
-                       if(vlen(self.origin-self.enemy.origin) < 3000 - bound(0, skill, 10) * 200)
-                               self.BUTTON_ATCK = bot_aim(1000000, 0, 0.001, false);
-                       else
-                               self.BUTTON_ATCK2 = bot_aim(1000000, 0, 0.001, false);
-
-                       return true;
-               }
-               case WR_THINK:
-               {
-                       if(WEP_CVAR(hmg, reload_ammo) && self.clip_load < WEP_CVAR(hmg, ammo)) // forced reload
-                               WEP_ACTION(self.weapon, WR_RELOAD);
-                       else
-                       {
-                               if (self.BUTTON_ATCK)
-                               if (weapon_prepareattack(0, 0))
-                               {
-                                       self.misc_bulletcounter = 0;
-                                       W_HeavyMachineGun_Attack_Auto();
-                               }
-                       }
-
-                       return true;
-               }
-               case WR_INIT:
-               {
-                       precache_model ("models/uziflash.md3");
-                       precache_model(W_Model("g_ok_hmg.md3"));
-                       precache_model(W_Model("v_ok_hmg.md3"));
-                       precache_model(W_Model("h_ok_hmg.iqm"));
-                       precache_sound (W_Sound("uzi_fire"));
-                       HMG_SETTINGS(WEP_SKIP_CVAR, WEP_SET_PROP);
-                       return true;
-               }
-               case WR_CHECKAMMO1:
-               {
-                       ammo_amount = self.ammo_nails >= WEP_CVAR(hmg, ammo);
-
-                       if(autocvar_g_balance_hmg_reload_ammo)
-                               ammo_amount += self.(weapon_load[WEP_HMG.m_id]) >= WEP_CVAR(hmg, ammo);
-
-                       return ammo_amount;
-               }
-               case WR_CHECKAMMO2:
-               {
-                       ammo_amount = self.ammo_nails >= WEP_CVAR(hmg, ammo);
-
-                       if(autocvar_g_balance_hmg_reload_ammo)
-                               ammo_amount += self.(weapon_load[WEP_HMG.m_id]) >= WEP_CVAR(hmg, ammo);
-
-                       return ammo_amount;
-               }
-               case WR_CONFIG:
-               {
-                       HMG_SETTINGS(WEP_CONFIG_WRITE_CVARS, WEP_CONFIG_WRITE_PROPS);
-                       return true;
-               }
-               case WR_RELOAD:
-               {
-                       W_Reload(WEP_CVAR(hmg, ammo), W_Sound("reload"));
-                       return true;
-               }
-               case WR_SUICIDEMESSAGE:
-               {
-                       return WEAPON_THINKING_WITH_PORTALS;
-               }
-               case WR_KILLMESSAGE:
-               {
-                       if(w_deathtype & HITTYPE_SECONDARY)
-                               return WEAPON_HMG_MURDER_SNIPE;
-                       else
-                               return WEAPON_HMG_MURDER_SPRAY;
-               }
-       }
-       return false;
-}
-#endif
-#ifdef CSQC
-bool W_HeavyMachineGun(int req)
-{
-       switch(req)
-       {
-               case WR_IMPACTEFFECT:
-               {
-                       vector org2;
-                       org2 = w_org + w_backoff * 2;
-                       pointparticles(particleeffectnum(EFFECT_MACHINEGUN_IMPACT), org2, w_backoff * 1000, 1);
-                       if(!w_issilent)
-                               if(w_random < 0.05)
-                                       sound(self, CH_SHOTS, W_Sound("ric1"), VOL_BASE, ATTEN_NORM);
-                               else if(w_random < 0.1)
-                                       sound(self, CH_SHOTS, W_Sound("ric2"), VOL_BASE, ATTEN_NORM);
-                               else if(w_random < 0.2)
-                                       sound(self, CH_SHOTS, W_Sound("ric3"), VOL_BASE, ATTEN_NORM);
-
-                       return true;
-               }
-               case WR_INIT:
-               {
-                       precache_sound(W_Sound("ric1"));
-                       precache_sound(W_Sound("ric2"));
-                       precache_sound(W_Sound("ric3"));
-                       return true;
-               }
-               case WR_ZOOMRETICLE:
-               {
-                       // no weapon specific image for this weapon
-                       return false;
-               }
-       }
-       return false;
-}
-#endif
-#endif
diff --git a/qcsrc/common/weapons/w_hook.qc b/qcsrc/common/weapons/w_hook.qc
deleted file mode 100644 (file)
index 6c5519e..0000000
+++ /dev/null
@@ -1,368 +0,0 @@
-#ifndef IMPLEMENTATION
-REGISTER_WEAPON(
-/* WEP_##id  */ HOOK,
-/* function  */ W_Hook,
-/* ammotype  */ ammo_fuel,
-/* impulse   */ 0,
-/* flags     */ WEP_FLAG_CANCLIMB | WEP_TYPE_SPLASH,
-/* rating    */ 0,
-/* color     */ '0 0.5 0',
-/* modelname */ "hookgun",
-/* simplemdl */ "foobar",
-/* crosshair */ "gfx/crosshairhook 0.5",
-/* wepimg    */ "weaponhook",
-/* refname   */ "hook",
-/* wepname   */ _("Grappling Hook")
-);
-
-#define HOOK_SETTINGS(w_cvar,w_prop) HOOK_SETTINGS_LIST(w_cvar, w_prop, HOOK, hook)
-#define HOOK_SETTINGS_LIST(w_cvar,w_prop,id,sn) \
-       w_cvar(id, sn, BOTH, animtime) \
-       w_cvar(id, sn, BOTH, refire) \
-       w_cvar(id, sn, PRI,  ammo) \
-       w_cvar(id, sn, PRI,  hooked_ammo) \
-       w_cvar(id, sn, PRI,  hooked_time_free) \
-       w_cvar(id, sn, PRI,  hooked_time_max) \
-       w_cvar(id, sn, SEC,  damage) \
-       w_cvar(id, sn, SEC,  duration) \
-       w_cvar(id, sn, SEC,  edgedamage) \
-       w_cvar(id, sn, SEC,  force) \
-       w_cvar(id, sn, SEC,  gravity) \
-       w_cvar(id, sn, SEC,  lifetime) \
-       w_cvar(id, sn, SEC,  power) \
-       w_cvar(id, sn, SEC,  radius) \
-       w_cvar(id, sn, SEC,  speed) \
-       w_cvar(id, sn, SEC,  health) \
-       w_cvar(id, sn, SEC,  damageforcescale) \
-       w_prop(id, sn, float,  switchdelay_raise, switchdelay_raise) \
-       w_prop(id, sn, float,  switchdelay_drop, switchdelay_drop) \
-       w_prop(id, sn, string, weaponreplace, weaponreplace) \
-       w_prop(id, sn, float,  weaponstart, weaponstart) \
-       w_prop(id, sn, float,  weaponstartoverride, weaponstartoverride) \
-       w_prop(id, sn, float,  weaponthrowable, weaponthrowable)
-
-#ifdef SVQC
-HOOK_SETTINGS(WEP_ADD_CVAR, WEP_ADD_PROP)
-
-.float dmg;
-.float dmg_edge;
-.float dmg_radius;
-.float dmg_force;
-.float dmg_power;
-.float dmg_duration;
-.float dmg_last;
-.float hook_refire;
-.float hook_time_hooked;
-.float hook_time_fueldecrease;
-#endif
-#endif
-#ifdef IMPLEMENTATION
-#ifdef SVQC
-
-void spawnfunc_weapon_hook(void)
-{
-       if(g_grappling_hook) // offhand hook
-       {
-               startitem_failed = true;
-               remove(self);
-               return;
-       }
-       weapon_defaultspawnfunc(WEP_HOOK.m_id);
-}
-
-void W_Hook_ExplodeThink(void)
-{
-       float dt, dmg_remaining_next, f;
-
-       dt = time - self.teleport_time;
-       dmg_remaining_next = pow(bound(0, 1 - dt / self.dmg_duration, 1), self.dmg_power);
-
-       f = self.dmg_last - dmg_remaining_next;
-       self.dmg_last = dmg_remaining_next;
-
-       RadiusDamage(self, self.realowner, self.dmg * f, self.dmg_edge * f, self.dmg_radius, self.realowner, world, self.dmg_force * f, self.projectiledeathtype, world);
-       self.projectiledeathtype |= HITTYPE_BOUNCE;
-       //RadiusDamage(self, world, self.dmg * f, self.dmg_edge * f, self.dmg_radius, world, world, self.dmg_force * f, self.projectiledeathtype, world);
-
-       if(dt < self.dmg_duration)
-               self.nextthink = time + 0.05; // soon
-       else
-               remove(self);
-}
-
-void W_Hook_Explode2(void)
-{
-       self.event_damage = func_null;
-       self.touch = func_null;
-       self.effects |= EF_NODRAW;
-
-       self.think = W_Hook_ExplodeThink;
-       self.nextthink = time;
-       self.dmg = WEP_CVAR_SEC(hook, damage);
-       self.dmg_edge = WEP_CVAR_SEC(hook, edgedamage);
-       self.dmg_radius = WEP_CVAR_SEC(hook, radius);
-       self.dmg_force = WEP_CVAR_SEC(hook, force);
-       self.dmg_power = WEP_CVAR_SEC(hook, power);
-       self.dmg_duration = WEP_CVAR_SEC(hook, duration);
-       self.teleport_time = time;
-       self.dmg_last = 1;
-       self.movetype = MOVETYPE_NONE;
-}
-
-void W_Hook_Damage(entity inflictor, entity attacker, float damage, int deathtype, vector hitloc, vector force)
-{
-       if(self.health <= 0)
-               return;
-
-       if(!W_CheckProjectileDamage(inflictor.realowner, self.realowner, deathtype, -1)) // no exceptions
-               return; // g_projectiles_damage says to halt
-
-       self.health = self.health - damage;
-
-       if(self.health <= 0)
-               W_PrepareExplosionByDamage(self.realowner, W_Hook_Explode2);
-}
-
-void W_Hook_Touch2(void)
-{
-       PROJECTILE_TOUCH;
-       self.use();
-}
-
-void W_Hook_Attack2(void)
-{
-       entity gren;
-
-       //W_DecreaseAmmo(WEP_CVAR_SEC(hook, ammo)); // WEAPONTODO: Figure out how to handle ammo with hook secondary (gravitybomb)
-       W_SetupShot(self, false, 4, W_Sound("hookbomb_fire"), CH_WEAPON_A, WEP_CVAR_SEC(hook, damage));
-
-       gren = spawn();
-       gren.owner = gren.realowner = self;
-       gren.classname = "hookbomb";
-       gren.bot_dodge = true;
-       gren.bot_dodgerating = WEP_CVAR_SEC(hook, damage);
-       gren.movetype = MOVETYPE_TOSS;
-       PROJECTILE_MAKETRIGGER(gren);
-       gren.projectiledeathtype = WEP_HOOK.m_id | HITTYPE_SECONDARY;
-       setorigin(gren, w_shotorg);
-       setsize(gren, '0 0 0', '0 0 0');
-
-       gren.nextthink = time + WEP_CVAR_SEC(hook, lifetime);
-       gren.think = adaptor_think2use_hittype_splash;
-       gren.use = W_Hook_Explode2;
-       gren.touch = W_Hook_Touch2;
-
-       gren.takedamage = DAMAGE_YES;
-       gren.health = WEP_CVAR_SEC(hook, health);
-       gren.damageforcescale = WEP_CVAR_SEC(hook, damageforcescale);
-       gren.event_damage = W_Hook_Damage;
-       gren.damagedbycontents = true;
-       gren.missile_flags = MIF_SPLASH | MIF_ARC;
-
-       gren.velocity = '0 0 1' * WEP_CVAR_SEC(hook, speed);
-       if(autocvar_g_projectiles_newton_style)
-               gren.velocity = gren.velocity + self.velocity;
-
-       gren.gravity = WEP_CVAR_SEC(hook, gravity);
-       //W_SetupProjVelocity_Basic(gren); // just falling down!
-
-       gren.angles = '0 0 0';
-       gren.flags = FL_PROJECTILE;
-
-       CSQCProjectile(gren, true, PROJECTILE_HOOKBOMB, true);
-
-       MUTATOR_CALLHOOK(EditProjectile, self, gren);
-}
-
-bool W_Hook(int req)
-{
-       float hooked_time_max, hooked_fuel;
-
-       switch(req)
-       {
-               case WR_AIM:
-               {
-                       // no bot AI for hook (yet?)
-                       return true;
-               }
-               case WR_THINK:
-               {
-                       if(self.BUTTON_ATCK || self.BUTTON_HOOK)
-                       {
-                               if(!self.hook)
-                               if(!(self.hook_state & HOOK_WAITING_FOR_RELEASE))
-                               if(!(self.hook_state & HOOK_FIRING))
-                               if(time > self.hook_refire)
-                               if(weapon_prepareattack(0, -1))
-                               {
-                                       W_DecreaseAmmo(WEP_CVAR_PRI(hook, ammo));
-                                       self.hook_state |= HOOK_FIRING;
-                                       weapon_thinkf(WFRAME_FIRE1, WEP_CVAR_PRI(hook, animtime), w_ready);
-                               }
-                       }
-
-                       if(self.BUTTON_ATCK2)
-                       {
-                               if(weapon_prepareattack(1, WEP_CVAR_SEC(hook, refire)))
-                               {
-                                       W_Hook_Attack2();
-                                       weapon_thinkf(WFRAME_FIRE2, WEP_CVAR_SEC(hook, animtime), w_ready);
-                               }
-                       }
-
-                       if(self.hook)
-                       {
-                               // if hooked, no bombs, and increase the timer
-                               self.hook_refire = max(self.hook_refire, time + WEP_CVAR_PRI(hook, refire) * W_WeaponRateFactor());
-
-                               // hook also inhibits health regeneration, but only for 1 second
-                               if(!(self.items & IT_UNLIMITED_WEAPON_AMMO))
-                                       self.pauseregen_finished = max(self.pauseregen_finished, time + autocvar_g_balance_pause_fuel_regen);
-                       }
-
-                       if(self.hook && self.hook.state == 1)
-                       {
-                               hooked_time_max = WEP_CVAR_PRI(hook, hooked_time_max);
-                               if(hooked_time_max > 0)
-                               {
-                                       if( time > self.hook_time_hooked + hooked_time_max )
-                                               self.hook_state |= HOOK_REMOVING;
-                               }
-
-                               hooked_fuel = WEP_CVAR_PRI(hook, hooked_ammo);
-                               if(hooked_fuel > 0)
-                               {
-                                       if( time > self.hook_time_fueldecrease )
-                                       {
-                                               if(!(self.items & IT_UNLIMITED_WEAPON_AMMO))
-                                               {
-                                                       if( self.ammo_fuel >= (time - self.hook_time_fueldecrease) * hooked_fuel )
-                                                       {
-                                                               W_DecreaseAmmo((time - self.hook_time_fueldecrease) * hooked_fuel);
-                                                               self.hook_time_fueldecrease = time;
-                                                               // decrease next frame again
-                                                       }
-                                                       else
-                                                       {
-                                                               self.ammo_fuel = 0;
-                                                               self.hook_state |= HOOK_REMOVING;
-                                                               W_SwitchWeapon_Force(self, w_getbestweapon(self));
-                                                       }
-                                               }
-                                       }
-                               }
-                       }
-                       else
-                       {
-                               self.hook_time_hooked = time;
-                               self.hook_time_fueldecrease = time + WEP_CVAR_PRI(hook, hooked_time_free);
-                       }
-
-                       if(self.BUTTON_CROUCH)
-                       {
-                               self.hook_state &= ~HOOK_PULLING;
-                               if(self.BUTTON_ATCK || self.BUTTON_HOOK)
-                                       self.hook_state &= ~HOOK_RELEASING;
-                               else
-                                       self.hook_state |= HOOK_RELEASING;
-                       }
-                       else
-                       {
-                               self.hook_state |= HOOK_PULLING;
-                               self.hook_state &= ~HOOK_RELEASING;
-
-                               if(self.BUTTON_ATCK || self.BUTTON_HOOK)
-                               {
-                                       // already fired
-                                       if(self.hook)
-                                               self.hook_state |= HOOK_WAITING_FOR_RELEASE;
-                               }
-                               else
-                               {
-                                       self.hook_state |= HOOK_REMOVING;
-                                       self.hook_state &= ~HOOK_WAITING_FOR_RELEASE;
-                               }
-                       }
-
-                       return true;
-               }
-               case WR_INIT:
-               {
-                       precache_model(W_Model("g_hookgun.md3"));
-                       precache_model(W_Model("v_hookgun.md3"));
-                       precache_model(W_Model("h_hookgun.iqm"));
-                       precache_sound(W_Sound("hook_impact")); // done by g_hook.qc
-                       precache_sound(W_Sound("hook_fire"));
-                       precache_sound(W_Sound("hookbomb_fire"));
-                       HOOK_SETTINGS(WEP_SKIP_CVAR, WEP_SET_PROP);
-                       return true;
-               }
-               case WR_SETUP:
-               {
-                       self.hook_state &= ~HOOK_WAITING_FOR_RELEASE;
-                       return true;
-               }
-               case WR_CHECKAMMO1:
-               {
-                       if(self.hook)
-                               return self.ammo_fuel > 0;
-                       else
-                               return self.ammo_fuel >= WEP_CVAR_PRI(hook, ammo);
-               }
-               case WR_CHECKAMMO2:
-               {
-                       // infinite ammo for now
-                       return true; // self.ammo_cells >= WEP_CVAR_SEC(hook, ammo); // WEAPONTODO: see above
-               }
-               case WR_CONFIG:
-               {
-                       HOOK_SETTINGS(WEP_CONFIG_WRITE_CVARS, WEP_CONFIG_WRITE_PROPS);
-                       return true;
-               }
-               case WR_RESETPLAYER:
-               {
-                       self.hook_refire = time;
-                       return true;
-               }
-               case WR_SUICIDEMESSAGE:
-               {
-                       return false;
-               }
-               case WR_KILLMESSAGE:
-               {
-                       return WEAPON_HOOK_MURDER;
-               }
-       }
-       return false;
-}
-#endif
-#ifdef CSQC
-bool W_Hook(int req)
-{
-       switch(req)
-       {
-               case WR_IMPACTEFFECT:
-               {
-                       vector org2;
-                       org2 = w_org + w_backoff * 2;
-                       pointparticles(particleeffectnum(EFFECT_HOOK_EXPLODE), org2, '0 0 0', 1);
-                       if(!w_issilent)
-                               sound(self, CH_SHOTS, W_Sound("hookbomb_impact"), VOL_BASE, ATTN_NORM);
-
-                       return true;
-               }
-               case WR_INIT:
-               {
-                       precache_sound(W_Sound("hookbomb_impact"));
-                       return true;
-               }
-               case WR_ZOOMRETICLE:
-               {
-                       // no weapon specific image for this weapon
-                       return false;
-               }
-       }
-       return false;
-}
-#endif
-#endif
diff --git a/qcsrc/common/weapons/w_machinegun.qc b/qcsrc/common/weapons/w_machinegun.qc
deleted file mode 100644 (file)
index da1eb33..0000000
+++ /dev/null
@@ -1,408 +0,0 @@
-#ifndef IMPLEMENTATION
-REGISTER_WEAPON(
-/* WEP_##id  */ MACHINEGUN,
-/* function  */ W_MachineGun,
-/* ammotype  */ ammo_nails,
-/* impulse   */ 3,
-/* flags     */ WEP_FLAG_RELOADABLE | WEP_TYPE_HITSCAN,
-/* rating    */ BOT_PICKUP_RATING_MID,
-/* color     */ '1 1 0',
-/* modelname */ "uzi",
-/* simplemdl */ "foobar",
-/* crosshair */ "gfx/crosshairuzi 0.6",
-/* wepimg    */ "weaponuzi",
-/* refname   */ "machinegun",
-/* wepname   */ _("Machine Gun")
-);
-
-#define MACHINEGUN_SETTINGS(w_cvar,w_prop) MACHINEGUN_SETTINGS_LIST(w_cvar, w_prop, MACHINEGUN, machinegun)
-#define MACHINEGUN_SETTINGS_LIST(w_cvar,w_prop,id,sn) \
-       w_cvar(id, sn, NONE, spread_min) \
-       w_cvar(id, sn, NONE, spread_max) \
-       w_cvar(id, sn, NONE, spread_add) \
-       w_cvar(id, sn, NONE, mode) \
-       w_cvar(id, sn, NONE, first) \
-       w_cvar(id, sn, NONE, first_damage) \
-       w_cvar(id, sn, NONE, first_force) \
-       w_cvar(id, sn, NONE, first_refire) \
-       w_cvar(id, sn, NONE, first_spread) \
-       w_cvar(id, sn, NONE, first_ammo) \
-       w_cvar(id, sn, NONE, solidpenetration) \
-       w_cvar(id, sn, NONE, sustained_damage) \
-       w_cvar(id, sn, NONE, sustained_force) \
-       w_cvar(id, sn, NONE, sustained_refire) \
-       w_cvar(id, sn, NONE, sustained_spread) \
-       w_cvar(id, sn, NONE, sustained_ammo) \
-       w_cvar(id, sn, NONE, burst) \
-       w_cvar(id, sn, NONE, burst_refire) \
-       w_cvar(id, sn, NONE, burst_refire2) \
-       w_cvar(id, sn, NONE, burst_animtime) \
-       w_cvar(id, sn, NONE, burst_speed) \
-       w_cvar(id, sn, NONE, burst_ammo) \
-       w_prop(id, sn, float,  reloading_ammo, reload_ammo) \
-       w_prop(id, sn, float,  reloading_time, reload_time) \
-       w_prop(id, sn, float,  switchdelay_raise, switchdelay_raise) \
-       w_prop(id, sn, float,  switchdelay_drop, switchdelay_drop) \
-       w_prop(id, sn, string, weaponreplace, weaponreplace) \
-       w_prop(id, sn, float,  weaponstart, weaponstart) \
-       w_prop(id, sn, float,  weaponstartoverride, weaponstartoverride) \
-       w_prop(id, sn, float,  weaponthrowable, weaponthrowable)
-
-#ifdef SVQC
-MACHINEGUN_SETTINGS(WEP_ADD_CVAR, WEP_ADD_PROP)
-#endif
-#endif
-#ifdef IMPLEMENTATION
-#ifdef SVQC
-
-void spawnfunc_weapon_machinegun(void)
-{
-       if(autocvar_sv_q3acompat_machineshotgunswap)
-       if(self.classname != "droppedweapon")
-       {
-               weapon_defaultspawnfunc(WEP_SHOCKWAVE.m_id);
-               return;
-       }
-       weapon_defaultspawnfunc(WEP_MACHINEGUN.m_id);
-}
-void spawnfunc_weapon_uzi(void) { spawnfunc_weapon_machinegun(); }
-
-void W_MachineGun_MuzzleFlash_Think(void)
-{
-       self.frame = self.frame + 2;
-       self.scale = self.scale * 0.5;
-       self.alpha = self.alpha - 0.25;
-       self.nextthink = time + 0.05;
-
-       if(self.alpha <= 0)
-       {
-               self.think = SUB_Remove;
-               self.nextthink = time;
-               self.realowner.muzzle_flash = world;
-               return;
-       }
-
-}
-
-void W_MachineGun_MuzzleFlash(void)
-{
-       if(self.muzzle_flash == world)
-               self.muzzle_flash = spawn();
-
-       // muzzle flash for 1st person view
-       setmodel(self.muzzle_flash, "models/uziflash.md3"); // precision set below
-
-       self.muzzle_flash.scale = 0.75;
-       self.muzzle_flash.think = W_MachineGun_MuzzleFlash_Think;
-       self.muzzle_flash.nextthink = time + 0.02;
-       self.muzzle_flash.frame = 2;
-       self.muzzle_flash.alpha = 0.75;
-       self.muzzle_flash.angles_z = random() * 180;
-       self.muzzle_flash.effects = EF_ADDITIVE | EF_FULLBRIGHT | EF_LOWPRECISION;
-       self.muzzle_flash.owner = self.muzzle_flash.realowner = self;
-}
-
-void W_MachineGun_Attack(int deathtype)
-{
-       W_SetupShot(self, true, 0, W_Sound("uzi_fire"), CH_WEAPON_A, ((self.misc_bulletcounter == 1) ? WEP_CVAR(machinegun, first_damage) : WEP_CVAR(machinegun, sustained_damage)));
-       if(!autocvar_g_norecoil)
-       {
-               self.punchangle_x = random() - 0.5;
-               self.punchangle_y = random() - 0.5;
-       }
-
-       // this attack_finished just enforces a cooldown at the end of a burst
-       ATTACK_FINISHED(self) = time + WEP_CVAR(machinegun, first_refire) * W_WeaponRateFactor();
-
-       if(self.misc_bulletcounter == 1)
-               fireBullet(w_shotorg, w_shotdir, WEP_CVAR(machinegun, first_spread), WEP_CVAR(machinegun, solidpenetration), WEP_CVAR(machinegun, first_damage), WEP_CVAR(machinegun, first_force), deathtype, 0);
-       else
-               fireBullet(w_shotorg, w_shotdir, WEP_CVAR(machinegun, sustained_spread), WEP_CVAR(machinegun, solidpenetration), WEP_CVAR(machinegun, sustained_damage), WEP_CVAR(machinegun, sustained_force), deathtype, 0);
-
-       Send_Effect(EFFECT_MACHINEGUN_MUZZLEFLASH, w_shotorg, w_shotdir * 1000, 1);
-
-       W_MachineGun_MuzzleFlash();
-       W_AttachToShotorg(self.muzzle_flash, '5 0 0');
-
-       // casing code
-       if(autocvar_g_casings >= 2)
-               SpawnCasing(((random() * 50 + 50) * v_right) - (v_forward * (random() * 25 + 25)) - ((random() * 5 - 70) * v_up), 2, vectoangles(v_forward),'0 250 0', 100, 3, self);
-
-       if(self.misc_bulletcounter == 1)
-               W_DecreaseAmmo(WEP_CVAR(machinegun, first_ammo));
-       else
-               W_DecreaseAmmo(WEP_CVAR(machinegun, sustained_ammo));
-}
-
-// weapon frames
-void W_MachineGun_Attack_Frame(void)
-{
-       if(self.weapon != self.switchweapon) // abort immediately if switching
-       {
-               w_ready();
-               return;
-       }
-       if(self.BUTTON_ATCK)
-       {
-               if(!WEP_ACTION(self.weapon, WR_CHECKAMMO2))
-               if(!(self.items & IT_UNLIMITED_WEAPON_AMMO))
-               {
-                       W_SwitchWeapon_Force(self, w_getbestweapon(self));
-                       w_ready();
-                       return;
-               }
-               self.misc_bulletcounter = self.misc_bulletcounter + 1;
-               W_MachineGun_Attack(WEP_MACHINEGUN.m_id);
-               weapon_thinkf(WFRAME_FIRE1, WEP_CVAR(machinegun, sustained_refire), W_MachineGun_Attack_Frame);
-       }
-       else
-               weapon_thinkf(WFRAME_FIRE1, WEP_CVAR(machinegun, sustained_refire), w_ready);
-}
-
-
-void W_MachineGun_Attack_Auto(void)
-{
-       float machinegun_spread;
-
-       if(!self.BUTTON_ATCK)
-       {
-               w_ready();
-               return;
-       }
-
-       if(!WEP_ACTION(self.weapon, WR_CHECKAMMO1))
-       if(!(self.items & IT_UNLIMITED_WEAPON_AMMO))
-       {
-               W_SwitchWeapon_Force(self, w_getbestweapon(self));
-               w_ready();
-               return;
-       }
-
-       W_DecreaseAmmo(WEP_CVAR(machinegun, sustained_ammo));
-
-       W_SetupShot(self, true, 0, W_Sound("uzi_fire"), CH_WEAPON_A, WEP_CVAR(machinegun, sustained_damage));
-       if(!autocvar_g_norecoil)
-       {
-               self.punchangle_x = random() - 0.5;
-               self.punchangle_y = random() - 0.5;
-       }
-
-       machinegun_spread = bound(WEP_CVAR(machinegun, spread_min), WEP_CVAR(machinegun, spread_min) + (WEP_CVAR(machinegun, spread_add) * self.misc_bulletcounter), WEP_CVAR(machinegun, spread_max));
-       fireBullet(w_shotorg, w_shotdir, machinegun_spread, WEP_CVAR(machinegun, solidpenetration), WEP_CVAR(machinegun, sustained_damage), WEP_CVAR(machinegun, sustained_force), WEP_MACHINEGUN.m_id, 0);
-
-       self.misc_bulletcounter = self.misc_bulletcounter + 1;
-
-       Send_Effect(EFFECT_MACHINEGUN_MUZZLEFLASH, w_shotorg, w_shotdir * 1000, 1);
-
-       W_MachineGun_MuzzleFlash();
-       W_AttachToShotorg(self.muzzle_flash, '5 0 0');
-
-       if(autocvar_g_casings >= 2) // casing code
-               SpawnCasing(((random() * 50 + 50) * v_right) - (v_forward * (random() * 25 + 25)) - ((random() * 5 - 70) * v_up), 2, vectoangles(v_forward),'0 250 0', 100, 3, self);
-
-       ATTACK_FINISHED(self) = time + WEP_CVAR(machinegun, first_refire) * W_WeaponRateFactor();
-       weapon_thinkf(WFRAME_FIRE1, WEP_CVAR(machinegun, sustained_refire), W_MachineGun_Attack_Auto);
-}
-
-void W_MachineGun_Attack_Burst(void)
-{
-       W_SetupShot(self, true, 0, W_Sound("uzi_fire"), CH_WEAPON_A, WEP_CVAR(machinegun, sustained_damage));
-       if(!autocvar_g_norecoil)
-       {
-               self.punchangle_x = random() - 0.5;
-               self.punchangle_y = random() - 0.5;
-       }
-
-       fireBullet(w_shotorg, w_shotdir, WEP_CVAR(machinegun, burst_speed), WEP_CVAR(machinegun, solidpenetration), WEP_CVAR(machinegun, sustained_damage), WEP_CVAR(machinegun, sustained_force), WEP_MACHINEGUN.m_id, 0);
-
-       Send_Effect(EFFECT_MACHINEGUN_MUZZLEFLASH, w_shotorg, w_shotdir * 1000, 1);
-
-       W_MachineGun_MuzzleFlash();
-       W_AttachToShotorg(self.muzzle_flash, '5 0 0');
-
-       if(autocvar_g_casings >= 2) // casing code
-               SpawnCasing(((random() * 50 + 50) * v_right) - (v_forward * (random() * 25 + 25)) - ((random() * 5 - 70) * v_up), 2, vectoangles(v_forward),'0 250 0', 100, 3, self);
-
-       self.misc_bulletcounter = self.misc_bulletcounter + 1;
-       if(self.misc_bulletcounter == 0)
-       {
-               ATTACK_FINISHED(self) = time + WEP_CVAR(machinegun, burst_refire2) * W_WeaponRateFactor();
-               weapon_thinkf(WFRAME_FIRE2, WEP_CVAR(machinegun, burst_animtime), w_ready);
-       }
-       else
-       {
-               weapon_thinkf(WFRAME_FIRE2, WEP_CVAR(machinegun, burst_refire), W_MachineGun_Attack_Burst);
-       }
-
-}
-
-bool W_MachineGun(int req)
-{
-       float ammo_amount;
-       switch(req)
-       {
-               case WR_AIM:
-               {
-                       if(vlen(self.origin-self.enemy.origin) < 3000 - bound(0, skill, 10) * 200)
-                               self.BUTTON_ATCK = bot_aim(1000000, 0, 0.001, false);
-                       else
-                               self.BUTTON_ATCK2 = bot_aim(1000000, 0, 0.001, false);
-
-                       return true;
-               }
-               case WR_THINK:
-               {
-                       if(WEP_CVAR(machinegun, reload_ammo) && self.clip_load < min(max(WEP_CVAR(machinegun, sustained_ammo), WEP_CVAR(machinegun, first_ammo)), WEP_CVAR(machinegun, burst_ammo))) // forced reload
-                               WEP_ACTION(self.weapon, WR_RELOAD);
-                       else if(WEP_CVAR(machinegun, mode) == 1)
-                       {
-                               if(self.BUTTON_ATCK)
-                               if(weapon_prepareattack(0, 0))
-                               {
-                                       self.misc_bulletcounter = 0;
-                                       W_MachineGun_Attack_Auto();
-                               }
-
-                               if(self.BUTTON_ATCK2)
-                               if(weapon_prepareattack(1, 0))
-                               {
-                                       if(!WEP_ACTION(self.weapon, WR_CHECKAMMO2))
-                                       if(!(self.items & IT_UNLIMITED_WEAPON_AMMO))
-                                       {
-                                               W_SwitchWeapon_Force(self, w_getbestweapon(self));
-                                               w_ready();
-                                               return false;
-                                       }
-
-                                       W_DecreaseAmmo(WEP_CVAR(machinegun, burst_ammo));
-
-                                       self.misc_bulletcounter = WEP_CVAR(machinegun, burst) * -1;
-                                       W_MachineGun_Attack_Burst();
-                               }
-                       }
-                       else
-                       {
-
-                               if(self.BUTTON_ATCK)
-                               if(weapon_prepareattack(0, 0))
-                               {
-                                       self.misc_bulletcounter = 1;
-                                       W_MachineGun_Attack(WEP_MACHINEGUN.m_id); // sets attack_finished
-                                       weapon_thinkf(WFRAME_FIRE1, WEP_CVAR(machinegun, sustained_refire), W_MachineGun_Attack_Frame);
-                               }
-
-                               if(self.BUTTON_ATCK2 && WEP_CVAR(machinegun, first))
-                               if(weapon_prepareattack(1, 0))
-                               {
-                                       self.misc_bulletcounter = 1;
-                                       W_MachineGun_Attack(WEP_MACHINEGUN.m_id | HITTYPE_SECONDARY); // sets attack_finished
-                                       weapon_thinkf(WFRAME_FIRE2, WEP_CVAR(machinegun, first_refire), w_ready);
-                               }
-                       }
-
-                       return true;
-               }
-               case WR_INIT:
-               {
-                       precache_model("models/uziflash.md3");
-                       precache_model(W_Model("g_uzi.md3"));
-                       precache_model(W_Model("v_uzi.md3"));
-                       precache_model(W_Model("h_uzi.iqm"));
-                       precache_sound(W_Sound("uzi_fire"));
-                       MACHINEGUN_SETTINGS(WEP_SKIP_CVAR, WEP_SET_PROP);
-                       return true;
-               }
-               case WR_CHECKAMMO1:
-               {
-                       if(WEP_CVAR(machinegun, mode) == 1)
-                               ammo_amount = self.WEP_AMMO(MACHINEGUN) >= WEP_CVAR(machinegun, sustained_ammo);
-                       else
-                               ammo_amount = self.WEP_AMMO(MACHINEGUN) >= WEP_CVAR(machinegun, first_ammo);
-
-                       if(WEP_CVAR(machinegun, reload_ammo))
-                       {
-                               if(WEP_CVAR(machinegun, mode) == 1)
-                                       ammo_amount += self.(weapon_load[WEP_MACHINEGUN.m_id]) >= WEP_CVAR(machinegun, sustained_ammo);
-                               else
-                                       ammo_amount += self.(weapon_load[WEP_MACHINEGUN.m_id]) >= WEP_CVAR(machinegun, first_ammo);
-                       }
-                       return ammo_amount;
-               }
-               case WR_CHECKAMMO2:
-               {
-                       if(WEP_CVAR(machinegun, mode) == 1)
-                               ammo_amount = self.WEP_AMMO(MACHINEGUN) >= WEP_CVAR(machinegun, burst_ammo);
-                       else
-                               ammo_amount = self.WEP_AMMO(MACHINEGUN) >= WEP_CVAR(machinegun, first_ammo);
-
-                       if(WEP_CVAR(machinegun, reload_ammo))
-                       {
-                               if(WEP_CVAR(machinegun, mode) == 1)
-                                       ammo_amount += self.(weapon_load[WEP_MACHINEGUN.m_id]) >= WEP_CVAR(machinegun, burst_ammo);
-                               else
-                                       ammo_amount += self.(weapon_load[WEP_MACHINEGUN.m_id]) >= WEP_CVAR(machinegun, first_ammo);
-                       }
-                       return ammo_amount;
-               }
-               case WR_CONFIG:
-               {
-                       MACHINEGUN_SETTINGS(WEP_CONFIG_WRITE_CVARS, WEP_CONFIG_WRITE_PROPS);
-                       return true;
-               }
-               case WR_RELOAD:
-               {
-                       W_Reload(min(max(WEP_CVAR(machinegun, sustained_ammo), WEP_CVAR(machinegun, first_ammo)), WEP_CVAR(machinegun, burst_ammo)), W_Sound("reload"));
-                       return true;
-               }
-               case WR_SUICIDEMESSAGE:
-               {
-                       return WEAPON_THINKING_WITH_PORTALS;
-               }
-               case WR_KILLMESSAGE:
-               {
-                       if(w_deathtype & HITTYPE_SECONDARY)
-                               return WEAPON_MACHINEGUN_MURDER_SNIPE;
-                       else
-                               return WEAPON_MACHINEGUN_MURDER_SPRAY;
-               }
-       }
-       return false;
-}
-#endif
-#ifdef CSQC
-bool W_MachineGun(int req)
-{
-       switch(req)
-       {
-               case WR_IMPACTEFFECT:
-               {
-                       vector org2;
-                       org2 = w_org + w_backoff * 2;
-                       pointparticles(particleeffectnum(EFFECT_MACHINEGUN_IMPACT), org2, w_backoff * 1000, 1);
-                       if(!w_issilent)
-                               if(w_random < 0.05)
-                                       sound(self, CH_SHOTS, W_Sound("ric1"), VOL_BASE, ATTN_NORM);
-                               else if(w_random < 0.1)
-                                       sound(self, CH_SHOTS, W_Sound("ric2"), VOL_BASE, ATTN_NORM);
-                               else if(w_random < 0.2)
-                                       sound(self, CH_SHOTS, W_Sound("ric3"), VOL_BASE, ATTN_NORM);
-
-                       return true;
-               }
-               case WR_INIT:
-               {
-                       precache_sound(W_Sound("ric1"));
-                       precache_sound(W_Sound("ric2"));
-                       precache_sound(W_Sound("ric3"));
-                       return true;
-               }
-               case WR_ZOOMRETICLE:
-               {
-                       // no weapon specific image for this weapon
-                       return false;
-               }
-       }
-       return false;
-}
-#endif
-#endif
diff --git a/qcsrc/common/weapons/w_minelayer.qc b/qcsrc/common/weapons/w_minelayer.qc
deleted file mode 100644 (file)
index 8048957..0000000
+++ /dev/null
@@ -1,623 +0,0 @@
-#ifndef IMPLEMENTATION
-REGISTER_WEAPON(
-/* WEP_##id  */ MINE_LAYER,
-/* function  */ W_MineLayer,
-/* ammotype  */ ammo_rockets,
-/* impulse   */ 4,
-/* flags     */ WEP_FLAG_MUTATORBLOCKED | WEP_FLAG_RELOADABLE | WEP_TYPE_SPLASH,
-/* rating    */ BOT_PICKUP_RATING_HIGH,
-/* color     */ '0.75 1 0',
-/* modelname */ "minelayer",
-/* simplemdl */ "foobar",
-/* crosshair */ "gfx/crosshairminelayer 0.9",
-/* wepimg    */ "weaponminelayer",
-/* refname   */ "minelayer",
-/* wepname   */ _("Mine Layer")
-);
-
-#define MINELAYER_SETTINGS(w_cvar,w_prop) MINELAYER_SETTINGS_LIST(w_cvar, w_prop, MINE_LAYER, minelayer)
-#define MINELAYER_SETTINGS_LIST(w_cvar,w_prop,id,sn) \
-       w_cvar(id, sn, NONE, ammo) \
-       w_cvar(id, sn, NONE, animtime) \
-       w_cvar(id, sn, NONE, damage) \
-       w_cvar(id, sn, NONE, damageforcescale) \
-       w_cvar(id, sn, NONE, detonatedelay) \
-       w_cvar(id, sn, NONE, edgedamage) \
-       w_cvar(id, sn, NONE, force) \
-       w_cvar(id, sn, NONE, health) \
-       w_cvar(id, sn, NONE, lifetime) \
-       w_cvar(id, sn, NONE, lifetime_countdown) \
-       w_cvar(id, sn, NONE, limit) \
-       w_cvar(id, sn, NONE, protection) \
-       w_cvar(id, sn, NONE, proximityradius) \
-       w_cvar(id, sn, NONE, radius) \
-       w_cvar(id, sn, NONE, refire) \
-       w_cvar(id, sn, NONE, remote_damage) \
-       w_cvar(id, sn, NONE, remote_edgedamage) \
-       w_cvar(id, sn, NONE, remote_force) \
-       w_cvar(id, sn, NONE, remote_radius) \
-       w_cvar(id, sn, NONE, speed) \
-       w_cvar(id, sn, NONE, time) \
-       w_prop(id, sn, float,  reloading_ammo, reload_ammo) \
-       w_prop(id, sn, float,  reloading_time, reload_time) \
-       w_prop(id, sn, float,  switchdelay_raise, switchdelay_raise) \
-       w_prop(id, sn, float,  switchdelay_drop, switchdelay_drop) \
-       w_prop(id, sn, string, weaponreplace, weaponreplace) \
-       w_prop(id, sn, float,  weaponstart, weaponstart) \
-       w_prop(id, sn, float,  weaponstartoverride, weaponstartoverride) \
-       w_prop(id, sn, float,  weaponthrowable, weaponthrowable)
-
-#ifdef SVQC
-MINELAYER_SETTINGS(WEP_ADD_CVAR, WEP_ADD_PROP)
-void W_MineLayer_Think(void);
-.float minelayer_detonate, mine_explodeanyway;
-.float mine_time;
-.vector mine_orientation;
-#endif
-#endif
-#ifdef IMPLEMENTATION
-#ifdef SVQC
-void spawnfunc_weapon_minelayer(void) { weapon_defaultspawnfunc(WEP_MINE_LAYER.m_id); }
-
-void W_MineLayer_Stick(entity to)
-{
-       spamsound(self, CH_SHOTS, W_Sound("mine_stick"), VOL_BASE, ATTN_NORM);
-
-       // in order for mines to face properly when sticking to the ground, they must be a server side entity rather than a csqc projectile
-
-       entity newmine;
-       newmine = spawn();
-       newmine.classname = self.classname;
-
-       newmine.bot_dodge = self.bot_dodge;
-       newmine.bot_dodgerating = self.bot_dodgerating;
-
-       newmine.owner = self.owner;
-       newmine.realowner = self.realowner;
-       setsize(newmine, '-4 -4 -4', '4 4 4');
-       setorigin(newmine, self.origin);
-       setmodel(newmine, "models/mine.md3");
-       newmine.angles = vectoangles(-trace_plane_normal); // face against the surface
-
-       newmine.mine_orientation = -trace_plane_normal;
-
-       newmine.takedamage = self.takedamage;
-       newmine.damageforcescale = self.damageforcescale;
-       newmine.health = self.health;
-       newmine.event_damage = self.event_damage;
-       newmine.spawnshieldtime = self.spawnshieldtime;
-       newmine.damagedbycontents = true;
-
-       newmine.movetype = MOVETYPE_NONE; // lock the mine in place
-       newmine.projectiledeathtype = self.projectiledeathtype;
-
-       newmine.mine_time = self.mine_time;
-
-       newmine.touch = func_null;
-       newmine.think = W_MineLayer_Think;
-       newmine.nextthink = time;
-       newmine.cnt = self.cnt;
-       newmine.flags = self.flags;
-
-       remove(self);
-       self = newmine;
-
-       if(to)
-               SetMovetypeFollow(self, to);
-}
-
-void W_MineLayer_Explode(void)
-{
-       if(other.takedamage == DAMAGE_AIM)
-               if(IS_PLAYER(other))
-                       if(DIFF_TEAM(self.realowner, other))
-                               if(other.deadflag == DEAD_NO)
-                                       if(IsFlying(other))
-                                               Send_Notification(NOTIF_ONE, self.realowner, MSG_ANNCE, ANNCE_ACHIEVEMENT_AIRSHOT);
-
-       self.event_damage = func_null;
-       self.takedamage = DAMAGE_NO;
-
-       RadiusDamage(self, self.realowner, WEP_CVAR(minelayer, damage), WEP_CVAR(minelayer, edgedamage), WEP_CVAR(minelayer, radius), world, world, WEP_CVAR(minelayer, force), self.projectiledeathtype, other);
-
-       if(self.realowner.weapon == WEP_MINE_LAYER.m_id)
-       {
-               entity oldself;
-               oldself = self;
-               self = self.realowner;
-               if(!WEP_ACTION(WEP_MINE_LAYER.m_id, WR_CHECKAMMO1))
-               {
-                       self.cnt = WEP_MINE_LAYER.m_id;
-                       ATTACK_FINISHED(self) = time;
-                       self.switchweapon = w_getbestweapon(self);
-               }
-               self = oldself;
-       }
-       self.realowner.minelayer_mines -= 1;
-       remove(self);
-}
-
-void W_MineLayer_DoRemoteExplode(void)
-{
-       self.event_damage = func_null;
-       self.takedamage = DAMAGE_NO;
-
-       if(self.movetype == MOVETYPE_NONE || self.movetype == MOVETYPE_FOLLOW)
-               self.velocity = self.mine_orientation; // particle fx and decals need .velocity
-
-       RadiusDamage(self, self.realowner, WEP_CVAR(minelayer, remote_damage), WEP_CVAR(minelayer, remote_edgedamage), WEP_CVAR(minelayer, remote_radius), world, world, WEP_CVAR(minelayer, remote_force), self.projectiledeathtype | HITTYPE_BOUNCE, world);
-
-       if(self.realowner.weapon == WEP_MINE_LAYER.m_id)
-       {
-               entity oldself;
-               oldself = self;
-               self = self.realowner;
-               if(!WEP_ACTION(WEP_MINE_LAYER.m_id, WR_CHECKAMMO1))
-               {
-                       self.cnt = WEP_MINE_LAYER.m_id;
-                       ATTACK_FINISHED(self) = time;
-                       self.switchweapon = w_getbestweapon(self);
-               }
-               self = oldself;
-       }
-       self.realowner.minelayer_mines -= 1;
-       remove(self);
-}
-
-void W_MineLayer_RemoteExplode(void)
-{
-       if(self.realowner.deadflag == DEAD_NO)
-               if((self.spawnshieldtime >= 0)
-                       ? (time >= self.spawnshieldtime) // timer
-                       : (vlen(NearestPointOnBox(self.realowner, self.origin) - self.origin) > WEP_CVAR(minelayer, remote_radius)) // safety device
-               )
-               {
-                       W_MineLayer_DoRemoteExplode();
-               }
-}
-
-void W_MineLayer_ProximityExplode(void)
-{
-       // make sure no friend is in the mine's radius. If there is any, explosion is delayed until he's at a safe distance
-       if(WEP_CVAR(minelayer, protection) && self.mine_explodeanyway == 0)
-       {
-               entity head;
-               head = findradius(self.origin, WEP_CVAR(minelayer, radius));
-               while(head)
-               {
-                       if(head == self.realowner || SAME_TEAM(head, self.realowner))
-                               return;
-                       head = head.chain;
-               }
-       }
-
-       self.mine_time = 0;
-       W_MineLayer_Explode();
-}
-
-int W_MineLayer_Count(entity e)
-{
-       int minecount = 0;
-       entity mine;
-       for(mine = world; (mine = find(mine, classname, "mine")); ) if(mine.realowner == e)
-               minecount += 1;
-
-       return minecount;
-}
-
-void W_MineLayer_Think(void)
-{
-       entity head;
-
-       self.nextthink = time;
-
-       if(self.movetype == MOVETYPE_FOLLOW)
-       {
-               if(LostMovetypeFollow(self))
-               {
-                       UnsetMovetypeFollow(self);
-                       self.movetype = MOVETYPE_NONE;
-               }
-       }
-
-       // our lifetime has expired, it's time to die - mine_time just allows us to play a sound for this
-       // TODO: replace this mine_trigger.wav sound with a real countdown
-       if((time > self.cnt) && (!self.mine_time) && (self.cnt > 0))
-       {
-               if(WEP_CVAR(minelayer, lifetime_countdown) > 0)
-                       spamsound(self, CH_SHOTS, W_Sound("mine_trigger"), VOL_BASE, ATTN_NORM);
-               self.mine_time = time + WEP_CVAR(minelayer, lifetime_countdown);
-               self.mine_explodeanyway = 1; // make the mine super aggressive -- Samual: Rather, make it not care if a team mate is near.
-       }
-
-       // a player's mines shall explode if he disconnects or dies
-       // TODO: Do this on team change too -- Samual: But isn't a player killed when they switch teams?
-       if(!IS_PLAYER(self.realowner) || self.realowner.deadflag != DEAD_NO || self.realowner.frozen)
-       {
-               other = world;
-               self.projectiledeathtype |= HITTYPE_BOUNCE;
-               W_MineLayer_Explode();
-               return;
-       }
-
-       // set the mine for detonation when a foe gets close enough
-       head = findradius(self.origin, WEP_CVAR(minelayer, proximityradius));
-       while(head)
-       {
-               if(IS_PLAYER(head) && head.deadflag == DEAD_NO && !head.frozen)
-               if(head != self.realowner && DIFF_TEAM(head, self.realowner)) // don't trigger for team mates
-               if(!self.mine_time)
-               {
-                       spamsound(self, CH_SHOTS, W_Sound("mine_trigger"), VOL_BASE, ATTN_NORM);
-                       self.mine_time = time + WEP_CVAR(minelayer, time);
-               }
-               head = head.chain;
-       }
-
-       // explode if it's time to
-       if(self.mine_time && time >= self.mine_time)
-       {
-               W_MineLayer_ProximityExplode();
-               return;
-       }
-
-       // remote detonation
-       if(self.realowner.weapon == WEP_MINE_LAYER.m_id)
-       if(self.realowner.deadflag == DEAD_NO)
-       if(self.minelayer_detonate)
-               W_MineLayer_RemoteExplode();
-}
-
-void W_MineLayer_Touch(void)
-{
-       if(self.movetype == MOVETYPE_NONE || self.movetype == MOVETYPE_FOLLOW)
-               return; // we're already a stuck mine, why do we get called? TODO does this even happen?
-
-       if(WarpZone_Projectile_Touch())
-       {
-               if(wasfreed(self))
-                       self.realowner.minelayer_mines -= 1;
-               return;
-       }
-
-       if(other && IS_PLAYER(other) && other.deadflag == DEAD_NO)
-       {
-               // hit a player
-               // don't stick
-       }
-       else
-       {
-               W_MineLayer_Stick(other);
-       }
-}
-
-void W_MineLayer_Damage(entity inflictor, entity attacker, float damage, int deathtype, vector hitloc, vector force)
-{
-       if(self.health <= 0)
-               return;
-
-       float is_from_enemy = (inflictor.realowner != self.realowner);
-
-       if(!W_CheckProjectileDamage(inflictor.realowner, self.realowner, deathtype, (is_from_enemy ? 1 : -1)))
-               return; // g_projectiles_damage says to halt
-
-       self.health = self.health - damage;
-       self.angles = vectoangles(self.velocity);
-