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

📄 m_mutant.pas

📁 delphi编的不错的贪吃蛇
💻 PAS
📖 第 1 页 / 共 2 页
字号:
    (firstframe: FRAME_run03;
     lastframe: FRAME_run08;
     frame: @mutant_frames_run[0]);

procedure mutant_run(self: edict_p); cdecl;
begin
  if (self.monsterinfo.aiflags AND AI_STAND_GROUND)>0 then
    self.monsterinfo.currentmove := @mutant_move_stand
  else
    self.monsterinfo.currentmove := @mutant_move_run;
end;


//
// MELEE
//
procedure mutant_hit_left(self: edict_p); cdecl;
Var aim: vec3_t;
begin
  VectorSet(aim, MELEE_DISTANCE, self.mins[0], 8);
  if fire_hit(Self, aim, 10 + (rand() mod 5), 100) then
    gi.sound(self, CHAN_WEAPON, sound_hit, 1, ATTN_NORM, 0)
  else
    gi.sound(self, CHAN_WEAPON, sound_swing, 1, ATTN_NORM, 0);
end;

procedure mutant_hit_right(self: edict_p); cdecl;
Var aim: vec3_t;
begin
  VectorSet(aim, MELEE_DISTANCE, self.maxs[0], 8);
  if fire_hit(Self, aim, 10 + (rand() mod 5), 100) then
    gi.sound (self, CHAN_WEAPON, sound_hit2, 1, ATTN_NORM, 0)
  else
    gi.sound (self, CHAN_WEAPON, sound_swing, 1, ATTN_NORM, 0);
end;

procedure mutant_check_refire(self: edict_p); cdecl;
begin
  if (self.enemy=Nil) or (not self.enemy.inuse) or (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_attack09;
end;

const
  mutant_frames_attack: Array[0..6] of mframe_t = (
    (aifunc: ai_charge; dist: 0),
    (aifunc: ai_charge; dist: 0),
    (aifunc: ai_charge; dist: 0; thinkfunc: mutant_hit_left),
    (aifunc: ai_charge; dist: 0),
    (aifunc: ai_charge; dist: 0),
    (aifunc: ai_charge; dist: 0; thinkfunc: mutant_hit_right),
    (aifunc: ai_charge; dist: 0; thinkfunc: mutant_check_refire)
  );
  mutant_move_attack: mmove_t =
    (firstframe: FRAME_attack09;
     lastframe: FRAME_attack15;
     frame: @mutant_frames_attack[0];
     endfunc: mutant_run);

procedure mutant_melee(self: edict_p); cdecl;
begin
  self.monsterinfo.currentmove := @mutant_move_attack;
end;


//
// ATTACK
//

procedure mutant_jump_touch(self, other: edict_p; plane: cplane_p; surf: csurface_p); cdecl;
Var point, normal: vec3_t; damage: Integer;
begin
  if self.health <= 0 then begin
    self.touch := nil;
    exit;
  end;

  if other.takedamage<>DAMAGE_NO then begin
    if VectorLength(self.velocity) > 400 then begin
      VectorCopy(self.velocity, normal);
      VectorNormalize(normal);
      VectorMA(self.s.origin, self.maxs[0], normal, point);
      damage := Trunc(40 + 10 * _random());
      T_Damage(other, self, self, self.velocity, point, normal, damage, damage, 0, MOD_UNKNOWN);
    end;
  end;

  if not M_CheckBottom(self) then begin
    if self.groundentity<>Nil then begin
      self.monsterinfo.nextframe := FRAME_attack02;
      self.touch := Nil;
    end;
    exit;
  end;

  self.touch := Nil;
end;

procedure mutant_jump_takeoff(self: edict_p); cdecl;
Var forwards: vec3_t;
begin
  gi.sound (self, CHAN_VOICE, sound_sight, 1, ATTN_NORM, 0);
  AngleVectors(self.s.angles, @forwards, Nil, Nil);
  self.s.origin[2]:= self.s.origin[2] + 1;
  VectorScale(forwards, 600, self.velocity);
  self.velocity[2] := 250;
  self.groundentity := Nil;
  self.monsterinfo.aiflags := self.monsterinfo.aiflags OR AI_DUCKED;
  self.monsterinfo.attack_finished := level.time + 3;
  self.touch := mutant_jump_touch;
end;

procedure mutant_check_landing(self: edict_p); cdecl;
begin
  if self.groundentity<>Nil then begin
    gi.sound(self, CHAN_WEAPON, sound_thud, 1, ATTN_NORM, 0);
    self.monsterinfo.attack_finished := 0;
    self.monsterinfo.aiflags := self.monsterinfo.aiflags and (not AI_DUCKED);
    exit;
  end;

  if level.time > self.monsterinfo.attack_finished then
    self.monsterinfo.nextframe := FRAME_attack02
  else
    self.monsterinfo.nextframe := FRAME_attack05;
end;

const
  mutant_frames_jump: Array[0..7] of mframe_t = (
    (aifunc: ai_charge; dist: 0),
    (aifunc: ai_charge; dist: 17),
    (aifunc: ai_charge; dist: 15; thinkfunc: mutant_jump_takeoff),
    (aifunc: ai_charge; dist: 15),
    (aifunc: ai_charge; dist: 15; thinkfunc: mutant_check_landing),
    (aifunc: ai_charge; dist: 0),
    (aifunc: ai_charge; dist: 3),
    (aifunc: ai_charge; dist: 0)
  );
  mutant_move_jump: mmove_t =
    (firstframe: FRAME_attack01;
     lastframe: FRAME_attack08;
     frame: @mutant_frames_jump[0];
     endfunc: mutant_run);

procedure mutant_jump(self: edict_p); cdecl;
begin
  self.monsterinfo.currentmove := @mutant_move_jump;
end;


//
// CHECKATTACK
//

function mutant_check_melee(self: edict_p): qboolean;
begin
  if range (self, self.enemy) = RANGE_MELEE then begin
    Result:=true;
    exit;
  end;
  Result:=false;
end;

function mutant_check_jump(self: edict_p): qboolean;
Var v: vec3_t; distance: Single;
begin
  if self.absmin[2] > self.enemy.absmin[2] + 0.75 * self.enemy.size[2] then begin
    Result:=False;
    exit;
  end;

  if self.absmax[2] < (self.enemy.absmin[2] + 0.25 * self.enemy.size[2]) then begin
    Result:=False;
    exit;
  end;

  v[0] := self.s.origin[0] - self.enemy.s.origin[0];
  v[1] := self.s.origin[1] - self.enemy.s.origin[1];
  v[2] := 0;
  distance := VectorLength(v);

  if distance < 100 then begin
    Result:=False;
    exit;
  end;
  if distance > 100 then begin
    if _random() < 0.9 then begin
      Result:=False;
      exit;
    end;
  end;

  Result:=true;
end;

function mutant_checkattack(self: edict_p): qboolean; cdecl;
begin
  if (self.enemy=Nil) or (self.enemy.health <=0) then begin
    Result:= false;
    exit;
  end;

  if mutant_check_melee(self) then begin
    self.monsterinfo.attack_state := AS_MELEE;
    result:=true;
    exit;
  end;

  if mutant_check_jump(self) then begin
    self.monsterinfo.attack_state := AS_MISSILE;
    // FIXME play a jump sound here
    result:= true;
    exit;
  end;

  Result:=false;
end;


//
// PAIN
//

Const
  mutant_frames_pain1: Array[0..4] of mframe_t = (
    (aifunc: ai_move; dist: 4),
    (aifunc: ai_move; dist: -3),
    (aifunc: ai_move; dist: -8),
    (aifunc: ai_move; dist: 2),
    (aifunc: ai_move; dist: 5)
  );
  mutant_move_pain1: mmove_t =
    (firstframe: FRAME_pain101;
     lastframe: FRAME_pain105;
     frame: @mutant_frames_pain1[0];
     endfunc: mutant_run);

  mutant_frames_pain2: Array[0..5] of mframe_t = (
    (aifunc: ai_move; dist: -24),
    (aifunc: ai_move; dist: 11),
    (aifunc: ai_move; dist: 5),
    (aifunc: ai_move; dist: -2),
    (aifunc: ai_move; dist: 6),
    (aifunc: ai_move; dist: 4)
  );
  mutant_move_pain2: mmove_t =
    (firstframe: FRAME_pain201;
     lastframe: FRAME_pain206;
     frame: @mutant_frames_pain2[0];
     endfunc: mutant_run);

  mutant_frames_pain3: Array[0..10] of mframe_t = (
    (aifunc: ai_move; dist: -22),
    (aifunc: ai_move; dist: 3),
    (aifunc: ai_move; dist: 3),
    (aifunc: ai_move; dist: 2),
    (aifunc: ai_move; dist: 1),
    (aifunc: ai_move; dist: 1),
    (aifunc: ai_move; dist: 6),
    (aifunc: ai_move; dist: 3),
    (aifunc: ai_move; dist: 2),
    (aifunc: ai_move; dist: 0),
    (aifunc: ai_move; dist: 1)
  );
  mutant_move_pain3: mmove_t =
    (firstframe: FRAME_pain301;
     lastframe: FRAME_pain311;
     frame: @mutant_frames_pain3[0];
     endfunc: mutant_run);

procedure mutant_pain(self, other: edict_p; kick: Single; damage: Integer); cdecl;
Var r: Single;
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;

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

  r := _random();
  if r < 0.33 then begin
    gi.sound(self, CHAN_VOICE, sound_pain1, 1, ATTN_NORM, 0);
    self.monsterinfo.currentmove := @mutant_move_pain1;
  end else if r < 0.66 then begin
    gi.sound(self, CHAN_VOICE, sound_pain2, 1, ATTN_NORM, 0);
    self.monsterinfo.currentmove := @mutant_move_pain2;
  end else begin
    gi.sound(self, CHAN_VOICE, sound_pain1, 1, ATTN_NORM, 0);
    self.monsterinfo.currentmove := @mutant_move_pain3;
  end;
end;


//
// DEATH
//

procedure mutant_dead(self: edict_p); cdecl;
begin
  VectorSet(self.mins, -16, -16, -24);
  VectorSet(self.maxs, 16, 16, -8);
  Integer(self.movetype) := Integer(MOVETYPE_TOSS);
  self.svflags := self.svflags OR SVF_DEADMONSTER;
  gi.linkentity(self);

  M_FlyCheck(self);
end;

const
  mutant_frames_death1: Array[0..8] of mframe_t = (
    (aifunc: ai_move; dist: 0),
    (aifunc: ai_move; dist: 0),
    (aifunc: ai_move; dist: 0),
    (aifunc: ai_move; dist: 0),
    (aifunc: ai_move; dist: 0),
    (aifunc: ai_move; dist: 0),
    (aifunc: ai_move; dist: 0),
    (aifunc: ai_move; dist: 0),
    (aifunc: ai_move; dist: 0)
  );
  mutant_move_death1: mmove_t = (
    firstframe: FRAME_death101;
    lastframe: FRAME_death109;
    frame: @mutant_frames_death1[0];
    endfunc: mutant_dead);

  mutant_frames_death2: Array[0..9] of mframe_t = (
    (aifunc: ai_move; dist: 0),
    (aifunc: ai_move; dist: 0),
    (aifunc: ai_move; dist: 0),
    (aifunc: ai_move; dist: 0),
    (aifunc: ai_move; dist: 0),
    (aifunc: ai_move; dist: 0),
    (aifunc: ai_move; dist: 0),
    (aifunc: ai_move; dist: 0),
    (aifunc: ai_move; dist: 0),
    (aifunc: ai_move; dist: 0)
  );
  mutant_move_death2: mmove_t =
    (firstframe: FRAME_death201;
     lastframe: FRAME_death210;
     frame: @mutant_frames_death2[0];
     endfunc: mutant_dead);

procedure mutant_die (self: edict_p; inflictor: edict_p; attacker: edict_p; damage: Integer; const point: vec3_t); cdecl;
Var n: Integer;
begin
  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;

  gi.sound(self, CHAN_VOICE, sound_death, 1, ATTN_NORM, 0);
  self.deadflag := DEAD_DEAD;
  self.takedamage := DAMAGE_YES;
  self.s.skinnum := 1;

  if _random() < 0.5 then
    self.monsterinfo.currentmove := @mutant_move_death1
  else
    self.monsterinfo.currentmove := @mutant_move_death2;
end;


//
// SPAWN
//

(*QUAKED monster_mutant (1 .5 0) (-32 -32 -24) (32 32 32) Ambush Trigger_Spawn Sight
*)
procedure SP_monster_mutant(self: edict_p);
begin
  if deathmatch.value<>0 then begin
    G_FreeEdict(self);
    exit;
  end;

  sound_swing := gi.soundindex('mutant/mutatck1.wav');
  sound_hit := gi.soundindex('mutant/mutatck2.wav');
  sound_hit2 := gi.soundindex('mutant/mutatck3.wav');
  sound_death := gi.soundindex('mutant/mutdeth1.wav');
  sound_idle := gi.soundindex('mutant/mutidle1.wav');
  sound_pain1 := gi.soundindex('mutant/mutpain1.wav');
  sound_pain2 := gi.soundindex('mutant/mutpain2.wav');
  sound_sight := gi.soundindex('mutant/mutsght1.wav');
  sound_search := gi.soundindex('mutant/mutsrch1.wav');
  sound_step1 := gi.soundindex('mutant/step1.wav');
  sound_step2 := gi.soundindex('mutant/step2.wav');
  sound_step3 := gi.soundindex('mutant/step3.wav');
  sound_thud := gi.soundindex('mutant/thud1.wav');

  self.movetype := MOVETYPE_STEP;
  self.solid := SOLID_BBOX;
  self.s.modelindex := gi.modelindex ('models/monsters/mutant/tris.md2');
  VectorSet(self.mins, -32, -32, -24);
  VectorSet(self.maxs, 32, 32, 48);

  self.health := 300;
  self.gib_health := -120;
  self.mass := 300;

  self.pain := mutant_pain;
  self.die := mutant_die;

  self.monsterinfo.stand := mutant_stand;
  self.monsterinfo.walk := mutant_walk;
  self.monsterinfo.run := mutant_run;
  self.monsterinfo.dodge := Nil;
  self.monsterinfo.attack := mutant_jump;
  self.monsterinfo.melee := mutant_melee;
  self.monsterinfo.sight := mutant_sight;
  self.monsterinfo.search := mutant_search;
  self.monsterinfo.idle := mutant_idle;
  self.monsterinfo.checkattack := mutant_checkattack;

  gi.linkentity(self);

  self.monsterinfo.currentmove := @mutant_move_stand;

  self.monsterinfo.scale := MODEL_SCALE;
  walkmonster_start(self);
end;

end.

⌨️ 快捷键说明

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