quake-painkeep/qwsrc/nweapons.qc

2482 lines
57 KiB
C++
Raw Permalink Normal View History

1997-08-12 00:00:00 +00:00
/*
*/
void (entity targ, entity inflictor, entity attacker, float damage) T_Damage;
void () player_run;
void(entity bomb, entity attacker, float rad, entity ignore) T_RadiusDamage;
void(vector org, vector vel, float damage) SpawnBlood;
void() SuperDamageSound;
// PAINKEEP TURRET_START
void() turret_dropTurret;
// TURRET_END
// BEARTRAP
void() beartrap_dropBearTrap;
// GRAVITY
void() drop_gravity;
// GRAPPLING_START
void() grap_fire;
void() grap_releaseHarpoon;
// GRAPPLING_END
// called by worldspawn
void() W_Precache =
{
precache_sound ("weapons/r_exp3.wav"); // new rocket explosion
precache_sound ("weapons/rocket1i.wav"); // spike gun
precache_sound ("weapons/sgun1.wav");
precache_sound ("weapons/guncock.wav"); // player shotgun
precache_sound ("weapons/ric1.wav"); // ricochet (used in c code)
precache_sound ("weapons/ric2.wav"); // ricochet (used in c code)
precache_sound ("weapons/ric3.wav"); // ricochet (used in c code)
precache_sound ("weapons/spike2.wav"); // super spikes
precache_sound ("weapons/tink1.wav"); // spikes tink (used in c code)
precache_sound ("weapons/grenade.wav"); // grenade launcher
precache_sound ("weapons/bounce.wav"); // grenade bounce
precache_sound ("weapons/shotgn2.wav"); // super shotgun
// PAINKEEP, precache all weapon models
// TURRET_START
/*
precache_model2 ("progs/nail.mdl");
precache_model2 ("progs/turgib1.mdl");
precache_model2 ("progs/turgib2.mdl");
precache_model2 ("progs/turgib3.mdl");
precache_model2 ("progs/turstand.mdl");
precache_model2 ("progs/turtop.mdl");
precache_sound2 ("weapons/turrt_3.wav");
precache_sound2 ("weapons/turcl_2b.wav");
// TURRET_END
// GRAVITY Moved to here so the cheat command would work correctly
precache_model ("progs/cubsmall.mdl");
precache_model ("progs/cube.mdl");
precache_model ("progs/cubel.mdl");
precache_sound ("misc/grav_new.wav");
precache_sound ("items/protect.wav");
// AIRG_MAIN_START
// prechache the AirFist fire sounds.
precache_sound ("weapons/agfire.wav"); // Air gun fire
precache_sound ("weapons/agfail.wav"); // Air gun failed fire
precache_sound ("weapons/agwater.wav"); // Air gun under water shot
precache_sound ("weapons/agwfail.wav"); // Air gun fail water shot
// AIRG_MAIN_END
// GRAPPLING_START
precache_sound ("weapons/graph_2b.wav"); // Hit solid
precache_sound ("weapons/grapf_1.wav"); // Hit fresh
precache_sound ("weapons/grapl_2.wav"); // Launch
precache_sound ("weapons/grapr_2.wav"); // Rope going out
precache_sound ("weapons/graps_2.wav"); // Rope coming back
precache_model ("progs/harpoon.mdl");
precache_model ("progs/harprope.mdl");
precache_model ("progs/harpcoil.mdl");
precache_model ("progs/g_harp.mdl");
precache_model ("progs/v_harp.mdl");
precache_sound ("misc/null.wav");
// GRAPPLING_END
// BOLT_START
precache_model ("progs/v_cl_off.mdl");
precache_model ("progs/v_cl_on.mdl");
precache_sound ("weapons/clight_1.wav");
precache_model ("progs/fryguy.mdl");
// BOLT_END
precache_model ("progs/v_fnail.mdl");
// COPB_START
precache_sound ("weapons/copb_1.wav"); // Fart sounds...
precache_sound ("weapons/copb_2.wav");
precache_sound ("weapons/copb_3.wav");
precache_sound ("weapons/copb_4.wav");
precache_sound ("weapons/copb_5.wav");
// COPB_END
*/
// TURRET_START
precache_model2 ("progs/nail.mdl");
precache_model2 ("progs/turgib1.mdl");
precache_model2 ("progs/turgib2.mdl");
precache_model2 ("progs/turgib3.mdl");
precache_model2 ("progs/turstand.mdl");
precache_model2 ("progs/turtop.mdl");
precache_sound2 ("weapons/sentry/turrt_3.wav");
precache_sound2 ("weapons/sentry/turcl_2b.wav");
// TURRET_END
// GRAVITY Moved to here so the cheat command would work correctly
precache_model ("progs/cubsmall.mdl");
precache_model ("progs/cube.mdl");
precache_model ("progs/cubel.mdl");
precache_sound ("misc/grav/grav_new.wav");
precache_sound ("items/protect.wav");
// AIRG_MAIN_START
// prechache the AirFist fire sounds.
precache_sound ("weapons/airfist/agfire.wav"); // Air gunfire
precache_sound ("weapons/airfist/agfail.wav"); // Air gunfailed fire
precache_sound ("weapons/airfist/agwater.wav"); // Air gun under water shot
precache_sound ("weapons/airfist/agwfail.wav"); // Air gun fail water shot
// AIRG_MAIN_END
// GRAPPLING_START
precache_sound ("weapons/grapple/graph_2b.wav"); // Hit solid
precache_sound ("weapons/grapple/grapf_1.wav"); // Hit fresh
precache_sound ("weapons/grapple/grapl_2.wav"); // Launch
precache_sound ("weapons/grapple/grapr_2.wav"); // Rope going out
precache_sound ("weapons/grapple/graps_2.wav"); // Rope coming back
precache_model ("progs/harpoon.mdl");
precache_model ("progs/harprope.mdl");
precache_model ("progs/harpcoil.mdl");
precache_model ("progs/g_harp.mdl");
precache_model ("progs/v_harp.mdl");
precache_sound ("misc/null.wav");
// GRAPPLING_END
// BOLT_START
precache_model ("progs/v_cl_off.mdl");
precache_model ("progs/v_cl_on.mdl");
precache_sound ("weapons/clight/clight_1.wav");
precache_model ("progs/fryguy.mdl");
// BOLT_END
precache_model ("progs/v_fnail.mdl");
// COPB_START
precache_sound ("weapons/copb/copb_1.wav"); // Fart sounds...
precache_sound ("weapons/copb/copb_2.wav");
precache_sound ("weapons/copb/copb_3.wav");
precache_sound ("weapons/copb/copb_4.wav");
precache_sound ("weapons/copb/copb_5.wav");
// COPB_END
// PULSE_GUN_START
precache_model("progs/pnail.mdl");
precache_model("progs/v_fnail.mdl");
precache_sound ("weapons/pulse/pulse_1.wav");
precache_sound("weapons/pulse/ric_1.wav");
precache_sound("weapons/pulse/ric_2.wav");
precache_sound("weapons/pulse/ric_3.wav");
// PULSE_GUN_END
// BEARTRAP
precache_sound ("weapons/btrap/btrap_1.wav");
precache_sound ("weapons/btrap/bdrop_1.wav");
precache_sound ("weapons/btrap/btrap_3.wav");
precache_model ("progs/beartrap.mdl");
precache_model ("progs/bearbld.mdl");
precache_model2 ("progs/beargib1.mdl");
precache_model2 ("progs/beargib2.mdl");
precache_model2 ("progs/beargib3.mdl");
precache_model2 ("progs/beargib4.mdl");
// EXPLODESHELLS_START
precache_model2 ("progs/v_eshot.mdl");
precache_model2 ("progs/v_eshot2.mdl");
precache_sound ("weapons/explode/expfire1.wav");
precache_sound ("weapons/explode/expfire2.wav");
precache_model2 ("progs/x_explo1.spr");
precache_model2 ("progs/x_explo2.spr");
// EXPLODESHELLS_END
// for the Hub map pop respawn
precache_sound ("items/protect.wav");
precache_sound ("items/protect2.wav");
precache_sound ("items/protect3.wav");
};
float() crandom =
{
return 2*(random() - 0.5);
};
/*
================
W_FireAxe
================
*/
void() W_FireAxe =
{
local vector source;
local vector org;
makevectors (self.v_angle);
source = self.origin + '0 0 16';
traceline (source, source + v_forward*64, FALSE, self);
if (trace_fraction == 1.0)
return;
org = trace_endpos - v_forward*4;
if (trace_ent.takedamage)
{
trace_ent.axhitme = 1;
SpawnBlood (org, '0 0 0', 20);
T_Damage (trace_ent, self, self, 20);
}
else
{ // hit wall
sound (self, CHAN_WEAPON, "player/axhit2.wav", 1, ATTN_NORM);
WriteByte (MSG_BROADCAST, SVC_TEMPENTITY);
WriteByte (MSG_BROADCAST, TE_GUNSHOT);
WriteCoord (MSG_BROADCAST, org_x);
WriteCoord (MSG_BROADCAST, org_y);
WriteCoord (MSG_BROADCAST, org_z);
}
};
//============================================================================
vector() wall_velocity =
{
local vector vel;
vel = normalize (self.velocity);
vel = normalize(vel + v_up*(random()- 0.5) + v_right*(random()- 0.5));
vel = vel + 2*trace_plane_normal;
vel = vel * 200;
return vel;
};
/*
================
SpawnMeatSpray
================
*/
void(vector org, vector vel) SpawnMeatSpray =
{
local entity missile, mpuff;
local vector org;
missile = spawn ();
missile.owner = self;
missile.movetype = MOVETYPE_BOUNCE;
missile.solid = SOLID_NOT;
makevectors (self.angles);
missile.velocity = vel;
missile.velocity_z = missile.velocity_z + 250 + 50*random();
missile.avelocity = '3000 1000 2000';
// set missile duration
missile.nextthink = time + 1;
missile.think = SUB_Remove;
setmodel (missile, "progs/zom_gib.mdl");
setsize (missile, '0 0 0', '0 0 0');
setorigin (missile, org);
// PAINKEEP SPLASH Make this entity splash
AddToSplash(missile);
};
/*
================
SpawnBlood
================
*/
void(vector org, vector vel, float damage) SpawnBlood =
{
particle (org, vel*0.1, 73, damage*2);
};
/*
================
spawn_touchblood
================
*/
void(float damage) spawn_touchblood =
{
local vector vel;
vel = wall_velocity () * 0.2;
SpawnBlood (self.origin + vel*0.01, vel, damage);
};
/*
================
SpawnChunk
================
*/
void(vector org, vector vel) SpawnChunk =
{
particle (org, vel*0.02, 0, 10);
};
/*
==============================================================================
MULTI-DAMAGE
Collects multiple small damages into a single damage
==============================================================================
*/
entity multi_ent;
float multi_damage;
void() ClearMultiDamage =
{
multi_ent = world;
multi_damage = 0;
};
void() ApplyMultiDamage =
{
if (!multi_ent)
return;
T_Damage (multi_ent, self, self, multi_damage);
};
void(entity hit, float damage) AddMultiDamage =
{
if (!hit)
return;
if (hit != multi_ent)
{
ApplyMultiDamage ();
multi_damage = damage;
multi_ent = hit;
}
else
multi_damage = multi_damage + damage;
};
/*
==============================================================================
BULLETS
==============================================================================
*/
// EXPLODESHELLS_START
void() es_explode1 = [0, es_explode2] {};
void() es_explode2 = [1, es_explode3] {};
void() es_explode3 = [2, es_explode4] {};
void() es_explode4 = [3, es_explode5] {};
void() es_explode5 = [4, SUB_Remove] {};
void() BecomeShellExplosion =
{
self.movetype = MOVETYPE_NONE;
self.velocity = '0 0 0';
self.touch = SUB_Null;
if(random() < 0.5)
{
setmodel (self, "progs/x_explo1.spr");
}
else
{
setmodel (self, "progs/x_explo2.spr");
}
self.solid = SOLID_NOT;
es_explode1 ();
};
void() explodeAttack =
{
local float damg;
damg = 12 + random() * 16;
if (self.enemy.health)
{
T_Damage (self.enemy, self, self.owner, damg );
}
// don't do radius damage to the other, because all the damage
// was done in the impact
T_RadiusDamage (self, self.owner, 28, self.enemy);
// sound (self, CHAN_WEAPON, "weapons/r_exp3.wav", 1, ATTN_NORM);
WriteByte (MSG_BROADCAST, SVC_TEMPENTITY);
WriteByte (MSG_BROADCAST, TE_EXPLOSION);
WriteCoord (MSG_BROADCAST, self.origin_x);
WriteCoord (MSG_BROADCAST, self.origin_y);
WriteCoord (MSG_BROADCAST, self.origin_z);
BecomeShellExplosion ();
};
void(float damage, vector dir) TraceExplodeAttack =
{
local entity explode;
explode = spawn();
explode.origin = trace_endpos - dir * 4;
explode.owner = self;
explode.enemy = trace_ent;
explode.classname = "ExplodeShellsAttack";
explode.weapon = self.weapon;
explode.nextthink = time + 0.10 + (random() * 0.75);
explode.think = explodeAttack;
};
void(float shotcount, vector dir, vector spread) FireExplodeShells =
{
local vector direction;
local vector src;
local float damage;
if(shotcount >= 2)
{
damage = 2;
}
else
{
damage = 1;
}
makevectors(self.v_angle);
src = self.origin + v_forward*10;
src_z = self.absmin_z + self.size_z * 0.7;
while (shotcount > 0)
{
direction = dir + crandom() * spread_x * v_right + crandom() * spread_y * v_up;
traceline (src, src + direction * 2048, FALSE, self);
if (trace_fraction != 1.0)
TraceExplodeAttack (damage, direction);
shotcount = shotcount - 1;
}
};
// EXPLODESHELLS_END
/*
================
TraceAttack
================
*/
void(float damage, vector dir) TraceAttack =
{
local vector vel, org;
vel = normalize(dir + v_up*crandom() + v_right*crandom());
vel = vel + 2*trace_plane_normal;
vel = vel * 200;
org = trace_endpos - dir*4;
if (trace_ent.takedamage)
{
SpawnBlood (org, vel*0.2, damage);
AddMultiDamage (trace_ent, damage);
}
else
{
WriteByte (MSG_BROADCAST, SVC_TEMPENTITY);
WriteByte (MSG_BROADCAST, TE_GUNSHOT);
WriteCoord (MSG_BROADCAST, org_x);
WriteCoord (MSG_BROADCAST, org_y);
WriteCoord (MSG_BROADCAST, org_z);
}
};
/*
================
FireBullets
Used by shotgun, super shotgun, and enemy soldier firing
Go to the trouble of combining multiple pellets into a single damage call.
================
*/
void(float shotcount, vector dir, vector spread) FireBullets =
{
local vector direction;
local vector src;
makevectors(self.v_angle);
src = self.origin + v_forward*10;
src_z = self.absmin_z + self.size_z * 0.7;
ClearMultiDamage ();
while (shotcount > 0)
{
direction = dir + crandom()*spread_x*v_right + crandom()*spread_y*v_up;
traceline (src, src + direction*2048, FALSE, self);
if (trace_fraction != 1.0)
TraceAttack (4, direction);
shotcount = shotcount - 1;
}
ApplyMultiDamage ();
};
/*
================
W_FireShotgun
================
*/
void() W_FireShotgun =
{
local vector dir;
self.punchangle_x = -2;
// EXPLODESHELLS_START
if(self.pk_explode_ammo) {
sound (self, CHAN_WEAPON, "weapons/explode/expfire1.wav", 1, ATTN_NORM);
self.currentammo = self.pk_explode_ammo = self.pk_explode_ammo - 1;
dir = aim (self, 100000);
FireExplodeShells((random() * 3) + 3, dir, '0.09 0.06 0');
// if run of out explode, switch to normal shells.
if(self.pk_explode_ammo == 0) {
self.currentammo = self.ammo_shells;
W_SetCurrentAmmo ();
}
} else {
sound (self, CHAN_WEAPON, "weapons/guncock.wav", 1, ATTN_NORM);
self.currentammo = self.ammo_shells = self.ammo_shells - 1;
dir = aim (self, 100000);
FireBullets (6, dir, '0.04 0.04 0');
}
// EXPLODESHELLS_END
};
/*
================
W_FireSuperShotgun
================
*/
void() W_FireSuperShotgun =
{
local vector dir;
if (self.currentammo == 1)
{
W_FireShotgun ();
return;
}
self.punchangle_x = -4;
// EXPLODESHELLS_START
if(self.pk_explode_ammo) {
sound (self, CHAN_WEAPON, "weapons/explode/expfire2.wav", 1, ATTN_NORM);
self.currentammo = self.pk_explode_ammo = self.pk_explode_ammo - 2;
dir = aim (self, 100000);
FireExplodeShells((random() * 4) + 6, dir, '0.14 0.08 0');
// if run of out explode, switch to normal shells.
if(self.pk_explode_ammo == 0) {
self.currentammo = self.ammo_shells;
W_SetCurrentAmmo ();
}
} else {
sound (self ,CHAN_WEAPON, "weapons/shotgn2.wav", 1, ATTN_NORM);
self.currentammo = self.ammo_shells = self.ammo_shells - 2;
dir = aim (self, 100000);
FireBullets (14, dir, '0.14 0.08 0');
}
// EXPLODESHELLS_END
};
/*
==============================================================================
ROCKETS
==============================================================================
*/
void() s_explode1 = [0, s_explode2] {};
void() s_explode2 = [1, s_explode3] {};
void() s_explode3 = [2, s_explode4] {};
void() s_explode4 = [3, s_explode5] {};
void() s_explode5 = [4, s_explode6] {};
void() s_explode6 = [5, SUB_Remove] {};
void() BecomeExplosion =
{
self.movetype = MOVETYPE_NONE;
self.velocity = '0 0 0';
self.touch = SUB_Null;
setmodel (self, "progs/s_explod.spr");
self.solid = SOLID_NOT;
s_explode1 ();
};
void() T_MissileTouch =
{
local float damg;
if (other == self.owner)
return; // don't explode on owner
if (pointcontents(self.origin) == CONTENT_SKY)
{
remove(self);
return;
}
damg = 100 + random()*20;
if (other.health)
{
if (other.classname == "monster_shambler")
damg = damg * 0.5; // mostly immune
T_Damage (other, self, self.owner, damg );
}
// don't do radius damage to the other, because all the damage
// was done in the impact
T_RadiusDamage (self, self.owner, 120, other);
// sound (self, CHAN_WEAPON, "weapons/r_exp3.wav", 1, ATTN_NORM);
self.origin = self.origin - 8*normalize(self.velocity);
WriteByte (MSG_BROADCAST, SVC_TEMPENTITY);
WriteByte (MSG_BROADCAST, TE_EXPLOSION);
WriteCoord (MSG_BROADCAST, self.origin_x);
WriteCoord (MSG_BROADCAST, self.origin_y);
WriteCoord (MSG_BROADCAST, self.origin_z);
BecomeExplosion ();
};
/*
================
W_FireRocket
================
*/
void() W_FireRocket =
{
local entity missile, mpuff;
self.currentammo = self.ammo_rockets = self.ammo_rockets - 1;
sound (self, CHAN_WEAPON, "weapons/sgun1.wav", 1, ATTN_NORM);
self.punchangle_x = -2;
missile = spawn ();
missile.owner = self;
missile.movetype = MOVETYPE_FLYMISSILE;
missile.solid = SOLID_BBOX;
missile.classname = "missile";
// set missile speed
makevectors (self.v_angle);
missile.velocity = aim(self, 1000);
missile.velocity = missile.velocity * 1000;
missile.angles = vectoangles(missile.velocity);
missile.touch = T_MissileTouch;
// set missile duration
missile.nextthink = time + 5;
missile.think = SUB_Remove;
setmodel (missile, "progs/missile.mdl");
setsize (missile, '0 0 0', '0 0 0');
setorigin (missile, self.origin + v_forward*8 + '0 0 16');
// PAINKEEP SPLASH Make this entity splash
AddToSplash(missile);
// PAINKEEP Correct death message info
missile.weapon = self.weapon;
};
/*
===============================================================================
LIGHTNING
===============================================================================
*/
/*
=================
LightningDamage
=================
*/
void(vector p1, vector p2, entity from, float damage) LightningDamage =
{
local entity e1, e2;
local vector f;
f = p2 - p1;
normalize (f);
f_x = 0 - f_y;
f_y = f_x;
f_z = 0;
f = f*16;
e1 = e2 = world;
traceline (p1, p2, FALSE, self);
if (trace_ent.takedamage)
{
particle (trace_endpos, '0 0 100', 225, damage*4);
T_Damage (trace_ent, from, from, damage);
if (self.classname == "player")
{
if (other.classname == "player")
trace_ent.velocity_z = trace_ent.velocity_z + 400;
}
}
e1 = trace_ent;
traceline (p1 + f, p2 + f, FALSE, self);
if (trace_ent != e1 && trace_ent.takedamage)
{
particle (trace_endpos, '0 0 100', 225, damage*4);
T_Damage (trace_ent, from, from, damage);
}
e2 = trace_ent;
traceline (p1 - f, p2 - f, FALSE, self);
if (trace_ent != e1 && trace_ent != e2 && trace_ent.takedamage)
{
particle (trace_endpos, '0 0 100', 225, damage*4);
T_Damage (trace_ent, from, from, damage);
}
};
void() W_FireLightning =
{
local vector org;
local float cells;
if (self.ammo_cells < 1)
{
self.weapon = W_BestWeapon ();
// PAINKEEP_START
self.pk_currentitem = W_BestPKWeapon();
// PAINKEEP_END
W_SetCurrentAmmo ();
return;
}
// explode if under water
if (self.waterlevel > 1)
{
cells = self.ammo_cells;
self.ammo_cells = 0;
W_SetCurrentAmmo ();
T_RadiusDamage (self, self, 35*cells, world);
return;
}
if (self.t_width < time)
{
sound (self, CHAN_WEAPON, "weapons/lhit.wav", 1, ATTN_NORM);
self.t_width = time + 0.6;
}
self.punchangle_x = -2;
self.currentammo = self.ammo_cells = self.ammo_cells - 1;
org = self.origin + '0 0 16';
traceline (org, org + v_forward*600, TRUE, self);
WriteByte (MSG_BROADCAST, SVC_TEMPENTITY);
WriteByte (MSG_BROADCAST, TE_LIGHTNING2);
WriteEntity (MSG_BROADCAST, self);
WriteCoord (MSG_BROADCAST, org_x);
WriteCoord (MSG_BROADCAST, org_y);
WriteCoord (MSG_BROADCAST, org_z);
WriteCoord (MSG_BROADCAST, trace_endpos_x);
WriteCoord (MSG_BROADCAST, trace_endpos_y);
WriteCoord (MSG_BROADCAST, trace_endpos_z);
LightningDamage (self.origin, trace_endpos + v_forward*4, self, 30);
};
//=============================================================================
void() GrenadeExplode =
{
T_RadiusDamage (self, self.owner, 120, world);
WriteByte (MSG_BROADCAST, SVC_TEMPENTITY);
WriteByte (MSG_BROADCAST, TE_EXPLOSION);
WriteCoord (MSG_BROADCAST, self.origin_x);
WriteCoord (MSG_BROADCAST, self.origin_y);
WriteCoord (MSG_BROADCAST, self.origin_z);
BecomeExplosion ();
};
void() GrenadeTouch =
{
if (other == self.owner)
return; // don't explode on owner
if (other.takedamage == DAMAGE_AIM)
{
GrenadeExplode();
return;
}
sound (self, CHAN_WEAPON, "weapons/bounce.wav", 1, ATTN_NORM); // bounce sound
if (self.velocity == '0 0 0')
self.avelocity = '0 0 0';
};
/*
================
W_FireGrenade
================
*/
void() W_FireGrenade =
{
local entity missile, mpuff;
self.currentammo = self.ammo_rockets = self.ammo_rockets - 1;
sound (self, CHAN_WEAPON, "weapons/grenade.wav", 1, ATTN_NORM);
self.punchangle_x = -2;
missile = spawn ();
missile.owner = self;
missile.movetype = MOVETYPE_BOUNCE;
missile.solid = SOLID_BBOX;
missile.classname = "grenade";
// set missile speed
makevectors (self.v_angle);
if (self.v_angle_x)
missile.velocity = v_forward*600 + v_up * 200 + crandom()*v_right*10 + crandom()*v_up*10;
else
{
missile.velocity = aim(self, 10000);
missile.velocity = missile.velocity * 600;
missile.velocity_z = 200;
}
missile.avelocity = '300 300 300';
missile.angles = vectoangles(missile.velocity);
missile.touch = GrenadeTouch;
// set missile duration
missile.nextthink = time + 2.5;
missile.think = GrenadeExplode;
setmodel (missile, "progs/grenade.mdl");
setsize (missile, '0 0 0', '0 0 0');
setorigin (missile, self.origin);
// PAINKEEP SPLASH Make this entity splash
AddToSplash(missile);
missile.weapon = self.weapon;
};
//=============================================================================
void() spike_touch;
void() superspike_touch;
// PULSE_GUN_START
void() pulse_touch;
// PULSE_GUN_END
/*
===============
launch_spike
Used for both the player and the ogre
===============
*/
void(vector org, vector dir) launch_spike =
{
newmis = spawn ();
newmis.owner = self;
newmis.movetype = MOVETYPE_FLYMISSILE;
newmis.solid = SOLID_BBOX;
newmis.angles = vectoangles(dir);
newmis.touch = spike_touch;
newmis.classname = "spike";
newmis.think = SUB_Remove;
newmis.nextthink = time + 6;
setmodel (newmis, "progs/spike.mdl");
setsize (newmis, VEC_ORIGIN, VEC_ORIGIN);
setorigin (newmis, org);
newmis.velocity = dir * 1000;
// PAINKEEP SPLASH Make this entity splash
AddToSplash(newmis);
// PAINKEEP Correct death message info
newmis.weapon = self.weapon;
};
void() W_FireSuperSpikes =
{
local vector dir;
local entity old;
sound (self, CHAN_WEAPON, "weapons/spike2.wav", 1, ATTN_NORM);
self.attack_finished = time + 0.2;
self.currentammo = self.ammo_nails = self.ammo_nails - 2;
dir = aim (self, 1000);
launch_spike (self.origin + '0 0 16', dir);
newmis.touch = superspike_touch;
setmodel (newmis, "progs/s_spike.mdl");
setsize (newmis, VEC_ORIGIN, VEC_ORIGIN);
self.punchangle_x = -2;
};
// PULSE_GUN_START
.entity theowner; // .owner replacement
void(float ox) W_FirePulseSpikes =
{
local vector dir;
local entity old;
makevectors(self.v_angle);
sound (self, CHAN_WEAPON, "weapons/pulse/pulse_1.wav", 1, ATTN_NORM);
//self.attack_finished = time + 0.4;
self.currentammo = self.ammo_nails = self.ammo_nails - 1;
dir = aim (self, 1000);
launch_spike (self.origin + '0 0 16' + v_right*ox, dir);
newmis.touch = pulse_touch;
newmis.theowner = self;
setmodel (newmis, "progs/pnail.mdl");
newmis.angles = vectoangles(dir);
setsize (newmis, VEC_ORIGIN, VEC_ORIGIN);
self.punchangle_x = -2;
// time limit
newmis.think = SUB_Remove;
newmis.nextthink = time + 2.0;
};
void(float ox) W_FireSpikes =
{
local vector dir;
local entity old;
makevectors (self.v_angle);
if (self.ammo_nails >= 2 && self.weapon == IT_SUPER_NAILGUN)
{
W_FireSuperSpikes ();
return;
}
if (self.ammo_nails < 1)
{
self.weapon = W_BestWeapon ();
// PAINKEEP_START
self.pk_currentitem = W_BestPKWeapon();
// PAINKEEP_END
W_SetCurrentAmmo ();
return;
}
W_FirePulseSpikes(ox);
};
// PULSE_GUN_END
.float hit_z;
void() spike_touch =
{
local float rand;
if (other == self.owner)
return;
if (other.solid == SOLID_TRIGGER)
return; // trigger field, do nothing
if (pointcontents(self.origin) == CONTENT_SKY)
{
remove(self);
return;
}
// hit something that bleeds
if (other.takedamage)
{
spawn_touchblood (9);
T_Damage (other, self, self.owner, 9);
}
else
{
WriteByte (MSG_BROADCAST, SVC_TEMPENTITY);
if (self.classname == "wizspike")
WriteByte (MSG_BROADCAST, TE_WIZSPIKE);
else if (self.classname == "knightspike")
WriteByte (MSG_BROADCAST, TE_KNIGHTSPIKE);
else
WriteByte (MSG_BROADCAST, TE_SPIKE);
WriteCoord (MSG_BROADCAST, self.origin_x);
WriteCoord (MSG_BROADCAST, self.origin_y);
WriteCoord (MSG_BROADCAST, self.origin_z);
}
remove(self);
};
void() superspike_touch =
{
local float rand;
if (other == self.owner)
return;
if (other.solid == SOLID_TRIGGER)
return; // trigger field, do nothing
if (pointcontents(self.origin) == CONTENT_SKY)
{
remove(self);
return;
}
// hit something that bleeds
if (other.takedamage)
{
spawn_touchblood (18);
T_Damage (other, self, self.owner, 18);
}
else
{
WriteByte (MSG_BROADCAST, SVC_TEMPENTITY);
WriteByte (MSG_BROADCAST, TE_SUPERSPIKE);
WriteCoord (MSG_BROADCAST, self.origin_x);
WriteCoord (MSG_BROADCAST, self.origin_y);
WriteCoord (MSG_BROADCAST, self.origin_z);
}
remove(self);
};
// PULSE_GUN_START
/*
rebound the pulse spike
*/
void() pulse_rebound =
{
self.velocity = normalize(self.velocity) * 1000;
self.movetype = MOVETYPE_FLYMISSILE;
self.angles = vectoangles(self.velocity);
self.think = SUB_Remove;
self.nextthink = self.ltime;
// we want to hurt the owner now...
self.owner = world;
};
void() pulse_touch =
{
local float rand;
// owner protected? hahahaha
//if (other == self.owner)
// return;
if (other.solid == SOLID_TRIGGER)
return; // trigger field, do nothing
if (pointcontents(self.origin) == CONTENT_SKY)
{
remove(self);
return;
}
// hit something that bleeds
if (other.takedamage)
{
spawn_touchblood (27);
self.owner = self.theowner;
T_Damage (other, self, self.owner, 27);
}
else
{
// play ricochet sound
rand = random() * 100;
if (rand < 33)
sound (self, CHAN_AUTO, "weapons/pulse/ric_1.wav", 1, ATTN_NORM);
else if (rand < 66)
sound (self, CHAN_AUTO, "weapons/pulse/ric_2.wav", 1, ATTN_NORM);
else
sound (self, CHAN_AUTO, "weapons/pulse/ric_3.wav", 1, ATTN_NORM);
WriteByte (MSG_BROADCAST, SVC_TEMPENTITY);
WriteByte (MSG_BROADCAST, TE_SUPERSPIKE);
WriteCoord (MSG_BROADCAST, self.origin_x);
WriteCoord (MSG_BROADCAST, self.origin_y);
WriteCoord (MSG_BROADCAST, self.origin_z);
// rebound
self.movetype = MOVETYPE_BOUNCE;
self.think = pulse_rebound;
self.ltime = self.nextthink;
self.nextthink = time + 0.1;
return;
}
remove(self);
};
// PULSE_GUN_END
/*
===============================================================================
PLAYER WEAPON USE
===============================================================================
*/
void() W_SetCurrentAmmo =
{
player_run (); // get out of any weapon firing states
self.items = self.items - ( self.items & (IT_SHELLS | IT_NAILS | IT_ROCKETS | IT_CELLS) );
// PAINKEEP_START
// PAINKEEP_PREVWEAPON_START
if ((self.prevweapon != self.weapon) || (self.pkprevweapon != self.pk_currentitem) || (self.forcewchange == 1))
{
self.lastweapon = self.prevweapon;
self.prevweapon = self.weapon;
self.pklastweapon = self.pkprevweapon;
self.pkprevweapon = self.pk_currentitem;
self.forcewchange = FALSE;
}
// PAINKEEP_PREVWEAPON_END
if (self.items & IT_INVISIBILITY)
sprint(self, "You have selected the ");
if (self.weapon == IT_AXE)
{
if(self.pk_currentitem == PK_IT_AXE)
{
self.currentammo = 0;
self.weaponmodel = "progs/v_axe.mdl";
self.weaponframe = 0;
if (self.items & IT_INVISIBILITY)
sprint(self, "Axe\n");
}
else if(self.pk_currentitem == PK_IT_GRAVITYWELL)
{
self.currentammo = self.pk_gravitywellammo;
self.weaponmodel = "progs/v_cube.mdl";
self.weaponframe = 0;
if (self.items & IT_INVISIBILITY)
sprint(self, "Gravity Well\n");
}
else if(self.pk_currentitem == PK_IT_TURRET)
{
self.currentammo = self.pk_turretammo;
self.weaponmodel = "progs/v_turret.mdl";
self.weaponframe = 0;
if (self.items & IT_INVISIBILITY)
sprint(self, "AutoSentry\n");
}
else if(self.pk_currentitem == PK_IT_CANPAB)
{
self.currentammo = self.pk_canpabammo;
self.weaponmodel = "progs/v_beans.mdl";
self.weaponframe = 0;
if (self.items & IT_INVISIBILITY)
sprint(self, "Can of Pork & Beans\n");
}
else if(self.pk_currentitem == PK_IT_GRAPGUN)
{
// GRAPPLING_START
self.currentammo = 1;
self.weaponmodel = "progs/v_harp.mdl";
if(self.grap_cornerchainNext != world)
{
self.weaponframe = 8;
}
else
{
self.weaponframe = 0;
}
if (self.items & IT_INVISIBILITY)
sprint(self, "Harpoon Gun\n");
// GRAPPLING_END
}
else if(self.pk_currentitem == PK_IT_BEARTRAP)
{
self.currentammo = self.pk_beartrapammo;
self.weaponmodel = "progs/v_bear.mdl";
self.weaponframe = 0;
if (self.items & IT_INVISIBILITY)
sprint(self, "Beartrap\n");
}
else if(self.pk_currentitem == PK_IT_AIRGUN)
{
self.currentammo = 1;
self.weaponmodel = "progs/v_airgun.mdl";
self.weaponframe = 0;
if (self.items & IT_INVISIBILITY)
sprint(self, "AirFist\n");
}
// BOLT_START
else if(self.pk_currentitem == PK_IT_CLIGHT)
{
self.currentammo = self.ammo_cells;
if(self.bolt_changeModelTimeout < time)
{
self.weaponmodel = "progs/v_cl_off.mdl";
}
else
{
self.weaponmodel = "progs/v_cl_on.mdl";
}
self.weaponframe = 0;
self.items = self.items | IT_CELLS;
if (self.items & IT_INVISIBILITY)
sprint(self, "Chain Thunderbolt\n");
}
// BOLT_END
}
else if (self.weapon == IT_SHOTGUN)
{
// EXPLODESHELLS_START
if(self.pk_explode_ammo) {
self.currentammo = self.pk_explode_ammo;
self.weaponmodel = "progs/v_eshot.mdl";
} else {
self.currentammo = self.ammo_shells;
self.weaponmodel = "progs/v_shot.mdl";
}
// EXPLODESHELLS_END
self.weaponframe = 0;
self.items = self.items | IT_SHELLS;
if (self.items & IT_INVISIBILITY)
sprint(self, "Shotgun\n");
}
else if (self.weapon == IT_SUPER_SHOTGUN)
{
// EXPLODESHELLS_START
if(self.pk_explode_ammo) {
self.currentammo = self.pk_explode_ammo;
self.weaponmodel = "progs/v_eshot2.mdl";
} else {
self.currentammo = self.ammo_shells;
self.weaponmodel = "progs/v_shot2.mdl";
}
// EXPLODESHELLS_END
self.weaponframe = 0;
self.items = self.items | IT_SHELLS;
if (self.items & IT_INVISIBILITY)
sprint(self, "Super Shotgun\n");
}
else if (self.weapon == IT_NAILGUN)
{
self.currentammo = self.ammo_nails;
// PULSE_GUN_START
self.weaponmodel = "progs/v_fnail.mdl";
self.weaponframe = 0;
self.items = self.items | IT_NAILS;
if (self.items & IT_INVISIBILITY)
sprint(self, "Pulse Rifle\n");
// PULSE_GUN_END
}
else if (self.weapon == IT_SUPER_NAILGUN)
{
self.currentammo = self.ammo_nails;
self.weaponmodel = "progs/v_nail2.mdl";
self.weaponframe = 0;
self.items = self.items | IT_NAILS;
if (self.items & IT_INVISIBILITY)
sprint(self, "Super Nailgun\n");
}
else if (self.weapon == IT_GRENADE_LAUNCHER)
{
self.currentammo = self.ammo_rockets;
self.weaponmodel = "progs/v_rock.mdl";
self.weaponframe = 0;
self.items = self.items | IT_ROCKETS;
if (self.items & IT_INVISIBILITY)
sprint(self, "Grenade Launcher\n");
}
else if (self.weapon == IT_ROCKET_LAUNCHER)
{
self.currentammo = self.ammo_rockets;
self.weaponmodel = "progs/v_rock2.mdl";
self.weaponframe = 0;
self.items = self.items | IT_ROCKETS;
if (self.items & IT_INVISIBILITY)
sprint(self, "Rocket Launcher\n");
}
else if (self.weapon == IT_LIGHTNING)
{
self.currentammo = self.ammo_cells;
self.weaponmodel = "progs/v_light.mdl";
self.weaponframe = 0;
self.items = self.items | IT_CELLS;
if (self.items & IT_INVISIBILITY)
sprint(self, "Thunderbolt\n");
}
else
{
self.currentammo = 0;
self.weaponmodel = "";
self.weaponframe = 0;
if (self.items & IT_INVISIBILITY)
sprint(self, "An Unknown Weapon???\n");
}
// PAINKEEP_END
};
float() W_BestWeapon =
{
local float it;
it = self.items;
// PAINKEEP_START
if(self.waterlevel <= 1 && self.ammo_cells >= 2 && (self.pk_items & PK_IT_CLIGHT))
return IT_AXE;
// PAINKEEP_END
if (self.waterlevel <= 1 && self.ammo_cells >= 1 && (it & IT_LIGHTNING) )
return IT_LIGHTNING;
if(self.ammo_nails >= 2 && (it & IT_SUPER_NAILGUN) )
return IT_SUPER_NAILGUN;
// EXPLODESHELLS_START
if((self.ammo_shells >= 2 || self.pk_explode_ammo >= 2) && (it & IT_SUPER_SHOTGUN) )
// EXPLODESHELLS_END
return IT_SUPER_SHOTGUN;
if(self.ammo_nails >= 1 && (it & IT_NAILGUN) )
return IT_NAILGUN;
// EXPLODESHELLS_START
if((self.ammo_shells >= 1 || self.pk_explode_ammo >= 1) && (it & IT_SHOTGUN) )
// EXPLODESHELLS_END
return IT_SHOTGUN;
// PAINKEEP_START
if (self.pk_items & PK_IT_AIRGUN)
return IT_AXE;
// PAINKEEP_END
return IT_AXE;
};
// PAINKEEP_START
float() W_BestPKWeapon =
{
if(self.weapon == IT_AXE)
{
if(self.waterlevel <= 1 && self.ammo_cells >= 2 && (self.pk_items & PK_IT_CLIGHT))
return PK_IT_CLIGHT;
if(self.pk_items & PK_IT_AIRGUN)
return PK_IT_AIRGUN;
}
return PK_IT_AXE;
};
// PAINKEEP_END
float() W_CheckNoAmmo =
{
if (self.currentammo > 0)
return TRUE;
// PAINKEEP_START
if (self.weapon == IT_AXE && self.pk_currentitem == PK_IT_AXE)
return TRUE;
// PAINKEEP_END
self.weapon = W_BestWeapon ();
// PAINKEEP_START
self.pk_currentitem = W_BestPKWeapon();
// PAINKEEP_END
W_SetCurrentAmmo ();
// drop the weapon down
return FALSE;
};
/*
============
W_Attack
An attack impulse can be triggered now
============
*/
void() player_axe1;
void() player_axeb1;
void() player_axec1;
void() player_axed1;
void() player_shot1;
void() player_nail1;
// PULSE_GUN_START
void() player_supernail1;
// PULSE_GUN_END
void() player_light1;
void() player_rocket1;
// BOLT_START
void() player_bolt1;
// BOLT_END
// COPB_START
void() copb_eatCan;
// COPB_END
void() W_Attack =
{
local float r;
if (!W_CheckNoAmmo ())
return;
makevectors (self.v_angle); // calculate forward angle for velocity
self.show_hostile = time + 1; // wake monsters up
if (self.weapon == IT_AXE)
{
// PAINKEEP_START
if(self.pk_currentitem == PK_IT_AXE)
{
sound (self, CHAN_WEAPON, "weapons/ax1.wav", 1, ATTN_NORM);
r = random();
if (r < 0.25)
player_axe1 ();
else if (r<0.5)
player_axeb1 ();
else if (r<0.75)
player_axec1 ();
else
player_axed1 ();
self.attack_finished = time + 0.5;
}
else if(self.pk_currentitem == PK_IT_GRAVITYWELL)
{
// drop Gravity Well
drop_gravity();
self.pk_gravitywellammo = self.pk_gravitywellammo - 1;
self.attack_finished = time + 0.5;
// check if run out, change to bestweapon then.
if(self.pk_gravitywellammo < 1)
{
self.pk_currentInventory = PK_IT_AXE;
self.weapon = W_BestWeapon ();
self.pk_currentitem = W_BestPKWeapon();
W_SetCurrentAmmo ();
}
}
else if(self.pk_currentitem == PK_IT_TURRET)
{
// Drop Turret
turret_dropTurret();
self.currentammo = self.pk_turretammo = self.pk_turretammo - 1;
self.attack_finished = time + 0.5;
if(self.pk_turretammo < 1)
{
self.pk_currentInventory = PK_IT_AXE;
self.weapon = W_BestWeapon ();
self.pk_currentitem = W_BestPKWeapon();
W_SetCurrentAmmo ();
}
}
else if(self.pk_currentitem == PK_IT_CANPAB)
{
if (self.health > 249)
return;
// Open can of pork & beans
// COPB_START
copb_eatCan();
self.pk_canpabammo = self.pk_canpabammo - 1;
// COPB_END
self.attack_finished = time + 0.5;
if(self.pk_canpabammo < 1)
{
self.pk_currentInventory = PK_IT_AXE;
self.weapon = W_BestWeapon ();
self.pk_currentitem = W_BestPKWeapon();
W_SetCurrentAmmo ();
}
}
else if(self.pk_currentitem == PK_IT_GRAPGUN)
{
// Fire grappling gun
// GRAPPLING_START
grap_fire();
// GRAPPLING_END
}
// BEARTRAP_START
else if(self.pk_currentitem == PK_IT_BEARTRAP)
{
// Drop bear trap
beartrap_dropBearTrap();
self.currentammo = self.pk_beartrapammo = self.pk_beartrapammo - 1;
self.attack_finished = time + 0.5;
if(self.pk_beartrapammo < 1)
{
self.pk_currentInventory = PK_IT_AXE;
self.weapon = W_BestWeapon ();
self.pk_currentitem = W_BestPKWeapon();
W_SetCurrentAmmo ();
}
}
// BEARTRAP_END
else if(self.pk_currentitem == PK_IT_AIRGUN)
{
// Fire the AirFist weapon
launch_horn();
}
else if(self.pk_currentitem == PK_IT_CLIGHT)
{
// Fire chain ligthning gun
// BOLT_START
self.weaponmodel = "progs/v_cl_on.mdl"; // change to fire model...
player_bolt1();
self.attack_finished = time + 0.1;
// BOLT_END
}
// PAINKEEP_END
}
else if (self.weapon == IT_SHOTGUN)
{
player_shot1 ();
W_FireShotgun ();
self.attack_finished = time + 0.5;
}
else if (self.weapon == IT_SUPER_SHOTGUN)
{
player_shot1 ();
W_FireSuperShotgun ();
self.attack_finished = time + 0.7;
}
else if (self.weapon == IT_NAILGUN)
{
player_nail1 ();
}
else if (self.weapon == IT_SUPER_NAILGUN)
{
// PULSE_GUN_START
player_supernail1 ();
// PULSE_GUN_END
}
else if (self.weapon == IT_GRENADE_LAUNCHER)
{
player_rocket1();
W_FireGrenade();
self.attack_finished = time + 0.6;
}
else if (self.weapon == IT_ROCKET_LAUNCHER)
{
player_rocket1();
W_FireRocket();
self.attack_finished = time + 0.8;
}
else if (self.weapon == IT_LIGHTNING)
{
player_light1();
self.attack_finished = time + 0.1;
sound (self, CHAN_AUTO, "weapons/lstart.wav", 1, ATTN_NORM);
}
};
// PAINKEEP_START
/*
============
HasAmmo
New for PainKeep, makes things a whole lot simplier
============
*/
float(float weaponnum, float pknum) HasAmmo =
{
if (weaponnum == IT_AXE)
{
if (pknum == PK_IT_CLIGHT)
{
if (self.ammo_cells < 2)
return FALSE;
}
else if (pknum == PK_IT_GRAVITYWELL)
{
if(self.pk_gravitywellammo < 1)
return FALSE;
}
else if (pknum == PK_IT_TURRET)
{
if(self.pk_turretammo < 1)
return FALSE;
}
else if (pknum == PK_IT_BEARTRAP)
{
if(self.pk_beartrapammo < 1)
return FALSE;
}
else if (pknum == PK_IT_CANPAB)
{
if(self.pk_canpabammo < 1)
return FALSE;
}
}
else if (weaponnum == IT_SHOTGUN)
{
// EXPLODESHELLS_START
if (self.ammo_shells < 1 && self.pk_explode_ammo < 1)
// EXPLODESHELLS_END
return FALSE;
}
else if (weaponnum == IT_SUPER_SHOTGUN)
{
// EXPLODESHELLS_START
if (self.ammo_shells < 2 && self.pk_explode_ammo < 2)
// EXPLODESHELLS_END
return FALSE;
}
else if (weaponnum == IT_NAILGUN)
{
if (self.ammo_nails < 1)
return FALSE;
}
else if (weaponnum == IT_SUPER_NAILGUN)
{
if (self.ammo_nails < 2)
return FALSE;
}
else if (weaponnum == IT_GRENADE_LAUNCHER)
{
if (self.ammo_rockets < 1)
return FALSE;
}
else if (weaponnum == IT_ROCKET_LAUNCHER)
{
if (self.ammo_rockets < 1)
return FALSE;
}
else if (weaponnum == IT_LIGHTNING)
{
if (self.ammo_cells < 1)
return FALSE;
}
return TRUE;
};
/*
============
CanSelect
New for PainKeep, makes things a whole lot simplier
============
*/
float(float weaponnum, float pknum) CanSelect =
{
// First, check that we have the weapon
if (!self.items & weaponnum)
return FALSE;
if (weaponnum == IT_AXE && !(self.pk_items & pknum))
return FALSE;
local float am;
am = HasAmmo(weaponnum, pknum);
return am;
};
// PAINKEEP_END
// PAINKEEP_START
void() pk_ChangeWeapon =
{
if(self.impulse == 30)
{
if(!(self.pk_items & PK_IT_AIRGUN))
return;
self.pk_currentitem = PK_IT_AIRGUN;
}
else if(self.impulse == 31 || self.impulse == 21 || self.impulse == 22)
{
if(!(self.pk_items & PK_IT_GRAPGUN))
return;
self.pk_currentitem = PK_IT_GRAPGUN;
}
else if(self.impulse == 32)
{
if(self.ammo_cells < 2 || !(self.pk_items & PK_IT_CLIGHT))
return;
self.pk_currentitem = PK_IT_CLIGHT;
}
else if(self.impulse == 33)
{
if(self.pk_gravitywellammo < 1)
return;
self.pk_currentInventory = self.pk_currentitem = PK_IT_GRAVITYWELL;
}
else if(self.impulse == 34)
{
if(self.pk_beartrapammo < 1)
return;
self.pk_currentInventory = self.pk_currentitem = PK_IT_BEARTRAP;
}
else if(self.impulse == 35)
{
if(self.pk_turretammo < 1)
return;
self.pk_currentInventory = self.pk_currentitem = PK_IT_TURRET;
}
else if(self.impulse == 36)
{
if(self.pk_canpabammo < 1)
return;
self.pk_currentInventory = self.pk_currentitem = PK_IT_CANPAB;
}
else if(self.impulse == 37)
{
self.pk_currentInventory = self.pk_currentitem = PK_IT_AXE;
}
else
{ // print the current inventory items out.
msg_entity = self;
WriteByte(MSG_ONE, SVC_CENTERPRINT);
// '\n\n\n\n\nYou Have:\nGravity Wells : '
WriteB3(MSG_ONE, 657930);
WriteB3(MSG_ONE, 5835274);
WriteB3(MSG_ONE, 2127215);
WriteB3(MSG_ONE, 7758152);
WriteB3(MSG_ONE, 670309);
WriteB3(MSG_ONE, 6386247);
WriteB3(MSG_ONE, 7629174);
WriteB3(MSG_ONE, 5709945);
WriteB3(MSG_ONE, 7105637);
WriteB3(MSG_ONE, 3809395);
WriteB3(MSG_ONE, 32);
WriteBFloat(MSG_ONE, self.pk_gravitywellammo);
// ' '
WriteB3(MSG_ONE, 2105376);
WriteB3(MSG_ONE, 2105376);
WriteB3(MSG_ONE, 2105376);
WriteB3(MSG_ONE, 2105376);
WriteB3(MSG_ONE, 2105376);
WriteB3(MSG_ONE, 2105376);
WriteB3(MSG_ONE, 2105376);
WriteB3(MSG_ONE, 2105376);
WriteB3(MSG_ONE, 2105376);
WriteB3(MSG_ONE, 2105376);
// '\nAutoSentry's : '
WriteB3(MSG_ONE, 7684362);
WriteB3(MSG_ONE, 5468020);
WriteB3(MSG_ONE, 7630437);
WriteB3(MSG_ONE, 2586994);
WriteB3(MSG_ONE, 3809395);
WriteB3(MSG_ONE, 32);
WriteBFloat(MSG_ONE, self.pk_turretammo);
// ' '
WriteB3(MSG_ONE, 2105376);
WriteB3(MSG_ONE, 2105376);
WriteB3(MSG_ONE, 2105376);
WriteB3(MSG_ONE, 2105376);
WriteB3(MSG_ONE, 2105376);
WriteB3(MSG_ONE, 2105376);
WriteB3(MSG_ONE, 2105376);
WriteB3(MSG_ONE, 2105376);
WriteB3(MSG_ONE, 2105376);
WriteB3(MSG_ONE, 2105376);
// '\nCan Of Pork & Beens : '
WriteB3(MSG_ONE, 6374154);
WriteB3(MSG_ONE, 5185646);
WriteB3(MSG_ONE, 5251174);
WriteB3(MSG_ONE, 7041647);
WriteB3(MSG_ONE, 2106912);
WriteB3(MSG_ONE, 6645058);
WriteB3(MSG_ONE, 2126702);
WriteB3(MSG_ONE, 8250);
WriteBFloat(MSG_ONE, self.pk_canpabammo);
// ' '
WriteB3(MSG_ONE, 2105376);
WriteB3(MSG_ONE, 2105376);
WriteB3(MSG_ONE, 2105376);
WriteB3(MSG_ONE, 2105376);
WriteB3(MSG_ONE, 2105376);
WriteB3(MSG_ONE, 2105376);
WriteB3(MSG_ONE, 2105376);
WriteB3(MSG_ONE, 2105376);
WriteB3(MSG_ONE, 2105376);
WriteB3(MSG_ONE, 2105376);
// '\nBear Traps : '
WriteB3(MSG_ONE, 6636042);
WriteB3(MSG_ONE, 2126433);
WriteB3(MSG_ONE, 6386260);
WriteB3(MSG_ONE, 2126704);
WriteB3(MSG_ONE, 8250);
WriteBFloat(MSG_ONE, self.pk_beartrapammo);
// ' '
WriteB3(MSG_ONE, 2105376);
WriteB3(MSG_ONE, 2105376);
WriteB3(MSG_ONE, 2105376);
WriteB3(MSG_ONE, 2105376);
WriteB3(MSG_ONE, 2105376);
WriteB3(MSG_ONE, 2105376);
WriteB3(MSG_ONE, 2105376);
WriteB3(MSG_ONE, 2105376);
WriteB3(MSG_ONE, 2105376);
WriteB3(MSG_ONE, 2105376);
WriteB3(MSG_ONE, 2105376);
// '\nExploding Shells : '
WriteB3(MSG_ONE, 7881994);
WriteB3(MSG_ONE, 7302256);
WriteB3(MSG_ONE, 7235940);
WriteB3(MSG_ONE, 5447783);
WriteB3(MSG_ONE, 7103848);
WriteB3(MSG_ONE, 2126700);
WriteB3(MSG_ONE, 8250);
WriteBFloat(MSG_ONE, self.pk_explode_ammo);
// ' '
WriteB3(MSG_ONE, 2105376);
WriteB3(MSG_ONE, 2105376);
WriteB3(MSG_ONE, 2105376);
WriteB3(MSG_ONE, 2105376);
WriteB3(MSG_ONE, 2105376);
WriteB3(MSG_ONE, 2105376);
WriteB3(MSG_ONE, 2105376);
WriteB3(MSG_ONE, 2105376);
WriteB3(MSG_ONE, 2105376);
WriteB3(MSG_ONE, 2105376);
WriteB3(MSG_ONE, 2105376);
// '\n'
WriteB3(MSG_ONE, 10);
if(self.pk_items & PK_IT_GRAPGUN)
{
// 'Harpoon Gun '
WriteB3(MSG_ONE, 7496008);
WriteB3(MSG_ONE, 7303024);
WriteB3(MSG_ONE, 4661358);
WriteB3(MSG_ONE, 2125429);
WriteB3(MSG_ONE, 32);
}
else
{
// ' '
WriteB3(MSG_ONE, 2105376);
WriteB3(MSG_ONE, 2105376);
WriteB3(MSG_ONE, 2105376);
WriteB3(MSG_ONE, 2105376);
WriteB3(MSG_ONE, 32);
}
if(self.pk_items & PK_IT_AIRGUN)
{
// 'AirFist '
WriteB3(MSG_ONE, 7498049);
WriteB3(MSG_ONE, 7563590);
WriteB3(MSG_ONE, 2105460);
WriteB3(MSG_ONE, 32);
}
else
{
// ' '
WriteB3(MSG_ONE, 2105376);
WriteB3(MSG_ONE, 2105376);
WriteB3(MSG_ONE, 2105376);
WriteB3(MSG_ONE, 32);
}
if(self.pk_items & PK_IT_CLIGHT)
{
// 'Chain Thunderbolt '
WriteB3(MSG_ONE, 6383683);
WriteB3(MSG_ONE, 2125417);
WriteB3(MSG_ONE, 7694420);
WriteB3(MSG_ONE, 6644846);
WriteB3(MSG_ONE, 7299698);
WriteB3(MSG_ONE, 2126956);
}
else
{
// ' '
WriteB3(MSG_ONE, 2105376);
WriteB3(MSG_ONE, 2105376);
WriteB3(MSG_ONE, 2105376);
WriteB3(MSG_ONE, 2105376);
WriteB3(MSG_ONE, 2105376);
WriteB3(MSG_ONE, 2105376);
}
WriteByte(MSG_ONE, 0);
return;
}
//
// set weapon, set ammo
//
self.weapon = IT_AXE;
self.forcewchange = TRUE;
W_SetCurrentAmmo ();
};
void() pk_cycleObjects =
{
while (1)
{
if(self.pk_currentitem == PK_IT_AXE)
self.pk_currentitem = PK_IT_GRAVITYWELL;
else if(self.pk_currentitem == PK_IT_GRAVITYWELL)
self.pk_currentitem = PK_IT_TURRET;
else if(self.pk_currentitem == PK_IT_TURRET)
self.pk_currentitem = PK_IT_BEARTRAP;
else if(self.pk_currentitem == PK_IT_BEARTRAP)
self.pk_currentitem = PK_IT_CANPAB;
else if(self.pk_currentitem == PK_IT_CANPAB)
self.pk_currentitem = PK_IT_AXE;
else
return; // get's here when the currentitem == a normal pk weapon
if (HasAmmo(IT_AXE, self.pk_currentitem))
{
self.pk_currentInventory = self.pk_currentitem;
return;
}
}
};
// PAINKEEP_END
/*
============
W_ChangeWeapon
============
*/
void() W_ChangeWeapon =
{
local float am, fl, fl2;
am = 0;
fl2 = 0;
if (self.impulse == 1)
{
fl = IT_AXE;
// PAINKEEP_START
if(self.weapon == IT_AXE)
{ // if already selected axe.
// toggle through all the objects we have.
pk_cycleObjects();
}
// select the current inventory item
fl2 = self.pk_currentInventory;
// PAINKEEP_END
}
else if (self.impulse == 2)
fl = IT_SHOTGUN;
else if (self.impulse == 3)
fl = IT_SUPER_SHOTGUN;
else if (self.impulse == 4)
fl = IT_NAILGUN;
else if (self.impulse == 5)
fl = IT_SUPER_NAILGUN;
else if (self.impulse == 6)
fl = IT_GRENADE_LAUNCHER;
else if (self.impulse == 7)
fl = IT_ROCKET_LAUNCHER;
else if (self.impulse == 8)
{
fl = IT_AXE;
fl2 = PK_IT_CLIGHT;
}
am = !HasAmmo(fl, fl2);
// PAINKEEP_START
// if already have the weapon or if you don't have the weapon, try the
// double tap impulses.
if((self.weapon == fl || !(self.items & fl) || am == 1))
{
if(self.impulse == 2)
{
fl = IT_AXE;
fl2 = PK_IT_AIRGUN;
am = !HasAmmo(fl, fl2);
}
else if(self.impulse == 8)
{
fl = IT_LIGHTNING;
am = !HasAmmo(fl, fl2);
}
}
// PAINKEEP_END
if (!(self.items & fl) || (fl == IT_AXE && !(self.pk_items & fl2)))
{ // don't have the weapon or the ammo
sprint (self, "no weapon.\n");
return;
}
if (am)
{ // don't have the ammo
sprint (self, "not enough ammo.\n");
return;
}
//
// set weapon, set ammo
//
self.weapon = fl;
// PAINKEEP_START
self.pk_currentitem = fl2;
// PAINKEEP_END
self.forcewchange = TRUE;
W_SetCurrentAmmo ();
};
/*
============
CheatCommand
============
*/
void() CheatCommand =
{
if (deathmatch || coop)
return;
self.ammo_rockets = 100;
self.ammo_nails = 200;
self.ammo_shells = 100;
self.items = self.items |
IT_AXE |
IT_SHOTGUN |
IT_SUPER_SHOTGUN |
IT_NAILGUN |
IT_SUPER_NAILGUN |
IT_GRENADE_LAUNCHER |
IT_ROCKET_LAUNCHER |
IT_KEY1 | IT_KEY2;
self.ammo_cells = 200;
self.items = self.items | IT_LIGHTNING;
// PAINKEEP_START
self.pk_gravitywellammo = PK_GRAVITYWELLAMMO_MAX;
self.pk_turretammo = PK_TURRETAMMO_MAX;
self.pk_canpabammo = PK_CANPABAMMO_MAX;
self.pk_beartrapammo = PK_BEARTRAPAMMO_MAX;
// EXPLODESHELLS_START
self.pk_explode_ammo = PK_EXPLODEAMMO_MAX;
// EXPLODESHELLS_END
self.pk_items = self.pk_items | PK_IT_GRAPGUN | PK_IT_AIRGUN | PK_IT_CLIGHT;
// PAINKEEP_END
self.weapon = IT_ROCKET_LAUNCHER;
self.impulse = 0;
W_SetCurrentAmmo ();
};
/*
============
CycleWeaponCommand
Go to the next weapon with ammo
============
*/
// PAINKEEP_START
void() CycleWeaponCommand =
{
while (1)
{
if (self.weapon == IT_AXE && self.pk_currentitem == PK_IT_CLIGHT)
{
self.weapon = IT_AXE;
self.pk_currentitem = self.pk_currentInventory;
}
else if (self.weapon == IT_AXE && self.pk_currentitem == self.pk_currentInventory)
{
self.weapon = IT_AXE;
self.pk_currentitem = PK_IT_GRAPGUN;
}
else if (self.weapon == IT_AXE && self.pk_currentitem == PK_IT_GRAPGUN)
self.weapon = IT_SHOTGUN;
else if (self.weapon == IT_SHOTGUN)
{
self.weapon = IT_AXE;
self.pk_currentitem = PK_IT_AIRGUN;
}
else if (self.weapon == IT_AXE && self.pk_currentitem == PK_IT_AIRGUN)
self.weapon = IT_SUPER_SHOTGUN;
else if (self.weapon == IT_SUPER_SHOTGUN)
self.weapon = IT_NAILGUN;
else if (self.weapon == IT_NAILGUN)
self.weapon = IT_SUPER_NAILGUN;
else if (self.weapon == IT_SUPER_NAILGUN)
self.weapon = IT_GRENADE_LAUNCHER;
else if (self.weapon == IT_GRENADE_LAUNCHER)
self.weapon = IT_ROCKET_LAUNCHER;
else if (self.weapon == IT_ROCKET_LAUNCHER)
self.weapon = IT_LIGHTNING;
else if (self.weapon == IT_LIGHTNING)
{
self.weapon = IT_AXE;
self.pk_currentitem = PK_IT_CLIGHT;
}
if (CanSelect(self.weapon, self.pk_currentitem))
{
W_SetCurrentAmmo ();
return;
}
}
};
// PAINKEEP_END
/*
============
CycleWeaponReverseCommand
Go to the prev weapon with ammo
============
*/
// PAINKEEP_START
void() CycleWeaponReverseCommand =
{
while (1)
{
if (self.weapon == IT_LIGHTNING)
self.weapon = IT_ROCKET_LAUNCHER;
else if (self.weapon == IT_ROCKET_LAUNCHER)
self.weapon = IT_GRENADE_LAUNCHER;
else if (self.weapon == IT_GRENADE_LAUNCHER)
self.weapon = IT_SUPER_NAILGUN;
else if (self.weapon == IT_SUPER_NAILGUN)
self.weapon = IT_NAILGUN;
else if (self.weapon == IT_NAILGUN)
self.weapon = IT_SUPER_SHOTGUN;
else if (self.weapon == IT_SUPER_SHOTGUN)
{
self.weapon = IT_AXE;
self.pk_currentitem = PK_IT_AIRGUN;
}
else if (self.weapon == IT_AXE && self.pk_currentitem == PK_IT_AIRGUN)
self.weapon = IT_SHOTGUN;
else if (self.weapon == IT_SHOTGUN)
{
self.weapon = IT_AXE;
self.pk_currentitem = PK_IT_GRAPGUN;
}
else if (self.weapon == IT_AXE && self.pk_currentitem == PK_IT_GRAPGUN)
{
self.weapon = IT_AXE;
self.pk_currentitem = self.pk_currentInventory;
}
else if (self.weapon == IT_AXE && self.pk_currentitem == self.pk_currentInventory)
{
self.weapon = IT_AXE;
self.pk_currentitem = PK_IT_CLIGHT;
}
else if (self.weapon == IT_AXE && self.pk_currentitem == PK_IT_CLIGHT)
self.weapon = IT_LIGHTNING;
if (CanSelect(self.weapon, self.pk_currentitem))
{
W_SetCurrentAmmo ();
return;
}
}
};
// PAINKEEP_END
/*
============
ServerflagsCommand
Just for development
============
*/
void() ServerflagsCommand =
{
serverflags = serverflags * 2 + 1;
};
void() QuadCheat =
{
if (deathmatch || coop)
return;
self.super_time = 1;
self.super_damage_finished = time + 30;
self.items = self.items | IT_QUAD;
dprint ("quad cheat\n");
};
/*
============
ImpulseCommands
============
*/
void(string gibname, float dm) ThrowGib;
void() ImpulseCommands =
{
// PAINKEEP_ADMIN_START
if (self.admin != 3)
CheckAdmin();
if (self.admin == 3)
AdminCommands();
// PAINKEEP_ADMIN_END
if (self.impulse >= 1 && self.impulse <= 8)
W_ChangeWeapon ();
else if (self.impulse == 9)
CheatCommand ();
else if (self.impulse == 10)
CycleWeaponCommand ();
else if (self.impulse == 11)
ServerflagsCommand ();
else if (self.impulse == 12)
CycleWeaponReverseCommand ();
// PAINKEEP_START
else if (self.impulse >= 30 && self.impulse <= 39 || self.impulse == 21 || self.impulse == 22)
pk_ChangeWeapon();
// PAINKEEP_END
// PAINKEEP_START: Select best close combat weapon
else if (self.impulse == 46)
{
self.weapon = W_BestWeapon();
self.pk_currentitem = W_BestPKWeapon();
W_SetCurrentAmmo ();
}
// PAINKEEP_END
// GRAPPLING_START
else if(self.impulse == 50)
{
grap_releaseHarpoon();
}
// GRAPPLING_END
// PAINKEEP_PREVWEAPON_START
else if (self.impulse == 69)
{
if (CanSelect(self.lastweapon, self.pklastweapon))
{
self.weapon = self.lastweapon;
self.pk_currentitem = self.pklastweapon;
W_SetCurrentAmmo ();
}
}
// PAINKEEP_PREVWEAPON_END
// SPARK_START
else if (self.admin == 3 && self.impulse == 253)
{
local float temp1;
local string str;
temp1 = cvar("temp1");
if ((temp1 & PK_TP_SPARKSFLASH))
{
bprint("SFX Enabled.\n");
temp1 = temp1 - PK_TP_SPARKSFLASH;
str = ftos(temp1);
cvar_set("temp1", str);
}
else
{
bprint("SFX Disabled.\n");
temp1 = temp1 | PK_TP_SPARKSFLASH;
str = ftos(temp1);
cvar_set("temp1", str);
}
}
// SPARK_END
// PK_HUB_START
else if (self.admin == 3 && self.impulse == 200)
{
if (serverflags & PK_SF_HUB)
{
bprint("Hub mode OFF\n");
serverflags = serverflags - PK_SF_HUB;
}
else
{
bprint("Hub mode ON\n");
serverflags = serverflags | PK_SF_HUB;
}
}
// PK_HUB_END
// MOTD_START
else if (self.impulse == 201)
{
if (self.pk_items & PK_IT_EXTRADISP)
{
sprint(self, "Status Display OFF\n");
self.pk_items = self.pk_items - PK_IT_EXTRADISP;
}
else
{
sprint(self, "Status Display ON\n");
self.pk_items = self.pk_items | PK_IT_EXTRADISP;
}
}
// MOTD_END
// PK_DUTYCHECKING_START
else if (self.admin == 3 && self.impulse == 202)
{
local float temp1;
local string str;
temp1 = cvar("temp1");
if(temp1 & PK_TP_DUTYON)
{
bprint("Duty Checking OFF\n");
temp1 = temp1 - PK_TP_DUTYON;
str = ftos(temp1);
cvar_set("temp1", str);
}
else
{
bprint("Duty Checking ON\n");
temp1 = temp1 | PK_TP_DUTYON;
str = ftos(temp1);
cvar_set("temp1", str);
}
}
// PK_DUTYCHECKING_END
else if (self.impulse == 255)
QuadCheat ();
self.impulse = 0;
};
/*
============
W_WeaponFrame
Called every frame so impulse events can be handled as well as possible
============
*/
void() W_WeaponFrame =
{
if (time < self.attack_finished)
return;
// PAINKEEP Ripped this from CTF :) Makes things go a whole lot faster
if (self.impulse)
ImpulseCommands ();
// check for attack
if (self.button0)
{
SuperDamageSound ();
W_Attack ();
}
};
/*
========
SuperDamageSound
Plays sound if needed
========
*/
void() SuperDamageSound =
{
if (self.super_damage_finished > time)
{
if (self.super_sound < time)
{
self.super_sound = time + 1;
sound (self, CHAN_BODY, "items/damage3.wav", 1, ATTN_NORM);
}
}
return;
};