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

📄 m_move.pas

📁 delphi编的不错的贪吃蛇
💻 PAS
📖 第 1 页 / 共 2 页
字号:
//100%
{----------------------------------------------------------------------------}
{                                                                            }
{ File(s): m_move.c                                                          }
{ Content: monster movement                                                  }
{                                                                            }
{ Initial conversion by : you_known (you_known@163.com)                      }
{ Initial conversion on : 2002-02-02                                         }
{                                                                            }
{ 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 on :  2003-Apr-17                                                  }
{ Updated by :  Scott Price (scott.price@totalise.co.uk)                     }
{ Updated on :  2003-May-19                                                  }
{ Updated by :  Scott Price (scott.price@totalise.co.uk)                     }
{                                                                            }
{----------------------------------------------------------------------------}
{ Notes:                                                                     }
{----------------------------------------------------------------------------}

unit m_move;

interface

uses
  q_shared,
  g_local;

function M_walkmove (ent: edict_p; yaw: single; dist: single): qboolean;
procedure M_MoveToGoal (ent: edict_p; dist: single);
procedure M_ChangeYaw (ent: edict_p);
function M_CheckBottom(ent: edict_p): qboolean;

implementation

uses
  GameUnit,
  g_utils, g_main, CPas;

const
  STEPSIZE = 18;


(*
=============
M_CheckBottom

Returns false if any part of the bottom of the entity is off an edge that
is not a staircase.

=============
*)
var
  c_yes, c_no: Smallint;

function M_CheckBottom(ent: edict_p): qboolean;
label
  realcheck;
var
  mins, maxs, start, stop: vec3_t;
  trace: trace_t;
  x, y: Smallint;
  mid, bottom: Single;
begin
  VectorAdd(ent^.s.origin, ent^.mins, mins);
  VectorAdd(ent^.s.origin, ent^.maxs, maxs);

// if all of the points under the corners are solid world, don't bother
// with the tougher checks
// the corners must be within 16 of the midpoint
  start[2] := mins[2] - 1;
  for x := 0 to 1 do
    for y := 0 to 1 do
    begin
      if x <> 0 then
        start[0] := maxs[0]
      else
        start[0] := mins[0];

      if y <> 0 then
        start[1] := maxs[1]
      else
        start[1] := mins[1];
      if gi.pointcontents(start) <> CONTENTS_SOLID then
        goto realcheck;
    end;

  c_yes := c_yes + 1;
  Result := True;          // we got out easy
  Exit;

realcheck:

  c_no := c_no + 1;
//
// check it for real...
//
  start[2] := mins[2];

// the midpoint must be within 16 of the bottom
  stop[0] := (mins[0] + maxs[0])*0.5;
  start[0] := stop[0];
  stop[1] := (mins[1] + maxs[1])*0.5;
  start[1] := stop[1];
  stop[2] := start[2] - 2*STEPSIZE;
  trace := gi.trace (@start, @vec3_origin, @vec3_origin, @stop, ent, MASK_MONSTERSOLID);

  if trace.fraction = 1.0 then
  begin
    Result := False;
    Exit;
  end;
  bottom := trace.endpos[2];
  mid := bottom;

// the corners must be within 16 of the midpoint
  for x := 0 to 1 do
    for y :=0 to 1 do
    begin
      if x <> 0 then
        stop[0] := maxs[0]
      else
        stop[0] := mins[0];

      start[0] := stop[0];

      if y <> 0 then
        stop[1] := maxs[1]
      else
        stop[1] := mins[1];

      start[1] := stop[1];

      trace := gi.trace (@start, @vec3_origin, @vec3_origin, @stop, ent, MASK_MONSTERSOLID);

      if (trace.fraction <> 1.0) and (trace.endpos[2] > bottom) then
        bottom := trace.endpos[2];
      if (trace.fraction = 1.0) or (mid - trace.endpos[2] > STEPSIZE) then
      begin
        Result := False;
        Exit;
      end;
    end;

  c_yes := c_yes + 1;
  Result := True;
end;



(*
=============
SV_movestep

Called by monster program code.
The move will be adjusted for slopes and stairs, but if the move isn't
possible, no move is done, false is returned, and
pr_global_struct->trace_normal is set to the normal of the blocking wall
=============
*)
//FIXME since we need to test end position contents here, can we avoid doing
//it again later in catagorize position?
function SV_movestep(ent: edict_p; const move: vec3_t; relink: qboolean): qboolean;
var
  dz: Single;
  oldorg, neworg, end_: vec3_t;
  trace: trace_t;
  i: Smallint;
  stepsizes: Single; //Well,case not sensitive,'stepsizes' replaced 'stepsize'.
  test: vec3_t;
  contents: smallint;
begin
// try the move
  VectorCopy (ent^.s.origin, oldorg);
  VectorAdd (ent^.s.origin, move, neworg);

// flying monsters don't step up
  if (ent^.flags and (FL_SWIM or FL_FLY) <> 0) then
  begin
  // try one move with vertical motion, then one without
    for i := 0 to 1 do
    begin
      VectorAdd(ent^.s.origin, move ,neworg);
      if (i = 0) and (ent^.enemy <> nil) then
      begin
        if (ent^.goalentity = nil) then
          ent^.goalentity := ent^.enemy;
        dz := ent^.s.origin[2] - ent^.goalentity^.s.origin[2];
        if (ent^.goalentity^.client <> nil) then
        begin
          if dz > 40 then
            neworg[2] := neworg[2] - 8;
          if not ((ent^.flags and FL_SWIM <> 0) and (ent^.waterlevel < 2)) then
            if dz < 30 then
              neworg[2] := neworg[2] + 8;
        end
        else
        begin
           if dz > 8 then
             neworg[2] := neworg[2] - 8
           else if dz > 0 then
             neworg[2] := neworg[2] - dz
           else if dz < -8 then
             neworg[2] := neworg[2] + 8
           else
             neworg[2] := neworg[2] + dz;
        end;
      end;
      trace := gi.trace (@ent^.s.origin, @ent^.mins, @ent^.maxs, @neworg, ent, MASK_MONSTERSOLID);

      // fly monsters don't enter water voluntarily
      if (ent^.flags and FL_FLY <> 0) then
      begin
        if (ent^.waterlevel = 0) then
        begin
          test[0] := trace.endpos[0];
          test[1] := trace.endpos[1];
          test[2] := trace.endpos[2] + ent^.mins[2] + 1;
          contents := gi.pointcontents(test);
          if (contents and MASK_WATER) <> 0 then
          begin
            Result := False;
            Exit;
          end;
        end;
      end;

      // swim monsters don't exit water voluntarily
      if (ent^.flags and FL_SWIM <> 0) then
      begin
        if (ent^.waterlevel < 2) then
        begin
           test[0] := trace.endpos[0];
           test[1] := trace.endpos[1];
           test[2] := trace.endpos[2] + ent^.mins[2] + 1;
           contents := gi.pointcontents(test);
           if (contents and MASK_WATER) = 0 then
           begin
             Result := False;
             Exit;
           end;
        end;
      end;

      if trace.fraction = 1 then
      begin
         VectorCopy (trace.endpos, ent^.s.origin);
         if relink then
         begin
           gi.linkentity (ent);
           G_TouchTriggers (ent);
         end;
         Result := True;
         Exit;
      end;

      if (ent^.enemy = nil) then
        Break;
    end;

    Result := False;
    Exit;
  end;

// push down from a step height above the wished position
  if (ent^.monsterinfo.aiflags and AI_NOSTEP = 0) then
    stepsizes := STEPSIZE
  else
    stepsizes := 1;

  neworg[2] := neworg[2] + stepsizes;
  VectorCopy (neworg, end_);
  end_[2] := end_[2] - stepsizes * 2;

  trace := gi.trace (@neworg, @ent^.mins, @ent^.maxs, @end_, ent, MASK_MONSTERSOLID);

  if trace.allsolid then
  begin
    Result := False;
    Exit;
  end;

  if trace.startsolid then
  begin
     neworg[2] := neworg[2] - stepsizes;
     trace := gi.trace (@neworg, @ent^.mins, @ent^.maxs, @end_, ent, MASK_MONSTERSOLID);
     if (trace.allsolid or trace.startsolid) then
     begin
       Result := False;
       Exit;
     end;
  end;

  // don't go in to water
  if ent^.waterlevel = 0 then
  begin
     test[0] := trace.endpos[0];
     test[1] := trace.endpos[1];
     test[2] := trace.endpos[2] + ent^.mins[2] + 1;
     contents := gi.pointcontents(test);

     if (contents and MASK_WATER) <> 0 then
     begin
       Result := False;
       Exit;
     end;
  end;

  if trace.fraction = 1 then
  begin
  // if monster had the ground pulled out, go ahead and fall
     if (ent^.flags and FL_PARTIALGROUND) <> 0 then
     begin
        VectorAdd (ent^.s.origin, move, ent^.s.origin);
        if relink then
        begin
           gi.linkentity (ent);
           G_TouchTriggers (ent);
        end;
        ent^.groundentity := nil;
        Result := True;

⌨️ 快捷键说明

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