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

📄 m_parasite.pas

📁 雷神之锤2(Quake2)Delphi源码
💻 PAS
📖 第 1 页 / 共 2 页
字号:

  parasite_move_drain : mmove_t =
        (
        FRAME_drain01,
        FRAME_drain18,
        parasite_frames_drain,
        parasite_start_run
        );

  parasite_frames_break : array[0..31] of mframe_t =
        (
        (ai_charge, 0,	 NULL),
	(ai_charge, -3,	 NULL),
	(ai_charge, 1,	 NULL),
	(ai_charge, 2,	 NULL),
	(ai_charge, -3,	 NULL),
	(ai_charge, 1,	 NULL),
	(ai_charge, 1,	 NULL),
	(ai_charge, 3,	 NULL),
	(ai_charge, 0,	 NULL),
	(ai_charge, -18, NULL),
	(ai_charge, 3,	 NULL),
	(ai_charge, 9,	 NULL),
	(ai_charge, 6,	 NULL),
	(ai_charge, 0,	 NULL),
	(ai_charge, -18, NULL),
	(ai_charge, 0,	 NULL),
	(ai_charge, 8,	 NULL),
	(ai_charge, 9,	 NULL),
	(ai_charge, 0,	 NULL),
	(ai_charge, -18, NULL),
	(ai_charge, 0,	 NULL),
	(ai_charge, 0,	 NULL),	// airborne
	(ai_charge, 0,	 NULL),	// airborne
	(ai_charge, 0,	 NULL),	// slides
	(ai_charge, 0,	 NULL),	// slides
	(ai_charge, 0,	 NULL), // slides
	(ai_charge, 0,	 NULL),	// slides
	(ai_charge, 4,	 NULL),
	(ai_charge, 11,	 NULL),
	(ai_charge, -2,	 NULL),
	(ai_charge, -5,	 NULL),
	(ai_charge, 1,	 NULL)
        );

  parasite_move_break : mmove_t =
        (
        FRAME_break01,
        FRAME_break32,
        parasite_frames_break,
        parasite_start_run
        );

  parasite_frames_death : array [0..6] of mframe_t =
        (
	(ai_move, 0, NULL),
	(ai_move, 0, NULL),
	(ai_move, 0, NULL),
	(ai_move, 0, NULL),
	(ai_move, 0, NULL),
	(ai_move, 0, NULL),
	(ai_move, 0, NULL)
        );

  parasite_move_death : mmove_t =
        (
        FRAME_death101,
        FRAME_death107,
        parasite_frames_death,
        parasite_dead
        );



var

  sound_pain1,
  sound_pain2,
  sound_die,
  sound_launch,
  sound_impact,
  sound_suck,
  sound_reelin,
  sound_sight,
  sound_tap,
  sound_scratch,
  sound_search: integer;

{
Procedure parasite_stand (self: ^edict_t);
Procedure parasite_start_run (self: ^edict_t);
Procedure parasite_run (self: ^edict_t);
Procedure parasite_walk (self: ^edict_t);
Procedure parasite_start_walk (self: ^edict_t);
Procedure parasite_end_fidget (self: ^edict_t);
Procedure parasite_do_fidget (self: ^edict_t);
Procedure parasite_refidget (self: ^edict_t);
}

procedure parasite_launch (self: ^edict_t);
begin
  gi.sound(self, CHAN_WEAPON, sound_launch, 1, ATTN_NORM, 0);
end;

Procedure parasite_reel_in (self: ^edict_t);
begin
  gi.sound (self, CHAN_WEAPON, sound_reelin, 1, ATTN_NORM, 0);
end;

Procedure parasite_sight (self, other: ^edict_t);
begin
  gi.sound (self, CHAN_WEAPON, sound_sight, 1, ATTN_NORM, 0);
end;

Procedure parasite_tap (self: ^edict_t);
begin
  gi.sound (self, CHAN_WEAPON, sound_tap, 1, ATTN_IDLE, 0);
end;

Procedure parasite_scratch (self: ^edict_t);
begin
  gi.sound (self, CHAN_WEAPON, sound_scratch, 1, ATTN_IDLE, 0);
end;

Procedure parasite_search (self: ^edict_t);
begin
  gi.sound (self, CHAN_WEAPON, sound_search, 1, ATTN_IDLE, 0);
end;



Procedure parasite_end_fidget (self: ^edict_t);
begin
  self^.monsterinfo.currentmove := &parasite_move_end_fidget;
end;

Procedure parasite_do_fidget (self: ^edict_t);
begin
  self^.monsterinfo.currentmove := &parasite_move_fidget;
end;

Procedure parasite_refidget (self: ^edict_t);
begin
  if (random() <= 0.8) then
    self^.monsterinfo.currentmove := parasite_move_fidget^
  else
    self^.monsterinfo.currentmove := parasite_move_end_fidget^;
end;

Procedure parasite_idle (self: ^edict_t);
begin
  self^.monsterinfo.currentmove := parasite_move_start_fidget^;
end;



Procedure parasite_stand (self: ^edict_t);
begin
  self^.monsterinfo.currentmove := parasite_move_stand^;
end;



Procedure parasite_start_run (self: ^edict_t);
begin
  if (self^.monsterinfo.aiflags and AI_STAND_GROUND) then
  	self^.monsterinfo.currentmove := parasite_move_stand^
  else
  	self^.monsterinfo.currentmove := parasite_move_start_run^;
end;

Procedure parasite_run (self: ^edict_t);
begin
  if (self^.monsterinfo.aiflags and AI_STAND_GROUND)
    self^.monsterinfo.currentmove := parasite_move_stand^;
  else
    self^.monsterinfo.currentmove := parasite_move_run^;
end;



Procedure parasite_start_walk (self: ^edict_t);
begin
  self^.monsterinfo.currentmove := parasite_move_start_walk^;
end;

Procedure parasite_walk (self: ^edict_t);
begin
  self^.monsterinfo.currentmove := parasite_move_walk^;
end;



Procedure parasite_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
  begin
    self^.pain_debounce_time := level.time + 3;
    if skill^.value <> 3 then
    begin
      if (random() < 0.5)
        gi.sound (self, CHAN_VOICE, sound_pain1, 1, ATTN_NORM, 0);
      else
        gi.sound (self, CHAN_VOICE, sound_pain2, 1, ATTN_NORM, 0);
        self^.monsterinfo.currentmove := parasite_move_pain1^;
    end;
  end;
end;


Function parasite_drain_attack_ok (start, _end: vec3_t): boolean;
var
  dir, angles: vec3_t;

begin
        // check for max distance
  VectorSubtract(start, _end, dir);
  if VectorLength(dir) > 256 then
    result:= false
  else
  begin
        // check for min/max pitch
    vectoangles (dir, angles);
    if angles[0] < -180 then
      angles[0] := angles[0] + 360;
    if abs(angles[0]) > 30 then
      result:= false
    else
      result:= true;
  end;
end;


Procedure parasite_drain_attack (self: ^edict_t);
var
  offset, start, f, r, _end, dir: vec3_t;
  tr: trace_t;
  damage: integer;

begin

  AngleVectors (self^.s.angles, f, r, NULL);
  VectorSet (offset, 24, 0, 6);
  G_ProjectSource (self^.s.origin, offset, f, r, start);
  VectorCopy (self^.enemy^.s.origin, _end);
  if not parasite_drain_attack_ok(start, _end) then
  begin
    _end[2] := self^.enemy^.s.origin[2] + self^.enemy^.maxs[2] - 8;
    if (!parasite_drain_attack_ok(start, _end))
    begin
      _end[2] := self^.enemy^.s.origin[2] + self^.enemy^.mins[2] + 8;
      if not parasite_drain_attack_ok(start, _end) then
      	return;
    end;
  end;
  VectorCopy (self^.enemy^.s.origin, _end);
  tr := gi.trace (start, NULL, NULL, _end, self, MASK_SHOT);
  if tr.ent <> self^.enemy then
    return;
  if self^.s.frame = FRAME_drain03 then
  begin
    damage := 5;
    gi.sound (self^.enemy, CHAN_AUTO, sound_impact, 1, ATTN_NORM, 0);
  end
  else
  begin
    if self^.s.frame = FRAME_drain04 then
      gi.sound (self, CHAN_WEAPON, sound_suck, 1, ATTN_NORM, 0);
    damage := 2;
  end;

  gi.WriteByte (svc_temp_entity);
  gi.WriteByte (TE_PARASITE_ATTACK);
  gi.WriteShort (self - g_edicts);
  gi.WritePosition (start);
  gi.WritePosition (_end);
  gi.multicast (self^.s.origin, MULTICAST_PVS);

  VectorSubtract (start, _end, dir);
  T_Damage (self^.enemy, self, self, dir, self^.enemy^.s.origin, vec3_origin, damage, 0, DAMAGE_NO_KNOCKBACK, MOD_UNKNOWN);
end;


{
=:=
Break Stuff Ends
=:=
}

Procedure parasite_attack (self: ^edict_t);
begin
//	if (random() <= 0.2)
//		self^.monsterinfo.currentmove := &parasite_move_break;
//	else
  self^.monsterinfo.currentmove := parasite_move_drain^;
end;



{
=:=
Death Stuff Starts
=:=
}

Procedure parasite_dead (self: ^edict_t);
begin
  VectorSet (self^.mins, -16, -16, -24);
  VectorSet (self^.maxs, 16, 16, -8);
  self^.movetype := MOVETYPE_TOSS;
  self^.svflags := self^.svflags or SVF_DEADMONSTER;
  self^.nextthink := 0;
  gi.linkentity (self);
end;


Procedure parasite_die (self, inflictor, attacker: ^edict_t, damage: integer, point: vec3_t);
var
  i: integer;
begin

// 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;
  end
  else
  if self^.deadflag <> DEAD_DEAD then
  begin
// regular death
    gi.sound (self, CHAN_VOICE, sound_die, 1, ATTN_NORM, 0);
    self^.deadflag := DEAD_DEAD;
    self^.takedamage := DAMAGE_YES;
    self^.monsterinfo.currentmove := parasite_move_death^;
  end;
end;

{
=:=
End Death Stuff
=:=
}

{QUAKED monster_parasite (1 .5 0) (-16 -16 -24) (16 16 32) Ambush Trigger_Spawn Sight
}
Procedure SP_monster_parasite (self: ^edict_t);
begin
  if deathmatch^.value <> 0 then
    G_FreeEdict (self)
  else
  begin
    sound_pain1 := gi.soundindex ('parasite/parpain1.wav');
    sound_pain2 := gi.soundindex ('parasite/parpain2.wav');
    sound_die := gi.soundindex ('parasite/pardeth1.wav');
    sound_launch := gi.soundindex('parasite/paratck1.wav');
    sound_impact := gi.soundindex('parasite/paratck2.wav');
    sound_suck := gi.soundindex('parasite/paratck3.wav');
    sound_reelin := gi.soundindex('parasite/paratck4.wav');
    sound_sight := gi.soundindex('parasite/parsght1.wav');
    sound_tap := gi.soundindex('parasite/paridle1.wav');
    sound_scratch := gi.soundindex('parasite/paridle2.wav');
    sound_search := gi.soundindex('parasite/parsrch1.wav');

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

    self^.health := 175;
    self^.gib_health := -50;
    self^.mass := 250;

    self^.pain := parasite_pain;
    self^.die := parasite_die;

    self^.monsterinfo.stand := parasite_stand;
    self^.monsterinfo.walk := parasite_start_walk;
    self^.monsterinfo.run := parasite_start_run;
    self^.monsterinfo.attack := parasite_attack;
    self^.monsterinfo.sight := parasite_sight;
    self^.monsterinfo.idle := parasite_idle;

    gi.linkentity (self);

    self^.monsterinfo.currentmove := parasite_move_stand^;
    self^.monsterinfo.scale := MODEL_SCALE;

    walkmonster_start (self);
  end;
end;

end.

⌨️ 快捷键说明

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