⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 cl_ents.pas

📁 delphi编的不错的贪吃蛇
💻 PAS
📖 第 1 页 / 共 3 页
字号:
{100%}
{----------------------------------------------------------------------------}
{                                                                            }
{ File(s): cl_ents.c                                                        }
{ Content: Quake2\Client - builds an intended movement command to send to the server }
{                                                                            }
{ Initial conversion by : Dart - hanhpham@web.de                           }
{ Initial conversion on : 04-April-2002                                        }
{                                                                            }
{ This File contains part of convertion of Quake2 source to ObjectPascal.    }
{ More information about this project can be found at:                       }
{ http://www.sulaco.co.za/quake2/                                            }
{                                                                            }
{ 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.                       }
{                                                                            }
{----------------------------------------------------------------------------}
{ * Updated:								                                                 }
{ 03-Jun-2002 Juha Hartikainen (juha@linearteam.org)                         }
{ - MANY language fixes                                                      }
{                                                                            }
{ 08-Jun-2002 Juha Hartikainen (juha@linearteam.org)                         }
{ - Finished conversion.                                                     }
{                                                                            }
{ * ToDo:                                                                    }
{ - All places with TODO define                                              }
{----------------------------------------------------------------------------}

{.$DEFINE TODO}
unit cl_ents;

interface

uses
  client,
  q_shared_add,
  q_shared;

procedure CL_AddEntities;
procedure CL_GetEntitySoundOrigin(ent: integer; var org: vec3_t);
function CL_ParseEntityBits(bits: PCardinal): integer;
procedure CL_ParseDelta(pfrom: entity_state_p; pto: entity_state_p; number: integer; bits: integer);
procedure CL_ParseFrame;

var
  //PGM
  vidref_val: integer;
  //PGM

implementation

uses
  Common,
  CPas,
  net_chan,
  cl_scrn,
  cl_pred,
  cl_main,
  cl_view,
  Files,
  ref,
  cl_parse,
  cl_newfx,
  cl_tent,
  {$IFDEF WIN32}
  vid_dll,
  {$ELSE}
  vid_so,
  {$ENDIF}
  cl_fx;

{*
=========================================================================

FRAME PARSING

=========================================================================
*}

{*
=================
CL_ParseEntityBits

Returns the entity number and the header bits
=================
*}
var
  bitcounts: array[0..32 - 1] of integer; /// just for protocol profiling

function CL_ParseEntityBits(bits: PCardinal): integer;
var
  b, total: Cardinal;
  i: integer;
  number: integer;
begin
  total := MSG_ReadByte(net_message);
  if (total and U_MOREBITS1 <> 0) then
  begin
    b := MSG_ReadByte(net_message);
    total := total or (b shl 8);
  end;
  if (total and U_MOREBITS2 <> 0) then
  begin
    b := MSG_ReadByte(net_message);
    total := total or (b shl 16);
  end;
  if (total and U_MOREBITS3 <> 0) then
  begin
    b := MSG_ReadByte(net_message);
    total := total or (b shl 24);
  end;
  // count the bits for net profiling
  for i := 0 to 32 - 1 do
    if (total and (1 shl i)) > 0 then
      inc(bitcounts[i]);
  if (total and U_NUMBER16 <> 0) then
    number := MSG_ReadShort(net_message)
  else
    number := MSG_ReadByte(net_message);
  bits^ := total;
  result := number;
end;

{*
==================
CL_ParseDelta

Can go from either a baseline or a previous packet_entity
==================
*}
procedure CL_ParseDelta(pfrom: entity_state_p; pto: entity_state_p; number: integer; bits: integer);
begin                                   // set everything to the state we are delta'ing from
  pto^ := pfrom^;

  VectorCopy(pfrom.origin, pto.old_origin);
  pto.number := number;

  if (bits and U_MODEL <> 0) then
    pto.modelindex := MSG_ReadByte(net_message);
  if (bits and U_MODEL2 <> 0) then
    pto.modelindex2 := MSG_ReadByte(net_message);
  if (bits and U_MODEL3 <> 0) then
    pto.modelindex3 := MSG_ReadByte(net_message);
  if (bits and U_MODEL4 <> 0) then
    pto.modelindex4 := MSG_ReadByte(net_message);
  if (bits and U_FRAME8 <> 0) then
    pto.frame := MSG_ReadByte(net_message);
  if (bits and U_FRAME16 <> 0) then
    pto.frame := MSG_ReadShort(net_message);

  if (bits and U_SKIN8 <> 0) and
    (bits and U_SKIN16 <> 0) then       //used for laser colors
    pto.skinnum := MSG_ReadLong(net_message)
  else if (bits and U_SKIN8 <> 0) then
    pto.skinnum := MSG_ReadByte(net_message)
  else if (bits and U_SKIN16 <> 0) then
    pto.skinnum := MSG_ReadShort(net_message);

  if ((bits and (U_EFFECTS8 or U_EFFECTS16)) = (U_EFFECTS8 or U_EFFECTS16)) then
    pto.effects := MSG_ReadLong(net_message)
  else if (bits and U_EFFECTS8 <> 0) then
    pto.effects := MSG_ReadByte(net_message)
  else if (bits and U_EFFECTS16 <> 0) then
    pto.effects := MSG_ReadShort(net_message);

  if ((bits and (U_RENDERFX8 or U_RENDERFX16)) = (U_RENDERFX8 or U_RENDERFX16)) then
    pto.renderfx := MSG_ReadLong(net_message)
  else if (bits and U_RENDERFX8 <> 0) then
    pto.renderfx := MSG_ReadByte(net_message)
  else if (bits and U_RENDERFX16 <> 0) then
    pto.renderfx := MSG_ReadShort(net_message);

  if (bits and U_ORIGIN1 <> 0) then
    pto.origin[0] := MSG_ReadCoord(net_message);
  if (bits and U_ORIGIN2 <> 0) then
    pto.origin[1] := MSG_ReadCoord(net_message);
  if (bits and U_ORIGIN3 <> 0) then
    pto.origin[2] := MSG_ReadCoord(net_message);

  if (bits and U_ANGLE1 <> 0) then
    pto.angles[0] := MSG_ReadAngle(net_message);
  if (bits and U_ANGLE2 <> 0) then
    pto.angles[1] := MSG_ReadAngle(net_message);
  if (bits and U_ANGLE3 <> 0) then
    pto.angles[2] := MSG_ReadAngle(net_message);

  if (bits and U_OLDORIGIN <> 0) then
    MSG_ReadPos(net_message, pto.old_origin);

  if (bits and U_SOUND <> 0) then
    pto.sound := MSG_ReadByte(net_message);

  if (bits and U_EVENT <> 0) then
    pto.event := entity_event_t(MSG_ReadByte(net_message))
  else
    pto.event := entity_event_t(0);

  if (bits and U_SOLID <> 0) then
    pto.solid := MSG_ReadShort(net_message);
end;

{*
==================
CL_DeltaEntity

Parses deltas from the given base and adds the resulting entity
to the current frame
==================
*}
procedure CL_DeltaEntity(frame: frame_p; newnum: integer; old: entity_state_p; bits: integer);
var
  ent: centity_p;
  state: entity_state_p;
begin
  ent := @cl_entities[newnum];

  state := @cl_parse_entities[cl.parse_entities and (MAX_PARSE_ENTITIES - 1)];
  inc(cl.parse_entities);
  inc(frame.num_entities);
  CL_ParseDelta(old, state, newnum, bits);

  // some data changes will force no lerping
  if (state.modelindex <> ent.current.modelindex) or
    (state.modelindex2 <> ent.current.modelindex2) or
    (state.modelindex3 <> ent.current.modelindex3) or
    (state.modelindex4 <> ent.current.modelindex4) or
    (abs(state.origin[0] - ent.current.origin[0]) > 512) or
    (abs(state.origin[1] - ent.current.origin[1]) > 512) or
    (abs(state.origin[2] - ent.current.origin[2]) > 512) or
    (state.event = EV_PLAYER_TELEPORT) or
    (state.event = EV_OTHER_TELEPORT) then
    ent.serverframe := -99;

  if (ent.serverframe <> cl.frame.serverframe - 1) then
  begin                                 // wasn't in last update, so initialize some things
    ent.trailcount := 1024;             // for diminishing rocket / grenade trails
    // duplicate the current state so lerping doesn't hurt anything
    ent.prev := state^;
    if (state.event = EV_OTHER_TELEPORT) then
    begin
      VectorCopy(state.origin, ent.prev.origin);
      VectorCopy(state.origin, ent.lerp_origin);
    end
    else
    begin
      VectorCopy(state.old_origin, ent.prev.origin);
      VectorCopy(state.old_origin, ent.lerp_origin);
    end;
  end
  else
  begin                                 // shuffle the last state to previous
    ent.prev := ent.current;
  end;

  ent.serverframe := cl.frame.serverframe;
  ent.current := state^;
end;

{*
==================
CL_ParsePacketEntities

An svc_packetentities has just been parsed, deal with the
rest of the data stream.
==================
*}
procedure CL_ParsePacketEntities(oldframe: frame_p; newframe: frame_p);
var
  newnum: integer;
  bits: Cardinal;
  oldstate: entity_state_p;
  oldindex, oldnum: integer;
begin
  newframe^.parse_entities := cl.parse_entities;
  newframe^.num_entities := 0;

  // delta from the entities present in oldframe
  oldindex := 0;
  if (oldframe = nil) then
    oldnum := 99999
  else
  begin
    if (oldindex >= oldframe^.num_entities) then
      oldnum := 99999
    else
    begin
      oldstate := @cl_parse_entities[(oldframe^.parse_entities + oldindex) and (MAX_PARSE_ENTITIES - 1)];
      oldnum := oldstate^.number;
    end;
  end;

  while (true) do
  begin
    newnum := CL_ParseEntityBits(@bits);
    if (newnum >= MAX_EDICTS) then
      Com_Error(ERR_DROP, 'CL_ParsePacketEntities: bad number:%d', [newnum]);

    if (net_message.readcount > net_message.cursize) then
      Com_Error(ERR_DROP, 'CL_ParsePacketEntities: end of message', []);

    if (newnum = 0) then
      break;

    while (oldnum < newnum) do
    begin                               // one or more entities from the old packet are unchanged
      if (cl_shownet.value = 3) then
        Com_Printf('   unchanged: %d'#10, [oldnum]);
      CL_DeltaEntity(newframe, oldnum, oldstate, 0);

      inc(oldindex);

      if (oldindex >= oldframe^.num_entities) then
        oldnum := 99999
      else
      begin
        oldstate := @cl_parse_entities[(oldframe^.parse_entities + oldindex) and (MAX_PARSE_ENTITIES - 1)];
        oldnum := oldstate.number;
      end;
    end;

    if (bits and U_REMOVE <> 0) then
    begin                               // the entity present in oldframe is not in the current frame
      if (cl_shownet.value = 3) then
        Com_Printf('   remove: %d'#10, [newnum]);
      if (oldnum <> newnum) then
        Com_Printf('U_REMOVE: oldnum != newnum'#10, []);

      inc(oldindex);

      if (oldindex >= oldframe.num_entities) then
        oldnum := 99999
      else
      begin
        oldstate := @cl_parse_entities[(oldframe^.parse_entities + oldindex) and (MAX_PARSE_ENTITIES - 1)];
        oldnum := oldstate^.number;
      end;
      continue;
    end;

    if (oldnum = newnum) then
    begin                               // delta from previous state
      if (cl_shownet.value = 3) then
        Com_Printf('   delta: %d'#10, [newnum]);
      CL_DeltaEntity(newframe, newnum, oldstate, bits);

      inc(oldindex);

      if (oldindex >= oldframe^.num_entities) then
        oldnum := 99999
      else
      begin
        oldstate := @cl_parse_entities[(oldframe^.parse_entities + oldindex) and (MAX_PARSE_ENTITIES - 1)];
        oldnum := oldstate^.number;
      end;
      continue;
    end;

    if (oldnum > newnum) then
    begin                               // delta from baseline
      if (cl_shownet.value = 3) then
        Com_Printf('   baseline: %d'#10, [newnum]);
      CL_DeltaEntity(newframe, newnum, @cl_entities[newnum].baseline, bits);
      continue;
    end;

  end;

  // any remaining entities in the old frame are copied over
  while (oldnum <> 99999) do
  begin                                 // one or more entities from the old packet are unchanged
    if (cl_shownet.value = 3) then
      Com_Printf('   unchanged: %d'#10, [oldnum]);
    CL_DeltaEntity(newframe, oldnum, oldstate, 0);

    inc(oldindex);

    if (oldindex >= oldframe.num_entities) then
      oldnum := 99999
    else
    begin
      oldstate := @cl_parse_entities[(oldframe^.parse_entities + oldindex) and (MAX_PARSE_ENTITIES - 1)];
      oldnum := oldstate.number;
    end;
  end;
end;

{*
===================
CL_ParsePlayerstate
===================
*}
procedure CL_ParsePlayerstate(oldframe: frame_p; newframe: frame_p);
var
  flags: integer;
  state: player_state_p;
  i: integer;
  statbits: integer;
begin
  state := @newframe.playerstate;

  // clear to old value before delta parsing
  if (oldframe <> nil) then
    state^ := oldframe.playerstate
  else
    FillChar(state^, sizeof(player_state_t), 0);

  flags := MSG_ReadShort(net_message);

  //
  // parse the pmove_state_t
  //
  if (flags and PS_M_TYPE <> 0) then
    state.pmove.pm_type := pmtype_t(MSG_ReadByte(net_message));

  if (flags and PS_M_ORIGIN <> 0) then
  begin
    state.pmove.origin[0] := MSG_ReadShort(net_message);
    state.pmove.origin[1] := MSG_ReadShort(net_message);
    state.pmove.origin[2] := MSG_ReadShort(net_message);
  end;

  if (flags and PS_M_VELOCITY <> 0) then
  begin
    state.pmove.velocity[0] := MSG_ReadShort(net_message);
    state.pmove.velocity[1] := MSG_ReadShort(net_message);
    state.pmove.velocity[2] := MSG_ReadShort(net_message);
  end;

  if (flags and PS_M_TIME <> 0) then
    state.pmove.pm_time := MSG_ReadByte(net_message);

  if (flags and PS_M_FLAGS <> 0) then
    state.pmove.pm_flags := MSG_ReadByte(net_message);

  if (flags and PS_M_GRAVITY <> 0) then
    state.pmove.gravity := MSG_ReadShort(net_message);

  if (flags and PS_M_DELTA_ANGLES <> 0) then
  begin
    state.pmove.delta_angles[0] := MSG_ReadShort(net_message);
    state.pmove.delta_angles[1] := MSG_ReadShort(net_message);
    state.pmove.delta_angles[2] := MSG_ReadShort(net_message);
  end;

  if (cl.attractloop) then
    state.pmove.pm_type := PM_FREEZE;   // demo playback

  //
  // parse the rest of the player_state_t
  //
  if (flags and PS_VIEWOFFSET <> 0) then
  begin
    state.viewoffset[0] := MSG_ReadChar(net_message) * 0.25;
    state.viewoffset[1] := MSG_ReadChar(net_message) * 0.25;
    state.viewoffset[2] := MSG_ReadChar(net_message) * 0.25;
  end;

  if (flags and PS_VIEWANGLES <> 0) then
  begin
    state.viewangles[0] := MSG_ReadAngle16(net_message);
    state.viewangles[1] := MSG_ReadAngle16(net_message);
    state.viewangles[2] := MSG_ReadAngle16(net_message);
  end;

  if (flags and PS_KICKANGLES <> 0) then
  begin
    state.kick_angles[0] := MSG_ReadChar(net_message) * 0.25;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -