Networking improvements. Make player entities and NPC networking
conditional. Only changed fields are networked. This is because the overall design seems mature enough.
This commit is contained in:
parent
31750420be
commit
44479cd637
12 changed files with 708 additions and 277 deletions
|
@ -99,7 +99,6 @@ CSQC_Init(float apilevel, string enginename, float engineversion)
|
|||
|
||||
/* Game specific inits */
|
||||
HUD_Init();
|
||||
|
||||
Scores_Init();
|
||||
Client_Init(apilevel, enginename, engineversion);
|
||||
DSP_Init();
|
||||
|
@ -210,6 +209,10 @@ CSQC_UpdateView(float w, float h, float focus)
|
|||
} else {
|
||||
setsensitivityscaler(pl.viewzoom);
|
||||
}
|
||||
|
||||
if (pl.viewzoom <= 0.0f) {
|
||||
setsensitivityscaler(1.0f);
|
||||
}
|
||||
|
||||
pl.viewzoom = oldzoom;
|
||||
|
||||
|
|
|
@ -17,7 +17,6 @@
|
|||
class monster_npc
|
||||
{
|
||||
int body;
|
||||
int inited;
|
||||
float frame_last;
|
||||
|
||||
virtual float() predraw;
|
||||
|
@ -26,12 +25,6 @@ class monster_npc
|
|||
float
|
||||
monster_npc::predraw(void)
|
||||
{
|
||||
/* Only do this once whenever the ent pops into view */
|
||||
if (!inited) {
|
||||
setcustomskin(this, "", sprintf("geomset 1 %i\n", body));
|
||||
inited = TRUE;
|
||||
}
|
||||
|
||||
if (lerpfrac > 0) {
|
||||
lerpfrac -= frametime * 5;
|
||||
if (lerpfrac < 0) {
|
||||
|
@ -58,28 +51,50 @@ monster_npc::predraw(void)
|
|||
void
|
||||
NPC_ReadEntity(float new)
|
||||
{
|
||||
float fl;
|
||||
monster_npc pl = (monster_npc)self;
|
||||
if (new == TRUE) {
|
||||
|
||||
if (new) {
|
||||
spawnfunc_monster_npc();
|
||||
pl.classname = "npc";
|
||||
pl.solid = SOLID_SLIDEBOX;
|
||||
pl.movetype = MOVETYPE_NONE;
|
||||
pl.drawmask = MASK_ENGINE;
|
||||
pl.customphysics = Empty;
|
||||
setsize( pl, VEC_HULL_MIN, VEC_HULL_MAX );
|
||||
setsize(pl, VEC_HULL_MIN + [0,0,36], VEC_HULL_MAX + [0,0,36]);
|
||||
}
|
||||
|
||||
/* TODO: make these conditional */
|
||||
pl.modelindex = readshort();
|
||||
pl.origin[0] = readcoord();
|
||||
pl.origin[1] = readcoord();
|
||||
pl.origin[2] = readcoord();
|
||||
pl.angles[1] = readfloat();
|
||||
pl.angles[2] = readfloat();
|
||||
pl.velocity[0] = readcoord();
|
||||
pl.velocity[1] = readcoord();
|
||||
pl.velocity[2] = readcoord();
|
||||
pl.frame = readbyte();
|
||||
pl.skin = readbyte();
|
||||
pl.body = readbyte();
|
||||
fl = readshort();
|
||||
|
||||
if (fl & NPC_MODELINDEX)
|
||||
pl.modelindex = readshort();
|
||||
if (fl & NPC_ORIGIN_X)
|
||||
pl.origin[0] = readcoord();
|
||||
if (fl & NPC_ORIGIN_Y)
|
||||
pl.origin[1] = readcoord();
|
||||
if (fl & NPC_ORIGIN_Z)
|
||||
pl.origin[2] = readcoord();
|
||||
if (fl & NPC_ANGLES_X)
|
||||
pl.angles[0] = readfloat();
|
||||
if (fl & NPC_ANGLES_Y)
|
||||
pl.angles[1] = readfloat();
|
||||
if (fl & NPC_ANGLES_Z)
|
||||
pl.angles[2] = readfloat();
|
||||
if (fl & NPC_VELOCITY_X)
|
||||
pl.velocity[0] = readcoord();
|
||||
if (fl & NPC_VELOCITY_Y)
|
||||
pl.velocity[1] = readcoord();
|
||||
if (fl & NPC_VELOCITY_Z)
|
||||
pl.velocity[2] = readcoord();
|
||||
if (fl & NPC_FRAME)
|
||||
pl.frame = readbyte();
|
||||
if (fl & NPC_SKIN)
|
||||
pl.skin = readbyte();
|
||||
if (fl & NPC_BODY)
|
||||
pl.body = readbyte();
|
||||
|
||||
if (new) {
|
||||
setcustomskin(pl, "", sprintf("geomset 1 %i\n", pl.body));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -14,29 +14,19 @@
|
|||
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
//FOR DEBUGGING ONLY, remove when prediction is trusted (along with the extra network bloat).
|
||||
static void warnifdiff(string name, __inout float expected, float got)
|
||||
{
|
||||
//this should only fire from prediction misses.
|
||||
//this hopefully only happens when the server's anti-time-banking logic does its thing, or for things caused by other players/ents getting in the way.
|
||||
|
||||
//if (expected != got)
|
||||
//print(sprintf("%s differs, expected %g, got %g\n", name, expected, got));
|
||||
|
||||
//enable the following line if you want to see if it actually makes a difference.
|
||||
//expected = got;
|
||||
}
|
||||
|
||||
void Player_ReadEntity(float flIsNew)
|
||||
void
|
||||
Player_ReadEntity(float new)
|
||||
{
|
||||
float fl;
|
||||
player pl = (player)self;
|
||||
if ( flIsNew == TRUE ) {
|
||||
|
||||
if (new == TRUE) {
|
||||
spawnfunc_player();
|
||||
pl.classname = "player";
|
||||
pl.solid = SOLID_SLIDEBOX;
|
||||
pl.drawmask = MASK_ENGINE;
|
||||
pl.customphysics = Empty;
|
||||
setsize( pl, VEC_HULL_MIN, VEC_HULL_MAX );
|
||||
setsize(pl, VEC_HULL_MIN, VEC_HULL_MAX);
|
||||
} else {
|
||||
int i;
|
||||
//FIXME: splitscreen
|
||||
|
@ -56,36 +46,58 @@ void Player_ReadEntity(float flIsNew)
|
|||
}
|
||||
}
|
||||
|
||||
pl.sequence = servercommandframe;
|
||||
pl.modelindex = readshort(); // TODO: make conditional
|
||||
pl.origin[0] = readcoord();
|
||||
pl.origin[1] = readcoord();
|
||||
pl.origin[2] = readcoord(); // TODO: make conditional
|
||||
pl.pitch = readfloat();
|
||||
pl.angles[1] = readfloat();
|
||||
pl.angles[2] = readfloat();
|
||||
pl.velocity[0] = readcoord();
|
||||
pl.velocity[1] = readcoord();
|
||||
pl.velocity[2] = readcoord();
|
||||
pl.flags = readfloat(); //make mostly conditional
|
||||
pl.activeweapon = readbyte(); // TODO: make conditional
|
||||
warnifdiff("weapontime", pl.weapontime, readfloat()); //remove
|
||||
pl.g_items = readfloat(); // TODO: make conditional
|
||||
pl.health = readbyte(); // TODO: make conditional
|
||||
pl.armor = readbyte(); // TODO: make conditional
|
||||
pl.movetype = readbyte(); // TODO: make conditional
|
||||
pl.view_ofs[2] = readfloat(); // TODO: make conditional
|
||||
pl.viewzoom = readfloat(); //remove? or make conditional
|
||||
warnifdiff("jumptime", pl.jumptime, readfloat()); //remove
|
||||
warnifdiff("teletime", pl.teleport_time, readfloat()); //remove
|
||||
|
||||
pl.baseframe = readbyte(); // TODO: make conditional
|
||||
pl.frame = readbyte(); // TODO: make conditional
|
||||
pl.sequence = servercommandframe;
|
||||
|
||||
pl.a_ammo1 = readbyte(); // TODO: make conditional
|
||||
pl.a_ammo2 = readbyte(); // TODO: make conditional
|
||||
pl.a_ammo3 = readbyte(); // TODO: make conditional
|
||||
warnifdiff("attack_next", pl.w_attack_next, readfloat()); //remove
|
||||
warnifdiff("idle_next", pl.w_idle_next, readfloat()); //remove
|
||||
setorigin( pl, pl.origin );
|
||||
fl = readfloat();
|
||||
|
||||
if (fl & PLAYER_MODELINDEX)
|
||||
pl.modelindex = readshort();
|
||||
|
||||
if (fl & PLAYER_ORIGIN) {
|
||||
pl.origin[0] = readcoord();
|
||||
pl.origin[1] = readcoord();
|
||||
}
|
||||
|
||||
if (fl & PLAYER_ORIGIN_Z)
|
||||
pl.origin[2] = readcoord();
|
||||
if (fl & PLAYER_ANGLES_X)
|
||||
pl.pitch = readfloat();
|
||||
if (fl & PLAYER_ANGLES_Y)
|
||||
pl.angles[1] = readfloat();
|
||||
if (fl & PLAYER_ANGLES_Z)
|
||||
pl.angles[2] = readfloat();
|
||||
|
||||
if (fl & PLAYER_VELOCITY) {
|
||||
pl.velocity[0] = readcoord();
|
||||
pl.velocity[1] = readcoord();
|
||||
}
|
||||
|
||||
if (fl & PLAYER_VELOCITY_Z)
|
||||
pl.velocity[2] = readcoord();
|
||||
if (fl & PLAYER_FLAGS)
|
||||
pl.flags = readfloat();
|
||||
if (fl & PLAYER_WEAPON)
|
||||
pl.activeweapon = readbyte();
|
||||
if (fl & PLAYER_ITEMS)
|
||||
pl.g_items = readfloat();
|
||||
if (fl & PLAYER_HEALTH)
|
||||
pl.health = readbyte();
|
||||
if (fl & PLAYER_ARMOR)
|
||||
pl.armor = readbyte();
|
||||
if (fl & PLAYER_MOVETYPE)
|
||||
pl.movetype = readbyte();
|
||||
if (fl & PLAYER_VIEWOFS)
|
||||
pl.view_ofs[2] = readfloat();
|
||||
if (fl & PLAYER_BASEFRAME)
|
||||
pl.baseframe = readbyte();
|
||||
if (fl & PLAYER_FRAME)
|
||||
pl.frame = readbyte();
|
||||
if (fl & PLAYER_AMMO1)
|
||||
pl.a_ammo1 = readbyte();
|
||||
if (fl & PLAYER_AMMO2)
|
||||
pl.a_ammo2 = readbyte();
|
||||
if (fl & PLAYER_AMMO3)
|
||||
pl.a_ammo3 = readbyte();
|
||||
|
||||
setorigin(pl, pl.origin);
|
||||
}
|
||||
|
|
|
@ -24,23 +24,24 @@ class item_suit:CBaseTrigger
|
|||
|
||||
void item_suit::touch(void)
|
||||
{
|
||||
if (other.classname == "player") {
|
||||
player pl = (player)other;
|
||||
/*if (pl.g_items & ITEM_SUIT) {
|
||||
return;
|
||||
}*/
|
||||
sound(other, CHAN_ITEM, "items/tr_kevlar.wav", 1, ATTN_NORM);
|
||||
/*pl.g_items |= ITEM_SUIT;*/
|
||||
if (other.classname != "player") {
|
||||
return;
|
||||
}
|
||||
player pl = (player)other;
|
||||
/*if (pl.g_items & ITEM_SUIT) {
|
||||
return;
|
||||
}*/
|
||||
sound(other, CHAN_ITEM, "items/tr_kevlar.wav", 1, ATTN_NORM);
|
||||
/*pl.g_items |= ITEM_SUIT;*/
|
||||
|
||||
CBaseTrigger::UseTargets();
|
||||
CBaseTrigger::UseTargets();
|
||||
|
||||
if (cvar("sv_playerslots") == 1) {
|
||||
remove(self);
|
||||
} else {
|
||||
Hide();
|
||||
think = Respawn;
|
||||
nextthink = time + 30.0f;
|
||||
}
|
||||
if (cvar("sv_playerslots") == 1) {
|
||||
remove(self);
|
||||
} else {
|
||||
Hide();
|
||||
think = Respawn;
|
||||
nextthink = time + 30.0f;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -54,7 +55,6 @@ void item_suit::Respawn(void)
|
|||
|
||||
think = __NULL__;
|
||||
nextthink = -1;
|
||||
sound(this, CHAN_ITEM, "items/suitchargeok1.wav", 1, ATTN_NORM, 150);
|
||||
}
|
||||
|
||||
void item_suit::item_suit(void)
|
||||
|
|
|
@ -55,8 +55,70 @@ void Game_PlayerPreThink(void)
|
|||
}
|
||||
void Game_PlayerPostThink(void)
|
||||
{
|
||||
player pl = (player)self;
|
||||
Animation_PlayerUpdate();
|
||||
self.SendFlags = 1;
|
||||
|
||||
if (pl.old_modelindex != pl.modelindex)
|
||||
pl.SendFlags |= PLAYER_MODELINDEX;
|
||||
if (pl.old_origin[0] != pl.origin[0])
|
||||
pl.SendFlags |= PLAYER_ORIGIN;
|
||||
if (pl.old_origin[1] != pl.origin[1])
|
||||
pl.SendFlags |= PLAYER_ORIGIN;
|
||||
if (pl.old_origin[2] != pl.origin[2])
|
||||
pl.SendFlags |= PLAYER_ORIGIN_Z;
|
||||
if (pl.old_angles[0] != pl.angles[0])
|
||||
pl.SendFlags |= PLAYER_ANGLES_X;
|
||||
if (pl.old_angles[1] != pl.angles[1])
|
||||
pl.SendFlags |= PLAYER_ANGLES_Y;
|
||||
if (pl.old_angles[2] != pl.angles[2])
|
||||
pl.SendFlags |= PLAYER_ANGLES_Z;
|
||||
if (pl.old_velocity[0] != pl.velocity[0])
|
||||
pl.SendFlags |= PLAYER_VELOCITY;
|
||||
if (pl.old_velocity[1] != pl.velocity[1])
|
||||
pl.SendFlags |= PLAYER_VELOCITY;
|
||||
if (pl.old_velocity[2] != pl.velocity[2])
|
||||
pl.SendFlags |= PLAYER_VELOCITY_Z;
|
||||
if (pl.old_flags != pl.flags)
|
||||
pl.SendFlags |= PLAYER_FLAGS;
|
||||
if (pl.old_activeweapon != pl.activeweapon)
|
||||
pl.SendFlags |= PLAYER_WEAPON;
|
||||
if (pl.old_items != pl.g_items)
|
||||
pl.SendFlags |= PLAYER_ITEMS;
|
||||
if (pl.old_health != pl.health)
|
||||
pl.SendFlags |= PLAYER_HEALTH;
|
||||
if (pl.old_armor != pl.armor)
|
||||
pl.SendFlags |= PLAYER_ARMOR;
|
||||
if (pl.old_movetype != pl.movetype)
|
||||
pl.SendFlags |= PLAYER_MOVETYPE;
|
||||
if (pl.old_viewofs != pl.view_ofs[2])
|
||||
pl.SendFlags |= PLAYER_VIEWOFS;
|
||||
if (pl.old_baseframe != pl.baseframe)
|
||||
pl.SendFlags |= PLAYER_BASEFRAME;
|
||||
if (pl.old_frame != pl.frame)
|
||||
pl.SendFlags |= PLAYER_FRAME;
|
||||
if (pl.old_a_ammo1 != pl.a_ammo1)
|
||||
pl.SendFlags |= PLAYER_AMMO1;
|
||||
if (pl.old_a_ammo2 != pl.a_ammo2)
|
||||
pl.SendFlags |= PLAYER_AMMO2;
|
||||
if (pl.old_a_ammo3 != pl.a_ammo3)
|
||||
pl.SendFlags |= PLAYER_AMMO3;
|
||||
|
||||
pl.old_modelindex = pl.modelindex;
|
||||
pl.old_origin = pl.origin;
|
||||
pl.old_angles = pl.angles;
|
||||
pl.old_velocity = pl.velocity;
|
||||
pl.old_flags = pl.flags;
|
||||
pl.old_activeweapon = pl.activeweapon;
|
||||
pl.old_items = pl.g_items;
|
||||
pl.old_health = pl.health;
|
||||
pl.old_armor = pl.armor;
|
||||
pl.old_movetype = pl.movetype;
|
||||
pl.old_viewofs = pl.view_ofs[2];
|
||||
pl.old_baseframe = pl.baseframe;
|
||||
pl.old_frame = pl.frame;
|
||||
pl.old_a_ammo1 = pl.a_ammo1;
|
||||
pl.old_a_ammo2 = pl.a_ammo2;
|
||||
pl.old_a_ammo3 = pl.a_ammo3;
|
||||
}
|
||||
void Game_RunClientCommand(void)
|
||||
{
|
||||
|
@ -106,7 +168,6 @@ void Game_PutClientInServer(void)
|
|||
|
||||
pl.classname = "player";
|
||||
pl.health = self.max_health = 100;
|
||||
//forceinfokey(self, "*dead", "0");
|
||||
pl.takedamage = DAMAGE_YES;
|
||||
pl.solid = SOLID_SLIDEBOX;
|
||||
pl.movetype = MOVETYPE_WALK;
|
||||
|
@ -115,19 +176,40 @@ void Game_PutClientInServer(void)
|
|||
pl.model = "models/player.mdl";
|
||||
|
||||
string mymodel = infokey(pl, "model");
|
||||
if (mymodel) {
|
||||
mymodel = sprintf("models/player/%s/%s.mdl", mymodel, mymodel);
|
||||
if (whichpack(mymodel)) {
|
||||
pl.model = mymodel;
|
||||
}
|
||||
}
|
||||
setmodel(pl, pl.model);
|
||||
if (mymodel) {
|
||||
mymodel = sprintf("models/player/%s/%s.mdl", mymodel, mymodel);
|
||||
if (whichpack(mymodel)) {
|
||||
pl.model = mymodel;
|
||||
}
|
||||
}
|
||||
setmodel(pl, pl.model);
|
||||
|
||||
setsize(pl, VEC_HULL_MIN, VEC_HULL_MAX);
|
||||
pl.view_ofs = VEC_PLAYER_VIEWPOS;
|
||||
pl.velocity = [0,0,0];
|
||||
pl.frame = 1;
|
||||
pl.SendEntity = Player_SendEntity;
|
||||
pl.SendFlags = PLAYER_MODELINDEX |
|
||||
PLAYER_ORIGIN |
|
||||
PLAYER_ORIGIN_Z |
|
||||
PLAYER_ANGLES_X |
|
||||
PLAYER_ANGLES_Y |
|
||||
PLAYER_ANGLES_Z |
|
||||
PLAYER_VELOCITY |
|
||||
PLAYER_VELOCITY_Z |
|
||||
PLAYER_FLAGS |
|
||||
PLAYER_WEAPON |
|
||||
PLAYER_ITEMS |
|
||||
PLAYER_HEALTH |
|
||||
PLAYER_ARMOR |
|
||||
PLAYER_MOVETYPE |
|
||||
PLAYER_VIEWOFS |
|
||||
PLAYER_BASEFRAME |
|
||||
PLAYER_FRAME |
|
||||
PLAYER_AMMO1 |
|
||||
PLAYER_AMMO2 |
|
||||
PLAYER_AMMO3;
|
||||
|
||||
pl.customphysics = Empty;
|
||||
pl.vPain = Player_Pain;
|
||||
pl.vDeath = Player_Death;
|
||||
|
|
|
@ -301,7 +301,7 @@ string sci_sndidle[] = {
|
|||
|
||||
class monster_scientist:CBaseEntity
|
||||
{
|
||||
int m_iBody;
|
||||
int body;
|
||||
vector m_vecLastUserPos;
|
||||
entity m_eUser;
|
||||
entity m_eRescuer;
|
||||
|
@ -313,6 +313,15 @@ class monster_scientist:CBaseEntity
|
|||
float m_flTraceTime;
|
||||
float m_flPitch;
|
||||
int m_iFlags;
|
||||
|
||||
int old_modelindex;
|
||||
vector old_origin;
|
||||
vector old_angles;
|
||||
vector old_velocity;
|
||||
int old_frame;
|
||||
int old_skin;
|
||||
int old_body;
|
||||
|
||||
void() monster_scientist;
|
||||
|
||||
virtual void() touch;
|
||||
|
@ -337,18 +346,35 @@ float monster_scientist::SendEntity(entity ePEnt, float fChanged)
|
|||
}
|
||||
|
||||
WriteByte(MSG_ENTITY, ENT_NPC);
|
||||
WriteShort(MSG_ENTITY, modelindex);
|
||||
WriteCoord(MSG_ENTITY, origin[0]);
|
||||
WriteCoord(MSG_ENTITY, origin[1]);
|
||||
WriteCoord(MSG_ENTITY, origin[2]);
|
||||
WriteFloat(MSG_ENTITY, angles[1]);
|
||||
WriteFloat(MSG_ENTITY, angles[2]);
|
||||
WriteCoord(MSG_ENTITY, velocity[0]);
|
||||
WriteCoord(MSG_ENTITY, velocity[1]);
|
||||
WriteCoord(MSG_ENTITY, velocity[2]);
|
||||
WriteByte(MSG_ENTITY, frame);
|
||||
WriteByte(MSG_ENTITY, skin);
|
||||
WriteByte(MSG_ENTITY, m_iBody);
|
||||
WriteShort(MSG_ENTITY, fChanged);
|
||||
|
||||
if (fChanged & NPC_MODELINDEX)
|
||||
WriteShort(MSG_ENTITY, modelindex);
|
||||
if (fChanged & NPC_ORIGIN_X)
|
||||
WriteCoord(MSG_ENTITY, origin[0]);
|
||||
if (fChanged & NPC_ORIGIN_Y)
|
||||
WriteCoord(MSG_ENTITY, origin[1]);
|
||||
if (fChanged & NPC_ORIGIN_Z)
|
||||
WriteCoord(MSG_ENTITY, origin[2]);
|
||||
if (fChanged & NPC_ANGLES_X)
|
||||
WriteFloat(MSG_ENTITY, angles[0]);
|
||||
if (fChanged & NPC_ANGLES_Y)
|
||||
WriteFloat(MSG_ENTITY, angles[1]);
|
||||
if (fChanged & NPC_ANGLES_Z)
|
||||
WriteFloat(MSG_ENTITY, angles[2]);
|
||||
if (fChanged & NPC_VELOCITY_X)
|
||||
WriteCoord(MSG_ENTITY, velocity[0]);
|
||||
if (fChanged & NPC_VELOCITY_Y)
|
||||
WriteCoord(MSG_ENTITY, velocity[1]);
|
||||
if (fChanged & NPC_VELOCITY_Z)
|
||||
WriteCoord(MSG_ENTITY, velocity[2]);
|
||||
if (fChanged & NPC_FRAME)
|
||||
WriteByte(MSG_ENTITY, frame);
|
||||
if (fChanged & NPC_SKIN)
|
||||
WriteByte(MSG_ENTITY, skin);
|
||||
if (fChanged & NPC_BODY)
|
||||
WriteByte(MSG_ENTITY, body);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
@ -546,7 +572,41 @@ void monster_scientist::Physics(void)
|
|||
|
||||
runstandardplayerphysics(this);
|
||||
Footsteps_Update();
|
||||
SendFlags = 1;
|
||||
|
||||
if (modelindex != old_modelindex)
|
||||
SendFlags |= NPC_MODELINDEX;
|
||||
if (origin[0] != old_origin[0])
|
||||
SendFlags |= NPC_ORIGIN_X;
|
||||
if (origin[1] != old_origin[1])
|
||||
SendFlags |= NPC_ORIGIN_Y;
|
||||
if (origin[2] != old_origin[2])
|
||||
SendFlags |= NPC_ORIGIN_Z;
|
||||
if (angles[0] != old_angles[0])
|
||||
SendFlags |= NPC_ANGLES_X;
|
||||
if (angles[1] != old_angles[1])
|
||||
SendFlags |= NPC_ANGLES_Y;
|
||||
if (angles[2] != old_angles[2])
|
||||
SendFlags |= NPC_ANGLES_Z;
|
||||
if (velocity[0] != old_velocity[0])
|
||||
SendFlags |= NPC_VELOCITY_X;
|
||||
if (velocity[1] != old_velocity[1])
|
||||
SendFlags |= NPC_VELOCITY_Y;
|
||||
if (velocity[2] != old_velocity[2])
|
||||
SendFlags |= NPC_VELOCITY_Z;
|
||||
if (frame != old_frame)
|
||||
SendFlags |= NPC_FRAME;
|
||||
if (skin != old_skin)
|
||||
SendFlags |= NPC_SKIN;
|
||||
if (body != old_body)
|
||||
SendFlags |= NPC_BODY;
|
||||
|
||||
old_modelindex = modelindex;
|
||||
old_origin = origin;
|
||||
old_angles = angles,
|
||||
old_velocity = velocity,
|
||||
old_frame = frame;
|
||||
old_skin = skin;
|
||||
old_body = body;
|
||||
|
||||
if (!(flags & FL_ONGROUND) && velocity[2] < -100) {
|
||||
if (!(m_iFlags & SCIF_FALLING)) {
|
||||
|
@ -624,7 +684,7 @@ void monster_scientist::vDeath(int iHitBody)
|
|||
think = Respawn;
|
||||
nextthink = time + 10.0f;
|
||||
|
||||
SendFlags = 1;
|
||||
SendFlags |= NPC_FRAME;
|
||||
m_eUser = world;
|
||||
customphysics = __NULL__;
|
||||
m_iFlags = 0x0;
|
||||
|
@ -676,6 +736,7 @@ void monster_scientist::Respawn(void)
|
|||
health = 50;
|
||||
velocity = [0,0,0];
|
||||
m_iFlags = 0x0;
|
||||
SendFlags = 0xff;
|
||||
|
||||
if (autocvar_sh_scialert) {
|
||||
m_iFlags |= SCIF_FEAR;
|
||||
|
@ -713,8 +774,8 @@ void monster_scientist::monster_scientist(void)
|
|||
|
||||
/* This stuff needs to be persistent because we can't guarantee that
|
||||
* the client-side geomset refresh happens. Don't shove this into Respawn */
|
||||
m_iBody = floor(random(1,5));
|
||||
switch (m_iBody) {
|
||||
body = floor(random(1,5));
|
||||
switch (body) {
|
||||
case 1:
|
||||
m_flPitch = 105;
|
||||
netname = "Walter";
|
||||
|
|
|
@ -14,25 +14,30 @@
|
|||
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
void Game_ClientConnect(void)
|
||||
var int autocvar_sv_networkeverything = FALSE;
|
||||
|
||||
void
|
||||
Game_ClientConnect(void)
|
||||
{
|
||||
entity a;
|
||||
bprint(PRINT_HIGH, sprintf("%s connected\n", self.netname));
|
||||
|
||||
int playercount = 0;
|
||||
for (entity eFind = world; (eFind = find(eFind, classname, "player"));) {
|
||||
for (a = world; (a = find(a, classname, "player"));) {
|
||||
playercount++;
|
||||
}
|
||||
|
||||
/* We're the first. */
|
||||
/* we're the first. respawn all entities? */
|
||||
if (playercount == 0) {
|
||||
for (entity a = world; (a = findfloat(a, gflags, GF_CANRESPAWN));) {
|
||||
CBaseEntity caw = (CBaseEntity)a;
|
||||
caw.Respawn();
|
||||
}
|
||||
for (a = world; (a = findfloat(a, gflags, GF_CANRESPAWN));) {
|
||||
CBaseEntity caw = (CBaseEntity)a;
|
||||
caw.Respawn();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Game_ClientDisconnect(void)
|
||||
void
|
||||
Game_ClientDisconnect(void)
|
||||
{
|
||||
bprint(PRINT_HIGH, sprintf("%s disconnected\n", self.netname));
|
||||
|
||||
|
@ -45,28 +50,117 @@ void Game_ClientDisconnect(void)
|
|||
self.SendFlags = 1;
|
||||
}
|
||||
|
||||
void Game_ClientKill(void)
|
||||
void
|
||||
Game_ClientKill(void)
|
||||
{
|
||||
Damage_Apply(self, self, self.health, self.origin, TRUE);
|
||||
}
|
||||
|
||||
void Game_PlayerPreThink(void)
|
||||
void
|
||||
Game_PlayerPreThink(void)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void Game_PlayerPostThink(void)
|
||||
void
|
||||
Game_PlayerPostThink(void)
|
||||
{
|
||||
player pl = (player)self;
|
||||
Animation_PlayerUpdate();
|
||||
self.SendFlags = 1;
|
||||
|
||||
if (pl.old_modelindex != pl.modelindex) {
|
||||
pl.SendFlags |= PLAYER_MODELINDEX;
|
||||
}
|
||||
if (pl.old_origin[0] != pl.origin[0]) {
|
||||
pl.SendFlags |= PLAYER_ORIGIN;
|
||||
}
|
||||
if (pl.old_origin[1] != pl.origin[1]) {
|
||||
pl.SendFlags |= PLAYER_ORIGIN;
|
||||
}
|
||||
if (pl.old_origin[2] != pl.origin[2]) {
|
||||
pl.SendFlags |= PLAYER_ORIGIN_Z;
|
||||
}
|
||||
if (pl.old_angles[0] != pl.angles[0]) {
|
||||
pl.SendFlags |= PLAYER_ANGLES_X;
|
||||
}
|
||||
if (pl.old_angles[1] != pl.angles[1]) {
|
||||
pl.SendFlags |= PLAYER_ANGLES_Y;
|
||||
}
|
||||
if (pl.old_angles[2] != pl.angles[2]) {
|
||||
pl.SendFlags |= PLAYER_ANGLES_Z;
|
||||
}
|
||||
if (pl.old_velocity[0] != pl.velocity[0]) {
|
||||
pl.SendFlags |= PLAYER_VELOCITY;
|
||||
}
|
||||
if (pl.old_velocity[1] != pl.velocity[1]) {
|
||||
pl.SendFlags |= PLAYER_VELOCITY;
|
||||
}
|
||||
if (pl.old_velocity[2] != pl.velocity[2]) {
|
||||
pl.SendFlags |= PLAYER_VELOCITY_Z;
|
||||
}
|
||||
if (pl.old_flags != pl.flags) {
|
||||
pl.SendFlags |= PLAYER_FLAGS;
|
||||
}
|
||||
if (pl.old_activeweapon != pl.activeweapon) {
|
||||
pl.SendFlags |= PLAYER_WEAPON;
|
||||
}
|
||||
if (pl.old_items != pl.g_items) {
|
||||
pl.SendFlags |= PLAYER_ITEMS;
|
||||
}
|
||||
if (pl.old_health != pl.health) {
|
||||
pl.SendFlags |= PLAYER_HEALTH;
|
||||
}
|
||||
if (pl.old_armor != pl.armor) {
|
||||
pl.SendFlags |= PLAYER_ARMOR;
|
||||
}
|
||||
if (pl.old_movetype != pl.movetype) {
|
||||
pl.SendFlags |= PLAYER_MOVETYPE;
|
||||
}
|
||||
if (pl.old_viewofs != pl.view_ofs[2]) {
|
||||
pl.SendFlags |= PLAYER_VIEWOFS;
|
||||
}
|
||||
if (pl.old_baseframe != pl.baseframe) {
|
||||
pl.SendFlags |= PLAYER_BASEFRAME;
|
||||
}
|
||||
if (pl.old_frame != pl.frame) {
|
||||
pl.SendFlags |= PLAYER_FRAME;
|
||||
}
|
||||
if (pl.old_a_ammo1 != pl.a_ammo1) {
|
||||
pl.SendFlags |= PLAYER_AMMO1;
|
||||
}
|
||||
if (pl.old_a_ammo2 != pl.a_ammo2) {
|
||||
pl.SendFlags |= PLAYER_AMMO2;
|
||||
}
|
||||
if (pl.old_a_ammo3 != pl.a_ammo3) {
|
||||
pl.SendFlags |= PLAYER_AMMO3;
|
||||
}
|
||||
|
||||
pl.old_modelindex = pl.modelindex;
|
||||
pl.old_origin = pl.origin;
|
||||
pl.old_angles = pl.angles;
|
||||
pl.old_velocity = pl.velocity;
|
||||
pl.old_flags = pl.flags;
|
||||
pl.old_activeweapon = pl.activeweapon;
|
||||
pl.old_items = pl.g_items;
|
||||
pl.old_health = pl.health;
|
||||
pl.old_armor = pl.armor;
|
||||
pl.old_movetype = pl.movetype;
|
||||
pl.old_viewofs = pl.view_ofs[2];
|
||||
pl.old_baseframe = pl.baseframe;
|
||||
pl.old_frame = pl.frame;
|
||||
pl.old_a_ammo1 = pl.a_ammo1;
|
||||
pl.old_a_ammo2 = pl.a_ammo2;
|
||||
pl.old_a_ammo3 = pl.a_ammo3;
|
||||
}
|
||||
void Game_RunClientCommand(void)
|
||||
void
|
||||
Game_RunClientCommand(void)
|
||||
{
|
||||
Footsteps_Update();
|
||||
QPhysics_Run(self);
|
||||
}
|
||||
|
||||
void Game_DecodeChangeParms(void)
|
||||
void
|
||||
Game_DecodeChangeParms(void)
|
||||
{
|
||||
player pl = (player)self;
|
||||
g_landmarkpos[0] = parm1;
|
||||
|
@ -81,7 +175,8 @@ void Game_DecodeChangeParms(void)
|
|||
pl.g_items = parm10;
|
||||
pl.activeweapon = parm11;
|
||||
}
|
||||
void Game_SetChangeParms(void)
|
||||
void
|
||||
Game_SetChangeParms(void)
|
||||
{
|
||||
player pl = (player)self;
|
||||
parm1 = g_landmarkpos[0];
|
||||
|
@ -97,7 +192,8 @@ void Game_SetChangeParms(void)
|
|||
parm11 = pl.activeweapon;
|
||||
}
|
||||
|
||||
void Game_PutClientInServer(void)
|
||||
void
|
||||
Game_PutClientInServer(void)
|
||||
{
|
||||
if (self.classname != "player") {
|
||||
spawnfunc_player();
|
||||
|
@ -107,7 +203,7 @@ void Game_PutClientInServer(void)
|
|||
entity spot;
|
||||
pl.classname = "player";
|
||||
pl.health = self.max_health = 100;
|
||||
//forceinfokey(self, "*dead", "0");
|
||||
|
||||
pl.takedamage = DAMAGE_YES;
|
||||
pl.solid = SOLID_SLIDEBOX;
|
||||
pl.movetype = MOVETYPE_WALK;
|
||||
|
@ -116,7 +212,7 @@ void Game_PutClientInServer(void)
|
|||
pl.model = "models/player.mdl";
|
||||
|
||||
string mymodel = infokey(pl, "model");
|
||||
|
||||
|
||||
if (mymodel) {
|
||||
mymodel = sprintf("models/player/%s/%s.mdl", mymodel, mymodel);
|
||||
if (whichpack(mymodel)) {
|
||||
|
@ -124,7 +220,7 @@ void Game_PutClientInServer(void)
|
|||
}
|
||||
}
|
||||
setmodel(pl, pl.model);
|
||||
|
||||
|
||||
setsize(pl, VEC_HULL_MIN, VEC_HULL_MAX);
|
||||
pl.view_ofs = VEC_PLAYER_VIEWPOS;
|
||||
pl.velocity = [0,0,0];
|
||||
|
@ -141,7 +237,6 @@ void Game_PutClientInServer(void)
|
|||
Game_DecodeChangeParms();
|
||||
|
||||
if (startspot != "") {
|
||||
print(sprintf("[LEVEL] Startspot is \"%s\"\n", startspot));
|
||||
setorigin(pl, Landmark_GetSpot());
|
||||
} else {
|
||||
spot = find(world, classname, "info_player_start");
|
||||
|
@ -162,40 +257,48 @@ void Game_PutClientInServer(void)
|
|||
}
|
||||
}
|
||||
|
||||
void SV_SendChat(entity eSender, string sMessage, entity eEnt, float fType)
|
||||
void
|
||||
SV_SendChat(entity sender, string msg, entity eEnt, float fType)
|
||||
{
|
||||
WriteByte(MSG_MULTICAST, SVC_CGAMEPACKET);
|
||||
WriteByte(MSG_MULTICAST, fType == 0 ? EV_CHAT:EV_CHAT_TEAM);
|
||||
WriteByte(MSG_MULTICAST, num_for_edict(eSender) - 1);
|
||||
WriteByte(MSG_MULTICAST, eSender.team);
|
||||
WriteString(MSG_MULTICAST, sMessage);
|
||||
WriteByte(MSG_MULTICAST, num_for_edict(sender) - 1);
|
||||
WriteByte(MSG_MULTICAST, sender.team);
|
||||
WriteString(MSG_MULTICAST, msg);
|
||||
if (eEnt) {
|
||||
msg_entity = eEnt;
|
||||
multicast([0,0,0], MULTICAST_ONE);
|
||||
} else {
|
||||
multicast([0,0,0], MULTICAST_ALL);
|
||||
}
|
||||
|
||||
localcmd(sprintf("echo [SERVER] %s: %s\n", sender.netname, msg));
|
||||
}
|
||||
|
||||
void Game_ParseClientCommand(string cmd)
|
||||
void
|
||||
Game_ParseClientCommand(string cmd)
|
||||
{
|
||||
tokenize(cmd);
|
||||
|
||||
if (argv(1) == "timeleft") {
|
||||
float fTimeLeft = cvar("mp_timelimit") - (time / 60);
|
||||
Vox_Singlecast(self, sprintf("we have %s minutes remaining", Vox_TimeToString(fTimeLeft)));
|
||||
string msg;
|
||||
string timestring;
|
||||
float timeleft;
|
||||
timeleft = cvar("mp_timelimit") - (time / 60);
|
||||
timestring = Vox_TimeToString(timeleft);
|
||||
msg = sprintf("we have %s minutes remaining", timestring);
|
||||
Vox_Singlecast(self, msg);
|
||||
return;
|
||||
}
|
||||
|
||||
if (argv(0) == "say") {
|
||||
localcmd(sprintf("echo [SERVER] %s: %s\n", self.netname, argv(1)));
|
||||
SV_SendChat(self, argv(1), world, 0);
|
||||
return;
|
||||
} else if (argv(0) == "say_team") {
|
||||
localcmd(sprintf("echo [TEAM %d] %s: %s\n", self.team, self.netname, argv(1)));
|
||||
for (entity eFind = world; (eFind = find(eFind, classname, "player"));) {
|
||||
if (eFind.team == self.team) {
|
||||
SV_SendChat(self, argv(1), eFind, 1);
|
||||
entity a;
|
||||
for (a = world; (a = find(a, classname, "player"));) {
|
||||
if (a.team == self.team) {
|
||||
SV_SendChat(self, argv(1), a, 1);
|
||||
}
|
||||
}
|
||||
return;
|
||||
|
@ -204,7 +307,8 @@ void Game_ParseClientCommand(string cmd)
|
|||
clientcommand(self, cmd);
|
||||
}
|
||||
|
||||
void Game_SetNewParms(void)
|
||||
void
|
||||
Game_SetNewParms(void)
|
||||
{
|
||||
|
||||
}
|
||||
|
|
|
@ -120,36 +120,72 @@ float Player_SendEntity(entity ePEnt, float fChanged)
|
|||
}
|
||||
|
||||
WriteByte(MSG_ENTITY, ENT_PLAYER);
|
||||
WriteShort(MSG_ENTITY, pl.modelindex);
|
||||
WriteCoord(MSG_ENTITY, pl.origin[0]);
|
||||
WriteCoord(MSG_ENTITY, pl.origin[1]);
|
||||
WriteCoord(MSG_ENTITY, pl.origin[2]);
|
||||
WriteFloat(MSG_ENTITY, pl.v_angle[0]);
|
||||
WriteFloat(MSG_ENTITY, pl.angles[1]);
|
||||
WriteFloat(MSG_ENTITY, pl.angles[2]);
|
||||
WriteCoord(MSG_ENTITY, pl.velocity[0]);
|
||||
WriteCoord(MSG_ENTITY, pl.velocity[1]);
|
||||
WriteCoord(MSG_ENTITY, pl.velocity[2]);
|
||||
WriteFloat(MSG_ENTITY, pl.flags);
|
||||
WriteByte(MSG_ENTITY, pl.activeweapon);
|
||||
WriteFloat(MSG_ENTITY, pl.weapontime);
|
||||
WriteFloat(MSG_ENTITY, pl.g_items);
|
||||
WriteByte(MSG_ENTITY, pl.health);
|
||||
WriteByte(MSG_ENTITY, pl.armor);
|
||||
WriteByte(MSG_ENTITY, pl.movetype);
|
||||
WriteFloat(MSG_ENTITY, pl.view_ofs[2]);
|
||||
WriteFloat(MSG_ENTITY, pl.viewzoom);
|
||||
WriteFloat(MSG_ENTITY, pl.jumptime);
|
||||
WriteFloat(MSG_ENTITY, pl.teleport_time);
|
||||
WriteFloat(MSG_ENTITY, fChanged);
|
||||
|
||||
WriteByte(MSG_ENTITY, pl.baseframe);
|
||||
WriteByte(MSG_ENTITY, pl.frame);
|
||||
/* really trying to get our moneys worth with 23 bits of mantissa */
|
||||
if (fChanged & PLAYER_MODELINDEX) {
|
||||
WriteShort(MSG_ENTITY, pl.modelindex);
|
||||
}
|
||||
if (fChanged & PLAYER_ORIGIN) {
|
||||
WriteCoord(MSG_ENTITY, pl.origin[0]);
|
||||
WriteCoord(MSG_ENTITY, pl.origin[1]);
|
||||
}
|
||||
if (fChanged & PLAYER_ORIGIN_Z) {
|
||||
WriteCoord(MSG_ENTITY, pl.origin[2]);
|
||||
}
|
||||
if (fChanged & PLAYER_ANGLES_X) {
|
||||
WriteFloat(MSG_ENTITY, pl.v_angle[0]);
|
||||
}
|
||||
if (fChanged & PLAYER_ANGLES_Y) {
|
||||
WriteFloat(MSG_ENTITY, pl.angles[1]);
|
||||
}
|
||||
if (fChanged & PLAYER_ANGLES_Z) {
|
||||
WriteFloat(MSG_ENTITY, pl.angles[2]);
|
||||
}
|
||||
if (fChanged & PLAYER_VELOCITY) {
|
||||
WriteCoord(MSG_ENTITY, pl.velocity[0]);
|
||||
WriteCoord(MSG_ENTITY, pl.velocity[1]);
|
||||
}
|
||||
if (fChanged & PLAYER_VELOCITY_Z) {
|
||||
WriteCoord(MSG_ENTITY, pl.velocity[2]);
|
||||
}
|
||||
if (fChanged & PLAYER_FLAGS) {
|
||||
WriteFloat(MSG_ENTITY, pl.flags);
|
||||
}
|
||||
if (fChanged & PLAYER_WEAPON) {
|
||||
WriteByte(MSG_ENTITY, pl.activeweapon);
|
||||
}
|
||||
if (fChanged & PLAYER_ITEMS) {
|
||||
WriteFloat(MSG_ENTITY, pl.g_items);
|
||||
}
|
||||
if (fChanged & PLAYER_HEALTH) {
|
||||
WriteByte(MSG_ENTITY, pl.health);
|
||||
}
|
||||
if (fChanged & PLAYER_ARMOR) {
|
||||
WriteByte(MSG_ENTITY, pl.armor);
|
||||
}
|
||||
if (fChanged & PLAYER_MOVETYPE) {
|
||||
WriteByte(MSG_ENTITY, pl.movetype);
|
||||
}
|
||||
if (fChanged & PLAYER_VIEWOFS) {
|
||||
WriteFloat(MSG_ENTITY, pl.view_ofs[2]);
|
||||
}
|
||||
if (fChanged & PLAYER_BASEFRAME) {
|
||||
WriteByte(MSG_ENTITY, pl.baseframe);
|
||||
}
|
||||
if (fChanged & PLAYER_FRAME) {
|
||||
WriteByte(MSG_ENTITY, pl.frame);
|
||||
}
|
||||
if (fChanged & PLAYER_AMMO1) {
|
||||
WriteByte(MSG_ENTITY, pl.a_ammo1);
|
||||
}
|
||||
if (fChanged & PLAYER_AMMO2) {
|
||||
WriteByte(MSG_ENTITY, pl.a_ammo2);
|
||||
}
|
||||
if (fChanged & PLAYER_AMMO3) {
|
||||
WriteByte(MSG_ENTITY, pl.a_ammo3);
|
||||
}
|
||||
|
||||
WriteByte(MSG_ENTITY, pl.a_ammo1);
|
||||
WriteByte(MSG_ENTITY, pl.a_ammo2);
|
||||
WriteByte(MSG_ENTITY, pl.a_ammo3);
|
||||
WriteFloat(MSG_ENTITY, pl.w_attack_next);
|
||||
WriteFloat(MSG_ENTITY, pl.w_idle_next);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
|
|
@ -25,3 +25,43 @@ enum {
|
|||
#endif
|
||||
ENT_DECAL
|
||||
};
|
||||
|
||||
/* entity update flags */
|
||||
enumflags {
|
||||
NPC_MODELINDEX,
|
||||
NPC_ORIGIN_X,
|
||||
NPC_ORIGIN_Y,
|
||||
NPC_ORIGIN_Z,
|
||||
NPC_ANGLES_X,
|
||||
NPC_ANGLES_Y,
|
||||
NPC_ANGLES_Z,
|
||||
NPC_VELOCITY_X,
|
||||
NPC_VELOCITY_Y,
|
||||
NPC_VELOCITY_Z,
|
||||
NPC_FRAME,
|
||||
NPC_SKIN,
|
||||
NPC_BODY
|
||||
};
|
||||
|
||||
enumflags {
|
||||
PLAYER_MODELINDEX,
|
||||
PLAYER_ORIGIN,
|
||||
PLAYER_ORIGIN_Z,
|
||||
PLAYER_ANGLES_X,
|
||||
PLAYER_ANGLES_Y,
|
||||
PLAYER_ANGLES_Z,
|
||||
PLAYER_VELOCITY,
|
||||
PLAYER_VELOCITY_Z,
|
||||
PLAYER_FLAGS,
|
||||
PLAYER_WEAPON,
|
||||
PLAYER_ITEMS,
|
||||
PLAYER_HEALTH,
|
||||
PLAYER_ARMOR,
|
||||
PLAYER_MOVETYPE,
|
||||
PLAYER_VIEWOFS,
|
||||
PLAYER_BASEFRAME,
|
||||
PLAYER_FRAME,
|
||||
PLAYER_AMMO1,
|
||||
PLAYER_AMMO2,
|
||||
PLAYER_AMMO3
|
||||
};
|
||||
|
|
|
@ -91,5 +91,23 @@ class player
|
|||
int ammo_tripmine;
|
||||
int ammo_snark;
|
||||
int ammo_hornet;
|
||||
|
||||
/* conditional networking */
|
||||
int old_modelindex;
|
||||
vector old_origin;
|
||||
vector old_angles;
|
||||
vector old_velocity;
|
||||
int old_flags;
|
||||
int old_activeweapon;
|
||||
int old_items;
|
||||
int old_health;
|
||||
int old_armor;
|
||||
int old_movetype;
|
||||
int old_viewofs;
|
||||
int old_baseframe;
|
||||
int old_frame;
|
||||
int old_a_ammo1;
|
||||
int old_a_ammo2;
|
||||
int old_a_ammo3;
|
||||
#endif
|
||||
};
|
||||
|
|
|
@ -89,6 +89,24 @@ class player
|
|||
int ammo_tripmine;
|
||||
int ammo_snark;
|
||||
int ammo_hornet;
|
||||
|
||||
/* conditional networking */
|
||||
int old_modelindex;
|
||||
vector old_origin;
|
||||
vector old_angles;
|
||||
vector old_velocity;
|
||||
int old_flags;
|
||||
int old_activeweapon;
|
||||
int old_items;
|
||||
int old_health;
|
||||
int old_armor;
|
||||
int old_movetype;
|
||||
int old_viewofs;
|
||||
int old_baseframe;
|
||||
int old_frame;
|
||||
int old_a_ammo1;
|
||||
int old_a_ammo2;
|
||||
int old_a_ammo3;
|
||||
#endif
|
||||
};
|
||||
|
||||
|
|
|
@ -16,18 +16,19 @@
|
|||
|
||||
enum
|
||||
{
|
||||
CROWBAR_IDLE,
|
||||
CROWBAR_DRAW,
|
||||
CROWBAR_HOLSTER,
|
||||
CROWBAR_ATTACK1HIT,
|
||||
CROWBAR_ATTACK1MISS,
|
||||
CROWBAR_ATTACK2MISS,
|
||||
CROWBAR_ATTACK2HIT,
|
||||
CROWBAR_ATTACK3MISS,
|
||||
CROWBAR_ATTACK3HIT
|
||||
CBAR_IDLE,
|
||||
CBAR_DRAW,
|
||||
CBAR_HOLSTER,
|
||||
CBAR_ATTACK1HIT,
|
||||
CBAR_ATTACK1MISS,
|
||||
CBAR_ATTACK2MISS,
|
||||
CBAR_ATTACK2HIT,
|
||||
CBAR_ATTACK3MISS,
|
||||
CBAR_ATTACK3HIT
|
||||
};
|
||||
|
||||
void w_crowbar_precache(void)
|
||||
void
|
||||
w_crowbar_precache(void)
|
||||
{
|
||||
precache_sound("weapons/cbar_miss1.wav");
|
||||
precache_sound("weapons/cbar_hit1.wav");
|
||||
|
@ -40,162 +41,203 @@ void w_crowbar_precache(void)
|
|||
precache_model("models/p_crowbar.mdl");
|
||||
}
|
||||
|
||||
void w_crowbar_updateammo(player pl)
|
||||
void
|
||||
w_crowbar_updateammo(player pl)
|
||||
{
|
||||
#ifdef SSQC
|
||||
Weapons_UpdateAmmo(pl, __NULL__, __NULL__, __NULL__);
|
||||
#endif
|
||||
}
|
||||
string w_crowbar_wmodel(void)
|
||||
|
||||
string
|
||||
w_crowbar_wmodel(void)
|
||||
{
|
||||
return "models/w_crowbar.mdl";
|
||||
}
|
||||
string w_crowbar_pmodel(void)
|
||||
string
|
||||
w_crowbar_pmodel(void)
|
||||
{
|
||||
return "models/p_crowbar.mdl";
|
||||
}
|
||||
string w_crowbar_deathmsg(void)
|
||||
|
||||
string
|
||||
w_crowbar_deathmsg(void)
|
||||
{
|
||||
return "%s was assaulted by %s's Crowbar.";
|
||||
}
|
||||
|
||||
void w_crowbar_draw(void)
|
||||
void
|
||||
w_CBAR_DRAW(void)
|
||||
{
|
||||
Weapons_SetModel("models/v_crowbar.mdl");
|
||||
Weapons_ViewAnimation(CROWBAR_DRAW);
|
||||
Weapons_ViewAnimation(CBAR_DRAW);
|
||||
}
|
||||
|
||||
void w_crowbar_holster(void)
|
||||
void
|
||||
w_CBAR_HOLSTER(void)
|
||||
{
|
||||
Weapons_ViewAnimation(CROWBAR_HOLSTER);
|
||||
Weapons_ViewAnimation(CBAR_HOLSTER);
|
||||
}
|
||||
void w_crowbar_primary(void)
|
||||
|
||||
void
|
||||
w_crowbar_primary(void)
|
||||
{
|
||||
int anim = 0;
|
||||
vector src;
|
||||
player pl = (player)self;
|
||||
|
||||
|
||||
if (pl.w_attack_next) {
|
||||
return;
|
||||
}
|
||||
|
||||
Weapons_MakeVectors();
|
||||
vector src = pl.origin + pl.view_ofs;
|
||||
traceline(src, src + (v_forward * 32), FALSE, pl);
|
||||
src = pl.origin + pl.view_ofs;
|
||||
traceline(src, src + (v_forward * 32), FALSE, pl);
|
||||
|
||||
int r = (float)input_sequence%3;
|
||||
switch (r) {
|
||||
case 0:
|
||||
Weapons_ViewAnimation(trace_fraction >= 1 ? CROWBAR_ATTACK1MISS:CROWBAR_ATTACK1HIT);
|
||||
break;
|
||||
case 1:
|
||||
Weapons_ViewAnimation(trace_fraction >= 1 ? CROWBAR_ATTACK2MISS:CROWBAR_ATTACK2HIT);
|
||||
break;
|
||||
default:
|
||||
Weapons_ViewAnimation(trace_fraction >= 1 ? CROWBAR_ATTACK3MISS:CROWBAR_ATTACK3HIT);
|
||||
}
|
||||
|
||||
if (trace_fraction >= 1.0) {
|
||||
pl.w_attack_next = 0.5f;
|
||||
} else {
|
||||
pl.w_attack_next = 0.25f;
|
||||
}
|
||||
|
||||
#ifdef SSQC
|
||||
if (pl.flags & FL_CROUCHING)
|
||||
Animation_PlayerTopTemp(ANIM_SHOOTCROWBAR, 0.5f);
|
||||
else
|
||||
Animation_PlayerTopTemp(ANIM_CR_SHOOTCROWBAR, 0.42f);
|
||||
|
||||
Weapons_PlaySound(pl, CHAN_WEAPON, "weapons/cbar_miss1.wav", 1, ATTN_NORM);
|
||||
int r = (float)input_sequence % 3;
|
||||
switch (r) {
|
||||
case 0:
|
||||
anim = trace_fraction >= 1 ? CBAR_ATTACK1MISS:CBAR_ATTACK1HIT;
|
||||
break;
|
||||
case 1:
|
||||
anim = trace_fraction >= 1 ? CBAR_ATTACK2MISS:CBAR_ATTACK2HIT;
|
||||
break;
|
||||
default:
|
||||
anim = trace_fraction >= 1 ? CBAR_ATTACK3MISS:CBAR_ATTACK3HIT;
|
||||
}
|
||||
Weapons_ViewAnimation(anim);
|
||||
|
||||
if (trace_fraction >= 1.0) {
|
||||
pl.w_attack_next = 0.5f;
|
||||
} else {
|
||||
pl.w_attack_next = 0.25f;
|
||||
}
|
||||
|
||||
pl.w_idle_next = 2.5f;
|
||||
|
||||
#ifdef SSQC
|
||||
if (pl.flags & FL_CROUCHING) {
|
||||
Animation_PlayerTopTemp(ANIM_SHOOTCROWBAR, 0.5f);
|
||||
} else {
|
||||
Animation_PlayerTopTemp(ANIM_CR_SHOOTCROWBAR, 0.42f);
|
||||
}
|
||||
|
||||
sound(pl, CHAN_WEAPON, "weapons/cbar_miss1.wav", 1, ATTN_NORM);
|
||||
|
||||
if (trace_fraction >= 1.0) {
|
||||
return;
|
||||
}
|
||||
|
||||
/* don't bother with decals, we got squibs */
|
||||
if (trace_ent.iBleeds) {
|
||||
Effect_CreateBlood(trace_endpos, [0,0,0]);
|
||||
} else {
|
||||
Effect_Impact(IMPACT_MELEE, trace_endpos, trace_plane_normal);
|
||||
|
||||
if (trace_ent.takedamage) {
|
||||
Damage_Apply(trace_ent, self, 10, trace_endpos, FALSE );
|
||||
|
||||
// TODO: Better way to find if it bleeds?
|
||||
if (trace_ent.iBleeds == 1) {
|
||||
if (random() < 0.33) {
|
||||
Weapons_PlaySound(pl, 8, "weapons/cbar_hitbod1.wav", 1, ATTN_NORM);
|
||||
} else if (random() < 0.66) {
|
||||
Weapons_PlaySound(pl, 8, "weapons/cbar_hitbod2.wav", 1, ATTN_NORM);
|
||||
} else {
|
||||
Weapons_PlaySound(pl, 8, "weapons/cbar_hitbod3.wav", 1, ATTN_NORM);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (trace_ent.takedamage) {
|
||||
Damage_Apply(trace_ent, self, 10, trace_endpos, FALSE );
|
||||
|
||||
if (!trace_ent.iBleeds) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (random() < 0.33) {
|
||||
sound(pl, 8, "weapons/cbar_hitbod1.wav", 1, ATTN_NORM);
|
||||
} else if (random() < 0.66) {
|
||||
sound(pl, 8, "weapons/cbar_hitbod2.wav", 1, ATTN_NORM);
|
||||
} else {
|
||||
if (random() < 0.5) {
|
||||
Weapons_PlaySound(pl, 8, "weapons/cbar_hit1.wav", 1, ATTN_NORM);
|
||||
} else {
|
||||
Weapons_PlaySound(pl, 8, "weapons/cbar_hit2.wav", 1, ATTN_NORM);
|
||||
}
|
||||
sound(pl, 8, "weapons/cbar_hitbod3.wav", 1, ATTN_NORM);
|
||||
}
|
||||
} else {
|
||||
if (random() < 0.5) {
|
||||
sound(pl, 8, "weapons/cbar_hit1.wav", 1, ATTN_NORM);
|
||||
} else {
|
||||
sound(pl, 8, "weapons/cbar_hit2.wav", 1, ATTN_NORM);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
pl.w_idle_next = 2.5f;
|
||||
}
|
||||
void w_crowbar_secondary(void)
|
||||
{
|
||||
|
||||
}
|
||||
void w_crowbar_reload(void)
|
||||
{
|
||||
|
||||
}
|
||||
void w_crowbar_release(void)
|
||||
|
||||
void
|
||||
w_crowbar_release(void)
|
||||
{
|
||||
player pl = (player)self;
|
||||
|
||||
if (pl.w_idle_next) {
|
||||
return;
|
||||
}
|
||||
|
||||
Weapons_ViewAnimation(CROWBAR_IDLE);
|
||||
Weapons_ViewAnimation(CBAR_IDLE);
|
||||
pl.w_idle_next = 15.0f;
|
||||
}
|
||||
|
||||
float w_crowbar_aimanim(void)
|
||||
float
|
||||
w_crowbar_aimanim(void)
|
||||
{
|
||||
return self.flags & FL_CROUCHING ? ANIM_CR_AIMCROWBAR : ANIM_AIMCROWBAR;
|
||||
}
|
||||
void w_crowbar_hudpic(int s, vector pos)
|
||||
|
||||
void
|
||||
w_crowbar_hudpic(int selected, vector pos)
|
||||
{
|
||||
#ifdef CSQC
|
||||
if (s) {
|
||||
drawsubpic(pos, [170,45], "sprites/640hud4.spr_0.tga", [0,0], [170/256,45/256], g_hud_color, 1, DRAWFLAG_ADDITIVE);
|
||||
if (selected) {
|
||||
drawsubpic(
|
||||
pos,
|
||||
[170,45],
|
||||
"sprites/640hud4.spr_0.tga",
|
||||
[0,0],
|
||||
[170/256,45/256],
|
||||
g_hud_color,
|
||||
1.0f,
|
||||
DRAWFLAG_ADDITIVE
|
||||
);
|
||||
} else {
|
||||
drawsubpic(pos, [170,45], "sprites/640hud1.spr_0.tga", [0,0], [170/256,45/256], g_hud_color, 1, DRAWFLAG_ADDITIVE);
|
||||
drawsubpic(
|
||||
pos,
|
||||
[170,45],
|
||||
"sprites/640hud1.spr_0.tga",
|
||||
[0,0],
|
||||
[170/256,45/256],
|
||||
g_hud_color,
|
||||
1.0f,
|
||||
DRAWFLAG_ADDITIVE
|
||||
);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
weapon_t w_crowbar =
|
||||
{
|
||||
ITEM_CROWBAR,
|
||||
0,
|
||||
0,
|
||||
"sprites/640hud1.spr_0.tga",
|
||||
[48,16],
|
||||
[192,0],
|
||||
w_crowbar_draw,
|
||||
w_crowbar_holster,
|
||||
w_crowbar_primary,
|
||||
w_crowbar_secondary,
|
||||
w_crowbar_reload,
|
||||
w_crowbar_release,
|
||||
__NULL__,
|
||||
w_crowbar_precache,
|
||||
__NULL__,
|
||||
w_crowbar_updateammo,
|
||||
w_crowbar_wmodel,
|
||||
w_crowbar_pmodel,
|
||||
w_crowbar_deathmsg,
|
||||
w_crowbar_aimanim,
|
||||
w_crowbar_hudpic
|
||||
.id = ITEM_CROWBAR,
|
||||
.slot = 0,
|
||||
.slot_pos = 0,
|
||||
.ki_spr = "sprites/640hud1.spr_0.tga",
|
||||
.ki_size = [48,16],
|
||||
.ki_xy = [192,0],
|
||||
.draw = w_CBAR_DRAW,
|
||||
.holster = w_CBAR_HOLSTER,
|
||||
.primary = w_crowbar_primary,
|
||||
.secondary = __NULL__,
|
||||
.reload = __NULL__,
|
||||
.release = w_crowbar_release,
|
||||
.crosshair = __NULL__,
|
||||
.precache = w_crowbar_precache,
|
||||
.pickup = __NULL__,
|
||||
.updateammo = w_crowbar_updateammo,
|
||||
.wmodel = w_crowbar_wmodel,
|
||||
.pmodel = w_crowbar_pmodel,
|
||||
.deathmsg = w_crowbar_deathmsg,
|
||||
.aimanim = w_crowbar_aimanim,
|
||||
.hudpic = w_crowbar_hudpic
|
||||
};
|
||||
|
||||
/* entity definitions for pickups */
|
||||
#ifdef SSQC
|
||||
void weapon_crowbar(void) {
|
||||
void
|
||||
weapon_crowbar(void)
|
||||
{
|
||||
Weapons_InitItem(WEAPON_CROWBAR);
|
||||
}
|
||||
#endif
|
||||
|
|
Loading…
Reference in a new issue