Git Repos / fte_dogmode / qc / monsters / playerclient.qc
Last update to this file was on 2024-11-20 at 23:54.
Show playerclient.qc
//==============================================================================
// client / player
//==============================================================================
//======================================================================
// constants
//======================================================================
#ifdef SSQC
const float PLAYER_HEALTH = 100; // id1 100
const float PLAYER_HEALTH_CORPSE = 30;
const vector PLAYER_HEAD_MINS = '-9.67 -12.38 -2.1';
const vector PLAYER_HEAD_MAXS = '11.49 50.7 30';
const vector PLAYER_CORPSE_C_MINS = '-50.28 -23.55 -49.85';
const vector PLAYER_CORPSE_C_MAXS = '30.66 14.49 30';
const vector PLAYER_CORPSE_E_MINS = '-38.72 -5.83 -50.45';
const vector PLAYER_CORPSE_E_MAXS = '28.73 33.85 30';
const vector PLAYER_CORPSE_AX_MINS = '-38.72 -5.83 -50.45';
const vector PLAYER_CORPSE_AX_MAXS = '28.73 33.85 30';
#endif
#ifdef CSQC
const float PLAYER_CROUCH_SMOOTH = 0.1f;
#endif
#if defined(CSQC) || defined(SSQC)
enumflags
{
PLAYER_NET_FRAME, // frame has changed
PLAYER_NET_MODEL, // model has changed
PLAYER_NET_ORIGIN, // origin has changed
PLAYER_NET_SIZE, // size has changed (mins, maxs)
PLAYER_NET_ANGLES, // player angles have changed
PLAYER_NET_VELOCITY, // velocity has changed
PLAYER_NET_FLAGS, // .flags & .pm_flags
PLAYER_NET_TIMERS, // .pm_timer
PLAYER_NET_EFFECTS, // .sveffects has changed
PLAYER_NET_SOLID, // .solid and/or .movetype have changed
PLAYER_NET_ITEMS, // .items (& others) have changed
PLAYER_NET_PUNCHANGLE // .punchangle has changed
};
#endif
//======================================================================
// globals
//======================================================================
#ifdef CSQC
float view_bob; // head bobbing -- CEV
float view_bob_old;
float view_crouch; // view smoothing for crouching -- CEV
float view_crouch_old;
float view_crouch_finished;
float view_punch1; // punchangle_x -- CEV
float view_punch2;
float view_punch_time;
float view_step; // view smoothing for steps -- CEV
float view_step_adjust;
float view_step_disable;
float view_step_oldz;
float view_step_time;
#endif
#ifdef SSQC
float modelindex_eyes;
float modelindex_player;
#endif
//======================================================================
// fields
//======================================================================
#ifdef SSQC
.float axhitme;
.float fly_sound;
.float jump_flag; // player jump flag
.float reset_items; // dumptruck_ds
#endif
#ifdef SSQC
.float air_finished; // when time > air_finished, drown
.float attack_finished;
.float pain_finished;
.float invincible_finished;
.float invisible_finished;
.float super_damage_finished;
.float radsuit_finished;
#endif
#ifdef SSQC
.float damage_time;
.float invincible_time, invincible_sound;
.float invisible_time, invisible_sound;
.float super_time, super_sound;
.float rad_time;
.float megahealth_rottime; // dumptruck_ds
#endif
#ifdef SSQC
.float step_time; // CEV
// set to time+0.2 whenever a client fires a weapon or takes damage.
// Used to alert monsters that otherwise would let the player go
.float show_hostile;
.string deathtype; // keeps track of how the player died
#endif
#ifdef SSQC
// DP_INPUTBUTTONS (in qw we set 1 to equal 3 to match zquake/fuhquake/mvdsv)
.float button3;
.float button4;
.float button5;
.float button6;
.float button7;
.float button8;
#endif
#ifdef CSQC
.float commandframe;
#endif
//======================================================================
// forward declarations
//======================================================================
// player
#ifdef CSQC
// PLAYER_PREDICTION_SAVE(e)
// PLAYER_PREDICTION_RESET(e)
// PLAYER_PREDICTION(e, endframe)
// PLAYER_VIEW_BOB(e)
// PLAYER_VIEW_CROUCH(e)
// PLAYER_VIEW_PUNCHANGLE()
// PLAYER_VIEW_ROLL(e)
// PLAYER_VIEW_STEPS(e)
void(float isnew) player_netreceive;
float() player_predraw;
static void() player_remove;
void(entity e) player_prediction_preframe;
void(entity e) player_prediction_postframe;
#endif
#ifdef SSQC
float(entity to, float netflags) player_netsend;
void() player_impulse_cheat; // impulse commands
void() player_impulse_quadcheat;
void() player_impulse_serverflags;
void() player_impulse_changeweapon;
void() player_impulse_cycleweapon;
void() player_impulse_cycleweaponreverse;
void() player_impulse;
void() player_superdamage_sound;
void() player_set_current_ammo; // ammo, weapon firing, attacks
float() player_best_weapon;
float() player_check_no_ammo;
void() player_fire_axe;
void() player_fire_shotgun;
void() player_fire_supershotgun;
void(float offset) player_fire_spikes;
void() player_fire_superspikes;
void() player_fire_grenade;
void() player_fire_tribolt;
void() player_fire_rocket;
void() player_fire_lightning;
void() player_attack;
void() player_set_suicide_frame; // pain, damage, death
void() player_pain_sound;
void() player_death_sound;
void() player_dead;
void() player_footstep; // thinking & animation frames
void() player_stand;
void() player_axstand;
void(void() axthink) player_run;
void(void() runthink) player_axrun;
void() pl_axstnd1; void() pl_axstnd2; void() pl_axstnd3; void() pl_axstnd4;
void() pl_axstnd5; void() pl_axstnd6; void() pl_axstnd7; void() pl_axstnd8;
void() pl_axstnd9; void() pl_axstnd10; void() pl_axstnd11; void() pl_axstnd12;
void() pl_stand1; void() pl_stand2; void() pl_stand3; void() pl_stand4;
void() pl_stand5;
void() pl_run1; void() pl_run2; void() pl_run3; void() pl_run4;
void() pl_run5; void() pl_run6;
void() pl_shot1; void() pl_shot2; void() pl_shot3; void() pl_shot4;
void() pl_shot5; void() pl_shot6;
void() pl_axe1; void() pl_axe2; void() pl_axe3; void() pl_axe4;
void() pl_axeb1; void() pl_axeb2; void() pl_axeb3; void() pl_axeb4;
void() pl_axec1; void() pl_axec2; void() pl_axec3; void() pl_axec4;
void() pl_axed1; void() pl_axed2; void() pl_axed3; void() pl_axed4;
void() pl_nail1; void() pl_nail2;
void() pl_light1; void() pl_light2;
void() pl_rocket1; void() pl_rocket2; void() pl_rocket3;
void() pl_rocket4; void() pl_rocket5; void() pl_rocket6;
void() pl_pain1; void() pl_pain2; void() pl_pain3;
void() pl_pain4; void() pl_pain5; void() pl_pain6;
void() pl_axpain1; void() pl_axpain2; void() pl_axpain3;
void() pl_axpain4; void() pl_axpain5; void() pl_axpain6;
void() pl_diea1; void() pl_diea2; void() pl_diea3; void() pl_diea4;
void() pl_diea5; void() pl_diea6; void() pl_diea7; void() pl_diea8;
void() pl_diea9; void() pl_diea10; void() pl_diea11;
void() pl_dieb1; void() pl_dieb2; void() pl_dieb3; void() pl_dieb4;
void() pl_dieb5; void() pl_dieb6; void() pl_dieb7; void() pl_dieb8;
void() pl_dieb9;
void() pl_diec1; void() pl_diec2; void() pl_diec3; void() pl_diec4;
void() pl_diec5; void() pl_diec6; void() pl_diec7; void() pl_diec8;
void() pl_diec9; void() pl_diec10; void() pl_diec11; void() pl_diec12;
void() pl_diec13; void() pl_diec14; void() pl_diec15;
void() pl_died1; void() pl_died2; void() pl_died3; void() pl_died4;
void() pl_died5; void() pl_died6; void() pl_died7; void() pl_died8;
void() pl_died9;
void() pl_diee1; void() pl_diee2; void() pl_diee3; void() pl_diee4;
void() pl_diee5; void() pl_diee6; void() pl_diee7; void() pl_diee8;
void() pl_diee9;
void() player_death_think;
void() player_prethink_watermove;
void() player_prethink;
void() player_postthink_powerups;
void() player_postthink;
void(entity attacker, float damage) player_pain;
void(vector dir) player_destroy_gib;
void(vector dir) player_destroy;
#endif
#if defined(CSQC) || defined(SSQC)
void() player_touch;
#endif
#ifdef SSQC
entity() player_init_selectspawnpoint; // initialization
void() player_init_level_parms;
void() player_respawn;
#endif
#if defined(CSQC) || defined(SSQC)
void(entity e) player_init;
#endif
#ifdef SSQC
strip void() player;
#endif
#ifdef SSQC
// gib_head_player
void(entity act, vector dir, float dmg) throw_gib_head_player;
void(entity e) gib_head_player_init;
void() gib_head_player;
#endif
#ifdef SSQC
// player_dead_axe
void() player_dead_axe;
#endif
#ifdef SSQC
// player_dead_face_down
void() player_dead_face_down;
#endif
#ifdef SSQC
// player_dead_on_side
void() player_dead_on_side;
#endif
//======================================================================
// frame macros
//======================================================================
$cd id1/models/player_4
$origin 0 -6 24
$base base
$skin skin
$frame axrun1 axrun2 axrun3 axrun4 axrun5 axrun6
$frame rockrun1 rockrun2 rockrun3 rockrun4 rockrun5 rockrun6
$frame stand1 stand2 stand3 stand4 stand5
$frame axstnd1 axstnd2 axstnd3 axstnd4 axstnd5 axstnd6
$frame axstnd7 axstnd8 axstnd9 axstnd10 axstnd11 axstnd12
$frame axpain1 axpain2 axpain3 axpain4 axpain5 axpain6
$frame pain1 pain2 pain3 pain4 pain5 pain6
$frame axdeth1 axdeth2 axdeth3 axdeth4 axdeth5 axdeth6
$frame axdeth7 axdeth8 axdeth9
$frame deatha1 deatha2 deatha3 deatha4 deatha5 deatha6 deatha7 deatha8
$frame deatha9 deatha10 deatha11
$frame deathb1 deathb2 deathb3 deathb4 deathb5 deathb6 deathb7 deathb8
$frame deathb9
$frame deathc1 deathc2 deathc3 deathc4 deathc5 deathc6 deathc7 deathc8
$frame deathc9 deathc10 deathc11 deathc12 deathc13 deathc14 deathc15
$frame deathd1 deathd2 deathd3 deathd4 deathd5 deathd6 deathd7
$frame deathd8 deathd9
$frame deathe1 deathe2 deathe3 deathe4 deathe5 deathe6 deathe7
$frame deathe8 deathe9
$frame nailatt1 nailatt2
$frame light1 light2
$frame rockatt1 rockatt2 rockatt3 rockatt4 rockatt5 rockatt6
$frame shotatt1 shotatt2 shotatt3 shotatt4 shotatt5 shotatt6
$frame axatt1 axatt2 axatt3 axatt4 axatt5 axatt6
$frame axattb1 axattb2 axattb3 axattb4 axattb5 axattb6
$frame axattc1 axattc2 axattc3 axattc4 axattc5 axattc6
$frame axattd1 axattd2 axattd3 axattd4 axattd5 axattd6
//------------------------------------------------------------------------------
//----------------------------------------------------------------------
// Player Class: spawn functions, animation, client handling, etc. -- CEV
//----------------------------------------------------------------------
// class player: entity
// {
//==============================================================
// Player/Client networking
//==============================================================
#ifdef CSQC
//--------------------------------------------------------------
#define PLAYER_PREDICTION_SAVE(e) \
{ \
e.origin_net = e.origin; \
e.velocity_net = e.velocity; \
e.angles_net = e.angles; \
e.flags_net = e.flags; \
e.pm_flags_net = e.pm_flags; \
e.pm_timer_net = e.pm_timer; \
}
//--------------------------------------------------------------
// was Pred_ResetPlayerPrediction in CSQCTest cs/prediction.qc
//--------------------------------------------------------------
#define PLAYER_PREDICTION_RESET(e) \
{ \
e.origin = e.origin_net; \
e.velocity = e.velocity_net; \
e.angles = e.angles_net; \
e.flags = e.flags_net; \
e.pm_flags = e.pm_flags_net; \
e.pm_timer = e.pm_timer_net; \
/* setsize (e, e.mins, e.maxs); */ \
if (e.pm_flags & PMF_CROUCHED) \
setsize (e, PM_CROUCH_MIN, PM_CROUCH_MAX); \
else \
setsize (e, PM_STAND_MIN, PM_STAND_MAX); \
if (e.commandframe < clientcommandframe - 128) \
/* avoid an infinite loop */ \
e.commandframe = clientcommandframe - 128; \
}
//--------------------------------------------------------------
// was Pred_RunMovement in CSQCTest cs/prediction.qc
//--------------------------------------------------------------
#define PLAYER_PREDICTION(e, endframe) \
{ \
if (servercommandframe >= e.commandframe + 63) \
{ \
/* we're meant to be updating the player faster than
* this. hopefully its just that we're throttled... */ \
/* you can comment out this block and the player will
* continue to be predicted locally. But its best to
* freeze them */ \
/* dprint ("player_prediction: slow update\n"); */ \
e.commandframe = servercommandframe - 63; \
} \
else \
{ \
if (getstatf(STAT_HEALTH) <= 0) \
{ \
/* dead, so don't run prediction. :D */ \
e.commandframe = clientcommandframe; \
if (getinputstate(e.commandframe - 1) == FALSE) \
{ \
dprint ("PLAYER_PREDICTION: noop?\n"); \
/* TODO CEV no-op ? */ \
} \
} \
else \
{ \
/* 'self' needs to be the entity moving for
* the macros below to work -- CEV */ \
local entity oself = self; \
self = e; \
/* update view_pl -- CEV */ \
if (self.entnum == player_localentnum) { \
if (self != view_pl) \
{ \
view_pl = self; \
} } \
for (float lc = e.commandframe + 1; \
lc <= endframe; lc++) \
{ \
local float f = getinputstate (lc); \
if (f == FALSE) \
{ \
/* no input from client */ \
break; \
} \
if (input_timelength <= 0) \
{ \
break; \
} \
/*
if (i == clientcommandframe)
CSQC_Input_Frame ();
*/ \
/* do the move; see pmove.qc -- CEV */ \
PM_MOVE_PRE () \
PM_MOVE_MOVETYPES () \
PM_MOVE_POST () \
/* don't do step smoothing when flagged
* not to -- CEV */ \
if (self.pm_flags & PMF_ONMOVINGENT) { \
if (view_step_disable == FALSE) \
{ \
view_step_disable = TRUE; \
} } \
else if (view_step_disable) \
{ \
view_step_disable = FALSE; \
} \
} \
/* restore 'self' -- CEV */ \
self = oself; \
/* add anything that was applied after
* (for low packet rate protocols) */ \
/* input_angles = view_angles; */ \
} \
} \
} \
//--------------------------------------------------------------
// PLAYER_VIEW_BOB -- view bob (based on Ironwail's V_CalcBob) -- CEV
//--------------------------------------------------------------
#define PLAYER_VIEW_BOB(e) \
{ \
local float cl_bob = autocvar (cl_bob, 0.02); \
local float cl_bobcycle = autocvar (cl_bobcycle, 0.6); \
if (cl_bob && cl_bobcycle) \
{ \
local float cl_bobup = autocvar (cl_bobup, 0.5); \
local float C = 0; \
C = time - rint((time / cl_bobcycle)) * cl_bobcycle; \
C /= cl_bobcycle; \
if (C < cl_bobup) \
C = M_PI * C / cl_bobup; \
else \
C = M_PI + M_PI * (C - cl_bobup) / \
(1.0 - cl_bobup); \
/* bob is proportional to velocity in the xy plane
* (don't count Z, or jumping messes it up) */ \
view_bob = vlen ([self.velocity_x, self.velocity_y]); \
view_bob *= cl_bob; \
view_bob = view_bob * 0.3 + view_bob * 0.7 * sin(C); \
view_bob = bound (-7, view_bob, 4); \
/* only bob when onground and try to limit abrupt
* view changes when landing -- CEV */ \
/* this is pretty tortured -- CEV */ \
if (e.pm_flags & PMF_ONGROUND && \
!(e.pm_flags & PMF_CROUCHSLIDE)) \
{ \
if (view_bob_old) \
{ \
if (fabs(view_bob) - \
fabs(view_bob_old) < cl_bob) \
{ \
view_bob_old = 0; \
} \
else \
{ \
view_bob = view_bob_old; \
} \
} \
} \
else \
{ \
if (view_bob_old) \
{ \
view_bob_old *= 0.9f; \
if (view_bob_old > 0) \
view_bob_old = max (PM_FLMIN, \
view_bob_old); \
else \
view_bob_old = min (-PM_FLMIN, \
view_bob_old); \
view_bob = view_bob_old; \
} \
else \
{ \
view_bob_old = view_bob; \
} \
} \
/*
dprint (sprintf("PLAYER_VIEW_BOB: view_bob "
"%g, old %g\n", view_bob, view_bob_old));
*/ \
} \
else \
{ \
if (view_bob) \
view_bob = 0; \
if (view_bob_old) \
view_bob_old = 0; \
} \
view_origin.z += view_bob; \
}
//--------------------------------------------------------------
// PLAYER_VIEW_CROUCH -- smooth crouching -- CEV
//--------------------------------------------------------------
#define PLAYER_VIEW_CROUCH(e) \
{ \
if (view_crouch_finished > time) \
{ \
if (view_crouch_old != e.view_ofs.z) \
{ \
local float zc; \
zc = 1 - (view_crouch_finished - time) / \
PLAYER_CROUCH_SMOOTH; \
view_crouch = lerp_hermite (view_crouch_old, \
e.view_ofs.z, zc); \
} \
} \
else \
{ \
if (view_crouch_old != e.view_ofs.z) \
view_crouch_old = e.view_ofs.z; \
view_crouch = e.view_ofs.z; \
} \
view_origin.z += view_crouch; \
}
//--------------------------------------------------------------
// PLAYER_VIEW_PUNCHANGLE -- punchangle code from Ironwail -- CEV
//--------------------------------------------------------------
#define PLAYER_VIEW_PUNCHANGLE() \
{ \
/* punchangle code from Ironwail -- CEV */ \
if (autocvar(v_gunkick, 1)) { \
if (view_punch2 || view_punch1) \
{ \
view_angles.x += view_punch2 + bound \
(0, (time - view_punch_time) / 0.1f, 1) * \
(view_punch1 - view_punch2); \
} } \
}
//--------------------------------------------------------------
// PLAYER_VIEW_ROLL -- sideways view roll code from Ironwail -- CEV
//--------------------------------------------------------------
#define PLAYER_VIEW_ROLL(e) \
{ \
local float view_rollspeed = autocvar (cl_rollspeed, 200); \
local float view_rollangle = autocvar (cl_rollangle, 2.0f); \
if (view_rollspeed && view_rollangle) \
{ \
local float view_roll = e.velocity * v_right; \
local float view_sign = view_roll < 0 ? -1 : 1; \
view_roll = fabs (view_roll); \
if (view_roll < view_rollspeed) \
view_roll *= view_rollangle / view_rollspeed; \
else \
view_roll = view_rollangle; \
view_angles.z += view_roll * view_sign; \
} \
}
//--------------------------------------------------------------
// PLAYER_VIEW_STEPS -- step smoothing, based on CSQCTest -- CEV
//--------------------------------------------------------------
#define PLAYER_VIEW_STEPS(e) \
{ \
local float view_step_diff = e.origin.z - view_step_oldz; \
if (view_step_disable == FALSE) { \
if (e.pm_flags & PMF_ONGROUND) { \
if (view_step_diff >= 4 && view_step_diff <= PM_STEPHEIGHT) \
{ \
if (e.speed) \
view_step_adjust = e.speed * 0.018; \
else \
view_step_adjust = PM_MAXSPEED * 0.018; \
view_step_adjust = bound (4, view_step_adjust, 16); \
/* evaluate out the remaining old step */ \
if (view_step_time - time > 0) \
view_step = (view_step_time - time) * \
view_step_adjust * view_step; \
else \
view_step = 0; \
view_step += view_step_diff; \
view_step_time = time + (1 / view_step_adjust); \
/*
dprint (sprintf("player_prediction_preframe: "
"pm_step %g, step %g, step_adjust %g\n",
view_pm_step, view_step, view_step_adjust));
*/ \
} } } \
view_step_oldz = e.origin.z; \
/* now do the adjustment -- CEV */ \
if (view_step_time - time > 0) \
view_origin.z -= (view_step_time - time) * \
view_step_adjust * view_step; \
}
//--------------------------------------------------------------
// called from CSQC_Ent_Update for CT_PLAYER entities
//--------------------------------------------------------------
void(float isnew) player_netreceive =
{
local float newframe = 0;
local float newmoveflags = 0;
local float netflags = ReadFloat ();
if (netflags & PLAYER_NET_FRAME)
newframe = ReadByte ();
if (netflags & PLAYER_NET_MODEL)
self.modelindex = ReadShort ();
if (netflags & PLAYER_NET_ORIGIN)
{
self.origin_x = ReadCoord ();
self.origin_y = ReadCoord ();
self.origin_z = ReadCoord ();
}
// we can safely infer PLAYER_NET_SIZE from .pm_flags;
// if it's necessary to transmit size (mins & maxs) in
// the future we'd do so here -- CEV
if (netflags & PLAYER_NET_ANGLES)
{
self.angles_x = ReadAngle ();
self.angles_y = ReadAngle ();
self.angles_z = ReadAngle ();
}
if (netflags & PLAYER_NET_VELOCITY)
{
self.velocity_x = ReadShort() * 0.125;
self.velocity_y = ReadShort() * 0.125;
self.velocity_z = ReadShort() * 0.125;
self.speed = vlen ([self.velocity_x,self.velocity_y,0]);
}
if (netflags & PLAYER_NET_FLAGS)
{
self.flags = ReadFloat ();
newmoveflags = ReadFloat ();
}
else
{
newmoveflags = self.pm_flags;
}
if (netflags & PLAYER_NET_TIMERS)
self.pm_timer = ReadFloat ();
if (netflags & PLAYER_NET_EFFECTS)
self.sveffects = ReadByte ();
if (netflags & PLAYER_NET_SOLID)
{
self.solid = ReadByte ();
self.movetype = ReadByte ();
}
if (netflags & PLAYER_NET_ITEMS)
self.items = ReadFloat ();
if (netflags & PLAYER_NET_PUNCHANGLE)
{
self.punchangle_x = ReadShort ();
// punchangle code from Ironwail -- CEV
if (self.entnum == player_localentnum) {
if (view_punch1 != self.punchangle_x)
{
view_punch2 = view_punch1;
view_punch1 = self.punchangle_x;
view_punch_time = time;
} }
}
if (isnew && !(self.predraw))
{
dprint ("player_netreceive: init player...\n");
self.pm_flags = newmoveflags;
player_init (self);
}
else if (self.pm_flags != newmoveflags)
{
if (newmoveflags & PMF_CROUCHED &&
(!(self.pm_flags & PMF_CROUCHED)))
{
self.pm_flags = newmoveflags;
PM_CrouchStart ();
}
else if ((!(newmoveflags & PMF_CROUCHED)) &&
self.pm_flags & PMF_CROUCHED)
{
self.pm_flags = newmoveflags;
PM_CrouchStop ();
}
else
{
if (newmoveflags & PMF_CROUCHED)
setsize (self, PM_CROUCH_MIN,
PM_CROUCH_MAX);
else
setsize (self, PM_STAND_MIN,
PM_STAND_MAX);
self.pm_flags = newmoveflags;
}
}
else
{
self.pm_flags = newmoveflags;
// Make sure mins & maxs match the server -- CEV
if (self.pm_flags & PMF_CROUCHED)
setsize (self, PM_CROUCH_MIN, PM_CROUCH_MAX);
else
setsize (self, PM_STAND_MIN, PM_STAND_MAX);
}
if (self.entnum == player_localentnum)
{
view_pl = self;
self.commandframe = servercommandframe;
PLAYER_PREDICTION_SAVE (self)
}
// TODO CEV movement interpolation for other players
if (newframe != self.frame || isnew)
{
self.frame2 = self.frame;
self.lerptime = time;
self.frame = newframe;
}
self.oldframe = self.frame;
};
//--------------------------------------------------------------
// Based on pieces of Pred_UpdateLocalMovement from CSQCTest
//--------------------------------------------------------------
float() player_predraw =
{
// player visual effects; this might need to be some place
// other than predraw for multiplayer support -- CEV
if (self.sveffects & EF_MUZZLEFLASH)
{
self.sveffects &= ~EF_MUZZLEFLASH;
makevectors ([0, self.angles_y, 0]);
pointparticles (particleeffectnum("te_muzzleflash"),
self.origin, v_forward, 1);
}
if (self.sveffects & EF_DIMLIGHT)
{
local vector col;
makevectors (self.v_angle);
// rely on sitems here instead of transmitting .items
// through SendEntity; might reduce net traffic? -- CEV
// sitems set in cl_hud already -- CEV
// sitems = getstatf (STAT_ITEMS, 0, 23);
// quad + pent, pent, quad, normal -- CEV
if (sitems & IT_INVULNERABILITY)
if (sitems & IT_QUAD)
col = '0.5 0.3 0.4';
else
col = '0.4 0 0';
else if (sitems & IT_QUAD)
col = '0.05 0.05 0.94';
else
col = '0.5 0.5 0.2';
// cubemap orientation is read from v_forward etc.
dynamiclight_add (self.origin, 200, col, 0, "",
PFLAGS_NOSHADOW);
}
if (self.lerptime)
self.lerpfrac = 1 - (time - self.lerptime) * 10;
if (self.entnum != player_localentnum)
self.renderflags = 0;
else
self.renderflags |= RF_EXTERNALMODEL;
addentity (self);
return PREDRAW_NEXT;
};
//--------------------------------------------------------------
static void() player_remove =
{
if (view_pl == self)
view_pl = world;
setmodel (self, "");
self.oldskin = "";
self.predraw = __NULL__;
};
//--------------------------------------------------------------
void(entity e) player_prediction_preframe =
{
if (serverkeyfloat(SERVERKEY_PAUSESTATE))
return;
if (intermission == TRUE)
{
view_origin = e.origin;
return;
}
// PLAYER_PREDICTION_SAVE (e)
PLAYER_PREDICTION (e, clientcommandframe)
view_origin = e.origin;
// view_origin: head bob, crouch smoothing, steps -- CEV
PLAYER_VIEW_BOB (e)
PLAYER_VIEW_CROUCH (e)
PLAYER_VIEW_STEPS (e)
// view_angles: punchangle, sideways view roll -- CEV
makevectors (view_angles);
PLAYER_VIEW_PUNCHANGLE ()
PLAYER_VIEW_ROLL (e)
};
//--------------------------------------------------------------
void(entity e) player_prediction_postframe =
{
PLAYER_PREDICTION_RESET (e)
setsize (e, e.mins, e.maxs);
setorigin (e, e.origin);
};
#endif
#ifdef SSQC
//--------------------------------------------------------------
// SendEntity -- transmit updates from server to client -- CEV
//--------------------------------------------------------------
float(entity to, float netflags) player_netsend =
{
WriteShort (MSG_ENTITY, self.classtype);
WriteFloat (MSG_ENTITY, netflags);
if (netflags & PLAYER_NET_FRAME)
WriteByte (MSG_ENTITY, self.frame);
if (netflags & PLAYER_NET_MODEL)
WriteShort (MSG_ENTITY, self.modelindex);
if (netflags & PLAYER_NET_ORIGIN)
{
WriteCoord (MSG_ENTITY, self.origin_x);
WriteCoord (MSG_ENTITY, self.origin_y);
WriteCoord (MSG_ENTITY, self.origin_z);
}
// we can safely infer PLAYER_NET_SIZE from .pm_flags;
// if it's necessary to transmit size (mins & maxs) in
// the future we'd do so here -- CEV
// if (netflags & PLAYER_NET_SIZE)
if (netflags & PLAYER_NET_ANGLES)
{
WriteAngle (MSG_ENTITY, self.angles_x);
WriteAngle (MSG_ENTITY, self.angles_y);
WriteAngle (MSG_ENTITY, self.angles_z);
}
if (netflags & PLAYER_NET_VELOCITY)
{
WriteShort (MSG_ENTITY, floor(self.velocity_x * 8));
WriteShort (MSG_ENTITY, floor(self.velocity_y * 8));
WriteShort (MSG_ENTITY, floor(self.velocity_z * 8));
}
if (netflags & PLAYER_NET_FLAGS)
{
WriteFloat (MSG_ENTITY, self.flags);
WriteFloat (MSG_ENTITY, self.pm_flags);
}
if (netflags & PLAYER_NET_TIMERS)
WriteFloat (MSG_ENTITY, self.pm_timer);
if (netflags & PLAYER_NET_EFFECTS)
WriteByte (MSG_ENTITY, self.sveffects);
if (netflags & PLAYER_NET_SOLID)
{
WriteByte (MSG_ENTITY, self.solid);
WriteByte (MSG_ENTITY, self.movetype);
}
if (netflags & PLAYER_NET_ITEMS)
WriteFloat (MSG_ENTITY, self.items);
if (netflags & PLAYER_NET_PUNCHANGLE)
{
WriteShort (MSG_ENTITY, self.punchangle_x);
self.punchangle_x = 0;
}
// only muzzleflash once, should be cleared elsewhere -- CEV
if (self.sveffects & EF_MUZZLEFLASH)
self.sveffects &= ~EF_MUZZLEFLASH;
return TRUE;
};
//==============================================================
// Client Input Handling
//==============================================================
//--------------------------------------------------------------
// CheatCommand
//--------------------------------------------------------------
void() player_impulse_cheat =
{
// 1998-07-29 Cheats coop fix by Maddes start
// if (deathmatch || coop)
if (deathmatch)
// 1998-07-29 Cheats coop fix by Maddes end
return;
self.ammo_cells = 200;
self.ammo_nails = 200;
self.ammo_rockets = 100;
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_LIGHTNING;
// support for item_key_custom -- iw
base_item_key_giveallkeys (self);
self.weapon = IT_ROCKET_LAUNCHER;
self.impulse = 0;
player_set_current_ammo ();
};
//--------------------------------------------------------------
void() player_impulse_quadcheat =
{
// 1998-07-29 Cheats coop fix by Maddes start
// if (deathmatch || coop)
if (deathmatch)
// 1998-07-29 Cheats coop fix by Maddes end
return;
self.super_time = 1;
self.super_damage_finished = time + 30;
self.items = self.items | IT_QUAD;
dprint ("player::quad_cheat: quad damage\n");
};
//--------------------------------------------------------------
// ServerflagsCommand -- Just for development
//--------------------------------------------------------------
void() player_impulse_serverflags =
{
// 1998-07-29 Cheats coop fix by Maddes start
if (deathmatch)
return;
// 1998-07-29 Cheats coop fix by Maddes end
serverflags = serverflags * 2 + 1;
};
//--------------------------------------------------------------
// ChangeWeaponCommand -- was W_ChangeWeapon
//--------------------------------------------------------------
void() player_impulse_changeweapon =
{
local float it, haveammo, fl;
// assign fl to silence a warning -- CEV
fl = IT_AXE;
it = self.items;
haveammo = TRUE;
switch (self.impulse)
{
case 1:
fl = IT_AXE;
break;
case 2:
fl = IT_SHOTGUN;
if (self.ammo_shells < 1)
haveammo = FALSE;
break;
case 3:
fl = IT_SUPER_SHOTGUN;
if (self.ammo_shells < 2)
haveammo = FALSE;
break;
case 4:
fl = IT_NAILGUN;
if (self.ammo_nails < 1)
haveammo = FALSE;
break;
case 5:
fl = IT_SUPER_NAILGUN;
if (self.ammo_nails < 2)
haveammo = FALSE;
break;
case 6:
fl = IT_GRENADE_LAUNCHER;
if (self.ammo_rockets < 1)
haveammo = FALSE;
break;
case 7:
fl = IT_ROCKET_LAUNCHER;
if (self.ammo_rockets < 1)
haveammo = FALSE;
break;
case 8:
fl = IT_LIGHTNING;
if (self.ammo_cells < 1)
haveammo = FALSE;
break;
default:
dprint (sprintf("player_impulse_changeweapon: "
"WARNING bad impulse: %f\n",
self.impulse));
return;
}
self.impulse = 0;
if (!(self.items & fl))
{
// don't have the weapon or the ammo
sprint (self, "no weapon.\n");
return;
}
if (haveammo == FALSE)
{
// don't have the ammo
sprint (self, "not enough ammo.\n");
return;
}
// set weapon, set ammo
self.weapon = fl;
player_set_current_ammo ();
};
//--------------------------------------------------------------
// CycleWeaponCommand -- Go to the next weapon with ammo
//--------------------------------------------------------------
void() player_impulse_cycleweapon =
{
local float haveammo;
self.impulse = 0;
while (1)
{
haveammo = TRUE;
if (self.weapon == IT_LIGHTNING)
{
self.weapon = IT_AXE;
}
else if (self.weapon == IT_AXE)
{
self.weapon = IT_SHOTGUN;
if (self.ammo_shells < 1)
haveammo = FALSE;
}
else if (self.weapon == IT_SHOTGUN)
{
self.weapon = IT_SUPER_SHOTGUN;
if (self.ammo_shells < 2)
haveammo = FALSE;
}
else if (self.weapon == IT_SUPER_SHOTGUN)
{
self.weapon = IT_NAILGUN;
if (self.ammo_nails < 1)
haveammo = FALSE;
}
else if (self.weapon == IT_NAILGUN)
{
self.weapon = IT_SUPER_NAILGUN;
if (self.ammo_nails < 2)
haveammo = FALSE;
}
else if (self.weapon == IT_SUPER_NAILGUN)
{
self.weapon = IT_GRENADE_LAUNCHER;
if (self.ammo_rockets < 1)
haveammo = FALSE;
}
else if (self.weapon == IT_GRENADE_LAUNCHER)
{
self.weapon = IT_ROCKET_LAUNCHER;
if (self.ammo_rockets < 1)
haveammo = FALSE;
}
else if (self.weapon == IT_ROCKET_LAUNCHER)
{
self.weapon = IT_LIGHTNING;
if (self.ammo_cells < 1)
haveammo = FALSE;
}
if ((self.items & self.weapon) && haveammo == TRUE)
{
player_set_current_ammo ();
return;
}
}
};
//--------------------------------------------------------------
// CycleWeaponReverseCommand -- Go to the prev weapon with ammo
//--------------------------------------------------------------
void() player_impulse_cycleweaponreverse =
{
local float haveammo;
self.impulse = 0;
while (1)
{
haveammo = TRUE;
if (self.weapon == IT_LIGHTNING)
{
self.weapon = IT_ROCKET_LAUNCHER;
if (self.ammo_rockets < 1)
haveammo = FALSE;
}
else if (self.weapon == IT_ROCKET_LAUNCHER)
{
self.weapon = IT_GRENADE_LAUNCHER;
if (self.ammo_rockets < 1)
haveammo = FALSE;
}
else if (self.weapon == IT_GRENADE_LAUNCHER)
{
self.weapon = IT_SUPER_NAILGUN;
if (self.ammo_nails < 2)
haveammo = FALSE;
}
else if (self.weapon == IT_SUPER_NAILGUN)
{
self.weapon = IT_NAILGUN;
if (self.ammo_nails < 1)
haveammo = FALSE;
}
else if (self.weapon == IT_NAILGUN)
{
self.weapon = IT_SUPER_SHOTGUN;
if (self.ammo_shells < 2)
haveammo = FALSE;
}
else if (self.weapon == IT_SUPER_SHOTGUN)
{
self.weapon = IT_SHOTGUN;
if (self.ammo_shells < 1)
haveammo = FALSE;
}
else if (self.weapon == IT_SHOTGUN)
{
self.weapon = IT_AXE;
}
else if (self.weapon == IT_AXE)
{
self.weapon = IT_LIGHTNING;
if (self.ammo_cells < 1)
haveammo = FALSE;
}
if ((self.items & self.weapon) && haveammo == TRUE)
{
player_set_current_ammo ();
return;
}
}
};
//--------------------------------------------------------------
// ImpulseCommands
//--------------------------------------------------------------
void() player_impulse =
{
switch (self.impulse)
{
case 1..8:
player_impulse_changeweapon ();
return;
case 9:
player_impulse_cheat ();
break;
case 10:
player_impulse_cycleweapon ();
break;
case 11:
player_impulse_serverflags ();
break;
case 12:
player_impulse_cycleweaponreverse ();
break;
case 100:
// dumptruck_ds version inspired by Copper
sprint (self, version);
break;
case 255:
player_impulse_quadcheat ();
break;
default:
dprint (sprintf("player_impulse: "
"unknown impulse %g\n", self.impulse));
break;
}
self.impulse = 0;
};
//==============================================================
// Client & Player Sounds
//==============================================================
//--------------------------------------------------------------
// SuperDamageSound -- Plays sound if needed
//--------------------------------------------------------------
void() player_superdamage_sound =
{
if (self.super_damage_finished > time &&
self.super_sound < time)
{
self.super_sound = time + 1;
sound (self, CHAN_AUTO, "items/damage3.wav",
VOL_HIGH, ATTN_NORM);
}
};
//==============================================================
// Ammo Handling, Weapon Switching, Attack
//==============================================================
//--------------------------------------------------------------
// player_set_current_ammo -- was W_SetCurrentAmmo in weapons.qc
//--------------------------------------------------------------
void() player_set_current_ammo =
{
// get out of any weapon firing states
pl_run1 ();
self.items = self.items - (self.items & (IT_SHELLS | IT_NAILS |
IT_ROCKETS | IT_CELLS));
if (self.weapon == IT_AXE)
{
self.currentammo = 0;
self.weaponmodel = "progs/v_axe.mdl";
}
else if (self.weapon == IT_SHOTGUN)
{
self.currentammo = self.ammo_shells;
self.weaponmodel = "progs/v_shot.mdl";
self.items = self.items | IT_SHELLS;
}
else if (self.weapon == IT_SUPER_SHOTGUN)
{
self.currentammo = self.ammo_shells;
self.weaponmodel = "progs/v_shot2.mdl";
self.items = self.items | IT_SHELLS;
}
else if (self.weapon == IT_NAILGUN)
{
self.currentammo = self.ammo_nails;
self.weaponmodel = "progs/v_nail.mdl";
self.items = self.items | IT_NAILS;
}
else if (self.weapon == IT_SUPER_NAILGUN)
{
self.currentammo = self.ammo_nails;
self.weaponmodel = "progs/v_nail2.mdl";
self.items = self.items | IT_NAILS;
}
else if (self.weapon == IT_GRENADE_LAUNCHER)
{
self.currentammo = self.ammo_rockets;
self.weaponmodel = "progs/v_rock.mdl";
self.items = self.items | IT_ROCKETS;
}
else if (self.weapon == IT_ROCKET_LAUNCHER)
{
self.currentammo = self.ammo_rockets;
self.weaponmodel = "progs/v_rock2.mdl";
self.items = self.items | IT_ROCKETS;
}
else if (self.weapon == IT_LIGHTNING)
{
self.currentammo = self.ammo_cells;
self.weaponmodel = "progs/v_light.mdl";
self.items = self.items | IT_CELLS;
}
else
{
self.currentammo = 0;
self.weaponmodel = "";
}
// TODO CEV
self.weaponframe = 0;
};
//--------------------------------------------------------------
// best_weapon -- was W_BestWeapon in weapons.qc
//--------------------------------------------------------------
float() player_best_weapon =
{
if (self.conlevel <= WATERLEVEL_FEET &&
self.ammo_cells >= 1 && (self.items & IT_LIGHTNING))
{
return IT_LIGHTNING;
}
if (self.ammo_nails >= 2 && (self.items & IT_SUPER_NAILGUN))
return IT_SUPER_NAILGUN;
if (self.ammo_shells >= 2 && (self.items & IT_SUPER_SHOTGUN))
return IT_SUPER_SHOTGUN;
if (self.ammo_nails >= 1 && (self.items & IT_NAILGUN))
return IT_NAILGUN;
if (self.ammo_shells >= 1 && (self.items & IT_SHOTGUN))
return IT_SHOTGUN;
return IT_AXE;
};
//--------------------------------------------------------------
float() player_check_no_ammo =
{
if (self.currentammo > 0)
return TRUE;
if (self.weapon == IT_AXE)
return TRUE;
self.weapon = player_best_weapon ();
player_set_current_ammo ();
// drop the weapon down
return FALSE;
};
//--------------------------------------------------------------
// Weapon 1: W_FireAxe
//--------------------------------------------------------------
void() player_fire_axe =
{
local vector source;
local vector org;
local float player_solid;
makevectors (self.v_angle);
source = self.origin + '0 0 16';
// set player to SOLID_BBOX, trace, then revert that change,
// as per comments on SOLID_CORPSE in fteextensions.qc -- CEV
player_solid = self.solid;
self.solid = SOLID_BBOX;
traceline (source, source + v_forward * 64, FALSE, self);
self.solid = player_solid;
if (trace_fraction == 1.0)
return;
org = trace_endpos - v_forward * 4;
if (trace_ent.takedamage)
{
trace_ent.axhitme = 1;
spawn_blood (org, '0 0 0', 20);
t_damage2 (trace_ent, self, self, 20);
}
else
{
// hit wall
sound (self, CHAN_WEAPON, "player/axhit2.wav",
VOL_HIGH, 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);
}
};
//--------------------------------------------------------------
// Weapon 2: W_FireShotgun
//--------------------------------------------------------------
void() player_fire_shotgun =
{
local vector org, dir, vdir;
local float vspeed;
sound (self, CHAN_WEAPON, "weapons/guncock.wav",
VOL_HIGH, ATTN_NORM);
self.punchangle_x = -2;
// self.SendFlags |= PLAYER_NET_PUNCHANGLE;
self.currentammo = self.ammo_shells = self.ammo_shells - 1;
// dir = aim (self, 100000);
makevectors (self.v_angle);
org = self.origin + (self.view_ofs - '0 0 16') +
(v_forward * 10) + (v_right * 0) + (v_up * 8);
dir = normalize (v_forward * BULLET_SPEED);
// 5 bullets instead of 6 -- CEV
for (float i = 0; i < 5; i++)
{
vspeed = crandom () * 10 + BULLET_SPEED;
vdir = dir + crandom() * 0.04 * v_right +
crandom() * 0.04 * v_up;
/*
vdir = dir +
((((i / 10.0) - 0.3) * 0.12) * v_right) +
((((i / 10.0) - 0.3) * 0.12) * v_up);
*/
vdir *= min (vspeed, world_maxvelocity);
spawn_projectile_bullet (self, org, vdir);
}
};
//--------------------------------------------------------------
// Weapon 3: W_FireSuperShotgun
//--------------------------------------------------------------
void() player_fire_supershotgun =
{
local vector org, dir, vdir;
local float vspeed;
if (self.currentammo == 1)
{
player_fire_shotgun ();
return;
}
sound (self, CHAN_WEAPON, "weapons/shotgn2.wav",
VOL_HIGH, ATTN_NORM);
self.punchangle_x = -4;
// self.SendFlags |= PLAYER_NET_PUNCHANGLE;
self.currentammo = self.ammo_shells = self.ammo_shells - 2;
// dir = aim (self, 100000);
makevectors (self.v_angle);
org = self.origin + (self.view_ofs - '0 0 16') +
(v_forward * 10) + (v_right * 0) + (v_up * 8);
dir = normalize (v_forward * BULLET_SPEED);
// 12 bullets instead of 14 -- CEV
for (float i = 0; i < 12; i++)
{
vspeed = crandom () * 10 + BULLET_SPEED;
vdir = dir + (crandom() * 0.14) * v_right +
(crandom() * 0.08) * v_up;
vdir *= min (vspeed, world_maxvelocity);
spawn_projectile_bullet (self, org, vdir);
}
};
//--------------------------------------------------------------
// Weapon 4: W_FireSpikes
//--------------------------------------------------------------
void(float offset) player_fire_spikes =
{
local vector dir;
local vector org = self.origin + self.view_ofs;
makevectors (self.v_angle);
if (self.ammo_nails >= 2 && self.weapon == IT_SUPER_NAILGUN)
{
player_fire_superspikes ();
return;
}
if (self.ammo_nails < 1)
{
self.weapon = player_best_weapon ();
player_set_current_ammo ();
return;
}
sound (self, CHAN_WEAPON, "weapons/rocket1i.wav",
VOL_HIGH, ATTN_NORM);
self.attack_finished = time + 0.2;
self.currentammo = self.ammo_nails = self.ammo_nails - 1;
dir = aim (self, SPIKE_SPEED);
// dir = normalize (dir);
// SetSpeed
dir *= min (SPIKE_SPEED, world_maxvelocity);
// seven Nailgun position fix - thanks to Greenwood
// -- dumptruck_ds
org += v_up * -8 + v_right * (offset * 0.5);
spawn_projectile_spike (self, org, dir, SPIKE_NORMAL_DAMAGE);
self.punchangle_x = -2;
// self.SendFlags |= PLAYER_NET_PUNCHANGLE;
};
//--------------------------------------------------------------
// Weapon 5: W_FireSuperSpikes
//--------------------------------------------------------------
void() player_fire_superspikes =
{
local vector dir;
local vector org = self.origin + (self.view_ofs - '0 0 4');
sound (self, CHAN_WEAPON, "weapons/spike2.wav",
VOL_HIGH, ATTN_NORM);
self.attack_finished = time + 0.2;
self.currentammo = self.ammo_nails = self.ammo_nails - 2;
dir = aim (self, SPIKE_SPEED);
// dir = normalize (dir);
// SetSpeed
dir *= min (SPIKE_SPEED, world_maxvelocity);
// seven Nailgun position fix - thanks to Greenwood
// -- dumptruck_ds
spawn_projectile_spike (self, org, dir, SPIKE_SUPER_DAMAGE);
self.punchangle_x = -2;
// self.SendFlags |= PLAYER_NET_PUNCHANGLE;
};
//--------------------------------------------------------------
// Weapon 6: W_FireGrenade
//--------------------------------------------------------------
void() player_fire_grenade =
{
local vector missile_velocity = '0 0 0';
local vector org = self.origin + (self.view_ofs - '0 0 8');
self.currentammo = self.ammo_rockets = self.ammo_rockets - 1;
sound (self, CHAN_WEAPON, "weapons/grenade.wav",
VOL_HIGH, ATTN_NORM);
self.punchangle_x = -2;
// self.SendFlags |= PLAYER_NET_PUNCHANGLE;
// set missile speed
makevectors (self.v_angle);
if (self.v_angle_x)
{
missile_velocity = v_forward * GRENADE_SPEED +
v_up * 200 + crandom() * v_right * 10 +
crandom() * v_up * 10;
}
else
{
missile_velocity = aim (self, 10000);
missile_velocity = missile_velocity * GRENADE_SPEED;
missile_velocity_z = 200;
}
spawn_projectile_grenade (self, org, missile_velocity);
};
//--------------------------------------------------------------
void() player_fire_tribolt =
{
local vector missile_vel = '0 0 0';
self.currentammo = self.ammo_rockets = self.ammo_rockets - 1;
sound (self, CHAN_WEAPON, "weapons/grenade.wav",
VOL_HIGH, ATTN_NORM);
self.punchangle_x = -2;
// self.SendFlags |= PLAYER_NET_PUNCHANGLE;
// called a tribolt 'cause there's three of 'em -- CEV
spawn_projectile_bolt (self, 0);
spawn_projectile_bolt (self, BOLT_FIRING_DELAY);
spawn_projectile_bolt (self, BOLT_FIRING_DELAY * 2.0f);
};
//--------------------------------------------------------------
// Weapon 7: W_FireRocket
//--------------------------------------------------------------
void() player_fire_rocket =
{
local vector org = self.origin + (self.view_ofs - '0 0 8');
local vector missile_velocity = '0 0 0';
self.currentammo = self.ammo_rockets = self.ammo_rockets - 1;
sound (self, CHAN_WEAPON, "weapons/sgun1.wav",
VOL_HIGH, ATTN_NORM);
self.punchangle_x = -2;
// self.SendFlags |= PLAYER_NET_PUNCHANGLE;
// set missile speed
makevectors (self.v_angle);
missile_velocity = aim (self, 1000);
missile_velocity *= ROCKET_SPEED;
org += v_forward * 8;
spawn_projectile_rocket (self, org, missile_velocity);
};
//--------------------------------------------------------------
// Weapon 8: W_FireLightning
//--------------------------------------------------------------
void() player_fire_lightning =
{
if (self.ammo_cells < 1)
{
self.weapon = player_best_weapon ();
player_set_current_ammo ();
return;
}
// explode if under water
if (self.conlevel > WATERLEVEL_FEET)
{
local float cells = self.ammo_cells;
self.ammo_cells = 0;
player_set_current_ammo ();
t_radiusdamage2 (self, self, 35 * cells, world);
return;
}
if (self.t_width < time)
{
sound (self, CHAN_WEAPON, "weapons/lhit.wav",
VOL_HIGH, ATTN_NORM);
self.t_width = time + 0.6;
}
self.punchangle_x = -2;
// self.SendFlags |= PLAYER_NET_PUNCHANGLE;
self.currentammo = self.ammo_cells = self.ammo_cells - 1;
// TODO CEV
local vector org = self.origin + (self.view_ofs - '0 0 8');
makevectors (self.v_angle);
// set player to SOLID_BBOX, trace, then revert that change,
// same as in fire_axe -- CEV
local float player_solid = self.solid;
self.solid = SOLID_BBOX;
traceline (org, org + v_forward * 600, TRUE, self);
self.solid = player_solid;
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);
fire_lightning (self.origin, trace_endpos + v_forward * 4,
self, 30);
};
//--------------------------------------------------------------
// PlayerAttack -- An attack impulse can be triggered now
//--------------------------------------------------------------
void() player_attack =
{
local float r;
if (player_check_no_ammo() == FALSE)
return;
// calculate forward angle for velocity
makevectors (self.v_angle);
// wake monsters up
self.show_hostile = time + 1;
if (self.weapon == IT_AXE)
{
sound (self, CHAN_WEAPON, "weapons/ax1.wav",
VOL_HIGH, ATTN_NORM);
r = random ();
if (r < 0.25)
pl_axe1 ();
else if (r < 0.5)
pl_axeb1 ();
else if (r < 0.75)
pl_axec1 ();
else
pl_axed1 ();
self.attack_finished = time + 0.5;
}
else if (self.weapon == IT_SHOTGUN)
{
pl_shot1 ();
player_fire_shotgun ();
self.attack_finished = time + 0.5;
}
else if (self.weapon == IT_SUPER_SHOTGUN)
{
pl_shot1 ();
player_fire_supershotgun ();
self.attack_finished = time + 0.7;
}
else if (self.weapon == IT_NAILGUN)
{
pl_nail1 ();
}
else if (self.weapon == IT_SUPER_NAILGUN)
{
pl_nail1 ();
}
else if (self.weapon == IT_GRENADE_LAUNCHER)
{
pl_rocket1 ();
// TODO CEV
// player_fire_grenade ();
player_fire_tribolt ();
// self.attack_finished = time + 0.6;
self.attack_finished = time + 1.3;
}
else if (self.weapon == IT_ROCKET_LAUNCHER)
{
pl_rocket1 ();
player_fire_rocket ();
self.attack_finished = time + 0.8;
}
else if (self.weapon == IT_LIGHTNING)
{
pl_light1 ();
self.attack_finished = time + 0.1;
sound (self, CHAN_AUTO, "weapons/lstart.wav",
VOL_HIGH, ATTN_NORM);
}
};
//==============================================================
// Pain and Death
//==============================================================
//--------------------------------------------------------------
void() player_set_suicide_frame =
{
// used by klill command and disconnect command
if (self.model != "progs/player.mdl")
// allready gibbed
return;
self.frame = $deatha11;
self.solid = SOLID_NOT;
self.movetype = MOVETYPE_TOSS;
self.deadflag = DEAD_DEAD;
self.nextthink = -1;
};
//--------------------------------------------------------------
// PainSound
//--------------------------------------------------------------
void() player_pain_sound =
{
local float rs;
if (self.health < 0)
return;
if (damage_attacker.classname == "teledeath")
{
sound (self, CHAN_VOICE, "player/teledth1.wav",
VOL_HIGH, ATTN_NONE);
return;
}
// water pain sounds
if (self.contype == CONTENT_WATER &&
self.conlevel == WATERLEVEL_EYES)
{
// PlayerDeathBubbles
spawn_air_bubbles (self, self.origin, 1);
if (random() > 0.5)
sound (self, CHAN_VOICE, "player/drown1.wav",
VOL_HIGH, ATTN_NORM);
else
sound (self, CHAN_VOICE, "player/drown2.wav",
VOL_HIGH, ATTN_NORM);
return;
}
// slime pain sounds
if (self.contype == CONTENT_SLIME)
{
// FIX ME put in some steam here
// 1998-08-10 Player gulps bubbles when hurt in slime
// by Maddes start
if (self.conlevel == WATERLEVEL_EYES)
// PlayerDeathBubbles
spawn_air_bubbles (self, self.origin, 1);
// 1998-08-10 Player gulps bubbles when hurt in slime
// by Maddes end
if (random() > 0.5)
sound (self, CHAN_VOICE, "player/lburn1.wav",
VOL_HIGH, ATTN_NORM);
else
sound (self, CHAN_VOICE, "player/lburn2.wav",
VOL_HIGH, ATTN_NORM);
return;
}
if (self.contype == CONTENT_LAVA)
{
if (random() > 0.5)
sound (self, CHAN_VOICE, "player/lburn1.wav",
VOL_HIGH, ATTN_NORM);
else
sound (self, CHAN_VOICE, "player/lburn2.wav",
VOL_HIGH, ATTN_NORM);
return;
}
if (self.pain_finished > time)
{
self.axhitme = 0;
return;
}
// don't make multiple pain sounds right after each other
self.pain_finished = time + 0.5;
// ax pain sound
if (self.axhitme == 1)
{
self.axhitme = 0;
sound (self, CHAN_VOICE, "player/axhit1.wav",
VOL_HIGH, ATTN_NORM);
return;
}
rs = rint ((random() * 5) + 1);
self.noise = "";
if (rs == 1)
self.noise = "player/pain1.wav";
else if (rs == 2)
self.noise = "player/pain2.wav";
else if (rs == 3)
self.noise = "player/pain3.wav";
else if (rs == 4)
self.noise = "player/pain4.wav";
else if (rs == 5)
self.noise = "player/pain5.wav";
else
self.noise = "player/pain6.wav";
sound (self, CHAN_VOICE, self.noise, VOL_HIGH, ATTN_NORM);
return;
};
//--------------------------------------------------------------
// PlayerDeathSound
//--------------------------------------------------------------
void() player_death_sound =
{
local float rs;
// water death sounds
if (self.conlevel == WATERLEVEL_EYES)
{
// PlayerDeathBubbles
spawn_air_bubbles (self, self.origin, 20);
sound (self, CHAN_VOICE, "player/h2odeath.wav",
VOL_HIGH, ATTN_NONE);
return;
}
rs = rint ((random() * 4) + 1);
if (rs == 1)
self.noise = "player/death1.wav";
else if (rs == 2)
self.noise = "player/death2.wav";
else if (rs == 3)
self.noise = "player/death3.wav";
else if (rs == 4)
self.noise = "player/death4.wav";
else if (rs == 5)
self.noise = "player/death5.wav";
sound (self, CHAN_VOICE, self.noise, VOL_HIGH, ATTN_NONE);
return;
};
//--------------------------------------------------------------
// PlayerDead -- the player is dead, hold them there
//--------------------------------------------------------------
void() player_dead =
{
self.nextthink = -1;
// allow respawn after a certain time
self.deadflag = DEAD_DEAD;
};
//==============================================================
// Player Think Functions
//==============================================================
//--------------------------------------------------------------
void() player_footstep =
{
// not moving, no steps
if (self.velocity_x == 0 || self.velocity_y == 0)
return;
// no steps when crouching
if (self.pm_flags & PMF_CROUCHED)
return;
// no steps when on a slick/icy surface
if (self.pm_flags & PMF_ONSLICK)
return;
// at least 200ms between steps
if (self.step_time >= time - 0.2)
return;
// no steps when submerged fully
if (self.conlevel >= WATERLEVEL_EYES)
return;
if (self.speed < PM_WALKSPEED * 0.9)
// no footsteps below PM_WALKSPEED * 0.9
return;
if (self.speed < PM_MAXSPEED * 0.9)
if (self.frame != $rockrun2 && self.frame != $axrun2)
// half the footsteps when walking
return;
local float vol = 0;
local string wav = "";
if (self.conlevel == WATERLEVEL_FEET)
{
// the water foot
vol = 0.3 + (random() * 0.1);
self.cnt = rint (random() * 3);
switch (self.cnt)
{
case 0:
wav = "player/stepwater1.ogg";
break;
case 1:
wav = "player/stepwater2.ogg";
break;
case 2:
wav = "player/stepwater3.ogg";
break;
case 3:
wav = "player/stepwater4.ogg";
}
}
else if (self.conlevel == WATERLEVEL_WAIST)
{
// the deep water foot
if (self.frame != $rockrun2 && self.frame != $axrun2)
return;
vol = 0.3 + (random() * 0.1);
if (self.cnt > 3)
self.cnt = 0;
switch (self.cnt)
{
case 0:
wav = "player/stepwade1.ogg";
break;
case 1:
wav = "player/stepwade2.ogg";
}
}
else
{
// call world_surface_type (which then calls out
// to compatibility modules) to get a material type
// under the player -- CEV
switch (world_surface_type(self, [0, 0, self.mins_z]))
{
case SURFACE_DIRT:
vol = 0.3 + (random() * 0.2);
if (self.cnt > 4)
self.cnt = 0;
wav = sprintf ("player/stepdirt%g.ogg",
self.cnt + 1);
break;
case SURFACE_METAL:
vol = 0.3 + (random() * 0.2);
self.cnt = rint (random() * 8);
wav = sprintf ("player/stepmetal%g.ogg",
self.cnt + 1);
break;
case SURFACE_WOOD:
vol = 0.3 + (random() * 0.2);
if (self.cnt > 3)
self.cnt = 0;
wav = sprintf ("player/stepwood%g.ogg",
self.cnt + 1);
break;
default:
// default is SURFACE_STONE -- CEV
vol = 0.3 + (random() * 0.2);
if (self.cnt > 5)
self.cnt = 0;
wav = sprintf ("player/stepstone%g.ogg",
self.cnt + 1);
}
}
sound (self, CHAN_FEET, wav, vol, ATTN_FEET);
self.cnt++;
self.step_time = time;
if (self.lefty == FALSE)
self.lefty = TRUE;
else
self.lefty = FALSE;
};
//--------------------------------------------------------------
void() player_stand =
{
self.weaponframe = 0;
if (self.velocity_x || self.velocity_y)
{
if (self.weapon == IT_AXE)
pl_axrun1 ();
else
pl_run1 ();
}
else if (self.weapon == IT_AXE)
{
pl_axstnd1 ();
}
};
//--------------------------------------------------------------
void() player_axstand =
{
self.weaponframe = 0;
if (self.velocity_x || self.velocity_y)
{
if (self.weapon == IT_AXE)
pl_axrun1 ();
else
pl_run1 ();
return;
}
else if (self.weapon != IT_AXE)
{
pl_stand1 ();
}
};
//--------------------------------------------------------------
void(void() axthink) player_run =
{
// dprint (sprintf("player_run: frame %g\n", self.frame));
if (self.velocity_x == 0 && self.velocity_y == 0)
pl_stand1 ();
else if (self.weapon == IT_AXE)
axthink ();
};
//--------------------------------------------------------------
void(void() runthink) player_axrun =
{
// dprint (sprintf("player_axrun: frame %g\n", self.frame));
if (self.velocity_x == 0 && self.velocity_y == 0)
pl_stand1 ();
else if (self.weapon != IT_AXE)
runthink ();
};
//--------------------------------------------------------------
// Player Axe Stand function
//--------------------------------------------------------------
void() pl_axstnd1 = [$axstnd1, pl_axstnd2] { player_axstand (); };
void() pl_axstnd2 = [$axstnd2, pl_axstnd3] { player_axstand (); };
void() pl_axstnd3 = [$axstnd3, pl_axstnd4] { player_axstand (); };
void() pl_axstnd4 = [$axstnd4, pl_axstnd5] { player_axstand (); };
void() pl_axstnd5 = [$axstnd5, pl_axstnd6] { player_axstand (); };
void() pl_axstnd6 = [$axstnd6, pl_axstnd7] { player_axstand (); };
void() pl_axstnd7 = [$axstnd7, pl_axstnd8] { player_axstand (); };
void() pl_axstnd8 = [$axstnd8, pl_axstnd9] { player_axstand (); };
void() pl_axstnd9 = [$axstnd9, pl_axstnd10] { player_axstand (); };
void() pl_axstnd10 = [$axstnd10, pl_axstnd11] { player_axstand (); };
void() pl_axstnd11 = [$axstnd11, pl_axstnd12] { player_axstand (); };
void() pl_axstnd12 = [$axstnd12, pl_axstnd1] { player_axstand (); };
//--------------------------------------------------------------
// Player Stand function
//--------------------------------------------------------------
void() pl_stand1 = [$stand1, pl_stand2] { player_stand (); };
void() pl_stand2 = [$stand2, pl_stand3] { player_stand (); };
void() pl_stand3 = [$stand3, pl_stand4] { player_stand (); };
void() pl_stand4 = [$stand4, pl_stand5] { player_stand (); };
void() pl_stand5 = [$stand5, pl_stand1] { player_stand (); };
//--------------------------------------------------------------
// Player Axe Run function
//--------------------------------------------------------------
void() pl_axrun1 = [$axrun1, pl_axrun2]
{
self.weaponframe = 0;
self.lefty = FALSE;
player_axrun (pl_run1);
};
void() pl_axrun2 = [$axrun2, pl_axrun3]
{
// left foot down
player_axrun (pl_run2);
if (self.flags & FL_ONGROUND)
player_footstep ();
};
void() pl_axrun3 = [$axrun3, pl_axrun4] { player_axrun (pl_run3); };
void() pl_axrun4 = [$axrun4, pl_axrun5] { player_axrun (pl_run4); };
void() pl_axrun5 = [$axrun5, pl_axrun6]
{
// right foot down
player_axrun (pl_run5);
if (self.flags & FL_ONGROUND)
player_footstep ();
};
void() pl_axrun6 = [$axrun6, pl_axrun1] { player_axrun (pl_run6); };
//--------------------------------------------------------------
// Player Run function
//--------------------------------------------------------------
void() pl_run1 = [$rockrun1, pl_run2]
{
self.weaponframe = 0;
self.lefty = FALSE;
player_run (pl_axrun1);
};
void() pl_run2 = [$rockrun2, pl_run3]
{
// left foot down
player_run (pl_axrun2);
if (self.flags & FL_ONGROUND)
player_footstep ();
};
void() pl_run3 = [$rockrun3, pl_run4] { player_run (pl_axrun3); };
void() pl_run4 = [$rockrun4, pl_run5] { player_run (pl_axrun4); };
void() pl_run5 = [$rockrun5, pl_run6]
{
// right foot down
player_run (pl_axrun5);
if (self.flags & FL_ONGROUND)
player_footstep ();
};
void() pl_run6 = [$rockrun6, pl_run1] { player_run (pl_axrun6); };
//--------------------------------------------------------------
// Player Projectile Attack
//--------------------------------------------------------------
void() pl_shot1 = [$shotatt1, pl_shot2]
{
self.weaponframe = 1;
self.sveffects |= EF_MUZZLEFLASH;
// self.SendFlags |= PLAYER_NET_EFFECTS;
};
void() pl_shot2 = [$shotatt2, pl_shot3] { self.weaponframe = 2; };
void() pl_shot3 = [$shotatt3, pl_shot4] { self.weaponframe = 3; };
void() pl_shot4 = [$shotatt4, pl_shot5] { self.weaponframe = 4; };
void() pl_shot5 = [$shotatt5, pl_shot6] { self.weaponframe = 5; };
void() pl_shot6 = [$shotatt6, pl_run1] { self.weaponframe = 6; };
//--------------------------------------------------------------
// Player Axe Attack A
//--------------------------------------------------------------
void() pl_axe1 = [$axatt1, pl_axe2] { self.weaponframe = 1; };
void() pl_axe2 = [$axatt2, pl_axe3] { self.weaponframe = 2; };
void() pl_axe3 = [$axatt3, pl_axe4]
{
self.weaponframe = 3;
player_fire_axe ();
};
void() pl_axe4 = [$axatt4, pl_run1] { self.weaponframe = 4; };
//--------------------------------------------------------------
// Player Axe Attack B
//--------------------------------------------------------------
void() pl_axeb1 = [$axattb1, pl_axeb2] { self.weaponframe = 5; };
void() pl_axeb2 = [$axattb2, pl_axeb3] { self.weaponframe = 6; };
void() pl_axeb3 = [$axattb3, pl_axeb4]
{
self.weaponframe = 7;
player_fire_axe ();
};
void() pl_axeb4 = [$axattb4, pl_run1] { self.weaponframe = 8; };
//--------------------------------------------------------------
// Player Axe Attack C
//--------------------------------------------------------------
void() pl_axec1 = [$axattc1, pl_axec2] { self.weaponframe = 1; };
void() pl_axec2 = [$axattc2, pl_axec3] { self.weaponframe = 2; };
void() pl_axec3 = [$axattc3, pl_axec4]
{
self.weaponframe = 3;
player_fire_axe ();
};
void() pl_axec4 = [$axattc4, pl_run1] { self.weaponframe = 4; };
//--------------------------------------------------------------
// Player Axe Attack D
//--------------------------------------------------------------
void() pl_axed1 = [$axattd1, pl_axed2] { self.weaponframe = 5; };
void() pl_axed2 = [$axattd2, pl_axed3] { self.weaponframe = 6; };
void() pl_axed3 = [$axattd3, pl_axed4]
{
self.weaponframe = 7;
player_fire_axe ();
};
void() pl_axed4 = [$axattd4, pl_run1] { self.weaponframe = 8; };
//--------------------------------------------------------------
// Player Nail Attack
//--------------------------------------------------------------
void() pl_nail1 = [$nailatt1, pl_nail2]
{
self.sveffects |= EF_MUZZLEFLASH;
// self.SendFlags |= PLAYER_NET_EFFECTS;
if (!self.button0)
{
pl_run1 ();
return;
}
self.weaponframe = self.weaponframe + 1;
if (self.weaponframe == 9)
self.weaponframe = 1;
player_superdamage_sound ();
player_fire_spikes (4);
self.attack_finished = time + 0.2;
};
void() pl_nail2 = [$nailatt2, pl_nail1]
{
self.sveffects |= EF_MUZZLEFLASH;
// self.SendFlags |= PLAYER_NET_EFFECTS;
if (!self.button0)
{
pl_run1 ();
return;
}
self.weaponframe = self.weaponframe + 1;
if (self.weaponframe == 9)
self.weaponframe = 1;
player_superdamage_sound ();
player_fire_spikes (-4);
self.attack_finished = time + 0.2;
};
//--------------------------------------------------------------
// Player LG Attack
//--------------------------------------------------------------
void() pl_light1 = [$light1, pl_light2]
{
self.sveffects |= EF_MUZZLEFLASH;
// self.SendFlags |= PLAYER_NET_EFFECTS;
if (!self.button0)
{
pl_run1 ();
return;
}
self.weaponframe = self.weaponframe + 1;
if (self.weaponframe == 5)
self.weaponframe = 1;
player_superdamage_sound ();
player_fire_lightning ();
self.attack_finished = time + 0.2;
};
void() pl_light2 = [$light2, pl_light1]
{
self.sveffects |= EF_MUZZLEFLASH;
// self.SendFlags |= PLAYER_NET_EFFECTS;
if (!self.button0)
{
pl_run1 ();
return;
}
self.weaponframe = self.weaponframe + 1;
if (self.weaponframe == 5)
self.weaponframe = 1;
player_superdamage_sound ();
player_fire_lightning ();
self.attack_finished = time + 0.2;
};
//--------------------------------------------------------------
// Player Rocket Attack
//--------------------------------------------------------------
void() pl_rocket1 = [$rockatt1, pl_rocket2]
{
self.weaponframe = 1;
self.sveffects |= EF_MUZZLEFLASH;
// self.SendFlags |= PLAYER_NET_EFFECTS;
};
void() pl_rocket2 = [$rockatt2, pl_rocket3] { self.weaponframe = 2; };
void() pl_rocket3 = [$rockatt3, pl_rocket4] { self.weaponframe = 3; };
void() pl_rocket4 = [$rockatt4, pl_rocket5] { self.weaponframe = 4; };
void() pl_rocket5 = [$rockatt5, pl_rocket6] { self.weaponframe = 5; };
void() pl_rocket6 = [$rockatt6, pl_run1] { self.weaponframe = 6; };
//--------------------------------------------------------------
// Player Pain state A
//--------------------------------------------------------------
void() pl_pain1 = [$pain1, pl_pain2]
{
player_pain_sound ();
self.weaponframe = 0;
};
void() pl_pain2 = [$pain2, pl_pain3] { };
void() pl_pain3 = [$pain3, pl_pain4] { };
void() pl_pain4 = [$pain4, pl_pain5] { };
void() pl_pain5 = [$pain5, pl_pain6] { };
void() pl_pain6 = [$pain6, pl_run1] { };
//--------------------------------------------------------------
// Player Axe Pain state A
//--------------------------------------------------------------
void() pl_axpain1 = [$axpain1, pl_axpain2]
{
player_pain_sound ();
self.weaponframe = 0;
};
void() pl_axpain2 = [$axpain2, pl_axpain3] {};
void() pl_axpain3 = [$axpain3, pl_axpain4] {};
void() pl_axpain4 = [$axpain4, pl_axpain5] {};
void() pl_axpain5 = [$axpain5, pl_axpain6] {};
void() pl_axpain6 = [$axpain6, pl_run1] {};
//--------------------------------------------------------------
// Player Death state A
//--------------------------------------------------------------
void() pl_diea1 = [$deatha1, pl_diea2] {};
void() pl_diea2 = [$deatha2, pl_diea3] {};
void() pl_diea3 = [$deatha3, pl_diea4] {};
void() pl_diea4 = [$deatha4, pl_diea5] {};
void() pl_diea5 = [$deatha5, pl_diea6] {};
void() pl_diea6 = [$deatha6, pl_diea7] {};
void() pl_diea7 = [$deatha7, pl_diea8] {};
void() pl_diea8 = [$deatha8, pl_diea9] {};
void() pl_diea9 = [$deatha9, pl_diea10] {};
void() pl_diea10 = [$deatha10, pl_diea11] {};
void() pl_diea11 = [$deatha11, pl_diea11] { player_dead (); };
//--------------------------------------------------------------
// Player Death state B
//--------------------------------------------------------------
void() pl_dieb1 = [$deathb1, pl_dieb2] {};
void() pl_dieb2 = [$deathb2, pl_dieb3] {};
void() pl_dieb3 = [$deathb3, pl_dieb4] {};
void() pl_dieb4 = [$deathb4, pl_dieb5] {};
void() pl_dieb5 = [$deathb5, pl_dieb6] {};
void() pl_dieb6 = [$deathb6, pl_dieb7] {};
void() pl_dieb7 = [$deathb7, pl_dieb8] {};
void() pl_dieb8 = [$deathb8, pl_dieb9] {};
void() pl_dieb9 = [$deathb9, pl_dieb9] { player_dead (); };
//--------------------------------------------------------------
// Player Death state C
//--------------------------------------------------------------
void() pl_diec1 = [$deathc1, pl_diec2] {};
void() pl_diec2 = [$deathc2, pl_diec3] {};
void() pl_diec3 = [$deathc3, pl_diec4] {};
void() pl_diec4 = [$deathc4, pl_diec5] {};
void() pl_diec5 = [$deathc5, pl_diec6] {};
void() pl_diec6 = [$deathc6, pl_diec7] {};
void() pl_diec7 = [$deathc7, pl_diec8] {};
void() pl_diec8 = [$deathc8, pl_diec9] {};
void() pl_diec9 = [$deathc9, pl_diec10] {};
void() pl_diec10 = [$deathc10, pl_diec11] {};
void() pl_diec11 = [$deathc11, pl_diec12] {};
void() pl_diec12 = [$deathc12, pl_diec13] {};
void() pl_diec13 = [$deathc13, pl_diec14] {};
void() pl_diec14 = [$deathc14, pl_diec15] {};
void() pl_diec15 = [$deathc15, pl_diec15] { player_dead (); };
//--------------------------------------------------------------
// Player Death state D
//--------------------------------------------------------------
void() pl_died1 = [$deathd1, pl_died2] {};
void() pl_died2 = [$deathd2, pl_died3] {};
void() pl_died3 = [$deathd3, pl_died4] {};
void() pl_died4 = [$deathd4, pl_died5] {};
void() pl_died5 = [$deathd5, pl_died6] {};
void() pl_died6 = [$deathd6, pl_died7] {};
void() pl_died7 = [$deathd7, pl_died8] {};
void() pl_died8 = [$deathd8, pl_died9] {};
void() pl_died9 = [$deathd9, pl_died9] { player_dead (); };
//--------------------------------------------------------------
// Player Death state E
//--------------------------------------------------------------
void() pl_diee1 = [$deathe1, pl_diee2] {};
void() pl_diee2 = [$deathe2, pl_diee3] {};
void() pl_diee3 = [$deathe3, pl_diee4] {};
void() pl_diee4 = [$deathe4, pl_diee5] {};
void() pl_diee5 = [$deathe5, pl_diee6] {};
void() pl_diee6 = [$deathe6, pl_diee7] {};
void() pl_diee7 = [$deathe7, pl_diee8] {};
void() pl_diee8 = [$deathe8, pl_diee9] {};
void() pl_diee9 = [$deathe9, pl_diee9] { player_dead (); };
//--------------------------------------------------------------
// Player Axe Death state A
//--------------------------------------------------------------
void() pl_die_ax1 = [$axdeth1, pl_die_ax2] {};
void() pl_die_ax2 = [$axdeth2, pl_die_ax3] {};
void() pl_die_ax3 = [$axdeth3, pl_die_ax4] {};
void() pl_die_ax4 = [$axdeth4, pl_die_ax5] {};
void() pl_die_ax5 = [$axdeth5, pl_die_ax6] {};
void() pl_die_ax6 = [$axdeth6, pl_die_ax7] {};
void() pl_die_ax7 = [$axdeth7, pl_die_ax8] {};
void() pl_die_ax8 = [$axdeth8, pl_die_ax9] {};
void() pl_die_ax9 = [$axdeth9, pl_die_ax9] { player_dead (); };
//--------------------------------------------------------------
// PlayerDeathThink -- called from prethink when dead
//--------------------------------------------------------------
void() player_death_think =
{
local float forward;
if ((self.flags & FL_ONGROUND))
{
forward = vlen (self.velocity);
forward = forward - 20;
if (forward <= 0)
self.velocity = '0 0 0';
else
self.velocity = forward *
normalize (self.velocity);
}
// wait for all buttons released
if (self.deadflag == DEAD_DEAD)
{
if (self.button2 || self.button1 || self.button0)
return;
self.deadflag = DEAD_RESPAWNABLE;
return;
}
// wait for any button down
if (!self.button2 && !self.button1 && !self.button0)
return;
self.button0 = 0;
self.button1 = 0;
self.button2 = 0;
player_respawn ();
};
//--------------------------------------------------------------
// WaterMove
//--------------------------------------------------------------
void() player_prethink_watermove =
{
if (self.movetype == MOVETYPE_NOCLIP)
{
self.air_finished = time + 120;
return;
}
if (self.health < 0)
return;
if (self.conlevel != WATERLEVEL_EYES)
{
if (self.air_finished < time)
sound (self, CHAN_VOICE, "player/gasp2.wav",
VOL_HIGH, ATTN_NORM);
else if (self.air_finished < time + 9)
sound (self, CHAN_VOICE, "player/gasp1.wav",
VOL_HIGH, ATTN_NORM);
self.air_finished = time + 12;
self.dmg = 2;
}
else if (self.air_finished < time)
{
// drown!
if (self.pain_finished < time)
{
self.dmg = self.dmg + 2;
if (self.dmg > 15)
self.dmg = 10;
self.deathtype = "drowning";
t_damage2 (self, world, world, self.dmg);
self.deathtype = "";
self.pain_finished = time + 1;
}
}
if (self.conlevel == WATERLEVEL_NONE)
{
if (self.flags & FL_INWATER)
{
// play leave water sound
sound (self, CHAN_AUTO, "misc/outwater.wav",
VOL_HIGH, ATTN_NORM);
self.flags &= ~FL_INWATER;
}
return;
}
if (self.contype == CONTENT_LAVA)
{
// do damage
if (self.damage_time < time)
{
if (self.radsuit_finished > time)
self.damage_time = time + 1;
else
self.damage_time = time + 0.2;
self.deathtype = "lava";
t_damage2 (self, world, world,
10 * self.conlevel);
self.deathtype = "";
}
}
else if (self.contype == CONTENT_SLIME)
{
// do damage
if (self.damage_time < time &&
self.radsuit_finished < time)
{
self.damage_time = time + 1;
self.deathtype = "slime";
t_damage2 (self, world, world,
4 * self.conlevel);
self.deathtype = "";
}
}
if (!(self.flags & FL_INWATER))
{
// player enter water sound
if (self.contype == CONTENT_LAVA)
sound (self, CHAN_AUTO, "player/inlava.wav",
VOL_HIGH, ATTN_NORM);
if (self.contype == CONTENT_WATER)
sound (self, CHAN_AUTO, "player/inh2o.wav",
VOL_HIGH, ATTN_NORM);
if (self.contype == CONTENT_SLIME)
sound (self, CHAN_AUTO, "player/slimbrn2.wav",
VOL_HIGH, ATTN_NORM);
self.flags |= FL_INWATER;
self.damage_time = 0;
}
};
//--------------------------------------------------------------
// Called by PlayerPreThink in entrypoints.qc -- CEV
//--------------------------------------------------------------
void() player_prethink =
{
local float do_ladder_physics = FALSE;
// If just spawned in, try to recover previous fog values
// from own client entity, if any
if (clean_up_client_stuff)
fog_set_from_ent (self, self);
self.gravity = self.wantedgravity;
player_prethink_watermove ();
if (self.deadflag >= DEAD_DEAD)
{
// dead, so run the death think -- CEV
player_death_think ();
return;
}
if (self.deadflag == DEAD_DYING)
// dying, so do nothing
return;
// teleporters can force a non-moving pause time
if (time < self.pausetime)
self.velocity = '0 0 0';
if (time > self.attack_finished && self.currentammo == 0
&& self.weapon != IT_AXE)
{
self.weapon = player_best_weapon ();
player_set_current_ammo ();
}
};
//--------------------------------------------------------------
// CheckPowerups -- Check for turning off powerups
//--------------------------------------------------------------
void() player_postthink_powerups =
{
if (self.health <= 0)
return;
// invisibility
if (self.invisible_finished)
{
// sound and screen flash when items starts to run out
if (self.invisible_sound < time)
{
sound (self, CHAN_AUTO, "items/inv3.wav",
VOL_MID, ATTN_IDLE);
self.invisible_sound = time +
((random() * 3) + 1);
}
if (self.invisible_finished < time + 3)
{
if (self.invisible_time == 1)
{
sprint (self, "Ring of Shadows magic is"
" fading\n");
stuffcmd (self, "bf\n");
sound (self, CHAN_AUTO,"items/inv2.wav",
VOL_HIGH, ATTN_NORM);
self.invisible_time = time + 1;
}
if (self.invisible_time < time)
{
self.invisible_time = time + 1;
stuffcmd (self, "bf\n");
}
}
if (self.invisible_finished < time)
{
// just stopped
self.items = self.items - IT_INVISIBILITY;
self.invisible_finished = 0;
self.invisible_time = 0;
}
// use the eyes
if (self.modelindex != modelindex_eyes)
{
self.frame = 0;
self.modelindex = modelindex_eyes;
// self.SendFlags |= PLAYER_NET_FRAME |
// PLAYER_NET_MODEL;
}
}
else
{
// don't use the eyes
if (self.modelindex != modelindex_player)
{
self.modelindex = modelindex_player;
// self.SendFlags |= PLAYER_NET_FRAME |
// PLAYER_NET_MODEL;
}
}
// invincibility
if (self.invincible_finished)
{
// sound and screen flash when items starts to run out
if (self.invincible_finished < time + 3)
{
if (self.invincible_time == 1)
{
sprint (self, "Protection is almost "
"burned out\n");
stuffcmd (self, "bf\n");
sound (self, CHAN_AUTO,
"items/protect2.wav",
VOL_HIGH, ATTN_NORM);
self.invincible_time = time + 1;
}
if (self.invincible_time < time)
{
self.invincible_time = time + 1;
stuffcmd (self, "bf\n");
}
}
if (self.invincible_finished < time)
{
// just stopped
self.items = self.items - IT_INVULNERABILITY;
self.invincible_time = 0;
self.invincible_finished = 0;
}
if (self.invincible_finished > time)
self.sveffects |= EF_DIMLIGHT;
else
self.sveffects &= ~EF_DIMLIGHT;
// self.SendFlags |= PLAYER_NET_EFFECTS;
}
// super damage
if (self.super_damage_finished)
{
// sound and screen flash when items starts to run out
if (self.super_damage_finished < time + 3)
{
if (self.super_time == 1)
{
sprint (self, "Quad Damage is wearing "
"off\n");
stuffcmd (self, "bf\n");
sound (self, CHAN_AUTO,
"items/damage2.wav",
VOL_HIGH, ATTN_NORM);
self.super_time = time + 1;
}
if (self.super_time < time)
{
self.super_time = time + 1;
stuffcmd (self, "bf\n");
}
}
if (self.super_damage_finished < time)
{
// just stopped
self.items = self.items - IT_QUAD;
self.super_damage_finished = 0;
self.super_time = 0;
}
if (self.super_damage_finished > time)
self.sveffects |= EF_DIMLIGHT;
else
self.sveffects &= ~EF_DIMLIGHT;
// self.SendFlags |= PLAYER_NET_EFFECTS;
}
// suit
if (self.radsuit_finished)
{
// don't drown
self.air_finished = time + 12;
// sound and screen flash when items starts to run out
if (self.radsuit_finished < time + 3)
{
if (self.rad_time == 1)
{
sprint (self, "Air supply in Biosuit "
"expiring\n");
stuffcmd (self, "bf\n");
sound (self, CHAN_AUTO,
"items/suit2.wav",
VOL_HIGH, ATTN_NORM);
self.rad_time = time + 1;
}
if (self.rad_time < time)
{
self.rad_time = time + 1;
stuffcmd (self, "bf\n");
}
}
if (self.radsuit_finished < time)
{
// just stopped
self.items = self.items - IT_SUIT;
self.rad_time = 0;
self.radsuit_finished = 0;
}
}
};
//--------------------------------------------------------------
// Called by PlayerPostThink in entrypoints.qc -- CEV
//--------------------------------------------------------------
void() player_postthink =
{
// load up the sendflags -- CEV
// if (self.oldorigin != self.origin)
// self.SendFlags |= PLAYER_NET_ORIGIN;
self.SendFlags = PLAYER_NET_FRAME | PLAYER_NET_MODEL |
PLAYER_NET_ORIGIN | PLAYER_NET_ANGLES |
PLAYER_NET_VELOCITY | PLAYER_NET_FLAGS |
PLAYER_NET_TIMERS | PLAYER_NET_EFFECTS |
PLAYER_NET_SOLID | PLAYER_NET_PUNCHANGLE;
if (self.view_ofs == '0 0 0')
// intermission or finale
return;
if (self.deadflag)
return;
if (self.pm_flags & PMF_ONGROUND)
{
if (self.pm_flags & PMF_CROUCHED)
{
// TODO CEV
local vector l = getlight (self.origin);
/*
l = normalize (l);
*/
/*
dprint (sprintf("player_postthink: light %v, "
"level %g\n", l, vlen(l)));
*/
}
}
// next block was in W_WeaponFrame -- CEV
if (time >= self.attack_finished)
{
if (self.impulse)
player_impulse ();
if (input_buttons & PM_BTN_ATTACK)
{
player_superdamage_sound ();
player_attack ();
}
}
// check to see if player landed and play landing sound
if (self.jump_flag < -300 && self.health > 0)
{
if (self.contype == CONTENT_WATER)
sound (self, CHAN_BODY, "player/h2ojump.wav",
VOL_HIGH, ATTN_NORM);
else if (self.jump_flag < -650)
{
self.deathtype = "falling";
t_damage2 (self, world, world, 5);
self.deathtype = "";
sound (self, CHAN_VOICE, "player/land2.wav",
VOL_HIGH, ATTN_NORM);
}
else
sound (self, CHAN_VOICE, "player/land.wav",
VOL_HIGH, ATTN_NORM);
self.jump_flag = 0;
}
// dumptruck_ds -- self replaces item_megahealth_rot in items.qc
if (self.health > self.max_health)
{
if (self.megahealth_rottime < time)
{
self.megahealth_rottime = time + 1;
self.health = self.health - 1;
}
else if (self.health <= 100)
{
// thanks ydrol!!!
self.items = self.items -
(self.items & IT_SUPERHEALTH);
}
}
player_postthink_powerups ();
};
//==============================================================
// Interaction
//==============================================================
//--------------------------------------------------------------
// player_pain
//--------------------------------------------------------------
void(entity attacker, float damage) player_pain =
{
if (self.weaponframe)
return;
if (self.invisible_finished > time)
// eyes don't have pain frames
return;
if (self.weapon == IT_AXE)
pl_axpain1 ();
else
pl_pain1 ();
};
//--------------------------------------------------------------
// gib_player
//--------------------------------------------------------------
void(vector dir) player_destroy_gib =
{
throw_gib_head_player (self, dir, self.health);
throw_gib_1 (self, dir, self.health);
throw_gib_2 (self, dir, self.health);
throw_gib_3 (self, dir, self.health);
self.deadflag = DEAD_DEAD;
if (damage_attacker.classname == "teledeath")
sound (self, CHAN_VOICE, "player/teledth1.wav",
VOL_HIGH, ATTN_NONE);
else if (damage_attacker.classname == "teledeath2")
sound (self, CHAN_VOICE, "player/teledth1.wav",
VOL_HIGH, ATTN_NONE);
else
if (random() < 0.5)
sound (self, CHAN_VOICE, "player/gib.wav",
VOL_HIGH, ATTN_NONE);
else
sound (self, CHAN_VOICE, "player/udeath.wav",
VOL_HIGH, ATTN_NONE);
};
//--------------------------------------------------------------
// PlayerDie
//--------------------------------------------------------------
void(vector dir) player_destroy =
{
local float i;
// 1998-07-23 Palette shift when player dies with quad/pentagram
// fix by Maddes start
// self.items = self.items - (self.items & IT_INVISIBILITY);
self.items = self.items - (self.items &
(IT_INVISIBILITY | IT_INVULNERABILITY |
IT_SUIT | IT_QUAD));
// 1998-07-23 Palette shift when player dies with quad/pentagram
// fix by Maddes end
// don't die as eyes
// self.invisible_finished = 0;
self.invincible_finished = 0;
self.super_damage_finished = 0;
self.radsuit_finished = 0;
// 1998-07-23 Glowing corpse of players which had quad/pentagram
// until respawn fix by Maddes
self.effects = 0;
self.sveffects = 0;
// don't use eyes
self.modelindex = modelindex_player;
if (deathmatch || coop)
item_backpack_drop (self);
self.weaponmodel = "";
self.view_ofs = '0 0 -8';
self.deadflag = DEAD_DYING;
self.solid = SOLID_NOT;
self.flags = self.flags - (self.flags & FL_ONGROUND);
self.movetype = MOVETYPE_TOSS;
if (self.velocity_z < 10)
self.velocity_z = self.velocity_z + random() * 300;
if (self.health < -40)
{
player_destroy_gib (dir);
return;
}
player_death_sound ();
self.angles_x = 0;
self.angles_z = 0;
if (self.weapon == IT_AXE)
{
pl_die_ax1 ();
return;
}
i = cvar ("temp1");
if (!i)
i = 1 + floor (random() * 6);
if (i == 1)
pl_diea1 ();
else if (i == 2)
pl_dieb1 ();
else if (i == 3)
pl_diec1 ();
else if (i == 4)
pl_died1 ();
else
pl_diee1 ();
};
#endif
#if defined(CSQC) || defined(SSQC)
//--------------------------------------------------------------
// by: Philip Martin aka: Kryten
// When on top of monsters or players you slide. This is a QuakeC
// problem. The function below fixes that problem.
// based on code given to Kryten by: Michael Turitzin (MaNiAc)
//--------------------------------------------------------------
void() player_touch =
{
// 1998-09-16 Sliding/not-jumping on monsters/boxes/players
// fix by Maddes/Kryten start
// can cause problems for monsters on top of a player,
// so only players
if (other.classtype != CT_PLAYER)
return;
if (other.health <= 0)
return;
if ((!(other.flags & FL_ONGROUND)) &&
((other.absmin_z >= self.absmax_z - 2)))
{
other.flags = other.flags + FL_ONGROUND;
}
// you can add other stuff like pushable players/monsters here
// 1998-09-16 Sliding/not-jumping on monsters/boxes/players
// fix by Maddes/Kryten end
};
#endif
//==============================================================
// Initialization
//==============================================================
#ifdef SSQC
//--------------------------------------------------------------
// SelectSpawnPoint -- Returns the entity to spawn at
//--------------------------------------------------------------
entity() player_init_selectspawnpoint =
{
local entity spot, thing;
local float pcount;
// testinfo_player_start is only found in regioned levels
spot = findfloat (world, classtype, CT_INFO_TESTPLAYERSTART);
if (spot)
return spot;
// choose a info_player_deathmatch point
if (coop)
{
lastspawn = findfloat (lastspawn, classtype,
CT_INFO_PLAYER_COOP);
if (lastspawn == world)
lastspawn = findfloat (lastspawn, classtype,
CT_INFO_PLAYER_START);
if (lastspawn != world)
return lastspawn;
}
else if (deathmatch)
{
spot = lastspawn;
// TODO CEV this loops infinitely if no
// info_player_deathmatch
while (1)
{
spot = findfloat (spot, classtype,
CT_INFO_PLAYER_DEATHMATCH);
if (spot != world)
{
if (spot == lastspawn)
return lastspawn;
pcount = 0;
thing = findradius (spot.origin, 32);
while (thing)
{
if (thing.classtype==CT_PLAYER)
pcount = pcount + 1;
thing = thing.chain;
}
if (pcount == 0)
{
lastspawn = spot;
return spot;
}
}
}
}
if (serverflags)
{
// return with a rune to start
spot = findfloat (world, classtype,
CT_INFO_PLAYER_START2);
if (spot)
return spot;
}
spot = findfloat (world, classtype, CT_INFO_PLAYER_START);
if (!spot)
error ("player_init_selectspawnpoint: "
"no info_player_start on level");
return spot;
};
//--------------------------------------------------------------
void() player_init_level_parms =
{
// Reset the player's inventory if they returned to the
// start map with a rune, or if the mapper set the
// "reset_items" field of worldspawn to a non-zero value.
// (The old "reset_items" check, which this replaces,
// had a comment from dumptruck_ds thanking Spike.) -- iw
if ((serverflags != 0 && world.model == "maps/start.bsp") ||
world.reset_items != 0)
{
SetNewParms ();
}
self.items = parm1;
self.health = parm2;
self.armorvalue = parm3;
self.ammo_shells = parm4;
self.ammo_nails = parm5;
self.ammo_rockets = parm6;
self.ammo_cells = parm7;
self.weapon = parm8;
self.armortype = parm9 * 0.01;
};
//--------------------------------------------------------------
// respawn -- called by ClientKill and DeadThink
//--------------------------------------------------------------
void() player_respawn =
{
if (coop)
{
// make a copy of the dead body for appearances sake
CopyToBodyQue (self);
// get the spawn parms as they were at level start
setspawnparms (self);
// respawn
player_init (self);
}
else if (deathmatch)
{
// make a copy of the dead body for appearances sake
CopyToBodyQue (self);
// set default spawn parms
SetNewParms ();
// respawn
player_init (self);
}
else
{
// restart the entire server
localcmd ("restart\n");
}
};
#endif
#if defined(CSQC) || defined(SSQC)
//--------------------------------------------------------------
// most of this was previously in PutClientInServer -- CEV
//--------------------------------------------------------------
void(entity e) player_init =
{
#ifdef SSQC
local entity spot = player_init_selectspawnpoint ();
#endif
// block common to both client & server -- CEV
e.classname = "player";
e.classtype = CT_PLAYER;
e.solid = SOLID_SLIDEBOX;
e.movetype = MOVETYPE_WALK;
e.touch = player_touch;
#ifdef CSQC
e.customphysics = sub_null;
e.drawmask = DRAWMASK_NORMAL;
e.predraw = player_predraw;
e.preframe = player_prediction_preframe;
e.postframe = player_prediction_postframe;
e.removefunc = player_remove;
e.view_ofs = PM_STAND_VIEWOFS;
e.velocity = '0 0 0';
setmodelindex (e, e.modelindex);
if (e.pm_flags & PMF_CROUCHED)
setsize (e, PM_CROUCH_MIN, PM_CROUCH_MAX);
else
setsize (e, PM_STAND_MIN, PM_STAND_MAX);
setorigin (e, e.origin);
#endif
#ifdef SSQC
e.flags = FL_CLIENT;
e.effects = 0;
e.gravity = 0;
e.wantedgravity = 0;
e.health = PLAYER_HEALTH;
e.takedamage = DAMAGE_AIM;
e.show_hostile = 0;
e.max_health = 100;
e.air_finished = time + 12;
// initial water damage
e.dmg = 2;
e.super_damage_finished = 0;
e.radsuit_finished = 0;
e.invisible_finished = 0;
e.invincible_finished = 0;
e.invincible_time = 0;
e.deathtype = "";
// support for item_key_custom -- iw
e.customkeys = 0;
// Setup cutscene stuff. Legacy code from Zerstorer.
// -- dumptruck_ds
e.script_count = 2;
e.script_delay = 1;
e.script_time = 0;
player_init_level_parms ();
player_set_current_ammo ();
e.attack_finished = time;
e.th_pain = player_pain;
e.destroy = player_destroy;
e.contentstransition = base_monster_contentstransition;
e.SendEntity = player_netsend;
e.deadflag = DEAD_NO;
// pausetime is set by teleporters to keep the player
// from moving for a while
e.pausetime = 0;
e.origin = spot.origin + '0 0 1';
e.angles = spot.angles;
// turn this way immediately
e.fixangle = TRUE;
// fog control.
// Looks if there's any fog values set at the current
// spawn point. If not, looks for those in worldspawn instead
if (spot.fog_density)
fog_save (e, spot.fog_density, spot.fog_color);
else if (world.fog_density)
fog_save (e, world.fog_density, world.fog_color);
if (spot.skyfog_density)
skyfog_save (e, spot.skyfog_density);
else if (world.skyfog_density)
skyfog_save (e, world.skyfog_density);
// decreased on subsequent frames, used to start some
// fog-related stuff
clean_up_client_stuff = 2;
// oh, this is a hack!
setmodel (e, "progs/eyes.mdl");
modelindex_eyes = e.modelindex;
// Drake -- dumptruck_ds
setmodel (e, "progs/s_null.spr");
// Drake -- dumptruck_ds
// setmodel (e, "progs/null_256.spr");
mindex_inviso = e.modelindex;
setmodel (e, "progs/player.mdl");
modelindex_player = e.modelindex;
setsize (e, PM_STAND_MIN, PM_STAND_MAX);
e.view_ofs = PM_STAND_VIEWOFS;
// Mod - Xian (May.20.97)
// Bug where player would have velocity from their last kill
e.velocity = '0 0 0';
// 1998-07-21 Player moves after respawn fix by Xian
// full send the new entity -- CEV
e.SendFlags = 0xffffff;
// pl_stand1 needs 'self' to be 'e' -- CEV
if (self == e)
pl_stand1 ();
else
sub_runvoidas (e, pl_stand1);
if (deathmatch || coop)
{
makevectors (e.angles);
spawn_tfog (e.origin + v_forward * 20);
}
spawn_tdeath (e.origin, e);
#endif
};
#endif
#ifdef SSQC
//--------------------------------------------------------------
strip void() player =
{
player_init (self);
};
#endif
// };
//=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
// Scenic Dead Monster Patch stuff here from DeadStuff mod -- dumptruck_ds
//=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
#ifdef SSQC
/*QUAKED gib_head_player (0 0.5 0.8) (-16 -16 0) (16 16 56) SOLID X X X X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
{
model ("progs/h_player.mdl");
}*/
//----------------------------------------------------------------------
// class gib_head_player: base_gib_head
// {
//--------------------------------------------------------------
// ThrowHead
//--------------------------------------------------------------
void(entity act, vector dir, float dmg) throw_gib_head_player =
{
base_gib_head_throw (act, dir, dmg, gib_head_player_init);
};
//--------------------------------------------------------------
void(entity e) gib_head_player_init =
{
// don't reset class if passed a client entity -- CEV
if (!(e.flags & FL_CLIENT))
{
e.classname = "gib_head_player";
e.classtype = CT_GORE_HEAD_PLAYER;
}
// gib_init interprets spawnflags and will set .solid -- CEV
base_gib_head_init (e);
if (e.mdl_head != "")
{
precache_model (e.mdl_head);
setmodel (e, e.mdl_head);
e.SendFlags |= PLAYER_NET_MODEL | PLAYER_NET_SOLID |
PLAYER_NET_SIZE;
}
else
{
precache_model ("progs/h_player.mdl");
setmodel (e, "progs/h_player.mdl");
if (e.solid == SOLID_BBOX)
setsize (e, PLAYER_HEAD_MINS, PLAYER_HEAD_MAXS);
else if (e.solid == SOLID_TRIGGER)
setsize (e, '-16 -16 0', '16 16 56');
e.SendFlags |= PLAYER_NET_MODEL | PLAYER_NET_SOLID |
PLAYER_NET_SIZE;
}
e.frame = 0;
};
//--------------------------------------------------------------
void() gib_head_player =
{
// new spawnflags for all entities -- iw
if (SUB_Inhibit())
return;
gib_head_player_init (self);
};
// };
#endif
#ifdef SSQC
/*QUAKED player_dead_axe (0 0.5 0.8) (-16 -16 -24) (16 16 32) SOLID X X X X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
{
model ({"path":"progs/player.mdl","frame":49});
}
*/
void() player_dead_axe =
{
// new spawnflags for all entities -- iw
if (SUB_Inhibit())
return;
precache_model ("progs/player.mdl");
setmodel (self, "progs/player.mdl");
self.frame = $axdeth9;
if (self.spawnflags & 1)
{
self.solid = SOLID_BBOX;
setsize (self, PLAYER_CORPSE_AX_MINS, PLAYER_CORPSE_AX_MAXS);
}
else
{
self.solid = SOLID_NOT;
}
};
#endif
#ifdef SSQC
/*QUAKED player_dead_face_down (0 0.5 0.8) (-16 -16 -24) (16 16 32) SOLID X X X X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
{
model ({"path":"progs/player.mdl","frame":84});
}
*/
void() player_dead_face_down =
{
// new spawnflags for all entities -- iw
if (SUB_Inhibit())
return;
precache_model ("progs/player.mdl");
setmodel (self, "progs/player.mdl");
self.frame = $deathc14;
if (self.spawnflags & 1)
{
self.solid = SOLID_BBOX;
setsize (self, PLAYER_CORPSE_C_MINS, PLAYER_CORPSE_C_MAXS);
}
else
{
self.solid = SOLID_NOT;
}
};
#endif
#ifdef SSQC
/*QUAKED player_dead_on_side (0 0.5 0.8) (-16 -16 -24) (16 16 32) SOLID X X X X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
{
model ({"path":"progs/player.mdl","frame":102});
}
*/
void() player_dead_on_side =
{
// new spawnflags for all entities -- iw
if (SUB_Inhibit())
return;
precache_model ("progs/player.mdl");
setmodel (self, "progs/player.mdl");
self.frame = $deathe9;
if (self.spawnflags & 1)
{
self.solid = SOLID_BBOX;
setsize (self, PLAYER_CORPSE_E_MINS, PLAYER_CORPSE_E_MAXS);
}
else
{
self.solid = SOLID_NOT;
}
};
#endif
//======================================================================
// END Scenic Dead Monster Patch stuff here from DeadStuff mod -- dumptruck_ds
//======================================================================
Return to the top of this page or return to the overview of this repo.
Log playerclient.qc
Date | Commit Message | Author | + | - |
---|---|---|---|---|
2024-11-20 | pmove refactor into prepoc macros, view bobbing | cev | +335 | -150 |
2024-09-17 | Ice, improved stairs, other movement changes | cev | +22 | -1 |
2024-07-17 | pmove changes, smooth crouching | cev | +96 | -71 |
2024-07-03 | pmove changes and fixes, improved climbing | cev | +34 | -40 |
2024-06-26 | pmove fixes, GL now a faux tribolt, wall climbing | cev | +56 | -265 |
2024-06-15 | Major update, committing as-is, will have bugs | cev | +848 | -211 |
2024-04-12 | Moveable gibs, heads, some bugfixes | cev | +110 | -111 |
2024-04-08 | Registered monsters, projectile bugfixes | cev | +5 | |
2024-04-05 | Player footsteps, shareware monsters, misc? | cev | +209 | -37 |
2024-03-24 | 2nd pass refactor, rework QC class structure | cev | +1051 | -994 |
2024-02-27 | Bullet projectile, pmove changes, misc | cev | +52 | -7 |
2024-02-18 | Client/player, projectiles, entrypoints refactor | cev | +2571 |
Return to the top of this page or return to the overview of this repo.