#ifdef REGISTER_WEAPON
REGISTER_WEAPON(
-/* WEP_##id */ SHOCKWAVE,
-/* function */ W_Shockwave,
-/* ammotype */ ammo_none,
-/* impulse */ 2,
-/* flags */ WEP_FLAG_NORMAL | WEP_TYPE_HITSCAN,
-/* rating */ BOT_PICKUP_RATING_LOW,
-/* color */ '0.5 0.25 0',
-/* model */ "shotgun",
-/* netname */ "shockwave",
-/* fullname */ _("Shockwave")
+/* WEP_##id */ SHOCKWAVE,
+/* function */ W_Shockwave,
+/* ammotype */ ammo_none,
+/* impulse */ 2,
+/* flags */ WEP_FLAG_NORMAL | WEP_TYPE_HITSCAN,
+/* rating */ BOT_PICKUP_RATING_LOW,
+/* color */ '0.5 0.25 0',
+/* modelname */ "shotgun",
+/* simplemdl */ "foobar",
+/* crosshair */ "gfx/crosshairshotgun 0.7",
+/* wepimg */ "weaponshotgun",
+/* refname */ "shockwave",
+/* wepname */ _("Shockwave")
);
#define SHOCKWAVE_SETTINGS(w_cvar,w_prop) SHOCKWAVE_SETTINGS_LIST(w_cvar, w_prop, SHOCKWAVE, shockwave)
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, weaponstartoverride, weaponstartoverride) \
+ w_prop(id, sn, float, weaponthrowable, weaponthrowable)
#ifdef SVQC
SHOCKWAVE_SETTINGS(WEP_ADD_CVAR, WEP_ADD_PROP)
#endif
#else
#ifdef SVQC
-void spawnfunc_weapon_shockwave()
+void spawnfunc_weapon_shockwave(void)
{
//if(autocvar_sv_q3acompat_machineshockwaveswap) // WEAPONTODO
if(autocvar_sv_q3acompat_machineshotgunswap)
weapon_defaultspawnfunc(WEP_SHOCKWAVE);
}
-#define MAX_SHOCKWAVE_HITS 5
+#define MAX_SHOCKWAVE_HITS 10
+#define DEBUG_SHOCKWAVE
.float swing_prev;
.entity swing_alreadyhit;
vector shockwave_hit_force[MAX_SHOCKWAVE_HITS];
// MELEE ATTACK MODE
-void W_Shockwave_Melee_Think()
+void W_Shockwave_Melee_Think(void)
{
// declarations
float i, f, swing, swing_factor, swing_damage, meleetime, is_player;
te_lightning2(world, targpos, self.realowner.origin + self.realowner.view_ofs + v_forward * 5 - v_up * 5);
te_customflash(targpos, 40, 2, '1 1 1');
- is_player = (trace_ent.classname == "player" || trace_ent.classname == "body");
+ is_player = (trace_ent.classname == "player" || trace_ent.classname == "body" || (trace_ent.flags & FL_MONSTER));
if((trace_fraction < 1) // if trace is good, apply the damage and remove self if necessary
&& (trace_ent.takedamage == DAMAGE_AIM)
}
}
-void W_Shockwave_Melee()
+void W_Shockwave_Melee(void)
{
sound(self, CH_WEAPON_A, "weapons/shotgun_melee.wav", VOL_BASE, ATTN_NORM);
weapon_thinkf(WFRAME_FIRE2, WEP_CVAR(shockwave, melee_animtime), w_ready);
vector final_force,
float final_damage)
{
- // WEAPONTODO: check if we hit MAX_SHOCKWAVE_HITS
if(!head) { return FALSE; }
float i;
-
- ++queue;
- for(i = 1; i <= queue; ++i)
+ for(i = 0; i <= queue; ++i)
{
if(shockwave_hit[i] == head)
{
return TRUE;
}
-void W_Shockwave_Attack()
+void W_Shockwave_Send(void)
+{
+ WriteByte(MSG_BROADCAST, SVC_TEMPENTITY);
+ WriteByte(MSG_BROADCAST, TE_CSQC_SHOCKWAVEPARTICLE);
+ WriteCoord(MSG_BROADCAST, w_shotorg_x);
+ WriteCoord(MSG_BROADCAST, w_shotorg_y);
+ WriteCoord(MSG_BROADCAST, w_shotorg_z);
+ WriteCoord(MSG_BROADCAST, w_shotdir_x);
+ WriteCoord(MSG_BROADCAST, w_shotdir_y);
+ WriteCoord(MSG_BROADCAST, w_shotdir_z);
+ WriteShort(MSG_BROADCAST, WEP_CVAR(shockwave, blast_distance));
+ WriteByte(MSG_BROADCAST, bound(0, WEP_CVAR(shockwave, blast_spread_max), 255));
+ WriteByte(MSG_BROADCAST, bound(0, WEP_CVAR(shockwave, blast_spread_min), 255));
+ WriteByte(MSG_BROADCAST, num_for_edict(self));
+}
+
+void W_Shockwave_Attack(void)
{
// declarations
float multiplier, multiplier_from_accuracy, multiplier_from_distance;
//entity transform = WarpZone_trace_transform;
// do the firing effect now
- //SendCSQCShockwaveParticle(attack_endpos); // WEAPONTODO
+ W_Shockwave_Send();
Damage_DamageInfo(
attack_hitpos,
WEP_CVAR(shockwave, blast_splash_damage),
final_force_z *= WEP_CVAR(shockwave, blast_force_zscale);
// queue damage with this calculated info
- if(W_Shockwave_Attack_CheckHit(queue, head, final_force, final_damage)) { ++queue; }
+ if(W_Shockwave_Attack_CheckHit(queue, head, final_force, final_damage)) { queue = min(queue + 1, MAX_SHOCKWAVE_HITS); }
#ifdef DEBUG_SHOCKWAVE
print(sprintf(
vector nearest_on_line = (w_shotorg + a * w_shotdir);
vector nearest_to_attacker = WarpZoneLib_NearestPointOnBox(center + head.mins, center + head.maxs, nearest_on_line);
- float distance_to_target = vlen(w_shotorg - nearest_to_attacker); // WEAPONTODO: use the findradius function for this
- if((distance_to_target <= WEP_CVAR(shockwave, blast_distance))
+ if((vlen(head.WarpZone_findradius_dist) <= WEP_CVAR(shockwave, blast_distance))
&& (W_Shockwave_Attack_IsVisible(head, nearest_on_line, w_shotorg, attack_endpos)))
{
// calculate importance of distance and accuracy for this attack
);
multiplier_from_distance = (1 -
(distance_to_hit ?
- min(1, (distance_to_target / distance_to_end))
+ min(1, (vlen(head.WarpZone_findradius_dist) / distance_to_end))
:
0
)
final_force_z *= WEP_CVAR(shockwave, blast_force_zscale);
// queue damage with this calculated info
- if(W_Shockwave_Attack_CheckHit(queue, head, final_force, final_damage)) { ++queue; }
+ if(W_Shockwave_Attack_CheckHit(queue, head, final_force, final_damage)) { queue = min(queue + 1, MAX_SHOCKWAVE_HITS); }
#ifdef DEBUG_SHOCKWAVE
print(sprintf(
for(i = 1; i <= queue; ++i)
{
- head = shockwave_hit[i];
- final_force = shockwave_hit_force[i];
- final_damage = shockwave_hit_damage[i];
+ head = shockwave_hit[i-1];
+ final_force = shockwave_hit_force[i-1];
+ final_damage = shockwave_hit_damage[i-1];
Damage(
head,
head.origin,
final_force
);
-
+
+ if(accuracy_isgooddamage(self.realowner, head))
+ {
+ print("wtf\n");
+ accuracy_add(self.realowner, WEP_SHOCKWAVE, 0, final_damage);
+ }
+
#ifdef DEBUG_SHOCKWAVE
print(sprintf(
"SHOCKWAVE by %s: damage = %f, force = %f.\n",
));
#endif
- shockwave_hit[i] = world;
- shockwave_hit_force[i] = '0 0 0';
- shockwave_hit_damage[i] = 0;
+ shockwave_hit[i-1] = world;
+ shockwave_hit_force[i-1] = '0 0 0';
+ shockwave_hit_damage[i-1] = 0;
}
}
precache_sound("misc/itempickup.wav");
precache_sound("weapons/shockwave_fire.wav");
precache_sound("weapons/shockwave_melee.wav");
- SHOCKWAVE_SETTINGS(WEP_SKIPCVAR, WEP_SET_PROP)
+ SHOCKWAVE_SETTINGS(WEP_SKIP_CVAR, WEP_SET_PROP)
return TRUE;
}
case WR_CHECKAMMO1:
return WEAPON_SHOCKWAVE_MURDER;
}
}
- return TRUE;
+ return FALSE;
}
#endif
#ifdef CSQC
{
vector org2;
org2 = w_org + w_backoff * 2;
- pointparticles(particleeffectnum("shockwave_impact"), org2, w_backoff * 1000, 1);
+ pointparticles(particleeffectnum("laser_impact"), org2, w_backoff * 1000, 1); // WEAPONTODO: replace with proper impact effect
return TRUE;
}
case WR_INIT:
return FALSE;
}
}
- return TRUE;
+ return FALSE;
}
#endif
#endif