void W_Plasma_Touch (void)
{
+ //self.velocity = self.velocity * 0.1;
+
PROJECTILE_TOUCH;
if (other.takedamage == DAMAGE_AIM) {
W_Plasma_Explode ();
} else {
+ //UpdateCSQCProjectile(self);
spamsound (self, CHAN_PROJECTILE, "weapons/electro_bounce.wav", VOL_BASE, ATTN_NORM);
self.projectiledeathtype |= HITTYPE_BOUNCE;
}
//sounds bad
CSQCProjectile(proj, TRUE, PROJECTILE_ELECTRO_BEAM, TRUE);
+
+ other = proj; MUTATOR_CALLHOOK(EditProjectile);
}
void W_Electro_Attack2()
proj.health = cvar("g_balance_electro_secondary_health");
proj.event_damage = W_Plasma_Damage;
proj.flags = FL_PROJECTILE;
-
+
+ proj.bouncefactor = cvar("g_balance_electro_secondary_bouncefactor");
+ proj.bouncestop = cvar("g_balance_electro_secondary_bouncestop");
+
#if 0
entity p2;
p2 = spawn();
#endif
CSQCProjectile(proj, TRUE, PROJECTILE_ELECTRO, FALSE); // no culling, it has sound
-}
-.entity lgbeam, exteriorlgbeam;
+ other = proj; MUTATOR_CALLHOOK(EditProjectile);
+ }
+
+.vector hook_start, hook_end;
+float lgbeam_send(entity to, float sf)
+{
+ WriteByte(MSG_ENTITY, ENT_CLIENT_LGBEAM);
+ sf = sf & 0x7F;
+ if(sound_allowed(MSG_BROADCAST, self.owner))
+ sf |= 0x80;
+ WriteByte(MSG_ENTITY, sf);
+ if(sf & 1)
+ {
+ WriteByte(MSG_ENTITY, num_for_edict(self.owner));
+ WriteCoord(MSG_ENTITY, cvar("g_balance_electro_primary_range"));
+ }
+ if(sf & 2)
+ {
+ WriteCoord(MSG_ENTITY, self.hook_start_x);
+ WriteCoord(MSG_ENTITY, self.hook_start_y);
+ WriteCoord(MSG_ENTITY, self.hook_start_z);
+ }
+ if(sf & 4)
+ {
+ WriteCoord(MSG_ENTITY, self.hook_end_x);
+ WriteCoord(MSG_ENTITY, self.hook_end_y);
+ WriteCoord(MSG_ENTITY, self.hook_end_z);
+ }
+ return TRUE;
+}
+.entity lgbeam;
.float prevlgfire;
void lgbeam_think()
{
self.owner.prevlgfire = time;
- if (self.owner.weaponentity.state != WS_INUSE || (self.owner.ammo_cells <= 0 && !(self.owner.items & IT_UNLIMITED_WEAPON_AMMO)) || self != self.owner.lgbeam || self.owner.deadflag != DEAD_NO || !self.owner.BUTTON_ATCK)
+ if (self != self.owner.lgbeam)
{
remove(self);
return;
}
+ if (self.owner.weaponentity.state != WS_INUSE || (self.owner.ammo_cells <= 0 && !(self.owner.items & IT_UNLIMITED_WEAPON_AMMO)) || self.owner.deadflag != DEAD_NO || !self.owner.BUTTON_ATCK)
+ {
+ if(self == self.owner.lgbeam)
+ self.owner.lgbeam = world;
+ remove(self);
+ return;
+ }
self.nextthink = time;
makevectors(self.owner.v_angle);
- vector angle;
- angle = v_forward;
-
- traceline_antilag(self.owner, self.owner.origin + self.owner.view_ofs, self.owner.origin + self.owner.view_ofs + angle * cvar("g_balance_electro_primary_range"), FALSE, self.owner, ANTILAG_LATENCY(self.owner));
+ float dt, f;
+ dt = frametime;
if not(self.owner.items & IT_UNLIMITED_WEAPON_AMMO)
- self.owner.ammo_cells = max(0, self.owner.ammo_cells - cvar("g_balance_electro_primary_ammo") * frametime);
+ {
+ if(cvar("g_balance_electro_primary_ammo"))
+ {
+ dt = min(dt, self.owner.ammo_cells / cvar("g_balance_electro_primary_ammo"));
+ self.owner.ammo_cells = max(0, self.owner.ammo_cells - cvar("g_balance_electro_primary_ammo") * frametime);
+ }
+ }
+
+ W_SetupShot_Range(self.owner, TRUE, 0, "", cvar("g_balance_electro_primary_damage") * dt, cvar("g_balance_electro_primary_range"));
+ WarpZone_traceline_antilag(self.owner, w_shotorg, w_shotend, MOVE_NORMAL, self.owner, ANTILAG_LATENCY(self.owner));
// apply the damage
- if(trace_fraction < 1)
+ if(trace_ent)
{
vector force;
- force = angle * cvar("g_balance_electro_primary_force") + '0 0 1' * cvar("g_balance_electro_primary_force_up");
- Damage (trace_ent, self.owner, self.owner, cvar("g_balance_electro_primary_damage") * frametime, WEP_ELECTRO, trace_endpos, force * frametime);
- W_Plasma_TriggerCombo(trace_endpos, cvar("g_balance_electro_primary_comboradius"), self.owner);
+ force = w_shotdir * cvar("g_balance_electro_primary_force") + '0 0 1' * cvar("g_balance_electro_primary_force_up");
+
+ f = ExponentialFalloff(cvar("g_balance_electro_primary_falloff_mindist"), cvar("g_balance_electro_primary_falloff_maxdist"), cvar("g_balance_electro_primary_falloff_halflifedist"), vlen(WarpZone_UnTransformOrigin(WarpZone_trace_transform, trace_endpos) - w_shotorg));
+
+ Damage (trace_ent, self.owner, self.owner, cvar("g_balance_electro_primary_damage") * dt * f, WEP_ELECTRO, trace_endpos, force * dt);
+ Damage_RecordDamage(self.owner, WEP_ELECTRO, cvar("g_balance_electro_primary_damage") * dt * f);
}
+ W_Plasma_TriggerCombo(trace_endpos, cvar("g_balance_electro_primary_comboradius"), self.owner);
// draw effect
- vector vecs, org;
- if(self.owner.weaponentity.movedir_x > 0)
+ if(w_shotorg != self.hook_start)
{
- vecs = self.owner.weaponentity.movedir;
- vecs_y = -vecs_y;
+ self.SendFlags |= 2;
+ self.hook_start = w_shotorg;
+ }
+ if(w_shotend != self.hook_end)
+ {
+ self.SendFlags |= 4;
+ self.hook_end = w_shotend;
}
- else
- vecs = '0 0 0';
- org = self.owner.origin + self.owner.view_ofs + v_forward * vecs_x + v_right * vecs_y + v_up * vecs_z;
-
- // TODO turn into a csqc entity
- WriteByte(MSG_BROADCAST, SVC_TEMPENTITY);
- WriteByte(MSG_BROADCAST, TE_CSQC_BEAM);
- WriteByte(MSG_BROADCAST, num_for_edict(self.owner));
- WriteByte(MSG_BROADCAST, sound_allowed(MSG_BROADCAST, self.owner) ? 1 : 2);
- WriteCoord(MSG_BROADCAST, trace_endpos_x);
- WriteCoord(MSG_BROADCAST, trace_endpos_y);
- WriteCoord(MSG_BROADCAST, trace_endpos_z);
- WriteCoord(MSG_BROADCAST, org_x);
- WriteCoord(MSG_BROADCAST, org_y);
- WriteCoord(MSG_BROADCAST, org_z);
}
// experimental lightning gun
// only play fire sound if 0.5 sec has passed since player let go the fire button
if(time - self.prevlgfire > 0.5)
{
- sound (self, CHAN_PROJECTILE, "weapons/lgbeam_fire.wav", VOL_BASE, ATTN_NORM);
+ sound (self, CHAN_WEAPON, "weapons/lgbeam_fire.wav", VOL_BASE, ATTN_NORM);
}
entity beam, oldself;
beam.shot_spread = 0;
beam.bot_dodge = TRUE;
beam.bot_dodgerating = cvar("g_balance_electro_primary_damage");
+ Net_LinkEntity(beam, FALSE, 0, lgbeam_send);
oldself = self;
self = beam;
{
if (self.BUTTON_ATCK)
{
- if (weapon_prepareattack(0, cvar("g_balance_electro_primary_refire")))
+ if (weapon_prepareattack(0, (cvar("g_balance_electro_lightning") ? 0 : cvar("g_balance_electro_primary_refire"))))
{
if(cvar("g_balance_electro_lightning"))
{
- if (self.BUTTON_ATCK_prev == 0)
+ if ((!self.lgbeam) || wasfreed(self.lgbeam))
{
W_Electro_Attack3();
}
weapon_thinkf(WFRAME_FIRE1, cvar("g_balance_electro_primary_animtime"), w_ready);
}
} else {
- self.BUTTON_ATCK_prev = 0;
+ if(cvar("g_balance_electro_lightning"))
+ {
+ if (self.BUTTON_ATCK_prev != 0)
+ {
+ ATTACK_FINISHED(self) = time + cvar("g_balance_electro_primary_refire") * W_WeaponRateFactor();
+ }
+ self.BUTTON_ATCK_prev = 0;
+ }
}
if (self.BUTTON_ATCK2)
else if (req == WR_CHECKAMMO1)
{
if(cvar("g_balance_electro_lightning"))
- return self.ammo_cells >= cvar("g_balance_electro_primary_ammo") * cvar("g_balance_electro_primary_refire");
+ return !cvar("g_balance_electro_primary_ammo") || (self.ammo_cells > 0);
else
return self.ammo_cells >= cvar("g_balance_electro_primary_ammo");
}
else if (req == WR_SUICIDEMESSAGE)
{
if(w_deathtype & HITTYPE_SECONDARY)
- w_deathtypestring = "could not remember where they put plasma";
+ w_deathtypestring = "%s could not remember where they put plasma";
else
- w_deathtypestring = "played with plasma";
+ w_deathtypestring = "%s played with plasma";
}
else if (req == WR_KILLMESSAGE)
{
if(w_deathtype & HITTYPE_SECONDARY)
{
if(w_deathtype & HITTYPE_SPLASH) // unchecked: BOUNCE
- w_deathtypestring = "just noticed #'s blue ball";
+ w_deathtypestring = "%s just noticed %s's blue ball";
else // unchecked: BOUNCE
- w_deathtypestring = "got in touch with #'s blue ball";
+ w_deathtypestring = "%s got in touch with %s's blue ball";
}
else
{
if(w_deathtype & HITTYPE_BOUNCE) // combo
- w_deathtypestring = "felt the electrifying air of #'s combo";
+ w_deathtypestring = "%s felt the electrifying air of %s's combo";
else if(w_deathtype & HITTYPE_SPLASH)
- w_deathtypestring = "got too close to #'s blue beam";
+ w_deathtypestring = "%s got too close to %s's blue beam";
else
- w_deathtypestring = "was blasted by #'s blue beam";
+ w_deathtypestring = "%s was blasted by %s's blue beam";
}
}
return TRUE;