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

📄 m_move.pas

📁 雷神之锤2(Quake2)Delphi源码
💻 PAS
📖 第 1 页 / 共 2 页
字号:
                       G_TouchTriggers (ent);
                    end;
                    result := True;
               end;
               VectorCopy (oldorg, ent^.s.origin);
               result := False;
           end;
          if (ent^.flags and FL_PARTILGROUND) then
           begin
              ent^.flags := ent^.flags and (not FL_PARTILGROUND);
           end;
           ent^.groundentity := trace.ent;
           ent^.groundentity_linkcount := 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:pedict);
var  ideal:single;
     current:single;
     move:single;
     speed:single;
begin
     current := anglemod (ent^.s.angles[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[YAW] := anglemod (current + move);
end;

(*
======================
SV_StepDirection

Turns to the movement direction, and walks the current distance if
facing it.

======================
*)
function SV_StepDirection (ent:pedict_t; 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))
         begin
		delta := ent^s.angles[YAW] - ent^.ideal_yaw;
		if ((delta > 45) and (delta < 315))
		 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;
         end;
	gi.linkentity (ent);
	G_TouchTriggers (ent);
	result := False;
end;

(*
======================
SV_FixCheckBottom

======================
*)
procedure SV_FixCheckBottom (ent:pedict_t);
begin
	ent^.flags := ent^.flags or FL_PARTIALGROUND;
end;

(*
================
SV_NewChaseDir

================
*)
const	DI_NODIR = -1;
procedure SV_NewChaseDir (actor:pedict_t; enemy:pedict_t; dist:single);
var  deltax,deltay:single;
     d[3]:single;
     tdir, olddir, turnaround:single;
begin
	//FIXME: how did we get here with no enemy
	if not (enemy) then
		exit;

	olddir := anglemod( int((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 d[2] := 45
                       else d[2] := 315;
                    tdir := d[2];
                 end
		else
                 begin
                    if d[2] = 90 then d[2] := 135
                       else d[2] := 215;
		    tdir := d[2];
                 end;
			
		if ((tdir <> turnaround) and (SV_StepDirection(actor, tdir, dist))) then
			exit;
         end;

// try other directions
	if ( ((random(360)and 3) and 1) 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 (random(360) and 1) then 	(*randomly determine direction of search*)
         begin
		for  tdir := 0 to 315 do
                 begin
                        tdir := tdir + 45;
			if ((tdir<>turnaround) and (SV_StepDirection(actor, tdir, dist)) ) then
					exit;
                 end;
         end
	else
         begin
		for tdir :=315 downto 0 do
                 begin
                        tdir := tdir - 45;
			if ((tdir<>turnaround) and (SV_StepDirection(actor, tdir, dist)) ) then
					exit;
                 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:pedict_t; goal:pedict_t; dist:single):qboolean;
var
      i:smallint;
begin
	for i:=0 to 2 do
         begin
		if (goal^.absmin[i] > ent^.absmax[i] + dist) then
			result := false;
		if (goal^.absmax[i] < ent^.absmin[i] - dist) then
			result := false;
         end;
	result :=true;
end;


(*
======================
M_MoveToGoal
======================
*)
procedure M_MoveToGoal (ent:pedict_t; dist:single);
var
	goal:pedict_t;
begin
	goal := ent^.goalentity;

	if (not ent^.groundentity and not(ent^.flags and (FL_FLY or FL_SWIM))) then
		exit;

// if the next step hits the enemy, return immediately
	if (ent^.enemy and  SV_CloseEnough (ent, ent^.enemy, dist) ) then
		exit;

// bump around...
	if ( (random(360)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:pedict_t; yaw:single; dist:single):qboolean;
var
	move:vec3_t;
begin
	if (not ent^.groundentity and not(ent^.flags and (FL_FLY or FL_SWIM))) then
		result := false;

	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 + -