📄 sv_ents.c
字号:
/*
Copyright (C) 1997-2001 Id Software, Inc.
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#include "server.h"
/*
=============================================================================
Encode a client frame onto the network channel
=============================================================================
*/
#if 0
// because there can be a lot of projectiles, there is a special
// network protocol for them
#define MAX_PROJECTILES 64
edict_t *projectiles[MAX_PROJECTILES];
int numprojs;
cvar_t *sv_projectiles;
qboolean SV_AddProjectileUpdate (edict_t *ent)
{
if (!sv_projectiles)
sv_projectiles = Cvar_Get("sv_projectiles", "1", 0);
if (!sv_projectiles->value)
return false;
if (!(ent->svflags & SVF_PROJECTILE))
return false;
if (numprojs == MAX_PROJECTILES)
return true;
projectiles[numprojs++] = ent;
return true;
}
void SV_EmitProjectileUpdate (sizebuf_t *msg)
{
byte bits[16]; // [modelindex] [48 bits] xyz p y 12 12 12 8 8 [entitynum] [e2]
int n, i;
edict_t *ent;
int x, y, z, p, yaw;
int len;
if (!numprojs)
return;
MSG_WriteByte (msg, numprojs);
for (n=0 ; n<numprojs ; n++)
{
ent = projectiles[n];
x = (int)(ent->s.origin[0]+4096)>>1;
y = (int)(ent->s.origin[1]+4096)>>1;
z = (int)(ent->s.origin[2]+4096)>>1;
p = (int)(256*ent->s.angles[0]/360)&255;
yaw = (int)(256*ent->s.angles[1]/360)&255;
len = 0;
bits[len++] = x;
bits[len++] = (x>>8) | (y<<4);
bits[len++] = (y>>4);
bits[len++] = z;
bits[len++] = (z>>8);
if (ent->s.effects & EF_BLASTER)
bits[len-1] |= 64;
if (ent->s.old_origin[0] != ent->s.origin[0] ||
ent->s.old_origin[1] != ent->s.origin[1] ||
ent->s.old_origin[2] != ent->s.origin[2]) {
bits[len-1] |= 128;
x = (int)(ent->s.old_origin[0]+4096)>>1;
y = (int)(ent->s.old_origin[1]+4096)>>1;
z = (int)(ent->s.old_origin[2]+4096)>>1;
bits[len++] = x;
bits[len++] = (x>>8) | (y<<4);
bits[len++] = (y>>4);
bits[len++] = z;
bits[len++] = (z>>8);
}
bits[len++] = p;
bits[len++] = yaw;
bits[len++] = ent->s.modelindex;
bits[len++] = (ent->s.number & 0x7f);
if (ent->s.number > 255) {
bits[len-1] |= 128;
bits[len++] = (ent->s.number >> 7);
}
for (i=0 ; i<len ; i++)
MSG_WriteByte (msg, bits[i]);
}
}
#endif
/*
=============
SV_EmitPacketEntities
Writes a delta update of an entity_state_t list to the message.
=============
*/
void SV_EmitPacketEntities (client_frame_t *from, client_frame_t *to, sizebuf_t *msg)
{
entity_state_t *oldent, *newent;
int oldindex, newindex;
int oldnum, newnum;
int from_num_entities;
int bits;
#if 0
if (numprojs)
MSG_WriteByte (msg, svc_packetentities2);
else
#endif
MSG_WriteByte (msg, svc_packetentities);
if (!from)
from_num_entities = 0;
else
from_num_entities = from->num_entities;
newindex = 0;
oldindex = 0;
while (newindex < to->num_entities || oldindex < from_num_entities)
{
if (newindex >= to->num_entities)
newnum = 9999;
else
{
newent = &svs.client_entities[(to->first_entity+newindex)%svs.num_client_entities];
newnum = newent->number;
}
if (oldindex >= from_num_entities)
oldnum = 9999;
else
{
oldent = &svs.client_entities[(from->first_entity+oldindex)%svs.num_client_entities];
oldnum = oldent->number;
}
if (newnum == oldnum)
{ // delta update from old position
// because the force parm is false, this will not result
// in any bytes being emited if the entity has not changed at all
// note that players are always 'newentities', this updates their oldorigin always
// and prevents warping
MSG_WriteDeltaEntity (oldent, newent, msg, false, newent->number <= maxclients->value);
oldindex++;
newindex++;
continue;
}
if (newnum < oldnum)
{ // this is a new entity, send it from the baseline
MSG_WriteDeltaEntity (&sv.baselines[newnum], newent, msg, true, true);
newindex++;
continue;
}
if (newnum > oldnum)
{ // the old entity isn't present in the new message
bits = U_REMOVE;
if (oldnum >= 256)
bits |= U_NUMBER16 | U_MOREBITS1;
MSG_WriteByte (msg, bits&255 );
if (bits & 0x0000ff00)
MSG_WriteByte (msg, (bits>>8)&255 );
if (bits & U_NUMBER16)
MSG_WriteShort (msg, oldnum);
else
MSG_WriteByte (msg, oldnum);
oldindex++;
continue;
}
}
MSG_WriteShort (msg, 0); // end of packetentities
#if 0
if (numprojs)
SV_EmitProjectileUpdate(msg);
#endif
}
/*
=============
SV_WritePlayerstateToClient
=============
*/
void SV_WritePlayerstateToClient (client_frame_t *from, client_frame_t *to, sizebuf_t *msg)
{
int i;
int pflags;
player_state_t *ps, *ops;
player_state_t dummy;
int statbits;
ps = &to->ps;
if (!from)
{
memset (&dummy, 0, sizeof(dummy));
ops = &dummy;
}
else
ops = &from->ps;
//
// determine what needs to be sent
//
pflags = 0;
if (ps->pmove.pm_type != ops->pmove.pm_type)
pflags |= PS_M_TYPE;
if (ps->pmove.origin[0] != ops->pmove.origin[0]
|| ps->pmove.origin[1] != ops->pmove.origin[1]
|| ps->pmove.origin[2] != ops->pmove.origin[2] )
pflags |= PS_M_ORIGIN;
if (ps->pmove.velocity[0] != ops->pmove.velocity[0]
|| ps->pmove.velocity[1] != ops->pmove.velocity[1]
|| ps->pmove.velocity[2] != ops->pmove.velocity[2] )
pflags |= PS_M_VELOCITY;
if (ps->pmove.pm_time != ops->pmove.pm_time)
pflags |= PS_M_TIME;
if (ps->pmove.pm_flags != ops->pmove.pm_flags)
pflags |= PS_M_FLAGS;
if (ps->pmove.gravity != ops->pmove.gravity)
pflags |= PS_M_GRAVITY;
if (ps->pmove.delta_angles[0] != ops->pmove.delta_angles[0]
|| ps->pmove.delta_angles[1] != ops->pmove.delta_angles[1]
|| ps->pmove.delta_angles[2] != ops->pmove.delta_angles[2] )
pflags |= PS_M_DELTA_ANGLES;
if (ps->viewoffset[0] != ops->viewoffset[0]
|| ps->viewoffset[1] != ops->viewoffset[1]
|| ps->viewoffset[2] != ops->viewoffset[2] )
pflags |= PS_VIEWOFFSET;
if (ps->viewangles[0] != ops->viewangles[0]
|| ps->viewangles[1] != ops->viewangles[1]
|| ps->viewangles[2] != ops->viewangles[2] )
pflags |= PS_VIEWANGLES;
if (ps->kick_angles[0] != ops->kick_angles[0]
|| ps->kick_angles[1] != ops->kick_angles[1]
|| ps->kick_angles[2] != ops->kick_angles[2] )
pflags |= PS_KICKANGLES;
if (ps->blend[0] != ops->blend[0]
|| ps->blend[1] != ops->blend[1]
|| ps->blend[2] != ops->blend[2]
|| ps->blend[3] != ops->blend[3] )
pflags |= PS_BLEND;
if (ps->fov != ops->fov)
pflags |= PS_FOV;
if (ps->rdflags != ops->rdflags)
pflags |= PS_RDFLAGS;
if (ps->gunframe != ops->gunframe)
pflags |= PS_WEAPONFRAME;
pflags |= PS_WEAPONINDEX;
//
// write it
//
MSG_WriteByte (msg, svc_playerinfo);
MSG_WriteShort (msg, pflags);
//
// write the pmove_state_t
//
if (pflags & PS_M_TYPE)
MSG_WriteByte (msg, ps->pmove.pm_type);
if (pflags & PS_M_ORIGIN)
{
MSG_WriteShort (msg, ps->pmove.origin[0]);
MSG_WriteShort (msg, ps->pmove.origin[1]);
MSG_WriteShort (msg, ps->pmove.origin[2]);
}
if (pflags & PS_M_VELOCITY)
{
MSG_WriteShort (msg, ps->pmove.velocity[0]);
MSG_WriteShort (msg, ps->pmove.velocity[1]);
MSG_WriteShort (msg, ps->pmove.velocity[2]);
}
if (pflags & PS_M_TIME)
MSG_WriteByte (msg, ps->pmove.pm_time);
if (pflags & PS_M_FLAGS)
MSG_WriteByte (msg, ps->pmove.pm_flags);
if (pflags & PS_M_GRAVITY)
MSG_WriteShort (msg, ps->pmove.gravity);
if (pflags & PS_M_DELTA_ANGLES)
{
MSG_WriteShort (msg, ps->pmove.delta_angles[0]);
MSG_WriteShort (msg, ps->pmove.delta_angles[1]);
MSG_WriteShort (msg, ps->pmove.delta_angles[2]);
}
//
// write the rest of the player_state_t
//
if (pflags & PS_VIEWOFFSET)
{
MSG_WriteChar (msg, ps->viewoffset[0]*4);
MSG_WriteChar (msg, ps->viewoffset[1]*4);
MSG_WriteChar (msg, ps->viewoffset[2]*4);
}
if (pflags & PS_VIEWANGLES)
{
MSG_WriteAngle16 (msg, ps->viewangles[0]);
MSG_WriteAngle16 (msg, ps->viewangles[1]);
MSG_WriteAngle16 (msg, ps->viewangles[2]);
}
if (pflags & PS_KICKANGLES)
{
MSG_WriteChar (msg, ps->kick_angles[0]*4);
MSG_WriteChar (msg, ps->kick_angles[1]*4);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -