diff --git a/quakec/basemod/basemod.txt b/quakec/basemod/basemod.txt index 31c2e616..199d87a6 100644 --- a/quakec/basemod/basemod.txt +++ b/quakec/basemod/basemod.txt @@ -13,11 +13,11 @@ Suicide backpack/quad/ring drop Condense bprint, sprint, centerprints te_explode sprite NQ/QW cross compatibility +Track oldbutton presses/weaponstate +Generic projectile spawning Todo - -Track oldbutton presses/weaponstate Samelevel 4 (exit acts as a spawnpoint teleporter) -Generic projectile spawning Effects/decal system Fix weird deathmatch modes, cvar checking Add monsters back @@ -31,4 +31,4 @@ Clean up backpack pickup prints? Decal system based on visibility from players? CSQC? Don't use newmis/spawn projectiles in front? -sv_gravity change? \ No newline at end of file +sv_gravity change? diff --git a/quakec/basemod/client.qc b/quakec/basemod/client.qc index 2d8dab21..bf3f8487 100644 --- a/quakec/basemod/client.qc +++ b/quakec/basemod/client.qc @@ -494,7 +494,6 @@ called each time a player enters a new level */ void() PutClientInServer = { - dprint("putclientinserver called\n"); local entity spot; self.classname = "player"; diff --git a/quakec/basemod/combat.qc b/quakec/basemod/combat.qc index 5a66103b..c2cc3e13 100644 --- a/quakec/basemod/combat.qc +++ b/quakec/basemod/combat.qc @@ -1,8 +1,7 @@ -void() T_MissileTouch; void() info_player_start; void(entity targ, entity attacker, INTEGER mod) ClientObituary; -void(entity inflictor, entity attacker, float damage, entity ignore, INTEGER mod) T_RadiusDamage; +void(entity inflictor, entity attacker, float damage, float radius, entity ignore, INTEGER mod) T_RadiusDamage; /*SERVER void() monster_death_use; @@ -284,13 +283,13 @@ void(entity targ, entity inflictor, entity attacker, float damage, INTEGER mod) T_RadiusDamage ============ */ -void(entity inflictor, entity attacker, float damage, entity ignore, INTEGER mod) T_RadiusDamage = +void(entity inflictor, entity attacker, float damage, float radius, entity ignore, INTEGER mod) T_RadiusDamage = { local float points; local entity head; local vector org; - head = findradius(inflictor.origin, damage+40); + head = findradius(inflictor.origin, radius); while (head) { diff --git a/quakec/basemod/defs.qc b/quakec/basemod/defs.qc index fe8a0bae..44154fa8 100644 --- a/quakec/basemod/defs.qc +++ b/quakec/basemod/defs.qc @@ -289,7 +289,6 @@ void end_sys_fields; // flag for structure dumping #define MOVETYPE_NOCLIP 8 #define MOVETYPE_FLYMISSILE 9 // fly with extra size against monsters #define MOVETYPE_BOUNCE 10 -#define MOVETYPE_BOUNCEMISSILE 11 // bounce with extra size // edict.solid values #define SOLID_NOT 0 // no interaction with other objects @@ -533,7 +532,6 @@ float AS_MISSILE = 4; // // player only fields // -.float voided; .float walkframe; // Zoid Additions @@ -643,6 +641,19 @@ entity newmis; float pausetime; // time to pause for monsters entity movetarget; // target entity to move to }; + struct { // fields used with generic projectiles + float damage_direct; // damage done with a direct hit + float damage_exp; // damage done from radius damage + float radius_exp; // radius of radius damage + INTEGER mod_direct; // mod type for direct hit + INTEGER mod_exp; // mod type for radius damage + float expire_time; // time when projectile dies + void() proj_think; // extra think function used with projectile + float proj_think_time; // interval between thinks + INTEGER proj_effect; // effect used with projectile + INTEGER voided; // projectile has been voided + float() proj_touch; // extra touch function used with projectile + }; // fields used with ambient sounds? /* struct { diff --git a/quakec/basemod/effects.qc b/quakec/basemod/effects.qc index 2b2f32ee..46023a96 100644 --- a/quakec/basemod/effects.qc +++ b/quakec/basemod/effects.qc @@ -230,39 +230,6 @@ void(vector org) TE_lightningblood = #endif }; -// view kicks -void(entity ent) VK_smallkick = -{ -#ifdef NETQUAKE - self.punchangle_x = -2; -#else - msg_entity = ent; - WriteByte (MSG_ONE, SVC_SMALLKICK); -#endif -} - -void(entity ent) VK_bigkick = -{ -#ifdef NETQUAKE - self.punchangle_x = -4; -#else - msg_entity = ent; - WriteByte (MSG_ONE, SVC_BIGKICK); -#endif -} - -// muzzle flash -void() muzzleflash = -{ -#ifdef NETQUAKE - self.effects |= EF_MUZZLEFLASH; -#else - WriteByte (MSG_MULTICAST, SVC_MUZZLEFLASH); - WriteEntity (MSG_MULTICAST, self); - multicast (self.origin, MULTICAST_PVS); -#endif -}; - // function pointers for TE calls var void(vector org, float damage) SpawnBlood = _SpawnBlood; var void(vector org) TE_explosion = _TE_explosion; @@ -305,3 +272,48 @@ void() EFF_SetEffects = if (eng_support & ENG_TEBLOOD) SpawnBlood = _SpawnBlood_TEBlood; // use TE_Blood builtin instead }; + +// view kicks +void(entity ent) VK_smallkick = +{ +#ifdef NETQUAKE + self.punchangle_x = -2; +#else + msg_entity = ent; + WriteByte (MSG_ONE, SVC_SMALLKICK); +#endif +} + +void(entity ent) VK_bigkick = +{ +#ifdef NETQUAKE + self.punchangle_x = -4; +#else + msg_entity = ent; + WriteByte (MSG_ONE, SVC_BIGKICK); +#endif +} + +// muzzle flash +void() muzzleflash = +{ +#ifdef NETQUAKE + self.effects |= EF_MUZZLEFLASH; +#else + WriteByte (MSG_MULTICAST, SVC_MUZZLEFLASH); + WriteEntity (MSG_MULTICAST, self); + multicast (self.origin, MULTICAST_PVS); +#endif +}; + +// touch blood functions +void(float damage) spawn_touchblood = +{ + 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 * 0.4; + SpawnBlood (self.origin + vel, damage); +}; diff --git a/quakec/basemod/misc.qc b/quakec/basemod/misc.qc index e1d6e5a2..015160e7 100644 --- a/quakec/basemod/misc.qc +++ b/quakec/basemod/misc.qc @@ -217,7 +217,7 @@ void() barrel_explode = self.takedamage = DAMAGE_NO; self.classname = "explo_box"; // did say self.owner, self.enemy should be set by Killed function - T_RadiusDamage (self, self.enemy, 160, self, MOD_EXPLOBOX); + T_RadiusDamage (self, self.enemy, 160, 200, self, MOD_EXPLOBOX); TE_explosion(self.origin + '0 0 32'); remove (self); }; @@ -292,75 +292,45 @@ void() misc_explobox2 = float SPAWNFLAG_SUPERSPIKE = 1; float SPAWNFLAG_LASER = 2; -void() Laser_Touch = -{ - local vector org; - - if (other == self.owner) - return; // don't explode on owner - - if (pointcontents(self.origin) == CONTENT_SKY) - { - remove(self); - return; - } - - sound (self, CHAN_WEAPON, "enforcer/enfstop.wav", 1, ATTN_STATIC); - org = self.origin - 8*normalize(self.velocity); - - if (other.health) - { - SpawnBlood (org, 15); - T_Damage (other, self, self.owner, 15, MOD_LASER); - } - else - { - TE_gunshot(org); - } - - remove(self); -}; - -void(vector org, vector vec) LaunchLaser = -{ - if (self.classname == "monster_enforcer") - sound (self, CHAN_WEAPON, "enforcer/enfire.wav", 1, ATTN_NORM); - - vec = normalize(vec); - - newmis = spawn(); - newmis.owner = self; - newmis.movetype = MOVETYPE_FLY; - newmis.solid = SOLID_BBOX; - newmis.effects = EF_DIMLIGHT; - - setmodel (newmis, "progs/laser.mdl"); - setsize (newmis, '0 0 0', '0 0 0'); - - setorigin (newmis, org); - - newmis.velocity = vec * 600; - newmis.angles = vectoangles(newmis.velocity); - - newmis.nextthink = time + 5; - newmis.think = SUB_Remove; - newmis.touch = Laser_Touch; -}; - void() spikeshooter_use = { if (self.spawnflags & SPAWNFLAG_LASER) { sound (self, CHAN_VOICE, "enforcer/enfire.wav", 1, ATTN_NORM); - LaunchLaser (self.origin, self.movedir); + PRJ_FireProjectile(self, + "progs/laser.mdl", + self.origin, + self.movedir * 600, + PE_LASER, + 15, + MOD_LASER, + 5); } else { sound (self, CHAN_VOICE, "weapons/spike2.wav", 1, ATTN_NORM); - launch_spike (self.origin, self.movedir); - newmis.velocity = self.movedir * 500; if (self.spawnflags & SPAWNFLAG_SUPERSPIKE) - newmis.touch = superspike_touch; + { + PRJ_FireProjectile(self, + "progs/s_spike.mdl", + self.origin, + self.movedir * 500, + PE_SUPERSPIKE, + 18, + MOD_SUPERSPIKE, + 6); + } + else + { + PRJ_FireProjectile(self, + "progs/spike.mdl", + self.origin, + self.movedir * 500, + PE_SPIKE, + 9, + MOD_SPIKE, + 6); + } } }; diff --git a/quakec/basemod/player.qc b/quakec/basemod/player.qc index 2c6dd76a..b44ed563 100644 --- a/quakec/basemod/player.qc +++ b/quakec/basemod/player.qc @@ -168,12 +168,12 @@ void() player_axed4 = [$axattd4, player_run ] {}; void() player_nail1 =[$nailatt1, player_nail2 ] { - if (self.weaponstate == WS_IDLE || intermission_running || self.impulse) + if (self.weaponstate == WS_IDLE || intermission_running) {player_run ();return;} }; void() player_nail2 =[$nailatt2, player_nail1 ] { - if (self.weaponstate == WS_IDLE || intermission_running || self.impulse) + if (self.weaponstate == WS_IDLE || intermission_running) {player_run ();return;} }; diff --git a/quakec/basemod/progs.src b/quakec/basemod/progs.src index a89e2dc9..5e8a2569 100644 --- a/quakec/basemod/progs.src +++ b/quakec/basemod/progs.src @@ -7,6 +7,7 @@ effects.qc obituary.qc combat.qc items.qc +proj.qc weapons.qc world.qc client.qc diff --git a/quakec/basemod/proj.qc b/quakec/basemod/proj.qc new file mode 100644 index 00000000..3791ab08 --- /dev/null +++ b/quakec/basemod/proj.qc @@ -0,0 +1,184 @@ + +// Generic projectile spawning code (PRJ) --- + +// projectile effect defines +#define PE_NONE 0 +#define PE_SPIKE 1 +#define PE_SUPERSPIKE 2 +#define PE_WIZSPIKE 3 +#define PE_KNIGHTSPIKE 4 +#define PE_GUNSHOT 5 +#define PE_EXPLOSION 6 +#define PE_EXPLOSIONGROUND 7 +#define PE_LASER 8 + +// functions used only by this QC file +float() _PRJ_Bounce = +{ + if (other.takedamage == DAMAGE_AIM) + return 0; // explode + + sound (self, CHAN_WEAPON, "weapons/bounce.wav", 1, ATTN_NORM); // bounce sound + if (self.velocity == '0 0 0') + self.avelocity = '0 0 0'; + + return 1; // keep bouncing +}; + +void() _PRJ_Touch = +{ + local entity ignore; + + // check validity of projectile + if (other == self.owner) + return; // don't explode on owner + + if (self.voided) { + return; + } + + if (pointcontents(self.origin) == CONTENT_SKY) + { + remove(self); + return; + } + + // handle custom touch + if (other != self) // didn't expire + if (self.proj_touch) // is valid function + if (self.proj_touch()) + return; + + // void projectile + self.voided = 1; + + // do projectile damage + ignore = self; + + if (other.health && self.damage_direct) + { + T_Damage (other, self, self.owner, self.damage_direct, self.mod_direct); + ignore = other; + } + + if (self.radius_exp) + T_RadiusDamage (self, self.owner, self.damage_exp, self.radius_exp, other, self.mod_exp); + + // run projectile effect + switch (self.proj_effect) + { + case PE_SPIKE: + if (ignore != self) // hit something + spawn_touchblood (self.damage_direct); + else if (other != self) // didn't expire + TE_spike(self.origin); + break; + case PE_SUPERSPIKE: + if (ignore != self) // hit something + spawn_touchblood (self.damage_direct); + else if (other != self) // didn't expire + TE_superspike(self.origin); + break; + case PE_WIZSPIKE: + if (ignore != self) // hit something + spawn_touchblood (self.damage_direct); + else if (other != self) // didn't expire + TE_wizspike(self.origin); + break; + case PE_KNIGHTSPIKE: + if (ignore != self) // hit something + spawn_touchblood (self.damage_direct); + else if (other != self) // didn't expire + TE_knightspike(self.origin); + break; + case PE_LASER: + if (other != self) + sound (self, CHAN_WEAPON, "enforcer/enfstop.wav", 1, ATTN_STATIC); + self.origin = self.origin - 8 * normalize(self.velocity); + case PE_GUNSHOT: + if (ignore != self) // hit something + spawn_touchblood (self.damage_direct); + else if (other != self) // didn't expire + TE_gunshot(self.origin); + break; + case PE_EXPLOSION: + self.origin = self.origin - 8 * normalize(self.velocity); + case PE_EXPLOSIONGROUND: + TE_explosion(self.origin); + break; + } + + remove(self); +}; + +void() _PRJ_Expire = +{ + other = self; + _PRJ_Touch(); +}; + +void() _PRJ_Think = +{ + if (self.expire_time > time) + { + _PRJ_Expire(); + return; + } + + newmis.proj_think(); + newmis.nextthink = time + newmis.proj_think_time; +}; + +// functions used by outside QC files +// set bouncy projectile function +void() PRJ_SetBouncyProjectile = +{ + newmis.proj_touch = _PRJ_Bounce; + newmis.movetype = MOVETYPE_BOUNCE; + newmis.avelocity = '300 300 300'; +}; + +// set radius damage function +void(INTEGER damg, INTEGER damgrad, INTEGER damgmod) PRJ_SetRadiusDamage = +{ + newmis.damage_exp = damg; + newmis.radius_exp = damgrad; + newmis.mod_exp = damgmod; +}; + +// extra think function, should always be called ONCE after the main spawn function +void(void() thinkfunc, float thinkres) PRJ_SetThink = +{ + newmis.think = _PRJ_Think; + newmis.nextthink = time + thinkres; + newmis.proj_think = thinkfunc; + newmis.proj_think_time = thinkres; +}; + +// main spawning function +void(entity parent, string modl, vector org, vector vel, INTEGER effect, INTEGER damg, INTEGER damgmod, float expiretime) PRJ_FireProjectile = +{ + newmis = spawn (); + newmis.owner = parent; + newmis.movetype = MOVETYPE_FLYMISSILE; + newmis.solid = SOLID_BBOX; +// newmis.classname = class; + newmis.velocity = vel; + + newmis.damage_direct = damg; + newmis.mod_direct = damgmod; + newmis.proj_effect = effect; + + newmis.touch = _PRJ_Touch; + newmis.expire_time = time + expiretime; + + newmis.think = _PRJ_Expire; + newmis.nextthink = time + expiretime; + + newmis.angles = vectoangles(newmis.velocity); + + setmodel (newmis, modl); + setsize (newmis, VEC_ORIGIN, VEC_ORIGIN); + setorigin (newmis, org); +}; + diff --git a/quakec/basemod/weapons.qc b/quakec/basemod/weapons.qc index a1a1dcfc..b5bc0ba4 100644 --- a/quakec/basemod/weapons.qc +++ b/quakec/basemod/weapons.qc @@ -2,7 +2,7 @@ */ void (entity targ, entity inflictor, entity attacker, float damage, INTEGER mod) T_Damage; void () player_run; -void(entity bomb, entity attacker, float rad, entity ignore, INTEGER mod) T_RadiusDamage; +void(entity inflictor, entity attacker, float damage, float radius, entity ignore, INTEGER mod) T_RadiusDamage; void(vector org, float damage) SpawnBlood; void() SuperDamageSound; @@ -66,20 +66,6 @@ void() W_FireAxe = //============================================================================ - -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 @@ -110,19 +96,6 @@ void(vector org, vector vel) SpawnMeatSpray = setorigin (missile, org); }; -/* -================ -spawn_touchblood -================ -*/ -void(float damage) spawn_touchblood = -{ - local vector vel; - - vel = wall_velocity () * 0.2; - SpawnBlood (self.origin + vel*0.01, damage); -}; - /* ============================================================================== @@ -307,61 +280,6 @@ ROCKETS ============================================================================== */ -void() T_MissileTouch = -{ - local float damg; - -// if (deathmatch == 4) -// { -// if ( ((other.weapon == 32) || (other.weapon == 16))) -// { -// if (random() < 0.1) -// { -// if (other != world) -// { -// // bprint (PRINT_HIGH, "Got here\n"); -// other.deathtype = "blaze"; -// T_Damage (other, self, self.owner, 1000 ); -// T_RadiusDamage (self, self.owner, 1000, other); -// } -// } -// } -// } - - if (other == self.owner) - return; // don't explode on owner - - if (self.voided) { - return; - } - self.voided = 1; - - if (pointcontents(self.origin) == CONTENT_SKY) - { - remove(self); - return; - } - - damg = 100 + random()*20; - - if (other.health) - T_Damage (other, self, self.owner, damg, MOD_ROCKET); - - // don't do radius damage to the other, because all the damage - // was done in the impact - - - T_RadiusDamage (self, self.owner, 120, other, MOD_ROCKETRADIUS); - -// sound (self, CHAN_WEAPON, "weapons/r_exp3.wav", 1, ATTN_NORM); - self.origin = self.origin - 8 * normalize(self.velocity); - - TE_explosion(self.origin); - remove(self); -}; - - - /* ================ W_FireRocket @@ -375,30 +293,15 @@ void() W_FireRocket = sound (self, CHAN_WEAPON, "weapons/sgun1.wav", 1, ATTN_NORM); VK_smallkick(self); - - newmis = spawn (); - newmis.owner = self; - newmis.movetype = MOVETYPE_FLYMISSILE; - newmis.solid = SOLID_BBOX; - -// set newmis speed - - makevectors (self.v_angle); - newmis.velocity = aim(self, 1000); - newmis.velocity = newmis.velocity * 1000; - newmis.angles = vectoangles(newmis.velocity); - - newmis.touch = T_MissileTouch; - newmis.voided = 0; - -// set newmis duration - newmis.nextthink = time + 5; - newmis.think = SUB_Remove; - newmis.classname = "rocket"; - - setmodel (newmis, "progs/missile.mdl"); - setsize (newmis, '0 0 0', '0 0 0'); - setorigin (newmis, self.origin + v_forward*8 + '0 0 16'); + PRJ_FireProjectile(self, + "progs/missile.mdl", + self.origin + v_forward*8 + '0 0 16', + aim(self, 1000) * 1000, + PE_EXPLOSION, + 100+random()*20, + MOD_ROCKET, + 5); + PRJ_SetRadiusDamage(120, 160, MOD_ROCKETRADIUS); }; /* @@ -454,6 +357,7 @@ void() W_FireLightning = { local vector org; local float cells; + local INTEGER expmod; if (self.ammo_cells < 1) { @@ -477,12 +381,12 @@ void() W_FireLightning = cells = self.ammo_cells; self.ammo_cells = 0; W_SetCurrentAmmo (); + expmod = MOD_SHAFTWATER; if (self.watertype == CONTENT_SLIME) - T_RadiusDamage (self, self, 35*cells, world, MOD_SHAFTSLIME); + expmod = MOD_SHAFTSLIME; else if (self.watertype == CONTENT_LAVA) - T_RadiusDamage (self, self, 35*cells, world, MOD_SHAFTLAVA); - else - T_RadiusDamage (self, self, 35*cells, world, MOD_SHAFTWATER); + expmod = MOD_SHAFTLAVA; + T_RadiusDamage (self, self, 35*cells, 40+35*cells, world, expmod); return; } @@ -505,156 +409,44 @@ void() W_FireLightning = LightningDamage (self.origin, trace_endpos + v_forward*4, self, 30); }; - -//============================================================================= - - -void() GrenadeExplode = -{ - if (self.voided) { - return; - } - self.voided = 1; - - T_RadiusDamage (self, self.owner, 120, world, MOD_GRENADE); - - TE_explosion(self.origin); - remove (self); -}; - -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 vector vel; + if (deathmatch != 4) self.currentammo = self.ammo_rockets = self.ammo_rockets - 1; sound (self, CHAN_WEAPON, "weapons/grenade.wav", 1, ATTN_NORM); - VK_smallkick(self); - - newmis = spawn (); - newmis.voided=0; - newmis.owner = self; - newmis.movetype = MOVETYPE_BOUNCE; - newmis.solid = SOLID_BBOX; - newmis.classname = "grenade"; - -// set newmis speed - - makevectors (self.v_angle); - if (self.v_angle_x) - newmis.velocity = v_forward*600 + v_up * 200 + crandom()*v_right*10 + crandom()*v_up*10; + vel = v_forward*600 + v_up * 200 + crandom()*v_right*10 + crandom()*v_up*10; else { - newmis.velocity = aim(self, 10000); - newmis.velocity = newmis.velocity * 600; - newmis.velocity_z = 200; + vel = aim(self, 10000) * 600; + vel_z = 200; } - newmis.avelocity = '300 300 300'; + VK_smallkick(self); + PRJ_FireProjectile(self, "progs/grenade.mdl", self.origin, vel, PE_EXPLOSIONGROUND, 0, 0, 2.5); + PRJ_SetRadiusDamage(120, 160, MOD_GRENADE); + PRJ_SetBouncyProjectile(); - newmis.angles = vectoangles(newmis.velocity); - - newmis.touch = GrenadeTouch; - -// set newmis duration if (deathmatch == 4) { - newmis.nextthink = time + 2.5; self.attack_finished = time + 1.1; T_Damage (self, self, self.owner, 10, MOD_GRENADE); } - else - newmis.nextthink = time + 2.5; - - newmis.think = GrenadeExplode; - - setmodel (newmis, "progs/grenade.mdl"); - setsize (newmis, '0 0 0', '0 0 0'); - setorigin (newmis, self.origin); }; //============================================================================= - -void() spike_touch; -void() superspike_touch; - - -/* -=============== -launch_spike - -Used for both the player and the ogre -=============== -*/ -void(vector org, vector dir) launch_spike = -{ - newmis = spawn (); - newmis.voided=0; - 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; -}; - -void() W_FireSuperSpikes = -{ - local vector dir; - - sound (self, CHAN_WEAPON, "weapons/spike2.wav", 1, ATTN_NORM); - if (deathmatch != 4) - 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); - VK_smallkick(self); -}; - void(float ox) W_FireSpikes = { - local vector dir; - - 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 (); @@ -665,87 +457,41 @@ void(float ox) W_FireSpikes = sound (self, CHAN_WEAPON, "weapons/rocket1i.wav", 1, ATTN_NORM); if (deathmatch != 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); VK_smallkick(self); + PRJ_FireProjectile(self, + "progs/spike.mdl", + self.origin + '0 0 16' + v_right*ox, + aim(self, 1000) * 1000, + PE_SPIKE, + 9, + MOD_SPIKE, + 6); }; -void() spike_touch = +void() W_FireSuperSpikes = { - if (other == self.owner) - return; - - if (self.voided) { - return; - } - self.voided = 1; - - if (other.solid == SOLID_TRIGGER) - return; // trigger field, do nothing - - if (pointcontents(self.origin) == CONTENT_SKY) + if (self.ammo_nails < 2) { - remove(self); + W_FireSpikes(0); return; } -// hit something that bleeds - if (other.takedamage) - { - spawn_touchblood (9); - T_Damage (other, self, self.owner, 9, MOD_SPIKE); - } - else - { - if (self.classname == "wizspike") - TE_wizspike(self.origin); - else if (self.classname == "knightspike") - TE_knightspike(self.origin); - else - TE_spike(self.origin); - } - - remove(self); + sound (self, CHAN_WEAPON, "weapons/spike2.wav", 1, ATTN_NORM); + if (deathmatch != 4) + self.currentammo = self.ammo_nails = self.ammo_nails - 2; + VK_smallkick(self); + PRJ_FireProjectile(self, + "progs/s_spike.mdl", + self.origin + '0 0 16', + aim(self, 1000) * 1000, + PE_SUPERSPIKE, + 18, + MOD_SUPERSPIKE, + 6); }; -void() superspike_touch = -{ - if (other == self.owner) - return; - - if (self.voided) { - return; - } - self.voided = 1; - - - 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, MOD_SUPERSPIKE); - } - else - { - TE_superspike(self.origin); - } - - remove(self); - -}; - - /* =============================================================================== @@ -1017,7 +763,7 @@ void() W_Attack = r = 0.1; break; case IT_SUPER_NAILGUN: - W_FireSpikes(0); + W_FireSuperSpikes(); r = 0.1; break; case IT_GRENADE_LAUNCHER: @@ -1403,4 +1149,3 @@ void() SuperDamageSound = return; }; -