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

📄 pmoveunit.pas

📁 delphi编的不错的贪吃蛇
💻 PAS
📖 第 1 页 / 共 3 页
字号:
    friction := pm_friction * 1.5;      // extra friction
    //control = speed < pm_stopspeed ? pm_stopspeed : speed;
    if (speed < pm_stopspeed) then
      control := pm_stopspeed
    else
      control := speed;
    drop := drop + control * friction * pml.frametime;

    // scale the velocity
    newspeed := speed - drop;
    if (newspeed < 0) then
      newspeed := 0;
    newspeed := newspeed / speed;

    VectorScale(pml.velocity, newspeed, pml.velocity);
  end;

  // accelerate
  fmove := pm.cmd.forwardmove;
  smove := pm.cmd.sidemove;

  VectorNormalize(pml.forward);
  VectorNormalize(pml.right);

  for i := 0 to 2 do
    wishvel[i] := pml.forward[i] * fmove + pml.right[i] * smove;
  wishvel[2] := wishvel[2] + pm.cmd.upmove;

  VectorCopy(wishvel, wishdir);
  wishspeed := VectorNormalize(wishdir);

  //
  // clamp to server defined max speed
  //
  if (wishspeed > pm_maxspeed) then
  begin
    VectorScale(wishvel, pm_maxspeed / wishspeed, wishvel);
    wishspeed := pm_maxspeed;
  end;

  currentspeed := DotProduct(pml.velocity, wishdir);
  addspeed := wishspeed - currentspeed;
  if (addspeed <= 0) then
    Exit;
  accelspeed := pm_accelerate * pml.frametime * wishspeed;
  if (accelspeed > addspeed) then
    accelspeed := addspeed;

  for i := 0 to 2 do
    pml.velocity[i] := pml.velocity[i] + accelspeed * wishdir[i];

  if (doclip) then
  begin
    for i := 0 to 2 do
      end_[i] := pml.origin[i] + pml.frametime * pml.velocity[i];

    trace := pm.trace(pml.origin, pm.mins, pm.maxs, end_);

    VectorCopy(trace.endpos, pml.origin);
  end
  else
  begin
    // move
    VectorMA(pml.origin, pml.frametime, pml.velocity, pml.origin);
  end;
end;

{*
==============
PM_CheckDuck

Sets mins, maxs, and pm->viewheight
==============
*}
procedure PM_CheckDuck;
var
  trace: trace_t;
begin
  pm.mins[0] := -16;
  pm.mins[1] := -16;

  pm.maxs[0] := 16;
  pm.maxs[1] := 16;

  if (pm.s.pm_type = PM_GIB) then
  begin
    pm.mins[2] := 0;
    pm.maxs[2] := 16;
    pm.viewheight := 8;
    Exit;
  end;

  pm.mins[2] := -24;

  if (pm.s.pm_type = PM_DEAD) then
  begin
    pm.s.pm_flags := pm.s.pm_flags or PMF_DUCKED;
  end
  else if (pm.cmd.upmove < 0) and (pm.s.pm_flags and PMF_ON_GROUND <> 0) then
  begin                                 // duck
    pm.s.pm_flags := pm.s.pm_flags or PMF_DUCKED;
  end
  else
  begin                                 // stand up if possible
    if (pm.s.pm_flags and PMF_DUCKED <> 0) then
    begin
      // try to stand up
      pm.maxs[2] := 32;
      trace := pm.trace(pml.origin, pm.mins, pm.maxs, pml.origin);
      if (not trace.allsolid) then
        pm.s.pm_flags := pm.s.pm_flags and not PMF_DUCKED;
    end;
  end;

  if (pm.s.pm_flags and PMF_DUCKED <> 0) then
  begin
    pm.maxs[2] := 4;
    pm.viewheight := -2;
  end
  else
  begin
    pm.maxs[2] := 32;
    pm.viewheight := 22;
  end;
end;

{*
==============
PM_DeadMove
==============
*}
procedure PM_DeadMove;
var
  forward_: Single;
begin
  if (pm.groundentity = nil) then
    Exit;

  // extra friction

  forward_ := VectorLength(pml.velocity);
  forward_ := forward_ - 20;
  if (forward_ <= 0) then
  begin
    VectorClear(pml.velocity);
  end
  else
  begin
    VectorNormalize(pml.velocity);
    VectorScale(pml.velocity, forward_, pml.velocity);
  end;
end;

function PM_GoodPosition: qboolean;
var
  trace: trace_t;
  origin, end_: vec3_t;
  i: Integer;
begin
  if (pm.s.pm_type = PM_SPECTATOR) then
  begin
    Result := True;
    Exit;
  end;

  for i := 0 to 2 do
  begin
    end_[i] := pm.s.origin[i] * 0.125;
    origin[i] := end_[i]
  end;
  trace := pm.trace(origin, pm.mins, pm.maxs, end_);

  Result := not trace.allsolid;
end;

{*
================
PM_SnapPosition

On exit, the origin will have a value that is pre-quantized to the 0.125
precision of the network channel and in a valid position.
================
*}
procedure PM_SnapPosition;
var
  sign: array[0..2] of Integer;
  i, j, bits: Integer;
  base: array[0..2] of Smallint;
{$IFDEF COMPILER6_UP}{$WRITEABLECONST ON}{$ENDIF}
const
  // try all single bits first
  jitterbits: array[0..7] of Integer = (0, 4, 1, 2, 3, 5, 6, 7);
{$IFDEF COMPILER6_UP}{$WRITEABLECONST OFF}{$ENDIF}
begin
  // snap velocity to eigths
  for i := 0 to 2 do
    pm.s.velocity[i] := Trunc(pml.velocity[i] * 8);

  for i := 0 to 2 do
  begin
    if (pml.origin[i] >= 0) then
      sign[i] := 1
    else
      sign[i] := -1;
    pm.s.origin[i] := Trunc(pml.origin[i] * 8);
    if (pm.s.origin[i] * 0.125 = pml.origin[i]) then
      sign[i] := 0;
  end;
  VectorCopy(pm.s.origin, base);

  // try all combinations
  for j := 0 to 7 do
  begin
    bits := jitterbits[j];
    VectorCopy(base, pm.s.origin);
    for i := 0 to 2 do
      if (bits and (1 shl i) <> 0) then
        pm.s.origin[i] := pm.s.origin[i] + sign[i];

    if PM_GoodPosition then
      Exit;
  end;

  // go back to the last position
  VectorCopy(pml.previous_origin, pm.s.origin);
  //Com_DPrintf ('using previous_origin', []);
end;

(*
//NO LONGER USED
/*
================
PM_InitialSnapPosition

================
*/
void PM_InitialSnapPosition (void)
{
 int		x, y, z;
 short	base[3];

 VectorCopy (pm->s.origin, base);

 for (z=1 ; z>=-1 ; z--)
 {
  pm->s.origin[2] = base[2] + z;
  for (y=1 ; y>=-1 ; y--)
  {
   pm->s.origin[1] = base[1] + y;
   for (x=1 ; x>=-1 ; x--)
   {
    pm->s.origin[0] = base[0] + x;
    if (PM_GoodPosition ())
    {
     pml.origin[0] = pm->s.origin[0]*0.125;
     pml.origin[1] = pm->s.origin[1]*0.125;
     pml.origin[2] = pm->s.origin[2]*0.125;
     VectorCopy (pm->s.origin, pml.previous_origin);
     return;
    }
   }
  }
 }

 Com_DPrintf ('Bad InitialSnapPosition'#10);
}
*)

{*
================
PM_InitialSnapPosition

================
*}
procedure PM_InitialSnapPosition;
var
  x, y, z: Integer;
  base: array[0..2] of Smallint;
{$IFDEF COMPILER6_UP}{$WRITEABLECONST ON}{$ENDIF}
const
  offset: array[0..2] of Integer = (0, -1, 1);
{$IFDEF COMPILER6_UP}{$WRITEABLECONST OFF}{$ENDIF}
begin
  VectorCopy(pm.s.origin, base);

  for z := 0 to 2 do
  begin
    pm.s.origin[2] := base[2] + offset[z];
    for y := 0 to 2 do
    begin
      pm.s.origin[1] := base[1] + offset[y];
      for x := 0 to 2 do
      begin
        pm.s.origin[0] := base[0] + offset[x];
        if PM_GoodPosition then
        begin
          pml.origin[0] := pm.s.origin[0] * 0.125;
          pml.origin[1] := pm.s.origin[1] * 0.125;
          pml.origin[2] := pm.s.origin[2] * 0.125;
          VectorCopy(pm.s.origin, pml.previous_origin);
          Exit;
        end;
      end;
    end;
  end;

  Com_DPrintf('Bad InitialSnapPosition'#10, ['']);
end;

{*
================
PM_ClampAngles

================
*}
procedure PM_ClampAngles;
var
  temp: Word;
  i: Integer;
begin
  if (pm.s.pm_flags and PMF_TIME_TELEPORT <> 0) then
  begin
    pm.viewangles[YAW] := SHORT2ANGLE(pm.cmd.angles[YAW] + pm.s.delta_angles[YAW]);
    pm.viewangles[PITCH] := 0;
    pm.viewangles[ROLL] := 0;
  end
  else
  begin
    // circularly clamp the angles with deltas
    for i := 0 to 2 do
    begin
      temp := pm.cmd.angles[i] + pm.s.delta_angles[i];
      pm.viewangles[i] := SHORT2ANGLE(temp);
    end;

    // don't let the player look up or down more than 90 degrees
    if (pm.viewangles[PITCH] > 89) and (pm.viewangles[PITCH] < 180) then
      pm.viewangles[PITCH] := 89
    else if (pm.viewangles[PITCH] < 271) and (pm.viewangles[PITCH] >= 180) then
      pm.viewangles[PITCH] := 271;
  end;
  AngleVectors(pm.viewangles, @pml.forward, @pml.right, @pml.up);
end;

{*
================
Pmove

Can be called by either the server or the client
================
*}
procedure Pmove(pmove: pmove_p);
var
  msec: Integer;
  angles: vec3_t;
begin
  pm := pmove;

  // clear results
  pm.numtouch := 0;
  VectorClear(pm.viewangles);
  pm.viewheight := 0;
  pm.groundentity := nil;
  pm.watertype := 0;
  pm.waterlevel := 0;

  // clear all pmove local vars
  FillChar(pml, SizeOf(pml), 0);

  // convert origin and velocity to float values
  pml.origin[0] := pm.s.origin[0] * 0.125;
  pml.origin[1] := pm.s.origin[1] * 0.125;
  pml.origin[2] := pm.s.origin[2] * 0.125;

  pml.velocity[0] := pm.s.velocity[0] * 0.125;
  pml.velocity[1] := pm.s.velocity[1] * 0.125;
  pml.velocity[2] := pm.s.velocity[2] * 0.125;

  // save old org in case we get stuck
  VectorCopy(pm.s.origin, pml.previous_origin);

  pml.frametime := pm.cmd.msec * 0.001;

  PM_ClampAngles;

  if (pm.s.pm_type = PM_SPECTATOR) then
  begin
    PM_FlyMove(False);
    PM_SnapPosition;
    Exit;
  end;

  if (pm.s.pm_type >= PM_DEAD) then
  begin
    pm.cmd.forwardmove := 0;
    pm.cmd.sidemove := 0;
    pm.cmd.upmove := 0;
  end;

  if (pm.s.pm_type = PM_FREEZE) then
    Exit;                               // no movement at all

  // set mins, maxs, and viewheight
  PM_CheckDuck;

  if (pm.snapinitial) then
    PM_InitialSnapPosition;

  // set groundentity, watertype, and waterlevel
  PM_CatagorizePosition;

  if (pm.s.pm_type = PM_DEAD) then
    PM_DeadMove;

  PM_CheckSpecialMovement;

  // drop timing counter
  if (pm.s.pm_time <> 0) then
  begin
    msec := pm.cmd.msec shr 3;
    if (msec = 0) then
      msec := 1;
    if (msec >= pm.s.pm_time) then
    begin
      pm.s.pm_flags := pm.s.pm_flags and not (PMF_TIME_WATERJUMP or PMF_TIME_LAND or PMF_TIME_TELEPORT);
      pm.s.pm_time := 0;
    end
    else
      pm.s.pm_time := pm.s.pm_time - msec;
  end;

  if (pm.s.pm_flags and PMF_TIME_TELEPORT <> 0) then
  begin                                 // teleport pause stays exactly in place
  end
  else if (pm.s.pm_flags and PMF_TIME_WATERJUMP <> 0) then
  begin                                 // waterjump has no control, but falls
    pml.velocity[2] := pml.velocity[2] - pm.s.gravity * pml.frametime;
    if (pml.velocity[2] < 0) then
    begin                               // cancel as soon as we are falling down again
      pm.s.pm_flags := pm.s.pm_flags and not (PMF_TIME_WATERJUMP or PMF_TIME_LAND or PMF_TIME_TELEPORT);
      pm.s.pm_time := 0;
    end;

    PM_StepSlideMove;
  end
  else
  begin
    PM_CheckJump;

    PM_Friction_func;

    if (pm.waterlevel >= 2) then
      PM_WaterMove
    else
    begin
      VectorCopy(pm.viewangles, angles);
      if (angles[PITCH] > 180) then
        angles[PITCH] := angles[PITCH] - 360;
      angles[PITCH] := angles[PITCH] / 3;

      AngleVectors(angles, @pml.forward, @pml.right, @pml.up);

      PM_AirMove;
    end;
  end;

  // set groundentity, watertype, and waterlevel for final spot
  PM_CatagorizePosition;

  PM_SnapPosition;
end;

end.

⌨️ 快捷键说明

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