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

📄 g_ai.pas

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

(* =============
ai_run_slide

Strafe sideways, but stay at aproximately the same range
============= *)
procedure ai_run_slide(self: Pedict_t, distance: Single);
var
  ofs: Single;
begin
  self^.ideal_yaw := enemy_yaw;
  M_ChangeYaw(self);

  if (self^.monsterinfo.lefty) then
     ofs := 90
  else
     ofs := -90;

  if (M_walkmove(self, self^.ideal_yaw + ofs, distance)) then
     Exit;

  self^.monsterinfo.lefty := (1 - self^.monsterinfo.lefty);
  M_walkmove(self, (self^.ideal_yaw - ofs), distance);
end;

(* =============
ai_checkattack

Decides if we're going to attack or do something else
used by ai_run and ai_stand
============= *)
function ai_checkattack(self: Pedict_t; dist: Single): qboolean;
var
  temp: vec3_t;
  hesDeadJim: qboolean;s
begin
  { this causes monsters to run blindly to the combat point w/o firing }
  if (self^.goalentity) then begin
     if (self^.monsterinfo.aiflags AND AI_COMBAT_POINT) <> 0 then begin
        Result := False;
        Exit;
     end;

     if (self^.monsterinfo.aiflags AND AI_SOUND_TARGET) <> 0 then begin
        if ((level.time - self^.enemy^.teleport_time) > 5.0) then begin
           if (self^.goalentity = self^.enemy) then begin
              if (self^.movetarget) then
                 self^.goalentity := self^.movetarget
              else
                 self^.goalentity := NULL;
           end;

           { TODO:  Translate the Line Below: }
           // ORIGINAL:  self->monsterinfo.aiflags &= ~AI_SOUND_TARGET;
           self^.monsterinfo.aiflags := self^.monsterinfo.aiflags AND (NOT AI_SOUND_TARGET);
           if (self^.monsterinfo.aiflags AND AI_TEMP_STAND_GROUND) <> 0 then
              { TODO:  Translate the Line Below: }
              // ORIGINAL:  self->monsterinfo.aiflags &= ~(AI_STAND_GROUND | AI_TEMP_STAND_GROUND);
              self^.monsterinfo.aiflags := self^.monsterinfo.aiflags AND (NOT (AI_STAND_GROUND OR AI_TEMP_STAND_GROUND));
        end else begin
            self^.show_hostile := (level.time + 1);
            Result := False;
            Exit;
        end;
     end;
  end;

  enemy_vis := False;

  { see if the enemy is dead }
  hesDeadJim := False;
  { TODO:  Translate the Line Below: }
  if ((self^.enemy = Nil) OR (NOT self^.enemy^.inuse)) then
     hesDeadJim := True
  else if (self^.monsterinfo.aiflags AND AI_MEDIC) then begin
       if (self^.enemy^.health > 0) then begin
          hesDeadJim := True;
          { TODO:  Translate the Line Below: }
          // ORIGINAL:  self->monsterinfo.aiflags &= ~AI_MEDIC;
          self^.monsterinfo.aiflags := self^.monsterinfo.aiflags AND (NOT AI_MEDIC);
       end;
  end else begin
      if (self^.monsterinfo.aiflags AND AI_BRUTAL) <> 0 then begin
         if (self^.enemy^.health <= -80) then
            hesDeadJim := True;
      end else begin
          if (self^.enemy^.health <= 0) then
             hesDeadJim := True;
      end;
  end;

  if (hesDeadJim) then begin
     self^.enemy := NULL;
     // FIXME: look all around for other targets
     { TODO:  Translate the Line Below: }
     // ORIGINAL:  if (self->oldenemy && self->oldenemy->health > 0)
     if ((self^.oldenemy <> Nil) AND (self^.oldenemy^.health > 0)) then begin
        self^.enemy := self^.oldenemy;
        self^.oldenemy := NULL;
        HuntTarget(self);
     end else begin
         if (self^.movetarget) then begin
            self^.goalentity := self^.movetarget;
            self^.monsterinfo.walk(self);
         end else begin
             { we need the pausetime otherwise the stand code
               will just revert to walking with no target and
               the monsters will wonder around aimlessly trying
               to hunt the world entity }
             self^.monsterinfo.pausetime := (level.time + 100000000);
             self^.monsterinfo.stand(self);
         end;

         Result := True;
         Exit;
     end;
  end;

  { wake up other monsters }
  self^.show_hostile := (level.time + 1);

  { check knowledge of enemy }
  enemy_vis := visible(self, self^.enemy);
  if (enemy_vis) then begin
     self^.monsterinfo.search_time := (level.time + 5);
     VectorCopy(self^.enemy^.s.origin, self^.monsterinfo.last_sighting);
  end;

  // look for other coop players here
  //	if (coop && self->monsterinfo.search_time < level.time)
  //	{
  //		if (FindTarget (self))
  //			return true;
  //	}

  enemy_infront := infront(self, self^.enemy);
  enemy_range := range(self, self^.enemy);
  VectorSubtract(self^.enemy^.s.origin, self^.s.origin, temp);
  enemy_yaw := vectoyaw(temp);


  // JDC self->ideal_yaw = enemy_yaw;

  if (self^.monsterinfo.attack_state = AS_MISSILE) then begin
     ai_run_missile(self);
     Result := True;
     Exit;
  end;

  if (self^.monsterinfo.attack_state = AS_MELEE) then begin
     ai_run_melee(self);
     Result := True;
  end;

  { if enemy is not currently visible, we will never attack }
  if (NOT enemy_vis) then begin
     Result := False;
     Exit;
  end;

  Result := self^.monsterinfo.checkattack(self);
end;

(* =============
ai_run

The monster has an enemy it is trying to kill
============= *)
procedure ai_run(self: Pedict_t; dist: Single);
var
  v, v_forward, v_right, left_target, right_target: vec3_t;
  tempgoal, save, marker: Pedict_t;
  new: qboolean;
  d1, d2, left, center, right: Single {float};
  tr: trace_t;
begin
  { Originally Removed comments by ID start the line like:
//             eg...}
  { if we're going to a combat point, just proceed }
  if (self^.monsterinfo.aiflags AND AI_COMBAT_POINT) <> 0 then begin
     M_MoveToGoal(self, dist);
     Exit;
  end;

  if (self^.monsterinfo.aiflags AND AI_SOUND_TARGET) <> 0 then begin
     VectorSubtract(self^.s.origin, self^.enemy^.s.origin, v);
     if (VectorLength(v) < 64) then begin
        { TODO:  Translate the Line Below: }
        // ORIGINAL:  self^.monsterinfo.aiflags |= (AI_STAND_GROUND OR AI_TEMP_STAND_GROUND);
        self^.monsterinfo.aiflags := self^.monsterinfo.aiflags OR (AI_STAND_GROUND OR AI_TEMP_STAND_GROUND);
        self^.monsterinfo.stand(self);
        Exit;
     end;

     M_MoveToGoal(self, dist);

     if (NOT FindTarget(self)) then
        Exit;
  end;

  if (ai_checkattack(self, dist)) then
     Exit;

  if (self^.monsterinfo.attack_state = AS_SLIDING) then begin
     ai_run_slide(self, dist);
     Exit;
  end;

  if (enemy_vis) then begin
//		if (self.aiflags & AI_LOST_SIGHT)
//			dprint("regained sight\n");
     M_MoveToGoal(self, dist);
     { TODO:  Translate the Line Below: }
     // ORIGINAL:  self->monsterinfo.aiflags &= ~AI_LOST_SIGHT;
     self^.monsterinfo.aiflags := self^.monsterinfo.aiflags AND (NOT AI_LOST_SIGHT);
     VectorCopy(self^.enemy^.s.origin, self^.monsterinfo.last_sighting);
     self^.monsterinfo.trail_time := level.time;
     Exit;
  end;

  { coop will change to another enemy if visible }
  if (coop^.value) then begin
     // FIXME: insane guys get mad with this, which causes crashes!
     if (FindTarget(self)) then
        Exit;
  end;

  { TODO:  Translate the Line Below: }
  // ORIGINAL:  if ((self->monsterinfo.search_time) && (level.time > (self->monsterinfo.search_time + 20)))
  if ((self^.monsterinfo.search_time <> 0) AND (level.time > (self^.monsterinfo.search_time + 20))) then begin
     M_MoveToGoal(self, dist);
     self^.monsterinfo.search_time := 0;
//		dprint("search timeout\n");
     Exit;
  end;

  save := self^.goalentity;
  tempgoal := G_Spawn();
  self^.goalentity := tempgoal;

  new := False;

  if ((self^.monsterinfo.aiflags AND AI_LOST_SIGHT) = 0) then begin
          // just lost sight of the player, decide where to go first
//		dprint("lost sight of player, last seen at "); dprint(vtos(self.last_sighting)); dprint("\n");
     { TODO:  Translate the Line Below: }
     // ORIGINAL:  self->monsterinfo.aiflags |= (AI_LOST_SIGHT | AI_PURSUIT_LAST_SEEN);
     self^.monsterinfo.aiflags := self^.monsterinfo.aiflags OR (AI_LOST_SIGHT OR AI_PURSUIT_LAST_SEEN);
     { TODO:  Translate the Line Below: }
     // ORIGINAL:  self->monsterinfo.aiflags &= ~(AI_PURSUE_NEXT | AI_PURSUE_TEMP);
     self^.monsterinfo.aiflags := self^.monsterinfo.aiflags AND (NOT (AI_PURSUE_NEXT OR AI_PURSUE_TEMP));
     new := True;
  end;

  if (self^.monsterinfo.aiflags AND AI_PURSUE_NEXT) <> 0 then begin
     { TODO:  Translate the Line Below: }
     // ORIGINAL:  self^.monsterinfo.aiflags &= ~AI_PURSUE_NEXT;
     self^.monsterinfo.aiflags := self^.monsterinfo.aiflags AND (NOT AI_PURSUE_NEXT);
//		dprint("reached current goal: "); dprint(vtos(self.origin)); dprint(" "); dprint(vtos(self.last_sighting)); dprint(" "); dprint(ftos(vlen(self.origin - self.last_sighting))); dprint("\n");

     { give ourself more time since we got this far }
     self^.monsterinfo.search_time := (level.time + 5);

     if (self^.monsterinfo.aiflags AND AI_PURSUE_TEMP) then begin
//			dprint("was temp goal; retrying original\n");
        { TODO:  Translate the Line Below: }
        // ORIGINAL:  self->monsterinfo.aiflags &= ~AI_PURSUE_TEMP;
        self^.monsterinfo.aiflags := self^.monsterinfo.aiflags AND (NOT AI_PURSUE_TEMP);
        marker := NULL;
        VectorCopy(self^.monsterinfo.saved_goal, self^.monsterinfo.last_sighting);
        new := True;
     end else if (self^.monsterinfo.aiflags AND AI_PURSUIT_LAST_SEEN) then begin
         { TODO:  Translate the Line Below: }
         // ORIGINAL:  self^.monsterinfo.aiflags &= ~AI_PURSUIT_LAST_SEEN;
         self^.monsterinfo.aiflags := self^.monsterinfo.aiflags AND (NOT AI_PURSUIT_LAST_SEEN);
         marker := PlayerTrail_PickFirst(self);
     end else begin
         marker := PlayerTrail_PickNext(self);
     end;

     if (marker) then begin
        VectorCopy(marker^.s.origin, self^.monsterinfo.last_sighting);
        self^.monsterinfo.trail_time := marker^.timestamp;
        // self->s.angles[YAW] = self->ideal_yaw = marker->s.angles[YAW];
        self^.ideal_yaw := marker^.s.angles[YAW];
        self^.s.angles[YAW] := self^.ideal_yaw;
//			dprint("heading is "); dprint(ftos(self.ideal_yaw)); dprint("\n");

//			debug_drawline(self.origin, self.last_sighting, 52);
        new := True;
     end;
  end;

  VectorSubtract(self^.s.origin, self^.monsterinfo.last_sighting, v);
  d1 := VectorLength(v);
  if (d1 <= dist) then begin
     { TODO:  Translate the Line Below: }
     // ORIGINAL:  self^.monsterinfo.aiflags |= AI_PURSUE_NEXT;
     self^.monsterinfo.aiflags := self^.monsterinfo.aiflags OR AI_PURSUE_NEXT;
     dist := d1;
  end;

  VectorCopy(self^.monsterinfo.last_sighting, self^.goalentity^.s.origin);

  if (new) then begin
//		gi.dprintf("checking for course correction\n");

     tr := gi.trace(self^.s.origin, self^.mins, self^.maxs, self^.monsterinfo.last_sighting, self, MASK_PLAYERSOLID);
     if (tr.fraction < 1) then begin
        VectorSubtract(self^.goalentity^.s.origin, self^.s.origin, v);
        d1 := VectorLength(v);
        center := tr.fraction;
        d2 := (d1 * ((center + 1) / 2));
        //self^.s.angles[YAW] = self^.ideal_yaw = vectoyaw(v);
        self^.ideal_yaw := vectoyaw(v);
        self^.s.angles[YAW] := self^.ideal_yaw;
        AngleVectors(self^.s.angles, v_forward, v_right, NULL);

        VectorSet(v, d2, -16, 0);
        G_ProjectSource(self^.s.origin, v, v_forward, v_right, left_target);
        tr := gi.trace(self^.s.origin, self^.mins, self^.maxs, left_target, self, MASK_PLAYERSOLID);
        left := tr.fraction;

        VectorSet(v, d2, 16, 0);
        G_ProjectSource(self^.s.origin, v, v_forward, v_right, right_target);
        tr := gi.trace(self^.s.origin, self^.mins, self^.maxs, right_target, self, MASK_PLAYERSOLID);
        right := tr.fraction;

        center := ((d1 * center) / d2);
        { TODO:  Translate the Line Below: }
        // ORIGINAL:  if (left >= center && left > right)
        if ((left >= center) AND (left > right)) then begin
           if (left < 1) then begin
              VectorSet(v, (d2 * left * 0.5), -16, 0);
              G_ProjectSource(self^.s.origin, v, v_forward, v_right, left_target);
//					gi.dprintf("incomplete path, go part way and adjust again\n");
           end;
           VectorCopy(self^.monsterinfo.last_sighting, self^.monsterinfo.saved_goal);
           { TODO:  Translate the Line Below: }
           // ORIGINAL:  self->monsterinfo.aiflags |= AI_PURSUE_TEMP;
           self^.monsterinfo.aiflags := self^.monsterinfo.aiflags OR AI_PURSUE_TEMP;
           VectorCopy(left_target, self^.goalentity^.s.origin);
           VectorCopy(left_target, self^.monsterinfo.last_sighting);
           VectorSubtract(self^.goalentity^.s.origin, self^.s.origin, v);
           //self^.s.angles[YAW] = self^.ideal_yaw = vectoyaw(v);
           self^.ideal_yaw := vectoyaw(v);
           self^.s.angles[YAW] := self^.ideal_yaw;
//				gi.dprintf("adjusted left\n");
//				debug_drawline(self.origin, self.last_sighting, 152);
        { TODO:  Translate the Line Below: }
        end else if ((right >= center) AND (right > left)) then begin
            if (right < 1) then begin
               VectorSet(v, (d2 * right * 0.5), 16, 0);
               G_ProjectSource(self^.s.origin, v, v_forward, v_right, right_target);
//					gi.dprintf("incomplete path, go part way and adjust again\n");
            end;
            VectorCopy(self^.monsterinfo.last_sighting, self^.monsterinfo.saved_goal);
            { TODO:  Translate the Line Below: }
            // ORIGINAL:  self->monsterinfo.aiflags |= AI_PURSUE_TEMP;
            self^.monsterinfo.aiflags := self^.monsterinfo.aiflags OR AI_PURSUE_TEMP;
            VectorCopy(right_target, self^.goalentity^.s.origin);
            VectorCopy(right_target, self^.monsterinfo.last_sighting);
            VectorSubtract(self^.goalentity^.s.origin, self^.s.origin, v);
            //self^.s.angles[YAW] = self^.ideal_yaw = vectoyaw(v);
            self^.ideal_yaw := vectoyaw(v);
            self^.s.angles[YAW] := self^.ideal_yaw;
//				gi.dprintf("adjusted right\n");
//				debug_drawline(self.origin, self.last_sighting, 152);
        end;
     end;
//		else gi.dprintf("course was fine\n");
  end;

  M_MoveToGoal(self, dist);

  G_FreeEdict(tempgoal);

  if (self) then
     self^.goalentity := save;
end;

end.

⌨️ 快捷键说明

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