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

📄 m_boss2.pas

📁 雷神之锤2(Quake2)Delphi源码
💻 PAS
📖 第 1 页 / 共 2 页
字号:
     (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: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: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:0; thinkfunc:nil));

  boss2_move_pain_heavy : mmove_t =
    (firstframe:FRAME_pain2; lastframe:FRAME_pain19; frame:boss2_frames_pain_heavy; endfunc:boss2_run);

  boss2_frames_pain_light : Array[0..3] 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:0; thinkfunc:nil));

  boss2_move_pain_light : mmove_t =
    (firstframe:FRAME_pain20; lastframe:FRAME_pain23; frame:boss2_frames_pain_light; endfunc:boss2_run);

  boss2_frames_death : Array[0..48] 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: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: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: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: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: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: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: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: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: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: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: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:0; thinkfunc:nil),
     (aifunc:ai_move; dist:0; thinkfunc:BossExplode));

  boss2_move_death : mmove_t =
    (firstframe:FRAME_death2; lastframe:FRAME_death50; frame:boss2_frames_death; endfunc:boss2_dead);

procedure boss2_stand(self : edict_t);
begin
  self.monsterinfo.currentmove := boss2_move_stand;
end;

procedure boss2_run(self : edict_t);
begin
  if (self.monsterinfo.aiflags and AI_STAND_GROUND) then
    self.monsterinfo.currentmove := boss2_move_stand
  else
    self.monsterinfo.currentmove := boss2_move_run;
end;

procedure boss2_walk(self : edict_t);
begin
  self.monsterinfo.currentmove := boss2_move_walk;
end;

procedure boss2_attack(self : edict_t);
var
  vec   : vec3_t;
  range : single;
begin
  VectorSubtract(self.enemy.s.origin, self.s.origin, vec);
  range := VectorLength(vec);
	
  if range <= 125 then
    self.monsterinfo.currentmove := boss2_move_attack_pre_mg
  else
  begin
    if random() <= 0.6 then
      self.monsterinfo.currentmove := boss2_move_attack_pre_mg
    else
      self.monsterinfo.currentmove := boss2_move_attack_rocket;
  end;
end;

procedure boss2_attack_mg(self : edict_t);
begin
  self.monsterinfo.currentmove := boss2_move_attack_mg;
end;

procedure boss2_reattack_mg(self : edict_t);
begin
  if infront(self, self.enemy) then
  begin
    if random() <= 0.7 then
      self.monsterinfo.currentmove := boss2_move_attack_mg;
    else
      self.monsterinfo.currentmove := boss2_move_attack_post_mg;
  end
  else
    self.monsterinfo.currentmove := boss2_move_attack_post_mg;
end;

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

  if level.time < self.pain_debounce_time then
    exit;

  self.pain_debounce_time := level.time + 3;
  // American wanted these at no attenuation
  if damage < 10 then
  begin
    gi.sound(self, CHAN_VOICE, sound_pain3, 1, ATTN_NONE, 0);
    self.monsterinfo.currentmove := boss2_move_pain_light;
  end
  else
  if damage < 30 then
  begin
    gi.sound(self, CHAN_VOICE, sound_pain1, 1, ATTN_NONE, 0);
    self.monsterinfo.currentmove := boss2_move_pain_light;
  end
  else
  begin
    gi.sound(self, CHAN_VOICE, sound_pain2, 1, ATTN_NONE, 0);
    self.monsterinfo.currentmove := boss2_move_pain_heavy;
  end;
end;

procedure boss2_dead(self : edict_t);
begin
  VectorSet(self.mins, -56, -56,  0);
  VectorSet(self.maxs,  56,  56, 80);
  self.movetype  := MOVETYPE_TOSS;
  self.svflags   := self.svflags or SVF_DEADMONSTER;
  self.nextthink := 0;
  gi.linkentity(self);
end;

procedure boss2_die(self, inflictor, attacker : edict_t; damage : integer; point : vec3_t);
var
  n : integer;
begin
  gi.sound(self, CHAN_VOICE, sound_death, 1, ATTN_NONE, 0);
  self.deadflag := DEAD_DEAD;
  self.takedamage := DAMAGE_NO;
  self.count := 0;
  self.monsterinfo.currentmove := boss2_move_death;

  {$IF FALSE}
    self.s.sound := 0;
    // check for gib
    if self.health <= self.gib_health then
    begin
      gi.sound(self, CHAN_VOICE, gi.soundindex('misc/udeath.wav'), 1, ATTN_NORM, 0);
      for n := 0 to 1 do
        ThrowGib(self, 'models/objects/gibs/bone/tris.md2', damage, GIB_ORGANIC);
      for n := 0 to 3 do
        ThrowGib(self, 'models/objects/gibs/sm_meat/tris.md2', damage, GIB_ORGANIC);
      ThrowHead (self, 'models/objects/gibs/head2/tris.md2', damage, GIB_ORGANIC);
      self.deadflag := DEAD_DEAD;
      exit;
    end;

    if self.deadflag = DEAD_DEAD then
      exit;

    self.deadflag := DEAD_DEAD;
    self.takedamage := DAMAGE_YES;
    self.monsterinfo.currentmove := boss2_move_death;
  {$IFEND}
end;

function Boss2_CheckAttack(self : edict_t):qboolean;
var
  spot1, spot2  : vec3_t;
  temp          : vec3_t;
  chance        : single;
  tr            : trace_t;
  enemy_infront : qboolean;
  enemy_range   : integer;
  enemy_yaw     : single;
begin
  if self.enemy.health > 0 then
  begin
    // see if any entities are in the way of the shot
    VectorCopy(self.s.origin, spot1);
    spot1[2] := spot1[2] + self.viewheight;
    VectorCopy(self.enemy.s.origin, spot2);
    spot2[2] := spot2[2] + self.enemy.viewheight;

    tr := gi.trace(spot1, nil, nil, spot2, self, (CONTENTS_SOLID or CONTENTS_MONSTER or CONTENTS_SLIME or CONTENTS_LAVA));

    // do we have a clear shot?
    if tr.ent not self.enemy then
      Result := false;
  end;
	
  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);

  self.ideal_yaw := enemy_yaw;


  // melee attack
  if enemy_range = RANGE_MELEE then
  begin
    if self.monsterinfo.melee then
      self.monsterinfo.attack_state := AS_MELEE
    else
      self.monsterinfo.attack_state := AS_MISSILE;
    Result := true;
  end;
	
  // missile attack
  if not(self.monsterinfo.attack) then
    Result := false;
		
  if level.time < self.monsterinfo.attack_finished then
    Result := false;
		
  if enemy_range = RANGE_FAR then
    Result := false;

  if (self.monsterinfo.aiflags and AI_STAND_GROUND) then
    chance := 0.4
  else
  if enemy_range = RANGE_MELEE then
    chance := 0.8
  else
  if enemy_range = RANGE_NEAR then
    chance = 0.8
  else
  if enemy_range = RANGE_MID then
    chance = 0.8
  else
    Result := false;

  if random() < chance then
  begin
    self.monsterinfo.attack_state    := AS_MISSILE;
    self.monsterinfo.attack_finished := level.time + 2*random();
    Result := true;
  end;

  if (self.flags and FL_FLY) then
  begin
    if random() < 0.3 then
      self.monsterinfo.attack_state := AS_SLIDING;
    else
      self.monsterinfo.attack_state := AS_STRAIGHT;
  end;

  Result := false;
end;



{QUAKED monster_boss2 (1 .5 0) (-56 -56 0) (56 56 80) Ambush Trigger_Spawn Sight
}
procedure SP_monster_boss2(self : edict_t);
begin
  if deathmatch.value then
  begin
    G_FreeEdict(self);
    exit;
  end;

  sound_pain1   := gi.soundindex('bosshovr/bhvpain1.wav');
  sound_pain2   := gi.soundindex('bosshovr/bhvpain2.wav');
  sound_pain3   := gi.soundindex('bosshovr/bhvpain3.wav');
  sound_death   := gi.soundindex('bosshovr/bhvdeth1.wav');
  sound_search1 := gi.soundindex('bosshovr/bhvunqv1.wav');

  self.s.sound  := gi.soundindex('bosshovr/bhvengn1.wav');

  self.movetype := MOVETYPE_STEP;
  self.solid := SOLID_BBOX;
  self.s.modelindex := gi.modelindex('models/monsters/boss2/tris.md2');
  VectorSet(self.mins, -56, -56,  0);
  VectorSet(self.maxs,  56,  56, 80);

  self.health := 2000;
  self.gib_health := -200;
  self.mass := 1000;

  self.flags := self.flags or FL_IMMUNE_LASER;

  self.pain := boss2_pain;
  self.die  := boss2_die;

  self.monsterinfo.stand       := boss2_stand;
  self.monsterinfo.walk        := boss2_walk;
  self.monsterinfo.run         := boss2_run;
  self.monsterinfo.attack      := boss2_attack;
  self.monsterinfo.search      := boss2_search;
  self.monsterinfo.checkattack := Boss2_CheckAttack;
  gi.linkentity(self);

  self.monsterinfo.currentmove := boss2_move_stand;
  self.monsterinfo.scale       := MODEL_SCALE;

  flymonster_start(self);
end;

end.

⌨️ 快捷键说明

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