📄 m_move.pas
字号:
Exit;
end;
Result := False; // walked off an edge
Exit;
end;
// check point traces down for dangling corners
VectorCopy (trace.endpos, ent^.s.origin);
if (not M_CheckBottom (ent)) then
begin
if (ent^.flags and FL_PARTIALGROUND) <> 0 then
begin
// entity had floor mostly pulled out from underneath it
// and is trying to correct
if relink then
begin
gi.linkentity (ent);
G_TouchTriggers (ent);
end;
Result := True;
Exit;
end;
VectorCopy (oldorg, ent^.s.origin);
Result := False;
Exit;
end;
if (ent^.flags and FL_PARTIALGROUND) <> 0 then
begin
ent^.flags := ent^.flags and (not FL_PARTIALGROUND);
end;
ent^.groundentity := trace.ent;
ent^.groundentity_linkcount := edict_p(trace.ent)^.linkcount;
// the move is ok
if relink then
begin
gi.linkentity (ent);
G_TouchTriggers (ent);
end;
Result := True;
end;
//============================================================================
(*
===============
M_ChangeYaw
===============
*)
procedure M_ChangeYaw (ent: edict_p);
var
ideal: single;
current: single;
move: single;
speed: single;
begin
current := anglemod (ent^.s.angles[q_shared.YAW]);
ideal := ent^.ideal_yaw;
if current = ideal then
Exit;
move := ideal - current;
speed := ent^.yaw_speed;
if ideal > current then
begin
if move >= 180 then
move := move - 360;
end
else
begin
if move <= -180 then
move := move + 360;
end;
if move > 0 then
begin
if move > speed then
move := speed;
end
else
begin
if move < -speed then
move := -speed;
end;
ent^.s.angles[q_shared.YAW] := anglemod (current + move);
end;
(*
======================
SV_StepDirection
Turns to the movement direction, and walks the current distance if
facing it.
======================
*)
function SV_StepDirection (ent: edict_p; yaw: single; dist: single): qboolean;
var
move, oldorigin: vec3_t;
delta: single;
begin
ent^.ideal_yaw := yaw;
M_ChangeYaw (ent);
yaw := yaw * M_PI * 2 / 360;
move[0] := cos(yaw) * dist;
move[1] := sin(yaw) * dist;
move[2] := 0;
VectorCopy (ent^.s.origin, oldorigin);
if (SV_movestep (ent, move, false)) then
begin
delta := ent^.s.angles[q_shared.YAW] - ent^.ideal_yaw;
if ((delta > 45) and (delta < 315)) then
begin // not turned far enough, so don't take the step
VectorCopy (oldorigin, ent^.s.origin);
end;
gi.linkentity (ent);
G_TouchTriggers (ent);
Result := True;
Exit;
end;
gi.linkentity (ent);
G_TouchTriggers (ent);
Result := False;
end;
(*
======================
SV_FixCheckBottom
======================
*)
procedure SV_FixCheckBottom (ent: edict_p);
begin
ent^.flags := ent^.flags or FL_PARTIALGROUND;
end;
(*
================
SV_NewChaseDir
================
*)
const DI_NODIR = -1;
procedure SV_NewChaseDir (actor: edict_p; enemy: edict_p; dist: single);
var
deltax, deltay: single;
d: array [0..2] of single;
tdir, olddir, turnaround: single;
begin
//FIXME: how did we get here with no enemy
if (enemy = nil) then
Exit;
olddir := anglemod(Trunc((actor^.ideal_yaw/45)*45) );
turnaround := anglemod(olddir - 180);
deltax := enemy^.s.origin[0] - actor^.s.origin[0];
deltay := enemy^.s.origin[1] - actor^.s.origin[1];
if (deltax > 10) then
d[1] := 0
else if (deltax < -10) then
d[1] := 180
else
d[1] := DI_NODIR;
if (deltay < -10) then
d[2] := 270
else if (deltay > 10) then
d[2] := 90
else
d[2] := DI_NODIR;
// try direct route
if ((d[1] <> DI_NODIR) and (d[2] <> DI_NODIR)) then
begin
if (d[1] = 0) then
begin
if d[2] = 90 then
tdir := 45
else
tdir := 315;
end
else
begin
if d[2] = 90 then
tdir := 135
else
tdir := 215;
end;
if ((tdir <> turnaround) and (SV_StepDirection(actor, tdir, dist))) then
Exit;
end;
// try other directions
if (((rand() and 3) and 1) <> 0) or (abs(deltay) > abs(deltax)) then
begin
tdir := d[1];
d[1] := d[2];
d[2] := tdir;
end;
if ((d[1] <> DI_NODIR) and (d[1] <> turnaround)
and (SV_StepDirection(actor, d[1], dist))) then
Exit;
if ((d[2] <> DI_NODIR) and (d[2] <> turnaround)
and (SV_StepDirection(actor, d[2], dist))) then
Exit;
(* there is no direct path to the player, so pick another direction *)
if ((olddir <> DI_NODIR) and (SV_StepDirection(actor, olddir, dist))) then
Exit;
if (rand() and 1) <> 0 then (*randomly determine direction of search*)
begin
tdir := 0;
while (tdir <= 315) do
begin
if ((tdir <> turnaround) and (SV_StepDirection(actor, tdir, dist)) ) then
Exit;
tdir := tdir + 45;
end;
end
else
begin
tdir := 315;
while (tdir >= 0) do
begin
if ((tdir <> turnaround) and (SV_StepDirection(actor, tdir, dist)) ) then
Exit;
tdir := tdir - 45;
end;
end;
if ((turnaround <> DI_NODIR) and (SV_StepDirection(actor, turnaround, dist)) ) then
Exit;
actor^.ideal_yaw := olddir; // can't move
// if a bridge was pulled out from underneath a monster, it may not have
// a valid standing position at all
if (not M_CheckBottom (actor)) then
SV_FixCheckBottom (actor);
end;
(*
======================
SV_CloseEnough
======================
*)
function SV_CloseEnough (ent: edict_p; goal: edict_p; dist: single): qboolean;
var
i: smallint;
begin
for i:= 0 to 2 do
begin
if (goal^.absmin[i] > ent^.absmax[i] + dist) then
begin
Result := false;
Exit;
end;
if (goal^.absmax[i] < ent^.absmin[i] - dist) then
begin
Result := false;
Exit;
end;
end;
Result := true;
end;
(*
======================
M_MoveToGoal
======================
*)
procedure M_MoveToGoal (ent: edict_p; dist: single);
var
goal: edict_p;
begin
goal := ent^.goalentity;
if (ent^.groundentity = nil) and ((ent^.flags and (FL_FLY or FL_SWIM)) = 0) then
Exit;
// if the next step hits the enemy, return immediately
if (ent^.enemy <> nil) and (SV_CloseEnough(ent, ent^.enemy, dist)) then
Exit;
// bump around...
if ((rand() and 3) = 1) or (not SV_StepDirection (ent, ent^.ideal_yaw, dist)) then
begin
if (ent^.inuse) then
SV_NewChaseDir (ent, goal, dist);
end;
end;
(*
===============
M_walkmove
===============
*)
function M_walkmove (ent: edict_p; yaw: single; dist: single): qboolean;
var
move: vec3_t;
begin
if (ent^.groundentity = nil) and ((ent^.flags and (FL_FLY or FL_SWIM)) = 0) then
begin
Result := false;
Exit;
end;
yaw := yaw * M_PI * 2 / 360;
move[0] := cos(yaw) * dist;
move[1] := sin(yaw) * dist;
move[2] := 0;
Result := SV_movestep(ent, move, true);
end;
end.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -