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

📄 pmoveunit.pas

📁 delphi编的不错的贪吃蛇
💻 PAS
📖 第 1 页 / 共 3 页
字号:

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

{*
=============
PM_AddCurrents
=============
*}
procedure PM_AddCurrents(var wishvel: vec3_t);
var
  v: vec3_t;
  s: Single;
begin
  //
  // account for ladders
  //

  if pml.ladder and (Abs(pml.velocity[2]) <= 200) then
  begin
    if ((pm.viewangles[PITCH] <= -15) and (pm.cmd.forwardmove > 0)) then
      wishvel[2] := 200
    else if ((pm.viewangles[PITCH] >= 15) and (pm.cmd.forwardmove > 0)) then
      wishvel[2] := -200
    else if (pm.cmd.upmove > 0) then
      wishvel[2] := 200
    else if (pm.cmd.upmove < 0) then
      wishvel[2] := -200
    else
      wishvel[2] := 0;

    // limit horizontal speed when on a ladder
    if (wishvel[0] < -25) then
      wishvel[0] := -25
    else if (wishvel[0] > 25) then
      wishvel[0] := 25;

    if (wishvel[1] < -25) then
      wishvel[1] := -25
    else if (wishvel[1] > 25) then
      wishvel[1] := 25;
  end;

  //
  // add water currents
  //

  if (pm.watertype and MASK_CURRENT <> 0) then
  begin
    VectorClear(v);

    if (pm.watertype and CONTENTS_CURRENT_0 <> 0) then
      v[0] := v[0] + 1;
    if (pm.watertype and CONTENTS_CURRENT_90 <> 0) then
      v[1] := v[1] + 1;
    if (pm.watertype and CONTENTS_CURRENT_180 <> 0) then
      v[0] := v[0] - 1;
    if (pm.watertype and CONTENTS_CURRENT_270 <> 0) then
      v[1] := v[1] - 1;
    if (pm.watertype and CONTENTS_CURRENT_UP <> 0) then
      v[2] := v[2] + 1;
    if (pm.watertype and CONTENTS_CURRENT_DOWN <> 0) then
      v[2] := v[2] - 1;

    s := pm_waterspeed;
    if (pm.waterlevel = 1) and (pm.groundentity <> nil) then
      s := s / 2;

    VectorMA(wishvel, s, v, wishvel);
  end;

  //
  // add conveyor belt velocities
  //

  if (pm.groundentity <> nil) then
  begin
    VectorClear(v);

    if (pml.groundcontents and CONTENTS_CURRENT_0 <> 0) then
      v[0] := v[0] + 1;
    if (pml.groundcontents and CONTENTS_CURRENT_90 <> 0) then
      v[1] := v[1] + 1;
    if (pml.groundcontents and CONTENTS_CURRENT_180 <> 0) then
      v[0] := v[0] - 1;
    if (pml.groundcontents and CONTENTS_CURRENT_270 <> 0) then
      v[1] := v[1] - 1;
    if (pml.groundcontents and CONTENTS_CURRENT_UP <> 0) then
      v[2] := v[2] + 1;
    if (pml.groundcontents and CONTENTS_CURRENT_DOWN <> 0) then
      v[2] := v[2] - 1;

    VectorMA(wishvel, 100 {* pm->groundentity->speed *}, v, wishvel);
  end;
end;

{*
===================
PM_WaterMove

===================
*}
procedure PM_WaterMove;
var
  i: Integer;
  wishvel: vec3_t;
  wishspeed: Single;
  wishdir: vec3_t;
begin
  //
  // user intentions
  //
  for i := 0 to 2 do
    wishvel[i] := pml.forward[i] * pm.cmd.forwardmove + pml.right[i] * pm.cmd.sidemove;

  if (pm.cmd.forwardmove = 0) and (pm.cmd.sidemove = 0) and (pm.cmd.upmove = 0) then
    wishvel[2] := wishvel[2] - 60       // drift towards bottom
  else
    wishvel[2] := wishvel[2] + pm.cmd.upmove;

  PM_AddCurrents(wishvel);

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

  if (wishspeed > pm_maxspeed) then
  begin
    VectorScale(wishvel, pm_maxspeed / wishspeed, wishvel);
    wishspeed := pm_maxspeed;
  end;
  wishspeed := wishspeed * 0.5;

  PM_Accelerate_func(wishdir, wishspeed, pm_wateraccelerate);

  PM_StepSlideMove;
end;

{*
===================
PM_AirMove

===================
*}
procedure PM_AirMove;
var
  i: Integer;
  wishvel: vec3_t;
  fmove, smove: Single;
  wishdir: vec3_t;
  wishspeed: Single;
  maxspeed: Single;
begin
  fmove := pm.cmd.forwardmove;
  smove := pm.cmd.sidemove;

  {
    pml.forward[2] = 0;
    pml.right[2] = 0;
    VectorNormalize (pml.forward);
    VectorNormalize (pml.right);
  }

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

  PM_AddCurrents(wishvel);

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

  //
  // clamp to server defined max speed
  //
  // maxspeed = (pm->s.pm_flags & PMF_DUCKED) ? pm_duckspeed : pm_maxspeed;
  if (pm.s.pm_flags and PMF_DUCKED) <> 0 then
    maxspeed := pm_duckspeed
  else
    maxspeed := pm_maxspeed;

  if (wishspeed > maxspeed) then
  begin
    VectorScale(wishvel, maxspeed / wishspeed, wishvel);
    wishspeed := maxspeed;
  end;

  if pml.ladder then
  begin
    PM_Accelerate_func(wishdir, wishspeed, pm_accelerate);
    if (wishvel[2] = 0) then
    begin
      if (pml.velocity[2] > 0) then
      begin
        pml.velocity[2] := pml.velocity[2] - pm.s.gravity * pml.frametime;
        if (pml.velocity[2] < 0) then
          pml.velocity[2] := 0;
      end
      else
      begin
        pml.velocity[2] := pml.velocity[2] + pm.s.gravity * pml.frametime;
        if (pml.velocity[2] > 0) then
          pml.velocity[2] := 0;
      end;
    end;
    PM_StepSlideMove;
  end
  else if (pm.groundentity <> nil) then
  begin                                 // walking on ground
    pml.velocity[2] := 0;               //!!! this is before the accel
    PM_Accelerate_func(wishdir, wishspeed, pm_accelerate);

    // PGM	-- fix for negative trigger_gravity fields
    //		pml.velocity[2] = 0;
    if (pm.s.gravity > 0) then
      pml.velocity[2] := 0
    else
      pml.velocity[2] := pml.velocity[2] - pm.s.gravity * pml.frametime;
    // PGM

    if (pml.velocity[0] = 0) and (pml.velocity[1] = 0) then
      Exit;
    PM_StepSlideMove;
  end
  else
  begin                                 // not on ground, so little effect on velocity
    if (pm_airaccelerate <> 0) then
      PM_AirAccelerate_func(wishdir, wishspeed, pm_accelerate)
    else
      PM_Accelerate_func(wishdir, wishspeed, 1);
    // add gravity
    pml.velocity[2] := pml.velocity[2] - pm.s.gravity * pml.frametime;
    PM_StepSlideMove;
  end;
end;

{*
=============
PM_CatagorizePosition
=============
*}
procedure PM_CatagorizePosition;
var
  point: vec3_t;
  cont: Integer;
  trace: trace_t;
  sample1: Integer;
  sample2: Integer;
begin
  // if the player hull point one unit down is solid, the player
  // is on ground

  // see if standing on something solid
  point[0] := pml.origin[0];
  point[1] := pml.origin[1];
  point[2] := pml.origin[2] - 0.25;
  if (pml.velocity[2] > 180) then       //!!ZOID changed from 100 to 180 (ramp accel)
  begin
    pm.s.pm_flags := pm.s.pm_flags and not PMF_ON_GROUND;
    pm.groundentity := nil;
  end
  else
  begin
    trace := pm.trace(pml.origin, pm.mins, pm.maxs, point);
    pml.groundplane := trace.plane;
    pml.groundsurface := trace.surface;
    pml.groundcontents := trace.contents;

    if (trace.ent = nil) or
      ((trace.plane.normal[2] < 0.7) and (not trace.startsolid)) then
    begin
      pm.groundentity := nil;
      pm.s.pm_flags := pm.s.pm_flags and not PMF_ON_GROUND;
    end
    else
    begin
      pm.groundentity := trace.ent;

      // hitting solid ground will end a waterjump
      if (pm.s.pm_flags and PMF_TIME_WATERJUMP <> 0) 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;

      if (pm.s.pm_flags and PMF_ON_GROUND) = 0 then
      begin                             // just hit the ground
        pm.s.pm_flags := pm.s.pm_flags or PMF_ON_GROUND;
        // don't do landing time if we were just going down a slope
        if (pml.velocity[2] < -200) then
        begin
          pm.s.pm_flags := pm.s.pm_flags or PMF_TIME_LAND;
          // don't allow another jump for a little while
          if (pml.velocity[2] < -400) then
            pm.s.pm_time := 25
          else
            pm.s.pm_time := 18;
        end;
      end;
    end;

    {
        if (trace.fraction < 1.0 && trace.ent && pml.velocity[2] < 0)
                pml.velocity[2] = 0;
    }

    if (pm.numtouch < MAXTOUCH) and (trace.ent <> nil) then
    begin
      pm.touchents[pm.numtouch] := trace.ent;
      Inc(pm.numtouch);
    end;
  end;

  //
  // get waterlevel, accounting for ducking
  //
  pm.waterlevel := 0;
  pm.watertype := 0;

  sample2 := Trunc(pm.viewheight - pm.mins[2]);
  sample1 := sample2 div 2;

  point[2] := pml.origin[2] + pm.mins[2] + 1;
  cont := pm.pointcontents(point);

  if (cont and MASK_WATER <> 0) then
  begin
    pm.watertype := cont;
    pm.waterlevel := 1;
    point[2] := pml.origin[2] + pm.mins[2] + sample1;
    cont := pm.pointcontents(point);
    if (cont and MASK_WATER <> 0) then
    begin
      pm.waterlevel := 2;
      point[2] := pml.origin[2] + pm.mins[2] + sample2;
      cont := pm.pointcontents(point);
      if (cont and MASK_WATER <> 0) then
        pm.waterlevel := 3;
    end;
  end;

end;

{*
=============
PM_CheckJump
=============
*}
procedure PM_CheckJump;
begin
  if (pm.s.pm_flags and PMF_TIME_LAND <> 0) then
  begin                                 // hasn't been long enough since landing to jump again
    Exit;
  end;

  if (pm.cmd.upmove < 10) then
  begin                                 // not holding jump
    pm.s.pm_flags := pm.s.pm_flags and not PMF_JUMP_HELD;
    Exit;
  end;

  // must wait for jump to be released
  if (pm.s.pm_flags and PMF_JUMP_HELD <> 0) then
    Exit;

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

  if (pm.waterlevel >= 2) then
  begin                                 // swimming, not jumping
    pm.groundentity := nil;

    if (pml.velocity[2] <= -300) then
      Exit;

    if (pm.watertype = CONTENTS_WATER) then
      pml.velocity[2] := 100
    else if (pm.watertype = CONTENTS_SLIME) then
      pml.velocity[2] := 80
    else
      pml.velocity[2] := 50;
    Exit;
  end;

  if (pm.groundentity = nil) then
    Exit;                               // in air, so no effect

  pm.s.pm_flags := pm.s.pm_flags or PMF_JUMP_HELD;

  pm.groundentity := nil;
  pml.velocity[2] := pml.velocity[2] + 270;
  if (pml.velocity[2] < 270) then
    pml.velocity[2] := 270;
end;

{*
=============
PM_CheckSpecialMovement
=============
*}
procedure PM_CheckSpecialMovement;
var
  spot: vec3_t;
  cont: Integer;
  flatforward: vec3_t;
  trace: trace_t;
begin
  if (pm.s.pm_time <> 0) then
    Exit;

  pml.ladder := False;

  // check for ladder
  flatforward[0] := pml.forward[0];
  flatforward[1] := pml.forward[1];
  flatforward[2] := 0;
  VectorNormalize(flatforward);

  VectorMA(pml.origin, 1, flatforward, spot);
  trace := pm.trace(pml.origin, pm.mins, pm.maxs, spot);
  if (trace.fraction < 1) and (trace.contents and CONTENTS_LADDER <> 0) then
    pml.ladder := True;

  // check for water jump
  if (pm.waterlevel <> 2) then
    Exit;

  VectorMA(pml.origin, 30, flatforward, spot);
  spot[2] := spot[2] + 4;
  cont := pm.pointcontents(spot);
  if (cont and CONTENTS_SOLID = 0) then
    Exit;

  spot[2] := spot[2] + 16;
  cont := pm.pointcontents(spot);
  if (cont <> 0) then
    exit;

  // jump out of water
  VectorScale(flatforward, 50, pml.velocity);
  pml.velocity[2] := 350;

  pm.s.pm_flags := pm.s.pm_flags or PMF_TIME_WATERJUMP;
  pm.s.pm_time := 255;
end;

{*
===============
PM_FlyMove
===============
*}
procedure PM_FlyMove(doclip: qboolean);
var
  speed, drop, friction, control, newspeed: Single;
  currentspeed, addspeed, accelspeed: Single;
  i: Integer;
  wishvel: vec3_t;
  fmove, smove: Single;
  wishdir: vec3_t;
  wishspeed: Single;
  end_: vec3_t;
  trace: trace_t;
begin
  pm.viewheight := 22;

  // friction

  speed := VectorLength(pml.velocity);
  if (speed < 1) then
  begin
    VectorCopy(vec3_origin, pml.velocity);
  end
  else
  begin
    drop := 0;

⌨️ 快捷键说明

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