2009-04-14 21:39:15 +00:00
|
|
|
/*
|
|
|
|
this file handles the local player, and marshalling between the different sorts of player models.
|
2008-10-16 22:00:54 +00:00
|
|
|
|
2009-04-14 21:39:15 +00:00
|
|
|
RefreshPlayer: Called from the engine each time a player (ent with player.mdl) is about to be drawn
|
|
|
|
ParsePlayer: Called from CSQC_Ent_Parse for csqc protocol ents
|
|
|
|
*/
|
2008-10-16 22:00:54 +00:00
|
|
|
|
2009-04-14 21:39:15 +00:00
|
|
|
#include "playerframes.inc"
|
2008-10-16 22:00:54 +00:00
|
|
|
|
2009-04-14 21:39:15 +00:00
|
|
|
static void() RemovePlayer;
|
2008-10-16 22:00:54 +00:00
|
|
|
|
2009-04-14 21:39:15 +00:00
|
|
|
enum
|
2008-10-16 22:00:54 +00:00
|
|
|
{
|
2009-04-14 21:39:15 +00:00
|
|
|
MF_BAD,
|
|
|
|
#ifdef MD3PMODELS
|
|
|
|
MF_QUAKE3,
|
|
|
|
#endif
|
|
|
|
#ifdef HLPMODELS
|
|
|
|
MF_HLPM,
|
|
|
|
#endif
|
|
|
|
MF_QUAKE
|
2008-10-16 22:00:54 +00:00
|
|
|
};
|
|
|
|
|
2009-04-14 21:39:15 +00:00
|
|
|
#ifdef NOEXTENSIONS //FRIK_FILE is an extension still, unfortunatly. but hey, the model code depends upon it more
|
|
|
|
#define strunzone(s) //so really we can get away with this for this module
|
|
|
|
#define strzone(s) ""
|
|
|
|
#endif
|
2008-10-16 22:00:54 +00:00
|
|
|
|
2009-04-14 21:39:15 +00:00
|
|
|
static void() Player_Interpolate =
|
|
|
|
{ //do some frame interpolation.
|
|
|
|
if (self.entnum == player_localentnum)
|
2008-10-16 22:00:54 +00:00
|
|
|
{
|
2009-04-19 01:15:18 +00:00
|
|
|
Pred_UpdateLocalMovement(self);
|
2008-10-16 22:00:54 +00:00
|
|
|
}
|
|
|
|
|
2009-04-14 21:39:15 +00:00
|
|
|
switch(self.modelstyle)
|
2008-10-16 22:00:54 +00:00
|
|
|
{
|
2009-04-14 21:39:15 +00:00
|
|
|
#ifdef MD3PMODELS
|
|
|
|
case MF_QUAKE3:
|
|
|
|
Anim_Draw();
|
|
|
|
break;
|
|
|
|
#endif
|
|
|
|
#ifdef HLPMODELS
|
|
|
|
case MF_HLPM:
|
|
|
|
HLPM_Draw();
|
|
|
|
break;
|
|
|
|
#endif
|
|
|
|
default:
|
|
|
|
if (self.lerptime)
|
|
|
|
self.lerpfrac = 1-(time-self.lerptime)*10;
|
2008-10-16 22:00:54 +00:00
|
|
|
|
2009-04-14 21:39:15 +00:00
|
|
|
if (chasecam || self.entnum != player_localentnum)
|
|
|
|
self.renderflags = 0;
|
|
|
|
else
|
|
|
|
self.renderflags = RF_EXTERNALMODEL;
|
|
|
|
|
|
|
|
#ifdef POWERUP_SHELLS
|
|
|
|
if (!isdp)
|
2008-10-16 22:00:54 +00:00
|
|
|
{
|
2009-04-14 21:39:15 +00:00
|
|
|
if (self.sveffects & SVE_INVIS)
|
|
|
|
self.forceshader = shaderforname("powerups/invisibility");
|
|
|
|
else
|
|
|
|
self.forceshader = 0;
|
|
|
|
|
|
|
|
self.fatness = 0;
|
|
|
|
|
|
|
|
if (!(self.sveffects & SVE_INVIS))
|
|
|
|
{
|
|
|
|
if (self.sveffects & SVE_QUAD)
|
|
|
|
{
|
|
|
|
addentity(self);
|
|
|
|
|
|
|
|
self.fatness = -2;
|
|
|
|
self.forceshader = shaderforname("powerups/quad");
|
|
|
|
}
|
|
|
|
if (self.sveffects & SVE_GOD)
|
|
|
|
{
|
|
|
|
addentity(self);
|
|
|
|
|
|
|
|
self.fatness = -2.8;
|
|
|
|
self.forceshader = shaderforname("powerups/regen");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
2008-10-16 22:00:54 +00:00
|
|
|
}
|
2009-04-14 21:39:15 +00:00
|
|
|
#endif
|
|
|
|
if (self.sveffects & SVE_INVIS)
|
|
|
|
setmodel(self, "progs/eyes.mdl");
|
|
|
|
else
|
|
|
|
setmodel(self, "progs/player.mdl");
|
|
|
|
break;
|
2008-10-16 22:00:54 +00:00
|
|
|
}
|
2009-04-14 21:39:15 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
static void(float g) Player_SetLocalInfoGender =
|
|
|
|
{
|
|
|
|
if (player_local == self)
|
2008-10-16 22:00:54 +00:00
|
|
|
{
|
2009-04-19 01:15:18 +00:00
|
|
|
//if it was forced, don't lie to everyone else.
|
|
|
|
if (cvar_string("cg_forceskin") != "")
|
|
|
|
return;
|
|
|
|
|
2009-04-14 21:39:15 +00:00
|
|
|
switch(g)
|
2008-10-16 22:00:54 +00:00
|
|
|
{
|
2009-04-14 21:39:15 +00:00
|
|
|
case GENDER_FEMALE:
|
|
|
|
localcmd("setinfo s f\n");
|
|
|
|
break;
|
|
|
|
case GENDER_MALE:
|
|
|
|
localcmd("setinfo s \"\"\n");
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
case GENDER_NEUTER:
|
|
|
|
localcmd("setinfo s n\n");
|
2008-10-16 22:00:54 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
2009-04-14 21:39:15 +00:00
|
|
|
}
|
2008-10-16 22:00:54 +00:00
|
|
|
|
2009-04-14 21:39:15 +00:00
|
|
|
static void() Player_SetQ1Model =
|
|
|
|
{
|
|
|
|
self.modelstyle = MF_QUAKE;
|
2008-10-16 22:00:54 +00:00
|
|
|
|
2009-04-14 21:39:15 +00:00
|
|
|
Player_SetLocalInfoGender(GENDER_MALE);
|
|
|
|
}
|
2008-10-16 22:00:54 +00:00
|
|
|
|
2009-04-14 21:39:15 +00:00
|
|
|
#ifdef MD3PMODELS
|
|
|
|
static void(string skinname) Player_SetQ3Model =
|
|
|
|
{
|
|
|
|
if (!Anim_SetModel(skinname))
|
|
|
|
{
|
|
|
|
Anim_UnsetModel();
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
Player_SetLocalInfoGender(Anim_GetGender());
|
|
|
|
self.modelstyle = MF_QUAKE3;
|
2008-10-16 22:00:54 +00:00
|
|
|
};
|
2009-04-14 21:39:15 +00:00
|
|
|
#endif
|
2008-10-16 22:00:54 +00:00
|
|
|
|
2009-04-14 21:39:15 +00:00
|
|
|
#ifdef HLPMODELS
|
|
|
|
static void(string skinname) Player_SetHLModel =
|
2008-10-16 22:00:54 +00:00
|
|
|
{
|
2009-04-14 21:39:15 +00:00
|
|
|
if (!HLPM_SetModel(skinname))
|
2008-10-16 22:00:54 +00:00
|
|
|
{
|
2009-04-14 21:39:15 +00:00
|
|
|
HLPM_UnsetModel();
|
|
|
|
return;
|
2008-10-16 22:00:54 +00:00
|
|
|
}
|
2009-04-14 21:39:15 +00:00
|
|
|
Player_SetLocalInfoGender(GENDER_MALE);
|
|
|
|
self.modelstyle = MF_HLPM;
|
2008-10-16 22:00:54 +00:00
|
|
|
};
|
2009-04-14 21:39:15 +00:00
|
|
|
#endif
|
2008-10-16 22:00:54 +00:00
|
|
|
|
2009-04-14 21:39:15 +00:00
|
|
|
static void() Player_UnsetModel =
|
|
|
|
{
|
|
|
|
switch(self.modelstyle)
|
2008-10-16 22:00:54 +00:00
|
|
|
{
|
2009-04-14 21:39:15 +00:00
|
|
|
#ifdef MD3PMODELS
|
|
|
|
case MF_QUAKE3:
|
|
|
|
Anim_UnsetModel();
|
|
|
|
break;
|
|
|
|
#endif
|
|
|
|
#ifdef HLPMODELS
|
|
|
|
case MF_HLPM:
|
|
|
|
HLPM_UnsetModel();
|
|
|
|
break;
|
|
|
|
#endif
|
|
|
|
default:
|
|
|
|
//nothing to do
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
self.modelstyle = MF_BAD;
|
|
|
|
setmodel(self, "");
|
|
|
|
};
|
2008-10-16 22:00:54 +00:00
|
|
|
|
2009-04-14 21:39:15 +00:00
|
|
|
static entity() Player_DupModel =
|
|
|
|
{
|
|
|
|
local entity e;
|
2008-10-16 22:00:54 +00:00
|
|
|
|
2009-04-14 21:39:15 +00:00
|
|
|
switch(self.modelstyle)
|
|
|
|
{
|
|
|
|
#ifdef MD3PMODELS
|
|
|
|
case MF_QUAKE3:
|
|
|
|
e = Anim_DupModel();
|
|
|
|
break;
|
|
|
|
#endif
|
|
|
|
#ifdef HLPMODELS
|
|
|
|
case MF_HLPM:
|
|
|
|
e = HLPM_DupModel();
|
|
|
|
break;
|
|
|
|
#endif
|
|
|
|
default:
|
|
|
|
e = spawn();
|
|
|
|
break;
|
2008-10-16 22:00:54 +00:00
|
|
|
}
|
2009-04-14 21:39:15 +00:00
|
|
|
e.modelstyle = self.modelstyle;
|
|
|
|
return e;
|
2008-10-16 22:00:54 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
.float starttime;
|
|
|
|
.float oldframe;
|
2009-04-14 21:39:15 +00:00
|
|
|
static void() bodythink =
|
2008-10-16 22:00:54 +00:00
|
|
|
{
|
|
|
|
local float final;
|
|
|
|
if (self.frame >= $axdeth1 && self.frame <= $axdeth9)
|
|
|
|
final = $axdeth9;
|
|
|
|
else if (self.frame >= $deatha1 && self.frame <= $deatha11)
|
|
|
|
final = $deatha11;
|
|
|
|
else if (self.frame >= $deathb1 && self.frame <= $deathb9)
|
|
|
|
final = $deathb9;
|
|
|
|
else if (self.frame >= $deathc1 && self.frame <= $deathc15)
|
|
|
|
final = $deathc15;
|
|
|
|
else if (self.frame >= $deathd1 && self.frame <= $deathd9)
|
|
|
|
final = $deathd9;
|
|
|
|
else if (self.frame >= $deathe1 && self.frame <= $deathe9)
|
|
|
|
final = $deathe9;
|
|
|
|
|
|
|
|
self.frame = self.frame+1;
|
|
|
|
|
|
|
|
if (self.frame > final)
|
|
|
|
self.frame = final;
|
|
|
|
|
|
|
|
self.nextthink = time + 0.1;
|
|
|
|
};
|
2009-04-14 21:39:15 +00:00
|
|
|
static void() DeadBodyPredraw =
|
2008-10-16 22:00:54 +00:00
|
|
|
{
|
|
|
|
float ftime;
|
|
|
|
ftime = time - self.starttime;
|
|
|
|
|
|
|
|
if (self.removetime < time)
|
|
|
|
{
|
2009-04-14 21:39:15 +00:00
|
|
|
Player_UnsetModel();
|
2008-10-16 22:00:54 +00:00
|
|
|
remove(self);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2009-04-14 21:39:15 +00:00
|
|
|
Movetype_Bounce();
|
2008-10-16 22:00:54 +00:00
|
|
|
|
|
|
|
Player_Interpolate();
|
|
|
|
self.origin_z -= ftime*0.5;
|
|
|
|
};
|
|
|
|
|
2009-04-14 21:39:15 +00:00
|
|
|
static void() JustRessed =
|
2008-10-16 22:00:54 +00:00
|
|
|
{
|
|
|
|
local entity e;
|
|
|
|
|
2009-04-14 21:39:15 +00:00
|
|
|
e = Player_DupModel();
|
2008-10-16 22:00:54 +00:00
|
|
|
e.frame = self.oldframe; //and stay dead!
|
|
|
|
e.frame2 = self.oldframe; //and stay dead!
|
|
|
|
setmodel(e, "progs/player.mdl");
|
|
|
|
e.origin = self.lastorg;
|
|
|
|
e.velocity = self.lastvel;
|
|
|
|
e.predraw = DeadBodyPredraw;
|
|
|
|
e.removetime = time + 30;
|
2009-04-14 21:39:15 +00:00
|
|
|
e.lerptime = time;
|
2008-10-16 22:00:54 +00:00
|
|
|
|
|
|
|
e.gibbable = GIB_PLAYER;
|
|
|
|
e.solid = SOLID_TRIGGER;
|
|
|
|
|
|
|
|
e.classname = "deadbody";
|
|
|
|
e.movetype = MOVETYPE_TOSS;
|
|
|
|
|
|
|
|
e.starttime = time;
|
|
|
|
e.nextthink = time + 0.1;
|
|
|
|
e.think = bodythink;
|
|
|
|
e.drawmask = self.drawmask;
|
|
|
|
};
|
|
|
|
|
2009-04-14 21:39:15 +00:00
|
|
|
static void() RemovePlayer =
|
2008-10-16 22:00:54 +00:00
|
|
|
{
|
2009-04-14 21:39:15 +00:00
|
|
|
if (player_local == self)
|
|
|
|
player_local = world;
|
|
|
|
|
2008-10-16 22:00:54 +00:00
|
|
|
if (self.haddied)
|
|
|
|
{
|
|
|
|
JustRessed();
|
|
|
|
self.haddied = false;
|
|
|
|
}
|
|
|
|
|
2009-04-14 21:39:15 +00:00
|
|
|
Player_UnsetModel();
|
|
|
|
|
2008-10-16 22:00:54 +00:00
|
|
|
strunzone(self.oldskin);
|
|
|
|
self.oldskin = "";
|
|
|
|
|
|
|
|
self.predraw = __NULL__;
|
|
|
|
};
|
|
|
|
|
|
|
|
void(float isnew) RefreshPlayer =
|
|
|
|
{
|
|
|
|
local string newskin;
|
|
|
|
|
|
|
|
self.predraw = Player_Interpolate;
|
|
|
|
|
|
|
|
if (isnew)
|
|
|
|
self.haddied = false;
|
|
|
|
|
|
|
|
//if its not new and they're not dead, but they were before..
|
|
|
|
if (self.frame < $axdeth1 || self.frame > $deathe9)
|
|
|
|
{
|
|
|
|
if (self.haddied)
|
|
|
|
{
|
|
|
|
JustRessed();
|
|
|
|
self.haddied = false;
|
|
|
|
}
|
2009-04-19 01:15:18 +00:00
|
|
|
self.solid = SOLID_BBOX;
|
2008-10-16 22:00:54 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
self.haddied = true;
|
2009-04-19 01:15:18 +00:00
|
|
|
self.solid = SOLID_NOT;
|
2008-10-16 22:00:54 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
self.lastorg = self.origin;
|
|
|
|
self.lastvel = self.velocity;
|
|
|
|
|
|
|
|
if (isnew)
|
|
|
|
{
|
|
|
|
if (self.entnum == player_localentnum)
|
|
|
|
{
|
|
|
|
player_local = self;
|
|
|
|
}
|
|
|
|
|
2009-04-14 21:39:15 +00:00
|
|
|
self.modelstyle = MF_BAD;
|
|
|
|
|
2008-10-16 22:00:54 +00:00
|
|
|
self.oldskin = strzone("");
|
|
|
|
self.drawmask = MASK_NORMAL;
|
|
|
|
|
|
|
|
self.removefunc = RemovePlayer;
|
|
|
|
}
|
|
|
|
|
2009-04-14 21:39:15 +00:00
|
|
|
if (self.sveffects & SVE_INVIS)
|
2008-10-16 22:00:54 +00:00
|
|
|
{
|
2009-04-14 21:39:15 +00:00
|
|
|
if (self.modelstyle != MF_QUAKE)
|
|
|
|
{
|
|
|
|
Player_UnsetModel();
|
|
|
|
Player_SetQ1Model(); //every model uses eyes
|
2008-10-16 22:00:54 +00:00
|
|
|
}
|
2009-04-14 21:39:15 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
newskin = cvar_string("cg_forceskin");
|
|
|
|
if (newskin == "")
|
|
|
|
newskin = getplayerkeyvalue(self.entnum-1, "model");
|
|
|
|
if (newskin == "")
|
|
|
|
newskin = getplayerkeyvalue(self.entnum-1, "skin");
|
|
|
|
if (newskin != self.oldskin)
|
2008-10-16 22:00:54 +00:00
|
|
|
{
|
2009-04-14 21:39:15 +00:00
|
|
|
Player_UnsetModel();
|
|
|
|
|
|
|
|
strunzone(self.oldskin);
|
|
|
|
self.oldskin = strzone(newskin);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (self.modelstyle == MF_BAD)
|
|
|
|
{
|
|
|
|
newskin = self.oldskin;
|
|
|
|
|
|
|
|
#ifdef MD3PMODELS
|
|
|
|
if (self.modelstyle == MF_BAD && newskin != "")
|
|
|
|
Player_SetHLModel(newskin);
|
|
|
|
#endif
|
|
|
|
#ifdef HLPMODELS
|
|
|
|
if (self.modelstyle == MF_BAD && newskin != "")
|
|
|
|
Player_SetQ3Model(newskin);
|
|
|
|
#endif
|
|
|
|
if (self.modelstyle == MF_BAD)
|
|
|
|
Player_SetQ1Model();
|
2008-10-16 22:00:54 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
setsize(self, VEC_HULL_MIN, VEC_HULL_MAX);
|
|
|
|
|
|
|
|
self.oldframe = self.frame;
|
|
|
|
|
|
|
|
if (player_local != self)
|
2009-04-14 21:39:15 +00:00
|
|
|
{
|
2008-10-16 22:00:54 +00:00
|
|
|
return;
|
2009-04-14 21:39:15 +00:00
|
|
|
}
|
2008-10-16 22:00:54 +00:00
|
|
|
|
2009-04-19 01:15:18 +00:00
|
|
|
Pred_PlayerUpdated(self);
|
2008-10-16 22:00:54 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
//this is sent after the server has run our movement command.
|
2009-04-14 21:39:15 +00:00
|
|
|
nonstatic void(float isnew) ParsePlayer =
|
2008-10-16 22:00:54 +00:00
|
|
|
{
|
|
|
|
local float f;
|
|
|
|
|
|
|
|
f = readbyte();
|
|
|
|
|
|
|
|
if (f != self.frame || isnew)
|
|
|
|
{
|
|
|
|
self.frame2 = self.frame;
|
|
|
|
self.lerptime = time;
|
|
|
|
self.frame = f;
|
|
|
|
}
|
|
|
|
|
|
|
|
self.angles_x = readbyte()*(360/256);
|
|
|
|
self.angles_y = readbyte()*(360/256);
|
|
|
|
self.origin_x = readcoord();
|
|
|
|
self.origin_y = readcoord();
|
|
|
|
self.origin_z = readcoord();
|
2009-04-14 21:39:15 +00:00
|
|
|
self.velocity_x = readshort();
|
|
|
|
self.velocity_y = readshort();
|
|
|
|
self.velocity_z = readshort();
|
2008-10-16 22:00:54 +00:00
|
|
|
self.colormap = self.entnum;
|
|
|
|
|
|
|
|
self.sveffects = readbyte();
|
|
|
|
|
|
|
|
RefreshPlayer(isnew);
|
|
|
|
};
|
|
|
|
|
2009-04-14 21:39:15 +00:00
|
|
|
#ifdef NOEXTENSIONS
|
|
|
|
#undef strunzone
|
|
|
|
#undef strzone
|
|
|
|
#endif
|