mirror of
https://github.com/nzp-team/fteqw.git
synced 2025-02-18 01:41:46 +00:00
generic projectile code
git-svn-id: https://svn.code.sf.net/p/fteqw/code/trunk@1066 fc73d0e0-1445-4013-8a0c-d673dee63da5
This commit is contained in:
parent
57cac0ac70
commit
99854ae8ec
10 changed files with 330 additions and 409 deletions
|
@ -13,11 +13,11 @@ Suicide backpack/quad/ring drop
|
||||||
Condense bprint, sprint, centerprints
|
Condense bprint, sprint, centerprints
|
||||||
te_explode sprite
|
te_explode sprite
|
||||||
NQ/QW cross compatibility
|
NQ/QW cross compatibility
|
||||||
|
Track oldbutton presses/weaponstate
|
||||||
|
Generic projectile spawning
|
||||||
|
|
||||||
Todo -
|
Todo -
|
||||||
Track oldbutton presses/weaponstate
|
|
||||||
Samelevel 4 (exit acts as a spawnpoint teleporter)
|
Samelevel 4 (exit acts as a spawnpoint teleporter)
|
||||||
Generic projectile spawning
|
|
||||||
Effects/decal system
|
Effects/decal system
|
||||||
Fix weird deathmatch modes, cvar checking
|
Fix weird deathmatch modes, cvar checking
|
||||||
Add monsters back
|
Add monsters back
|
||||||
|
@ -31,4 +31,4 @@ Clean up backpack pickup prints?
|
||||||
Decal system based on visibility from players?
|
Decal system based on visibility from players?
|
||||||
CSQC?
|
CSQC?
|
||||||
Don't use newmis/spawn projectiles in front?
|
Don't use newmis/spawn projectiles in front?
|
||||||
sv_gravity change?
|
sv_gravity change?
|
||||||
|
|
|
@ -494,7 +494,6 @@ called each time a player enters a new level
|
||||||
*/
|
*/
|
||||||
void() PutClientInServer =
|
void() PutClientInServer =
|
||||||
{
|
{
|
||||||
dprint("putclientinserver called\n");
|
|
||||||
local entity spot;
|
local entity spot;
|
||||||
|
|
||||||
self.classname = "player";
|
self.classname = "player";
|
||||||
|
|
|
@ -1,8 +1,7 @@
|
||||||
|
|
||||||
void() T_MissileTouch;
|
|
||||||
void() info_player_start;
|
void() info_player_start;
|
||||||
void(entity targ, entity attacker, INTEGER mod) ClientObituary;
|
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
|
/*SERVER
|
||||||
void() monster_death_use;
|
void() monster_death_use;
|
||||||
|
@ -284,13 +283,13 @@ void(entity targ, entity inflictor, entity attacker, float damage, INTEGER mod)
|
||||||
T_RadiusDamage
|
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 float points;
|
||||||
local entity head;
|
local entity head;
|
||||||
local vector org;
|
local vector org;
|
||||||
|
|
||||||
head = findradius(inflictor.origin, damage+40);
|
head = findradius(inflictor.origin, radius);
|
||||||
|
|
||||||
while (head)
|
while (head)
|
||||||
{
|
{
|
||||||
|
|
|
@ -289,7 +289,6 @@ void end_sys_fields; // flag for structure dumping
|
||||||
#define MOVETYPE_NOCLIP 8
|
#define MOVETYPE_NOCLIP 8
|
||||||
#define MOVETYPE_FLYMISSILE 9 // fly with extra size against monsters
|
#define MOVETYPE_FLYMISSILE 9 // fly with extra size against monsters
|
||||||
#define MOVETYPE_BOUNCE 10
|
#define MOVETYPE_BOUNCE 10
|
||||||
#define MOVETYPE_BOUNCEMISSILE 11 // bounce with extra size
|
|
||||||
|
|
||||||
// edict.solid values
|
// edict.solid values
|
||||||
#define SOLID_NOT 0 // no interaction with other objects
|
#define SOLID_NOT 0 // no interaction with other objects
|
||||||
|
@ -533,7 +532,6 @@ float AS_MISSILE = 4;
|
||||||
//
|
//
|
||||||
// player only fields
|
// player only fields
|
||||||
//
|
//
|
||||||
.float voided;
|
|
||||||
.float walkframe;
|
.float walkframe;
|
||||||
|
|
||||||
// Zoid Additions
|
// Zoid Additions
|
||||||
|
@ -643,6 +641,19 @@ entity newmis;
|
||||||
float pausetime; // time to pause for monsters
|
float pausetime; // time to pause for monsters
|
||||||
entity movetarget; // target entity to move to
|
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?
|
// fields used with ambient sounds?
|
||||||
/*
|
/*
|
||||||
struct {
|
struct {
|
||||||
|
|
|
@ -230,39 +230,6 @@ void(vector org) TE_lightningblood =
|
||||||
#endif
|
#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
|
// function pointers for TE calls
|
||||||
var void(vector org, float damage) SpawnBlood = _SpawnBlood;
|
var void(vector org, float damage) SpawnBlood = _SpawnBlood;
|
||||||
var void(vector org) TE_explosion = _TE_explosion;
|
var void(vector org) TE_explosion = _TE_explosion;
|
||||||
|
@ -305,3 +272,48 @@ void() EFF_SetEffects =
|
||||||
if (eng_support & ENG_TEBLOOD)
|
if (eng_support & ENG_TEBLOOD)
|
||||||
SpawnBlood = _SpawnBlood_TEBlood; // use TE_Blood builtin instead
|
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);
|
||||||
|
};
|
||||||
|
|
|
@ -217,7 +217,7 @@ void() barrel_explode =
|
||||||
self.takedamage = DAMAGE_NO;
|
self.takedamage = DAMAGE_NO;
|
||||||
self.classname = "explo_box";
|
self.classname = "explo_box";
|
||||||
// did say self.owner, self.enemy should be set by Killed function
|
// 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');
|
TE_explosion(self.origin + '0 0 32');
|
||||||
remove (self);
|
remove (self);
|
||||||
};
|
};
|
||||||
|
@ -292,75 +292,45 @@ void() misc_explobox2 =
|
||||||
float SPAWNFLAG_SUPERSPIKE = 1;
|
float SPAWNFLAG_SUPERSPIKE = 1;
|
||||||
float SPAWNFLAG_LASER = 2;
|
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 =
|
void() spikeshooter_use =
|
||||||
{
|
{
|
||||||
if (self.spawnflags & SPAWNFLAG_LASER)
|
if (self.spawnflags & SPAWNFLAG_LASER)
|
||||||
{
|
{
|
||||||
sound (self, CHAN_VOICE, "enforcer/enfire.wav", 1, ATTN_NORM);
|
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
|
else
|
||||||
{
|
{
|
||||||
sound (self, CHAN_VOICE, "weapons/spike2.wav", 1, ATTN_NORM);
|
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)
|
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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -168,12 +168,12 @@ void() player_axed4 = [$axattd4, player_run ] {};
|
||||||
|
|
||||||
void() player_nail1 =[$nailatt1, player_nail2 ]
|
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;}
|
{player_run ();return;}
|
||||||
};
|
};
|
||||||
void() player_nail2 =[$nailatt2, player_nail1 ]
|
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;}
|
{player_run ();return;}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -7,6 +7,7 @@ effects.qc
|
||||||
obituary.qc
|
obituary.qc
|
||||||
combat.qc
|
combat.qc
|
||||||
items.qc
|
items.qc
|
||||||
|
proj.qc
|
||||||
weapons.qc
|
weapons.qc
|
||||||
world.qc
|
world.qc
|
||||||
client.qc
|
client.qc
|
||||||
|
|
184
quakec/basemod/proj.qc
Normal file
184
quakec/basemod/proj.qc
Normal file
|
@ -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);
|
||||||
|
};
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
*/
|
*/
|
||||||
void (entity targ, entity inflictor, entity attacker, float damage, INTEGER mod) T_Damage;
|
void (entity targ, entity inflictor, entity attacker, float damage, INTEGER mod) T_Damage;
|
||||||
void () player_run;
|
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(vector org, float damage) SpawnBlood;
|
||||||
void() SuperDamageSound;
|
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
|
SpawnMeatSpray
|
||||||
|
@ -110,19 +96,6 @@ void(vector org, vector vel) SpawnMeatSpray =
|
||||||
setorigin (missile, org);
|
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
|
W_FireRocket
|
||||||
|
@ -375,30 +293,15 @@ void() W_FireRocket =
|
||||||
sound (self, CHAN_WEAPON, "weapons/sgun1.wav", 1, ATTN_NORM);
|
sound (self, CHAN_WEAPON, "weapons/sgun1.wav", 1, ATTN_NORM);
|
||||||
|
|
||||||
VK_smallkick(self);
|
VK_smallkick(self);
|
||||||
|
PRJ_FireProjectile(self,
|
||||||
newmis = spawn ();
|
"progs/missile.mdl",
|
||||||
newmis.owner = self;
|
self.origin + v_forward*8 + '0 0 16',
|
||||||
newmis.movetype = MOVETYPE_FLYMISSILE;
|
aim(self, 1000) * 1000,
|
||||||
newmis.solid = SOLID_BBOX;
|
PE_EXPLOSION,
|
||||||
|
100+random()*20,
|
||||||
// set newmis speed
|
MOD_ROCKET,
|
||||||
|
5);
|
||||||
makevectors (self.v_angle);
|
PRJ_SetRadiusDamage(120, 160, MOD_ROCKETRADIUS);
|
||||||
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');
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -454,6 +357,7 @@ void() W_FireLightning =
|
||||||
{
|
{
|
||||||
local vector org;
|
local vector org;
|
||||||
local float cells;
|
local float cells;
|
||||||
|
local INTEGER expmod;
|
||||||
|
|
||||||
if (self.ammo_cells < 1)
|
if (self.ammo_cells < 1)
|
||||||
{
|
{
|
||||||
|
@ -477,12 +381,12 @@ void() W_FireLightning =
|
||||||
cells = self.ammo_cells;
|
cells = self.ammo_cells;
|
||||||
self.ammo_cells = 0;
|
self.ammo_cells = 0;
|
||||||
W_SetCurrentAmmo ();
|
W_SetCurrentAmmo ();
|
||||||
|
expmod = MOD_SHAFTWATER;
|
||||||
if (self.watertype == CONTENT_SLIME)
|
if (self.watertype == CONTENT_SLIME)
|
||||||
T_RadiusDamage (self, self, 35*cells, world, MOD_SHAFTSLIME);
|
expmod = MOD_SHAFTSLIME;
|
||||||
else if (self.watertype == CONTENT_LAVA)
|
else if (self.watertype == CONTENT_LAVA)
|
||||||
T_RadiusDamage (self, self, 35*cells, world, MOD_SHAFTLAVA);
|
expmod = MOD_SHAFTLAVA;
|
||||||
else
|
T_RadiusDamage (self, self, 35*cells, 40+35*cells, world, expmod);
|
||||||
T_RadiusDamage (self, self, 35*cells, world, MOD_SHAFTWATER);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -505,156 +409,44 @@ void() W_FireLightning =
|
||||||
LightningDamage (self.origin, trace_endpos + v_forward*4, self, 30);
|
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
|
W_FireGrenade
|
||||||
================
|
================
|
||||||
*/
|
*/
|
||||||
void() W_FireGrenade =
|
void() W_FireGrenade =
|
||||||
{
|
{
|
||||||
|
local vector vel;
|
||||||
|
|
||||||
if (deathmatch != 4)
|
if (deathmatch != 4)
|
||||||
self.currentammo = self.ammo_rockets = self.ammo_rockets - 1;
|
self.currentammo = self.ammo_rockets = self.ammo_rockets - 1;
|
||||||
|
|
||||||
sound (self, CHAN_WEAPON, "weapons/grenade.wav", 1, ATTN_NORM);
|
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)
|
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
|
else
|
||||||
{
|
{
|
||||||
newmis.velocity = aim(self, 10000);
|
vel = aim(self, 10000) * 600;
|
||||||
newmis.velocity = newmis.velocity * 600;
|
vel_z = 200;
|
||||||
newmis.velocity_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)
|
if (deathmatch == 4)
|
||||||
{
|
{
|
||||||
newmis.nextthink = time + 2.5;
|
|
||||||
self.attack_finished = time + 1.1;
|
self.attack_finished = time + 1.1;
|
||||||
T_Damage (self, self, self.owner, 10, MOD_GRENADE);
|
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 =
|
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)
|
if (self.ammo_nails < 1)
|
||||||
{
|
{
|
||||||
self.weapon = W_BestWeapon ();
|
self.weapon = W_BestWeapon ();
|
||||||
|
@ -665,87 +457,41 @@ void(float ox) W_FireSpikes =
|
||||||
sound (self, CHAN_WEAPON, "weapons/rocket1i.wav", 1, ATTN_NORM);
|
sound (self, CHAN_WEAPON, "weapons/rocket1i.wav", 1, ATTN_NORM);
|
||||||
if (deathmatch != 4)
|
if (deathmatch != 4)
|
||||||
self.currentammo = self.ammo_nails = self.ammo_nails - 1;
|
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);
|
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)
|
if (self.ammo_nails < 2)
|
||||||
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);
|
W_FireSpikes(0);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// hit something that bleeds
|
sound (self, CHAN_WEAPON, "weapons/spike2.wav", 1, ATTN_NORM);
|
||||||
if (other.takedamage)
|
if (deathmatch != 4)
|
||||||
{
|
self.currentammo = self.ammo_nails = self.ammo_nails - 2;
|
||||||
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);
|
|
||||||
|
|
||||||
|
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;
|
r = 0.1;
|
||||||
break;
|
break;
|
||||||
case IT_SUPER_NAILGUN:
|
case IT_SUPER_NAILGUN:
|
||||||
W_FireSpikes(0);
|
W_FireSuperSpikes();
|
||||||
r = 0.1;
|
r = 0.1;
|
||||||
break;
|
break;
|
||||||
case IT_GRENADE_LAUNCHER:
|
case IT_GRENADE_LAUNCHER:
|
||||||
|
@ -1403,4 +1149,3 @@ void() SuperDamageSound =
|
||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue