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()
{
local entity proj;
- W_SetupShot_ProjectileSize (self, '0 0 -3', '0 0 -3', FALSE, 2, "weapons/electro_fire2.wav", cvar("g_balance_electro_secondary_damage"));
+ W_SetupShot_ProjectileSize (self, '0 0 -4', '0 0 -4', FALSE, 2, "weapons/electro_fire2.wav", cvar("g_balance_electro_secondary_damage"));
w_shotdir = v_forward; // no TrueAim for grenades please
pointparticles(particleeffectnum("electro_muzzleflash"), w_shotorg, w_shotdir * 1000, 1);
proj.movetype = MOVETYPE_BOUNCE;
W_SETUPPROJECTILEVELOCITY_UP(proj, g_balance_electro_secondary);
proj.touch = W_Plasma_Touch;
- setsize(proj, '0 0 -3', '0 0 -3');
+ setsize(proj, '0 0 -4', '0 0 -4');
proj.takedamage = DAMAGE_YES;
proj.damageforcescale = cvar("g_balance_electro_secondary_damageforcescale");
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;
-void lgbeam_think()
+ other = proj; MUTATOR_CALLHOOK(EditProjectile);
+ }
+
+.vector hook_start, hook_end;
+float lgbeam_send(entity to, float sf)
{
- if (self.owner.weaponentity.state != WS_INUSE || (self.owner.ammo_cells <= 0 && !(self.owner.items & IT_UNLIMITED_WEAPON_AMMO)) || self != self.owner.lgbeam)
+ 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)
{
- remove(self);
- return;
+ WriteByte(MSG_ENTITY, num_for_edict(self.owner));
+ WriteCoord(MSG_ENTITY, cvar("g_balance_electro_primary_range"));
}
-
- self.nextthink = time;
-
- makevectors(self.owner.v_angle);
- vector angle;
- angle = v_forward;
-
- vector force;
- force = angle * cvar("g_balance_electro_primary_force");
-
- 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));
-
- self.scale = vlen(self.owner.origin - trace_endpos) / 256 * (0.75 + 0.75 * random());
+ 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;
}
-
-void exteriorlgbeam_think()
+.entity lgbeam;
+.float prevlgfire;
+void lgbeam_think()
{
- if (self.owner.weaponentity.state != WS_INUSE || (self.owner.ammo_cells <= 0 && !(self.owner.items & IT_UNLIMITED_WEAPON_AMMO)) || self != self.owner.exteriorlgbeam)
+ self.owner.prevlgfire = time;
+ if (self != self.owner.lgbeam)
{
- sound (self, CHAN_PROJECTILE, "sound/misc/null.wav", VOL_BASE, ATTN_NORM);
remove(self);
return;
}
-
- if (time - self.shot_spread + random() * 0.2 > 0)
+ 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)
{
- self.shot_spread = time + 2;
- sound (self, CHAN_PROJECTILE, "turrets/phaser.wav", VOL_BASE, ATTN_NORM);
+ if(self == self.owner.lgbeam)
+ self.owner.lgbeam = world;
+ remove(self);
+ return;
}
- if not(self.items & IT_UNLIMITED_WEAPON_AMMO)
- self.ammo_cells = self.ammo_cells - cvar("g_balance_electro_primary_ammo") * frametime;
-
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)
+ {
+ 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") + trace_ent.velocity * cvar("g_balance_electro_primary_velocityfactor") + '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);
- }
+ force = w_shotdir * cvar("g_balance_electro_primary_force") + '0 0 1' * cvar("g_balance_electro_primary_force_up");
- self.angles = '0 0 0';
- self.scale = vlen(gettaginfo(self, 0) - trace_endpos) / 256 * (0.75 + 0.75 * random());
+ 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));
- // v_forward, v_right, v_up now are the ACTUAL directions
- // express self.angles in terms of them to aim at target!
- self.angles = vectoangles('1 0 0' * (angle * v_forward) + '0 -1 0' * (angle * v_right) + '0 0 1' * (angle * v_up));
+ 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
+ if(w_shotorg != self.hook_start)
+ {
+ self.SendFlags |= 2;
+ self.hook_start = w_shotorg;
+ }
+ if(w_shotend != self.hook_end)
+ {
+ self.SendFlags |= 4;
+ self.hook_end = w_shotend;
+ }
}
// experimental lightning gun
void W_Electro_Attack3 (void)
{
+ // 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_WEAPON, "weapons/lgbeam_fire.wav", VOL_BASE, ATTN_NORM);
+ }
+
entity beam, oldself;
self.lgbeam = beam = spawn();
- setmodel(beam,"models/turrets/phaser_beam.md3");
- beam.effects = EF_LOWPRECISION;
beam.solid = SOLID_NOT;
beam.think = lgbeam_think;
beam.owner = self;
beam.movetype = MOVETYPE_NONE;
- if(gettagindex(self.weaponentity, "shot"))
- setattachment(beam, self.weaponentity, "shot");
- else
- setattachment(beam, self.weaponentity, "tag_shot");
-
- oldself = self;
- self = beam;
- self.think();
- self = oldself;
-
- self.exteriorlgbeam = beam = spawn();
- setmodel(beam,"models/turrets/phaser_beam.md3");
- beam.effects = EF_LOWPRECISION;
- beam.solid = SOLID_NOT;
- beam.think = exteriorlgbeam_think;
- beam.owner = self;
- beam.movetype = MOVETYPE_NONE;
- //beam.viewmodelforclient = self;
- if(self.weaponentity.oldorigin_x > 0)
- {
- setattachment(beam, self.exteriorweaponentity, "");
- setorigin(beam, self.weaponentity.oldorigin);
- }
- else
- {
- if(gettagindex(self.exteriorweaponentity, "shot"))
- setattachment(beam, self.exteriorweaponentity, "shot");
- else
- setattachment(beam, self.exteriorweaponentity, "tag_shot");
- }
-
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;
self = oldself;
}
+void ElectroInit()
+{
+ weapon_action(WEP_ELECTRO, WR_PRECACHE);
+ electro_shotorigin[0] = shotorg_adjust_values(CL_Weapon_GetShotOrg(WEP_ELECTRO), FALSE, FALSE, 1);
+ electro_shotorigin[1] = shotorg_adjust_values(CL_Weapon_GetShotOrg(WEP_ELECTRO), FALSE, FALSE, 2);
+ electro_shotorigin[2] = shotorg_adjust_values(CL_Weapon_GetShotOrg(WEP_ELECTRO), FALSE, FALSE, 3);
+ electro_shotorigin[3] = shotorg_adjust_values(CL_Weapon_GetShotOrg(WEP_ELECTRO), FALSE, FALSE, 4);
+}
+
void spawnfunc_weapon_electro (void)
{
weapon_defaultspawnfunc(WEP_ELECTRO);
else if (req == WR_THINK)
{
if (self.BUTTON_ATCK)
- if (weapon_prepareattack(0, cvar("g_balance_electro_primary_refire")))
{
- if(cvar("g_balance_electro_lightning"))
+ if (weapon_prepareattack(0, (cvar("g_balance_electro_lightning") ? 0 : cvar("g_balance_electro_primary_refire"))))
{
- if (self.BUTTON_ATCK_prev == 0)
+ if(cvar("g_balance_electro_lightning"))
+ {
+ if ((!self.lgbeam) || wasfreed(self.lgbeam))
+ {
+ W_Electro_Attack3();
+ }
+ self.BUTTON_ATCK_prev = 1;
+ }
+ else
{
- W_Electro_Attack3();
+ W_Electro_Attack();
}
+ weapon_thinkf(WFRAME_FIRE1, cvar("g_balance_electro_primary_animtime"), w_ready);
}
- else
+ } else {
+ if(cvar("g_balance_electro_lightning"))
{
- W_Electro_Attack();
+ if (self.BUTTON_ATCK_prev != 0)
+ {
+ ATTACK_FINISHED(self) = time + cvar("g_balance_electro_primary_refire") * W_WeaponRateFactor();
+ }
+ self.BUTTON_ATCK_prev = 0;
}
- weapon_thinkf(WFRAME_FIRE1, cvar("g_balance_electro_primary_animtime"), w_ready);
}
+
if (self.BUTTON_ATCK2)
if (time >= self.electro_secondarytime)
if (weapon_prepareattack(1, cvar("g_balance_electro_secondary_refire")))
precache_sound ("weapons/electro_impact.wav");
precache_sound ("weapons/electro_impact_combo.wav");
if(cvar("g_balance_electro_lightning"))
- precache_sound ("weapons/crylink_fire2.wav");
+ {
+ precache_sound ("weapons/lgbeam_fire.wav");
+ }
}
else if (req == WR_SETUP)
weapon_setup(WEP_ELECTRO);
else if (req == WR_CHECKAMMO1)
- return self.ammo_cells >= cvar("g_balance_electro_primary_ammo");
+ {
+ if(cvar("g_balance_electro_lightning"))
+ 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_CHECKAMMO2)
return self.ammo_cells >= cvar("g_balance_electro_secondary_ammo");
else if (req == WR_RESETPLAYER)
{
self.electro_secondarytime = time;
}
- self.BUTTON_ATCK_prev = self.BUTTON_ATCK;
return TRUE;
};
#endif
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;