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

📄 cl_ents.pas

📁 delphi编的不错的贪吃蛇
💻 PAS
📖 第 1 页 / 共 3 页
字号:
    state.kick_angles[1] := MSG_ReadChar(net_message) * 0.25;
    state.kick_angles[2] := MSG_ReadChar(net_message) * 0.25;
  end;

  if (flags and PS_WEAPONINDEX <> 0) then
  begin
    state.gunindex := MSG_ReadByte(net_message);
  end;

  if (flags and PS_WEAPONFRAME <> 0) then
  begin
    state.gunframe := MSG_ReadByte(net_message);
    state.gunoffset[0] := MSG_ReadChar(net_message) * 0.25;
    state.gunoffset[1] := MSG_ReadChar(net_message) * 0.25;
    state.gunoffset[2] := MSG_ReadChar(net_message) * 0.25;
    state.gunangles[0] := MSG_ReadChar(net_message) * 0.25;
    state.gunangles[1] := MSG_ReadChar(net_message) * 0.25;
    state.gunangles[2] := MSG_ReadChar(net_message) * 0.25;
  end;

  if (flags and PS_BLEND <> 0) then
  begin
    state.blend[0] := MSG_ReadByte(net_message) / 255.0;
    state.blend[1] := MSG_ReadByte(net_message) / 255.0;
    state.blend[2] := MSG_ReadByte(net_message) / 255.0;
    state.blend[3] := MSG_ReadByte(net_message) / 255.0;
  end;

  if (flags and PS_FOV <> 0) then
    state.fov := MSG_ReadByte(net_message);

  if (flags and PS_RDFLAGS <> 0) then
    state.rdflags := MSG_ReadByte(net_message);

  // parse stats
  statbits := MSG_ReadLong(net_message);
  for i := 0 to MAX_STATS - 1 do
    if (statbits and (1 shl i) <> 0) then
      state.stats[i] := MSG_ReadShort(net_message);
end;

{*
==================
CL_FireEntityEvents

==================
*}
procedure CL_FireEntityEvents(frame: frame_p);
var
  s1: entity_state_p;
  pnum, num: integer;
begin
  for pnum := 0 to frame.num_entities - 1 do
  begin
    num := (frame.parse_entities + pnum) and (MAX_PARSE_ENTITIES - 1);
    s1 := @cl_parse_entities[num];
    if (Integer(s1.event) <> 0) then
      CL_EntityEvent(s1);
    // EF_TELEPORTER acts like an event, but is not cleared each frame
    if (s1.effects and EF_TELEPORTER <> 0) then
      CL_TeleporterParticles(s1);
  end;
end;

{*
================
CL_ParseFrame
================
*}
procedure CL_ParseFrame;
var
  cmd: integer;
  len: integer;
  old: frame_p;
begin
  fillchar(cl.frame, sizeof(cl.frame), 0);

  {
   CL_ClearProjectiles(); // clear projectiles for new frame
  }

  cl.frame.serverframe := MSG_ReadLong(net_message);
  cl.frame.deltaframe := MSG_ReadLong(net_message);
  cl.frame.servertime := cl.frame.serverframe * 100;

  // BIG HACK to let old demos continue to work
  if (cls.serverProtocol <> 26) then
    cl.surpressCount := MSG_ReadByte(net_message);

  if (cl_shownet.value = 3) then
    Com_Printf('   frame:%d  delta:%d'#10, [cl.frame.serverframe,
      cl.frame.deltaframe]);

  // If the frame is delta compressed from data that we
  // no longer have available, we must suck up the rest of
  // the frame, but not use it, then ask for a non-compressed
  // message
  if (cl.frame.deltaframe <= 0) then
  begin
    cl.frame.valid := true;             // uncompressed frame
    old := nil;
    cls.demowaiting := false;           // we can start recording now
  end
  else
  begin
    old := @cl.frames[cl.frame.deltaframe and UPDATE_MASK];
    if (not old.valid) then
    begin                               // should never happen
      Com_Printf('Delta from invalid frame (not supposed to happen!).'#10, []);
    end;
    if (old.serverframe <> cl.frame.deltaframe) then
    begin                               // The frame that the server did the delta from
      // is too old, so we can't reconstruct it properly.
      Com_Printf('Delta frame too old.'#10, []);
    end
    else if (cl.parse_entities - old.parse_entities > MAX_PARSE_ENTITIES - 128) then
    begin
      Com_Printf('Delta parse_entities too old.'#10, []);
    end
    else
      cl.frame.valid := true;           // valid delta parse
  end;

  // clamp time
  if (cl.time > cl.frame.servertime) then
    cl.time := cl.frame.servertime
  else if (cl.time < cl.frame.servertime - 100) then
    cl.time := cl.frame.servertime - 100;

  // read areabits
  len := MSG_ReadByte(net_message);
  MSG_ReadData(net_message, @cl.frame.areabits, len);

  // read playerinfo
  cmd := MSG_ReadByte(net_message);
  SHOWNET(svc_strings[cmd]);
  if (cmd <> Integer(svc_playerinfo)) then
    Com_Error(ERR_DROP, 'CL_ParseFrame: not playerinfo', []);
  CL_ParsePlayerstate(old, @cl.frame);

  // read packet entities
  cmd := MSG_ReadByte(net_message);
  SHOWNET(svc_strings[cmd]);
  if (cmd <> Integer(svc_packetentities)) then
    Com_Error(ERR_DROP, 'CL_ParseFrame: not packetentities', []);
  CL_ParsePacketEntities(old, @cl.frame);

  {
   if (cmd = svc_packetentities2) then
    CL_ParseProjectiles();
  }

   // save the frame off in the backup array for later delta comparisons
  cl.frames[cl.frame.serverframe and UPDATE_MASK] := cl.frame;

  if (cl.frame.valid) then
  begin                                 // getting a valid frame message ends the connection process
    if (cls.state <> ca_active) then
    begin
      cls.state := ca_active;
      cl.force_refdef := true;
      cl.predicted_origin[0] := cl.frame.playerstate.pmove.origin[0] * 0.125;
      cl.predicted_origin[1] := cl.frame.playerstate.pmove.origin[1] * 0.125;
      cl.predicted_origin[2] := cl.frame.playerstate.pmove.origin[2] * 0.125;
      VectorCopy(cl.frame.playerstate.viewangles, cl.predicted_angles);
      if (cls.disable_servercount <> cl.servercount) and
        (cl.refresh_prepped) then
        SCR_EndLoadingPlaque();         // get rid of loading plaque
    end;
    cl.sound_prepped := true;           // can start mixing ambient sounds

    // fire entity events
    CL_FireEntityEvents(@cl.frame);
    CL_CheckPredictionError();
  end;
end;

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

INTERPOLATE BETWEEN FRAMES TO GET RENDERING PARMS

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

function S_RegisterSexedModel(ent: entity_state_p; base: pchar): model_p;
var
  n: integer;
  p: pchar;
  mdl: model_p;
  model: array[0..MAX_QPATH - 1] of char;
  buffer: array[0..MAX_QPATH - 1] of char;
begin
  // determine what model the client is using
  model[0] := #0;
  n := CS_PLAYERSKINS + ent.number - 1;
  if (cl.configstrings[n][0] <> #0) then
  begin
    p := strchr(cl.configstrings[n], Byte('\'));
    if (p <> nil) then
    begin
      p := p + 1;
      strcpy(model, p);
      p := strchr(model, Byte('/'));
      if (p <> nil) then
        p^ := #0;
    end;
  end;
  // if we can't figure it out, they're male
  if (model[0] = #0) then
    strcpy(model, 'male');

  Com_sprintf(buffer, sizeof(buffer), 'players/%s/%s', [model, base + 1]);
  mdl := re.RegisterModel(buffer);
  if (mdl = nil) then
  begin
    // not found, try default weapon model
    Com_sprintf(buffer, sizeof(buffer), 'players/%s/weapon.md2', [model]);
    mdl := re.RegisterModel(buffer);
    if (mdl = nil) then
    begin
      // no, revert to the male model
      Com_sprintf(buffer, sizeof(buffer), 'players/%s/%s', ['male', base + 1]);
      mdl := re.RegisterModel(buffer);
      if (mdl = nil) then
      begin
        // last try, default male weapon.md2
        Com_sprintf(buffer, sizeof(buffer), 'players/male/weapon.md2', []);
        mdl := re.RegisterModel(buffer);
      end;
    end;
  end;

  Result := mdl;
end;

{*
===============
CL_AddPacketEntities

===============
*}
var
  bfg_lightramp: array[0..5] of integer = (300, 400, 600, 300, 150, 75);

procedure CL_AddPacketEntities(frame: frame_p);
var
  ent: entity_t;
  s1: entity_state_p;
  autorotate: single;
  i: integer;
  pnum: integer;
  cent: centity_p;
  autoanim: integer;
  ci: clientinfo_p;
  effects, renderfx: LongWord;
  forward_, start: vec3_t;
  a1, a2: single;
  intensity: single;
begin
  // bonus items rotate at a fixed rate
  autorotate := anglemod(cl.time / 10);

  // brush models can auto animate their frames
  autoanim := Trunc(2 * cl.time / 1000);

  FillChar(ent, sizeof(ent), #0);

  for pnum := 0 to frame.num_entities - 1 do
  begin
    s1 := @cl_parse_entities[(frame.parse_entities + pnum) and (MAX_PARSE_ENTITIES - 1)];

    cent := @cl_entities[s1.number];

    effects := s1.effects;
    renderfx := s1.renderfx;

    // set frame
    if (effects and EF_ANIM01 <> 0) then
      ent.frame := autoanim and 1
    else if (effects and EF_ANIM23 <> 0) then
      ent.frame := 2 + (autoanim and 1)
    else if (effects and EF_ANIM_ALL <> 0) then
      ent.frame := autoanim
    else if (effects and EF_ANIM_ALLFAST <> 0) then
      ent.frame := Trunc(cl.time / 100)
    else
      ent.frame := s1.frame;

    // quad and pent can do different things on client
    if (effects and EF_PENT <> 0) then
    begin
      effects := effects and (not EF_PENT);
      effects := effects or EF_COLOR_SHELL;
      renderfx := renderfx or RF_SHELL_RED;
    end;

    if (effects and EF_QUAD <> 0) then
    begin
      effects := effects and (not EF_QUAD);
      effects := effects or EF_COLOR_SHELL;
      renderfx := renderfx or RF_SHELL_BLUE;
    end;
    //======
    // PMM
    if (effects and EF_DOUBLE <> 0) then
    begin
      effects := effects and (not EF_DOUBLE);
      effects := effects or EF_COLOR_SHELL;
      renderfx := renderfx or RF_SHELL_DOUBLE;
    end;

    if (effects and EF_HALF_DAMAGE <> 0) then
    begin
      effects := effects and (not EF_HALF_DAMAGE);
      effects := effects or EF_COLOR_SHELL;
      renderfx := effects or RF_SHELL_HALF_DAM;
    end;
    // pmm
    //======
    ent.oldframe := cent.prev.frame;
    ent.backlerp := 1.0 - cl.lerpfrac;

    if ((renderfx and (RF_FRAMELERP or RF_BEAM)) <> 0) then
    begin
      // step origin discretely, because the frames
      // do the animation properly
      VectorCopy(cent.current.origin, vec3_t(ent.origin));
      VectorCopy(cent.current.old_origin, vec3_t(ent.oldorigin));
    end
    else
    begin                               // interpolate origin
      for i := 0 to 2 do
      begin
        ent.origin[i] := cent.prev.origin[i] + cl.lerpfrac *
          (cent.current.origin[i] - cent.prev.origin[i]);
        ent.oldorigin[i] := ent.origin[i];
      end;
    end;

    // create a new entity

    // tweak the color of beams
    if ((renderfx and RF_BEAM) <> 0) then
    begin
      // the four beam colors are encoded in 32 bits of skinnum (hack)
      ent.alpha := 0.30;
      ent.skinnum := (s1.skinnum shr ((rand() mod 4) * 8)) and $FF;
      ent.model := nil;
    end
    else
    begin
      // set skin
      if (s1.modelindex = 255) then
      begin
        // use custom player skin
        ent.skinnum := 0;
        ci := @cl.clientinfo[s1.skinnum and $FF];
        ent.skin := ci.skin;
        ent.model := ci.model;
        if (ent.skin = nil) or (ent.model = nil) then
        begin
          ent.skin := cl.baseclientinfo.skin;
          ent.model := cl.baseclientinfo.model;
        end;

        //============
        //PGM
        if ((renderfx and RF_USE_DISGUISE) <> 0) then
        begin
          if (strncmp(ent.skin, 'players/male', 12) = 0) then
          begin
            ent.skin := re.RegisterSkin('players/male/disguise.pcx');
            ent.model := re.RegisterModel('players/male/tris.md2');
          end
          else if (strncmp(ent.skin, 'players/female', 14) = 0) then
          begin
            ent.skin := re.RegisterSkin('players/female/disguise.pcx');
            ent.model := re.RegisterModel('players/female/tris.md2');
          end
          else if (strncmp(ent.skin, 'players/cyborg', 14) = 0) then
          begin
            ent.skin := re.RegisterSkin('players/cyborg/disguise.pcx');
            ent.model := re.RegisterModel('players/cyborg/tris.md2');
          end;
        end;
        //PGM
        //============
      end
      else
      begin
        ent.skinnum := s1.skinnum;
        ent.skin := nil;
        ent.model := cl.model_draw[s1.modelindex];
      end;
    end;

    // only used for black hole model right now, FIXME: do better
    if (renderfx = RF_TRANSLUCENT) then
      ent.alpha := 0.70;

    // render effects (fullbright, translucent, etc)
    if ((effects and EF_COLOR_SHELL) <> 0) then
      ent.flags := 0                    // renderfx go on color shell entity
    else
      ent.flags := renderfx;

    // calculate angles
    if ((effects and EF_ROTATE) <> 0) then
    begin
      // some bonus items auto-rotate
      ent.angles[0] := 0;
      ent.angles[1] := autorotate;
      ent.angles[2] := 0;
    end
      // RAFAEL
    else if ((effects and EF_SPINNINGLIGHTS) <> 0) then
    begin
      ent.angles[0] := 0;
      ent.angles[1] := anglemod(cl.time / 2) + s1.angles[1];
      ent.angles[2] := 180;
      begin
        AngleVectors(vec3_t(ent.angles), @forward_, nil, nil);
        VectorMA(vec3_t(ent.origin), 64, forward_, start);
        V_AddLight(start, 100, 1, 0, 0);
      end;
    end
    else
    begin                               // interpolate angles
      for i := 0 to 2 do
      begin
        a1 := cent.current.angles[i];
        a2 := cent.prev.angles[i];
        ent.angles[i] := LerpAngle(a2, a1, cl.lerpfrac);
      end;
    end;

    if (s1.number = cl.playernum + 1) then
    begin
      ent.flags := ent.flags or RF_VIEWERMODEL; // only draw from mirrors
      // FIXME: still pass to refresh

      if (effects and EF_FLAG1 <> 0) then
        V_AddLight(vec3_t(ent.origin), 225, 1.0, 0.1, 0.1)
      else if (effects and EF_FLAG2 <> 0) then
        V_AddLight(vec3_t(ent.origin), 225, 0.1, 0.1, 1.0)
      else if (effects and EF_TAGTRAIL <> 0) then //PGM
        V_AddLight(vec3_t(ent.origin), 225, 1.0, 1.0, 0.0) //PGM
      else if (effects and EF_TRACKERTRAIL <> 0) then //PGM
        V_AddLight(vec3_t(ent.origin), 225, -1.0, -1.0, -1.0); //PGM

      continue;
    end;

    // if set to invisible, skip
    if (s1.modelindex = 0) then
      continue;

    if ((effects and EF_BFG) <> 0) then
    begin
      ent.flags := ent.flags or RF_TRANSLUCENT;
      ent.alpha := 0.30;
    end;

    // RAFAEL
    if ((effects and EF_PLASMA) <> 0) then
    begin
      ent.flags := ent.flags or RF_TRANSLUCENT;
      ent.alpha := 0.6;
    end;

    if ((effects and EF_SPHERETRANS) <> 0) then
    begin
      ent.flags := ent.flags or RF_TRANSLUCENT;
      // PMM - *sigh*  yet more EF overloading
      if ((effects and EF_TRACKERTRAIL) <> 0) then
        ent.alpha := 0.6

⌨️ 快捷键说明

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