📄 cl_parse.pas
字号:
bits: Integer;
newnum: Integer;
nilstate: entity_state_t;
begin
FillChar(nilstate, sizeof(nilstate), 0);
newnum := CL_ParseEntityBits(@bits);
es := @cl_entities[newnum].baseline;
CL_ParseDelta(@nilstate, es, newnum, bits);
end;
{*
================
CL_LoadClientinfo
================
*}
procedure CL_LoadClientinfo(ci: clientinfo_p; s: pchar);
var
i: Integer;
t: PChar;
model_name: array[0..MAX_QPATH - 1] of char;
skin_name: array[0..MAX_QPATH - 1] of char;
model_filename: array[0..MAX_QPATH - 1] of char;
skin_filename: array[0..MAX_QPATH - 1] of char;
weapon_filename: array[0..MAX_QPATH - 1] of char;
begin
strncpy(ci^.cinfo, s, sizeof(ci^.cinfo));
ci^.cinfo[sizeof(ci^.cinfo) - 1] := #0;
// isolate the player's name
strncpy(ci^.name, s, sizeof(ci^.name));
ci^.name[sizeof(ci^.name) - 1] := #0;
t := strstr(s, '\');
if (t <> nil) then
begin
ci^.name[t - s] := #0;
s := t + 1;
end;
if (cl_noskins^.value <> 0) or (s^ = #0) then
begin
Com_sprintf(model_filename, sizeof(model_filename), 'players/male/tris.md2', []);
Com_sprintf(weapon_filename, sizeof(weapon_filename), 'players/male/weapon.md2', []);
Com_sprintf(skin_filename, sizeof(skin_filename), 'players/male/grunt.pcx', []);
Com_sprintf(ci^.iconname, sizeof(ci^.iconname), '/players/male/grunt_i.pcx', []);
ci^.model := re.RegisterModel(model_filename);
FillChar(ci^.weaponmodel, sizeof(ci^.weaponmodel), 0);
ci^.weaponmodel[0] := re.RegisterModel(weapon_filename);
ci^.skin := re.RegisterSkin(skin_filename);
ci^.icon := re.RegisterPic(ci^.iconname);
end
else
begin
// isolate the model name
strcpy(model_name, s);
t := strstr(model_name, '/');
if (t = nil) then
t := strstr(model_name, '\');
if (t = nil) then
t := model_name;
t^ := #0;
// isolate the skin name
strcpy(skin_name, s + strlen(model_name) + 1);
// model file
Com_sprintf(model_filename, sizeof(model_filename), 'players/%s/tris.md2', [model_name]);
ci^.model := re.RegisterModel(model_filename);
if (ci^.model = nil) then
begin
strcpy(model_name, 'male');
Com_sprintf(model_filename, sizeof(model_filename), 'players/male/tris.md2', []);
ci^.model := re.RegisterModel(model_filename);
end;
// skin file
Com_sprintf(skin_filename, sizeof(skin_filename), 'players/%s/%s.pcx', [model_name, skin_name]);
ci^.skin := re.RegisterSkin(skin_filename);
// if we don't have the skin and the model wasn't male,
// see if the male has it (this is for CTF's skins)
if (ci^.skin = nil) and (Q_stricmp(model_name, 'male') <> 0) then
begin
// change model to male
strcpy(model_name, 'male');
Com_sprintf(model_filename, sizeof(model_filename), 'players/male/tris.md2', []);
ci^.model := re.RegisterModel(model_filename);
// see if the skin exists for the male model
Com_sprintf(skin_filename, sizeof(skin_filename), 'players/%s/%s.pcx', [model_name, skin_name]);
ci^.skin := re.RegisterSkin(skin_filename);
end;
// if we still don't have a skin, it means that the male model didn't have
// it, so default to grunt
if (ci^.skin = nil) then
begin
// see if the skin exists for the male model
Com_sprintf(skin_filename, sizeof(skin_filename), 'players/%s/grunt.pcx', [model_name, skin_name]);
ci^.skin := re.RegisterSkin(skin_filename);
end;
// weapon file
for i := 0 to num_cl_weaponmodels - 1 do
begin
Com_sprintf(weapon_filename, sizeof(weapon_filename), 'players/%s/%s', [model_name, cl_weaponmodels[i]]);
ci^.weaponmodel[i] := re.RegisterModel(weapon_filename);
if (ci^.weaponmodel[i] = nil) and (strcmp(model_name, 'cyborg') = 0) then
begin
// try male
Com_sprintf(weapon_filename, sizeof(weapon_filename), 'players/male/%s', [cl_weaponmodels[i]]);
ci^.weaponmodel[i] := re.RegisterModel(weapon_filename);
end;
if (cl_vwep^.value = 0) then
break; // only one when vwep is off
end;
// icon file
Com_sprintf(ci^.iconname, sizeof(ci^.iconname), '/players/%s/%s_i.pcx', [model_name, skin_name]);
ci^.icon := re.RegisterPic(ci^.iconname);
end;
// must have loaded all data types to be valud
if (ci^.skin = nil) or (ci^.icon = nil) or (ci^.model = nil) or (ci^.weaponmodel[0] = nil) then
begin
ci^.skin := nil;
ci^.icon := nil;
ci^.model := nil;
ci^.weaponmodel[0] := nil;
end;
end;
{*
================
CL_ParseClientinfo
Load the skin, icon, and model for a client
================
*}
procedure CL_ParseClientinfo(player: Integer);
var
s: pchar;
ci: clientinfo_p;
begin
s := cl.configstrings[player + CS_PLAYERSKINS];
ci := @cl.clientinfo[player];
CL_LoadClientinfo(ci, s);
end;
{*
================
CL_ParseConfigString
================
*}
procedure CL_ParseConfigString();
var
i: Integer;
s: PChar;
olds: array[0..MAX_QPATH - 1] of char;
begin
i := MSG_ReadShort(net_message);
if (i < 0) or (i >= MAX_CONFIGSTRINGS) then
Com_Error(ERR_DROP, 'configstring > MAX_CONFIGSTRINGS');
s := MSG_ReadString(net_message);
strncpy(olds, cl.configstrings[i], sizeof(olds));
olds[sizeof(olds) - 1] := #0;
strcpy(cl.configstrings[i], s);
// do something apropriate
if (i >= CS_LIGHTS) and (i < CS_LIGHTS + MAX_LIGHTSTYLES) then
CL_SetLightstyle(i - CS_LIGHTS)
else if (i = CS_CDTRACK) then
begin
if (cl.refresh_prepped) then
CDAudio_Play(StrToInt(cl.configstrings[CS_CDTRACK]), true);
end
else if (i >= CS_MODELS) and (i < CS_MODELS + MAX_MODELS) then
begin
if (cl.refresh_prepped) then
begin
cl.model_draw[i - CS_MODELS] := re.RegisterModel(cl.configstrings[i]);
if (cl.configstrings[i][0] = '*') then
cl.model_clip[i - CS_MODELS] := CM_InlineModel(cl.configstrings[i])
else
cl.model_clip[i - CS_MODELS] := nil;
end;
end
else if (i >= CS_SOUNDS) and (i < CS_SOUNDS + MAX_MODELS) then
begin
if (cl.refresh_prepped) then
cl.sound_precache[i - CS_SOUNDS] := S_RegisterSound(cl.configstrings[i]);
end
else if (i >= CS_IMAGES) and (i < CS_IMAGES + MAX_MODELS) then
begin
if (cl.refresh_prepped) then
cl.image_precache[i - CS_IMAGES] := re.RegisterPic(cl.configstrings[i]);
end
else if (i >= CS_PLAYERSKINS) and (i < CS_PLAYERSKINS + MAX_CLIENTS) then
begin
if (cl.refresh_prepped) and (strcmp(olds, s) <> 0) then
CL_ParseClientinfo(i - CS_PLAYERSKINS);
end;
end;
{*
=====================================================================
ACTION MESSAGES
=====================================================================
*}
{*
==================
CL_ParseStartSoundPacket
==================
*}
procedure CL_ParseStartSoundPacket();
var
pos_v: vec3_t;
pos: PSingle;
channel, ent: Integer;
sound_num: Integer;
volume: Single;
attenuation: Single;
flags: Integer;
ofs: Single;
begin
flags := MSG_ReadByte(net_message);
sound_num := MSG_ReadByte(net_message);
if (flags and SND_VOLUME <> 0) then
volume := MSG_ReadByte(net_message) / 255.0
else
volume := DEFAULT_SOUND_PACKET_VOLUME;
if (flags and SND_ATTENUATION <> 0) then
attenuation := MSG_ReadByte(net_message) / 64.0
else
attenuation := DEFAULT_SOUND_PACKET_ATTENUATION;
if (flags and SND_OFFSET <> 0) then
ofs := MSG_ReadByte(net_message) / 1000.0
else
ofs := 0;
if (flags and SND_ENT <> 0) then
begin
// entity reletive
channel := MSG_ReadShort(net_message);
ent := channel shr 3;
if (ent > MAX_EDICTS) then
Com_Error(ERR_DROP, 'CL_ParseStartSoundPacket: ent = %i', [ent]);
channel := channel and 7;
end
else
begin
ent := 0;
channel := 0;
end;
if (flags and SND_POS <> 0) then
begin
// positioned in space
MSG_ReadPos(net_message, pos_v);
pos := @pos_v;
end
else // use entity number
pos := nil;
if (cl.sound_precache[sound_num] = nil) then
exit;
S_StartSound(vec3_p(pos), ent, channel, cl.sound_precache[sound_num], volume, attenuation, ofs);
end;
procedure SHOWNET(s: pchar);
begin
if (cl_shownet^.value >= 2) then
Com_Printf('%3d:%s'#10, [net_message.readcount - 1, s]);
end;
{*
=====================
CL_ParseServerMessage
=====================
*}
procedure CL_ParseServerMessage();
var
cmd: Integer;
s: PChar;
i: Integer;
begin
//
// if recording demos, copy the message out
//
if (cl_shownet^.value = 1) then
Com_Printf('%i ', [net_message.cursize])
else if (cl_shownet^.value >= 2) then
Com_Printf('------------------'#10);
//
// parse the message
//
while (true) do
begin
if (net_message.readcount > net_message.cursize) then
begin
Com_Error(ERR_DROP, 'CL_ParseServerMessage: Bad server message');
break;
end;
cmd := MSG_ReadByte(net_message);
if (cmd = -1) then
begin
SHOWNET('END OF MESSAGE');
break;
end;
if (cl_shownet^.value >= 2) then
begin
if (svc_strings[cmd] = nil) then
Com_Printf('%3d:BAD CMD %d'#10, [net_message.readcount - 1, cmd])
else
SHOWNET(svc_strings[cmd]);
end;
// other commands
case svc_ops_e(cmd) of
svc_nop:
// Com_Printf ("svc_nop\n");
;
svc_disconnect:
Com_Error(ERR_DISCONNECT, 'Server disconnected'#10);
svc_reconnect:
begin
Com_Printf('Server disconnected, reconnecting'#10);
if (cls.download > 0) then
begin
//ZOID, close download
FileClose(cls.download);
cls.download := 0;
end;
cls.state := ca_connecting;
cls.connect_time := -99999; // CL_CheckForResend() will fire immediately
end;
svc_print:
begin
i := MSG_ReadByte(net_message);
if (i = PRINT_CHAT) then
begin
S_StartLocalSound('misc/talk.wav');
con.ormask := 128;
end;
Com_Printf('%s', [MSG_ReadString(net_message)]);
con.ormask := 0;
end;
svc_centerprint:
SCR_CenterPrint(MSG_ReadString(net_message));
svc_stufftext:
begin
s := MSG_ReadString(net_message);
Com_DPrintf('stufftext: %s'#10, [s]);
Cbuf_AddText(s);
end;
svc_serverdata:
begin
Cbuf_Execute(); // make sure any stuffed commands are done
CL_ParseServerData();
end;
svc_configstring:
CL_ParseConfigString();
svc_sound:
CL_ParseStartSoundPacket();
svc_spawnbaseline:
CL_ParseBaseline();
svc_temp_entity:
CL_ParseTEnt();
svc_muzzleflash:
CL_ParseMuzzleFlash();
svc_muzzleflash2:
CL_ParseMuzzleFlash2();
svc_download:
CL_ParseDownload();
svc_frame:
CL_ParseFrame();
svc_inventory:
CL_ParseInventory();
svc_layout:
begin
s := MSG_ReadString(net_message);
strncpy(cl.layout, s, sizeof(cl.layout) - 1);
end;
svc_playerinfo,
svc_packetentities,
svc_deltapacketentities:
Com_Error(ERR_DROP, 'Out of place frame data');
else
begin
Com_Error(ERR_DROP, 'CL_ParseServerMessage: Illegible server message'#10);
end;
end;
end;
CL_AddNetgraph();
//
// we don't know if it is ok to save a demo message until
// after we have parsed the frame
//
if (cls.demorecording) and (not cls.demowaiting) then
CL_WriteDemoMessage();
end;
end.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -