fteqw/quakec/csqctest/src/cs/player.qc

411 lines
7.6 KiB
C++
Raw Normal View History

/*
this file handles the local player, and marshalling between the different sorts of player models.
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
*/
#include "playerframes.inc"
static void() RemovePlayer;
enum
{
MF_BAD,
#ifdef MD3PMODELS
MF_QUAKE3,
#endif
#ifdef HLPMODELS
MF_HLPM,
#endif
MF_QUAKE
};
#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
static void() Player_Interpolate =
{ //do some frame interpolation.
if (self.entnum == player_localentnum)
{
Pred_UpdateLocalMovement();
self.origin = pmove_org;
self.angles = input_angles;
self.angles_x = self.angles_x * -0.3333;
}
switch(self.modelstyle)
{
#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;
if (chasecam || self.entnum != player_localentnum)
self.renderflags = 0;
else
self.renderflags = RF_EXTERNALMODEL;
#ifdef POWERUP_SHELLS
if (!isdp)
{
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;
}
#endif
if (self.sveffects & SVE_INVIS)
setmodel(self, "progs/eyes.mdl");
else
setmodel(self, "progs/player.mdl");
break;
}
};
static void(float g) Player_SetLocalInfoGender =
{
if (player_local == self)
{
switch(g)
{
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");
break;
}
}
}
static void() Player_SetQ1Model =
{
self.modelstyle = MF_QUAKE;
Player_SetLocalInfoGender(GENDER_MALE);
}
#ifdef MD3PMODELS
static void(string skinname) Player_SetQ3Model =
{
if (!Anim_SetModel(skinname))
{
Anim_UnsetModel();
return;
}
Player_SetLocalInfoGender(Anim_GetGender());
self.modelstyle = MF_QUAKE3;
};
#endif
#ifdef HLPMODELS
static void(string skinname) Player_SetHLModel =
{
if (!HLPM_SetModel(skinname))
{
HLPM_UnsetModel();
return;
}
Player_SetLocalInfoGender(GENDER_MALE);
self.modelstyle = MF_HLPM;
};
#endif
static void() Player_UnsetModel =
{
switch(self.modelstyle)
{
#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, "");
};
static entity() Player_DupModel =
{
local entity e;
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;
}
e.modelstyle = self.modelstyle;
return e;
};
.float starttime;
.float oldframe;
static void() bodythink =
{
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;
};
static void() DeadBodyPredraw =
{
float ftime;
ftime = time - self.starttime;
if (self.removetime < time)
{
Player_UnsetModel();
remove(self);
return;
}
Movetype_Bounce();
Player_Interpolate();
self.origin_z -= ftime*0.5;
};
static void() JustRessed =
{
local entity e;
e = Player_DupModel();
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;
e.lerptime = time;
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;
};
static void() RemovePlayer =
{
if (player_local == self)
player_local = world;
if (self.haddied)
{
JustRessed();
self.haddied = false;
}
Player_UnsetModel();
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;
}
}
else
{
self.haddied = true;
}
self.lastorg = self.origin;
self.lastvel = self.velocity;
if (isnew)
{
if (self.entnum == player_localentnum)
{
player_local = self;
}
self.modelstyle = MF_BAD;
self.oldskin = strzone("");
self.drawmask = MASK_NORMAL;
self.removefunc = RemovePlayer;
}
if (self.sveffects & SVE_INVIS)
{
if (self.modelstyle != MF_QUAKE)
{
Player_UnsetModel();
Player_SetQ1Model(); //every model uses eyes
}
}
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)
{
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();
}
}
setsize(self, VEC_HULL_MIN, VEC_HULL_MAX);
self.oldframe = self.frame;
if (player_local != self)
{
return;
}
Pred_PlayerUpdated();
};
//this is sent after the server has run our movement command.
nonstatic void(float isnew) ParsePlayer =
{
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();
self.velocity_x = readshort();
self.velocity_y = readshort();
self.velocity_z = readshort();
self.colormap = self.entnum;
self.sveffects = readbyte();
RefreshPlayer(isnew);
};
#ifdef NOEXTENSIONS
#undef strunzone
#undef strzone
#endif