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

📄 m_soldier.pas

📁 雷神之锤2(Quake2)Delphi源码
💻 PAS
📖 第 1 页 / 共 4 页
字号:
  if random() < 0.5 then
    self.monsterinfo.currentmove := soldier_move_walk1
  else
    self.monsterinfo.currentmove := soldier_move_walk2;
end;


//
// RUN
//

const
  soldier_frames_start_run : Array[0..1] of mframe_t =
    ((aifunc:ai_run; dist:7; thinkfunc:nil),
     (aifunc:ai_run; dist:5; thinkfunc:nil));

  soldier_move_start_run : mmove_t =
    (firstframe:FRAME_run01; lastframe:FRAME_run02; frame:soldier_frames_start_run; endfunc:soldier_run);

  soldier_frames_run : Array[0..5] of mframe_t =
    ((aifunc:ai_run; dist:10; thinkfunc:nil),
     (aifunc:ai_run; dist:11; thinkfunc:nil),
     (aifunc:ai_run; dist:11; thinkfunc:nil),
     (aifunc:ai_run; dist:16; thinkfunc:nil),
     (aifunc:ai_run; dist:10; thinkfunc:nil),
     (aifunc:ai_run; dist:15; thinkfunc:nil));

  soldier_move_run : mmove_t =
    (firstframe:FRAME_run03; lastframe:FRAME_run08; frame:soldier_frames_run; endfunc:nil);

procedure soldier_run(self : edict_t);
begin
  if (self.monsterinfo.aiflags) and (AI_STAND_GROUND) then
  begin
    self.monsterinfo.currentmove := soldier_move_stand1;
    exit;
  end;

  if (self.monsterinfo.currentmove = soldier_move_walk1) or
     (self.monsterinfo.currentmove = soldier_move_walk2) or
     (self.monsterinfo.currentmove = soldier_move_start_run) then
    self.monsterinfo.currentmove := soldier_move_run
  else
    self.monsterinfo.currentmove := soldier_move_start_run;
end;

//
// PAIN
//

const
  soldier_frames_pain1 : Array[0..4] of mframe_t =
    ((aifunc:ai_move; dist:-3; thinkfunc:nil),
     (aifunc:ai_move; dist:4;  thinkfunc:nil),
     (aifunc:ai_move; dist:1;  thinkfunc:nil),
     (aifunc:ai_move; dist:1;  thinkfunc:nil),
     (aifunc:ai_move; dist:0;  thinkfunc:nil));

  soldier_move_pain1 : mmove_t =
    (firstframe:FRAME_pain101; lastframe:FRAME_pain105; frame:soldier_frames_pain1; endfunc:soldier_run);

  soldier_frames_pain2 : Array[0..6] of mframe_t =
    ((aifunc:ai_move; dist:-13; thinkfunc:nil),
     (aifunc:ai_move; dist:-1;  thinkfunc:nil),
     (aifunc:ai_move; dist:2;   thinkfunc:nil),
     (aifunc:ai_move; dist:4;   thinkfunc:nil),
     (aifunc:ai_move; dist:2;   thinkfunc:nil),
     (aifunc:ai_move; dist:3;   thinkfunc:nil),
     (aifunc:ai_move; dist:2;   thinkfunc:nil));

  soldier_move_pain2 : mmove_t =
    (firstframe:FRAME_pain201; lastframe:FRAME_pain207; frame:soldier_frames_pain2; endfunc:soldier_run);

  soldier_frames_pain3 : Array[0..17] of mframe_t =
    ((aifunc:ai_move; dist:-8; thinkfunc:nil),
     (aifunc:ai_move; dist:10; thinkfunc:nil),
     (aifunc:ai_move; dist:-4; thinkfunc:nil),
     (aifunc:ai_move; dist:-1; thinkfunc:nil),
     (aifunc:ai_move; dist:-3; thinkfunc:nil),
     (aifunc:ai_move; dist:0;  thinkfunc:nil),
     (aifunc:ai_move; dist:3;  thinkfunc:nil),
     (aifunc:ai_move; dist:0;  thinkfunc:nil),
     (aifunc:ai_move; dist:0;  thinkfunc:nil),
     (aifunc:ai_move; dist:0;  thinkfunc:nil),
     (aifunc:ai_move; dist:0;  thinkfunc:nil),
     (aifunc:ai_move; dist:1;  thinkfunc:nil),
     (aifunc:ai_move; dist:0;  thinkfunc:nil),
     (aifunc:ai_move; dist:1;  thinkfunc:nil),
     (aifunc:ai_move; dist:2;  thinkfunc:nil),
     (aifunc:ai_move; dist:4;  thinkfunc:nil),
     (aifunc:ai_move; dist:3;  thinkfunc:nil),
     (aifunc:ai_move; dist:2;  thinkfunc:nil));

  soldier_move_pain3 : mmove_t =
    (firstframe:FRAME_pain301; lastframe:FRAME_pain318; frame:soldier_frames_pain3; endfunc:soldier_run);

  soldier_frames_pain4 : Array[0..16] of mframe_t =
    ((aifunc:ai_move; dist:0;   thinkfunc:nil),
     (aifunc:ai_move; dist:0;   thinkfunc:nil),
     (aifunc:ai_move; dist:0;   thinkfunc:nil),
     (aifunc:ai_move; dist:-10; thinkfunc:nil),
     (aifunc:ai_move; dist:-6;  thinkfunc:nil),
     (aifunc:ai_move; dist:8;   thinkfunc:nil),
     (aifunc:ai_move; dist:4;   thinkfunc:nil),
     (aifunc:ai_move; dist:1;   thinkfunc:nil),
     (aifunc:ai_move; dist:0;   thinkfunc:nil),
     (aifunc:ai_move; dist:2;   thinkfunc:nil),
     (aifunc:ai_move; dist:5;   thinkfunc:nil),
     (aifunc:ai_move; dist:2;   thinkfunc:nil),
     (aifunc:ai_move; dist:-1;  thinkfunc:nil),
     (aifunc:ai_move; dist:-1;  thinkfunc:nil),
     (aifunc:ai_move; dist:3;   thinkfunc:nil),
     (aifunc:ai_move; dist:2;   thinkfunc:nil),
     (aifunc:ai_move; dist:0;   thinkfunc:nil));

  soldier_move_pain4 : mmove_t =
    (firstframe:FRAME_pain401; lastframe:FRAME_pain417; frame:soldier_frames_pain4; endfunc:soldier_run);

procedure soldier_pain (self, other : edict_t; kick : single; damage : integer);
var
  r : single;
  n : integer;
begin
  if self.health < (self.max_health / 2) then
    self.s.skinnum := self.s.skinnum or 1;

  if level.time < self.pain_debounce_time then
  begin
    if ((self.velocity[2] > 100) and
       ((self.monsterinfo.currentmove = soldier_move_pain1) or
       (self.monsterinfo.currentmove = soldier_move_pain2) or
       (self.monsterinfo.currentmove = soldier_move_pain3))) then
      self.monsterinfo.currentmove := soldier_move_pain4;

    exit;
  end;

  self.pain_debounce_time := level.time + 3;

  n := self.s.skinnum or 1;
  if n = 1 then
    gi.sound(self, CHAN_VOICE, sound_pain_light, 1, ATTN_NORM, 0)
  else
  if n = 3 then
    gi.sound(self, CHAN_VOICE, sound_pain, 1, ATTN_NORM, 0)
  else
    gi.sound(self, CHAN_VOICE, sound_pain_ss, 1, ATTN_NORM, 0);

  if self.velocity[2] > 100 then
  begin
    self.monsterinfo.currentmove := soldier_move_pain4;
    exit;
  end;

  if skill.value = 3 then
    exit;		// no pain anims in nightmare

    r = random();

    if r < 0.33 then
      self.monsterinfo.currentmove := soldier_move_pain1
    else
    if r < 0.66 then
      self.monsterinfo.currentmove := soldier_move_pain2
    else
      self.monsterinfo.currentmove := soldier_move_pain3;
end;


//
// ATTACK
//

var

  blaster_flash : Array[0..3] of integer =
    (MZ2_SOLDIER_BLASTER_1, MZ2_SOLDIER_BLASTER_2,
     MZ2_SOLDIER_BLASTER_3, MZ2_SOLDIER_BLASTER_4,
     MZ2_SOLDIER_BLASTER_5, MZ2_SOLDIER_BLASTER_6,
     MZ2_SOLDIER_BLASTER_7, MZ2_SOLDIER_BLASTER_8);

  shotgun_flash : Array[0..3] of integer =
    (MZ2_SOLDIER_SHOTGUN_1, MZ2_SOLDIER_SHOTGUN_2,
     MZ2_SOLDIER_SHOTGUN_3, MZ2_SOLDIER_SHOTGUN_4,
     MZ2_SOLDIER_SHOTGUN_5, MZ2_SOLDIER_SHOTGUN_6,
     MZ2_SOLDIER_SHOTGUN_7, MZ2_SOLDIER_SHOTGUN_8);

  machinegun_flash : Array[0..3] of integer =
    (MZ2_SOLDIER_MACHINEGUN_1, MZ2_SOLDIER_MACHINEGUN_2,
     MZ2_SOLDIER_MACHINEGUN_3, MZ2_SOLDIER_MACHINEGUN_4,
     MZ2_SOLDIER_MACHINEGUN_5, MZ2_SOLDIER_MACHINEGUN_6,
     MZ2_SOLDIER_MACHINEGUN_7, MZ2_SOLDIER_MACHINEGUN_8);

procedure soldier_fire(self : edict_t; flash_number : integer);
var
  start, fwrd, right, up, aim, dir, eend : vec3_t;
  r, u : single;
  flash_index : integer;
begin
  if self.s.skinnum < 2 then
    flash_index := blaster_flash[flash_number]
  else
  if self.s.skinnum < 4 then
    flash_index := shotgun_flash[flash_number]
  else
    flash_index := machinegun_flash[flash_number];

  AngleVectors(self.s.angles, fwrd, right, nil);
  G_ProjectSource(self.s.origin, monster_flash_offset[flash_index], fwrd, right, start);

  if flash_number = 5 or flash_number = 6 then
    VectorCopy(fwrd, aim)
  else
  begin
    VectorCopy(self.enemy.s.origin, eend);
    eend[2] := eend[2] + self.enemy.viewheight;
    VectorSubtract(eend, start, aim);
    vectoangles(aim, dir);
    AngleVectors(dir, fwrd, right, up);

    r := crandom()*1000;
    u := crandom()*500;
    VectorMA(start, 8192, fwrd, eend);
    VectorMA(eend, r, right, eend);
    VectorMA(eend, u, up, eend);

    VectorSubtract(eend, start, aim);
    VectorNormalize(aim);
  end;

  if self.s.skinnum <= 1 then
    monster_fire_blaster(self, start, aim, 5, 600, flash_index, EF_BLASTER)
  else
  if self.s.skinnum <= 3 then
    monster_fire_shotgun(self, start, aim, 2, 1, DEFAULT_SHOTGUN_HSPREAD, DEFAULT_SHOTGUN_VSPREAD, DEFAULT_SHOTGUN_COUNT, flash_index)
  else
  if not(self.monsterinfo.aiflags and AI_HOLD_FRAME) then
    self.monsterinfo.pausetime := level.time + (3 + random(8)) * FRAMETIME;

  monster_fire_bullet(self, start, aim, 2, 4, DEFAULT_BULLET_HSPREAD, DEFAULT_BULLET_VSPREAD, flash_index);

  if level.time >= self.monsterinfo.pausetime then
    self.monsterinfo.aiflags := (self.monsterinfo.aiflags and AI_HOLD_FRAME)
  else
    self.monsterinfo.aiflags := (self.monsterinfo.aiflags or AI_HOLD_FRAME);
end;

// ATTACK1 (blaster/shotgun)

procedure soldier_fire1(self : edict_t);
begin
  soldier_fire(self, 0);
end;

procedure soldier_attack1_refire1(self : edict_t);
begin
  if self.s.skinnum > 1 then
    return;

  if self.enemy.health <= 0 then
    return;

  if ((skill.value = 3) and (random() < 0.5)) or (range(self, self.enemy) = RANGE_MELEE) then
    self.monsterinfo.nextframe := FRAME_attak102
  else
    self.monsterinfo.nextframe := FRAME_attak110;
end;

procedure soldier_attack1_refire2(self : edict_t);
begin
  if self.s.skinnum < 2 then
    return;

  if self.enemy.health <= 0 then
    return;

  if ((skill.value = 3) and (random() < 0.5)) or (range(self, self.enemy) = RANGE_MELEE) then
    self.monsterinfo.nextframe := FRAME_attak102;
end;

const
  soldier_frames_attack1 : Array[0..11] of mframe_t =
    ((aifunc:ai_charge; dist:0; thinkfunc:nil),
     (aifunc:ai_charge; dist:0; thinkfunc:nil),
     (aifunc:ai_charge; dist:0; thinkfunc:soldier_fire1),
     (aifunc:ai_charge; dist:0; thinkfunc:nil),
     (aifunc:ai_charge; dist:0; thinkfunc:nil),
     (aifunc:ai_charge; dist:0; thinkfunc:soldier_attack1_refire1),
     (aifunc:ai_charge; dist:0; thinkfunc:nil),
     (aifunc:ai_charge; dist:0; thinkfunc:soldier_cock),
     (aifunc:ai_charge; dist:0; thinkfunc:soldier_attack1_refire2),
     (aifunc:ai_charge; dist:0; thinkfunc:nil),
     (aifunc:ai_charge; dist:0; thinkfunc:nil),
     (aifunc:ai_charge; dist:0; thinkfunc:nil));

  soldier_move_attack1 : mmove_t =
    (firstframe:FRAME_attak101; lastframe:FRAME_attak112; frame:soldier_frames_attack1; endfunc:soldier_run);

// ATTACK2 (blaster/shotgun)

procedure soldier_fire2(self : edict_t);
begin
  soldier_fire (self, 1);
end;

procedure soldier_attack2_refire1(self : edict_t);
begin
  if self.s.skinnum > 1 then
    exit;

  if self.enemy.health <= 0 then
    exit;

  if ((skill.value = 3) and (random() < 0.5)) or (range(self, self.enemy) = RANGE_MELEE) then
    self.monsterinfo.nextframe := FRAME_attak204
  else
    self.monsterinfo.nextframe := FRAME_attak216;
end;

procedure soldier_attack2_refire2(self : edict_t);
begin
  if self.s.skinnum < 2 then
    exit;

  if self.enemy.health <= 0 then
    exit;

  if ((skill.value = 3) and (random() < 0.5)) or (range(self, self.enemy) = RANGE_MELEE) then
    self.monsterinfo.nextframe := FRAME_attak204;
end;

const
  soldier_frames_attack2 : Array[0..17] of mframe_t =
    ((aifunc:ai_charge; dist:0; thinkfunc:nil),
     (aifunc:ai_charge; dist:0; thinkfunc:nil),
     (aifunc:ai_charge; dist:0; thinkfunc:nil),
     (aifunc:ai_charge; dist:0; thinkfunc:nil),
     (aifunc:ai_charge; dist:0; thinkfunc:soldier_fire2),
     (aifunc:ai_charge; dist:0; thinkfunc:nil),
     (aifunc:ai_charge; dist:0; thinkfunc:nil),
     (aifunc:ai_charge; dist:0; thinkfunc:soldier_attack2_refire1),
     (aifunc:ai_charge; dist:0; thinkfunc:nil),
     (aifunc:ai_charge; dist:0; thinkfunc:nil),
     (aifunc:ai_charge; dist:0; thinkfunc:nil),

⌨️ 快捷键说明

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