📄 m_gunner.pas
字号:
gunner_move_death: mmove_t = (firstframe:FRAME_death01; lastframe:FRAME_death11; frame:@gunner_frames_death; endfunc:gunner_dead);
procedure gunner_die (self, inflictor, attacker: edict_p; damage: integer; const point: vec3_t); cdecl;
var n: 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;
exit;
end;
if self.deadflag = DEAD_DEAD then Exit;
// regular death
gi.sound (self, CHAN_VOICE, sound_death, 1, ATTN_NORM, 0);
self.deadflag := DEAD_DEAD;
self.takedamage := DAMAGE_YES;
self.monsterinfo.currentmove := @gunner_move_death;
end;
procedure gunner_duck_down (self: edict_p); cdecl;
begin
if self.monsterinfo.aiflags and AI_DUCKED <> 0 then
Exit;
self.monsterinfo.aiflags := self.monsterinfo.aiflags or AI_DUCKED;
if skill.value >= 2 then
begin
if _random() > 0.5 then
GunnerGrenade (self);
end;
self.maxs[2] := self.maxs[2] - 32;
self.takedamage := DAMAGE_YES;
self.monsterinfo.pausetime := level.time + 1;
gi.linkentity (self);
end;
procedure gunner_duck_hold (self: edict_p); cdecl;
begin
if level.time >= self.monsterinfo.pausetime then
self.monsterinfo.aiflags := self.monsterinfo.aiflags and not AI_HOLD_FRAME
else
self.monsterinfo.aiflags := self.monsterinfo.aiflags or AI_HOLD_FRAME;
end;
procedure gunner_duck_up (self: edict_p); cdecl;
begin
self.monsterinfo.aiflags := self.monsterinfo.aiflags and not AI_DUCKED;
self.maxs[2] := self.maxs[2] + 32;
self.takedamage := DAMAGE_AIM;
gi.linkentity (self);
end;
const
gunner_frames_duck: array[0..7] of mframe_t =
(
(aifunc:ai_move; dist: 1; thinkfunc:gunner_duck_down),
(aifunc:ai_move; dist: 1; thinkfunc:nil),
(aifunc:ai_move; dist: 1; thinkfunc:gunner_duck_hold),
(aifunc:ai_move; dist: 0; thinkfunc:nil),
(aifunc:ai_move; dist: -1; thinkfunc:nil),
(aifunc:ai_move; dist: -1; thinkfunc:nil),
(aifunc:ai_move; dist: 0; thinkfunc:gunner_duck_up),
(aifunc:ai_move; dist: -1; thinkfunc:nil)
);
gunner_move_duck: mmove_t = (firstframe:FRAME_duck01; lastframe:FRAME_duck08; frame:@gunner_frames_duck; endfunc:gunner_run);
procedure gunner_dodge (self, attacker: edict_p; eta: single); cdecl;
begin
if _random() > 0.25 then
Exit;
if self.enemy = nil then
self.enemy := attacker;
self.monsterinfo.currentmove := @gunner_move_duck;
end;
procedure gunner_opengun (self: edict_p); cdecl;
begin
gi.sound (self, CHAN_VOICE, sound_open, 1, ATTN_IDLE, 0);
end;
procedure GunnerFire (self: edict_p); cdecl;
var
start,
forward, right,
target, aim: vec3_t;
flash_number: Integer;
begin
flash_number := MZ2_GUNNER_MACHINEGUN_1 + (self.s.frame - FRAME_attak216);
AngleVectors (self.s.angles, @forward, @right, nil);
G_ProjectSource (self.s.origin, monster_flash_offset[flash_number], forward, right, start);
// project enemy back a bit and target there
VectorCopy (self.enemy.s.origin, target);
VectorMA (target, -0.2, self.enemy.velocity, target);
target[2] := target[2] + self.enemy.viewheight;
VectorSubtract (target, start, aim);
VectorNormalize (aim);
monster_fire_bullet (self, start, aim, 3, 4, DEFAULT_BULLET_HSPREAD, DEFAULT_BULLET_VSPREAD, flash_number);
end;
procedure GunnerGrenade (self: edict_p);
var
start,
forward, right, aim: vec3_t;
flash_number: integer;
begin
if (Self.s.frame = FRAME_attak105) then
flash_number := MZ2_GUNNER_GRENADE_1
else if (Self.s.frame = FRAME_attak108) then
flash_number := MZ2_GUNNER_GRENADE_2
else if (Self.s.frame = FRAME_attak111) then
flash_number := MZ2_GUNNER_GRENADE_3
else // (self.s.frame = FRAME_attak114)
flash_number := MZ2_GUNNER_GRENADE_4;
AngleVectors (self.s.angles, @forward, @right, nil);
G_ProjectSource (self.s.origin, monster_flash_offset[flash_number], forward, right, start);
//FIXME : do a spread -225 -75 75 225 degrees around forward
VectorCopy (forward, aim);
monster_fire_grenade (self, start, aim, 50, 600, flash_number);
end;
const
gunner_frames_attack_chain : array[0..6] of mframe_t =
(
(*
ai_chacrge, 0, nil,
ai_charge, 0, nil,
ai_charge, 0, nil,
ai_charge, 0, nil,
ai_charge, 0, nil,
ai_charge, 0, nil,
ai_charge, 0, nil,
ai_charge, 0, nil,
*)
(aifunc:ai_charge; dist:0; thinkfunc:gunner_opengun),
(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:nil),
(aifunc:ai_charge; dist:0; thinkfunc:nil)
);
gunner_move_attack_chain: mmove_t = (firstframe:FRAME_attak209; lastframe:FRAME_attak215; frame:@gunner_frames_attack_chain; endfunc:gunner_fire_chain);
gunner_frames_fire_chain : array[0..7] of mframe_t=
(
(aifunc:ai_charge; dist:0; thinkfunc:GunnerFire),
(aifunc:ai_charge; dist:0; thinkfunc:GunnerFire),
(aifunc:ai_charge; dist:0; thinkfunc:GunnerFire),
(aifunc:ai_charge; dist:0; thinkfunc:GunnerFire),
(aifunc:ai_charge; dist:0; thinkfunc:GunnerFire),
(aifunc:ai_charge; dist:0; thinkfunc:GunnerFire),
(aifunc:ai_charge; dist:0; thinkfunc:GunnerFire),
(aifunc:ai_charge; dist:0; thinkfunc:GunnerFire)
);
gunner_move_fire_chain: mmove_t = (firstframe:FRAME_attak216; lastframe:FRAME_attak223; frame:@gunner_frames_fire_chain; endfunc:gunner_fire_chain);
gunner_frames_endfire_chain : array[0..6] 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:nil),
(aifunc:ai_charge; dist:0; thinkfunc:nil),
(aifunc:ai_charge; dist:0; thinkfunc:nil)
);
gunner_move_endfire_chain: mmove_t = (firstframe:FRAME_attak224; lastframe:FRAME_attak230; frame:@gunner_frames_endfire_chain; endfunc:gunner_run);
gunner_frames_attack_grenade : array[0..20] 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:GunnerGrenade),
(aifunc:ai_charge; dist:0; thinkfunc:nil),
(aifunc:ai_charge; dist:0; thinkfunc:nil),
(aifunc:ai_charge; dist:0; thinkfunc:GunnerGrenade),
(aifunc:ai_charge; dist:0; thinkfunc:nil),
(aifunc:ai_charge; dist:0; thinkfunc:nil),
(aifunc:ai_charge; dist:0; thinkfunc:GunnerGrenade),
(aifunc:ai_charge; dist:0; thinkfunc:nil),
(aifunc:ai_charge; dist:0; thinkfunc:nil),
(aifunc:ai_charge; dist:0; thinkfunc:GunnerGrenade),
(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:nil),
(aifunc:ai_charge; dist:0; thinkfunc:nil),
(aifunc:ai_charge; dist:0; thinkfunc:nil)
);
gunner_move_attack_grenade: mmove_t = (firstframe:FRAME_attak101; lastframe:FRAME_attak121; frame:@gunner_frames_attack_grenade; endfunc:gunner_run);
procedure gunner_attack(self: edict_p); cdecl;
begin
if (range (self, self.enemy) = RANGE_MELEE) then
begin
self.monsterinfo.currentmove := @gunner_move_attack_chain;
end
else
begin
if (_random() <= 0.5) then
self.monsterinfo.currentmove := @gunner_move_attack_grenade
else
self.monsterinfo.currentmove := @gunner_move_attack_chain;
end;
end;
procedure gunner_fire_chain(self: edict_p);
begin
self.monsterinfo.currentmove := @gunner_move_fire_chain;
end;
procedure gunner__chain(self: edict_p);
begin
if (self.enemy.health > 0) then
if ( visible (self, self.enemy) ) then
if (_random() <= 0.5) then
begin
self.monsterinfo.currentmove := @gunner_move_fire_chain;
Exit;
end;
self.monsterinfo.currentmove := @gunner_move_endfire_chain;
end;
// QUAKED monster_gunner (1 .5 0) (-16 -16 -24) (16 16 32) Ambush Trigger_Spawn Sight
procedure SP_monster_gunner(self: edict_p);
begin
if (deathmatch.Value <> 0) then
begin
G_FreeEdict (self);
exit;
end;
sound_death := gi.soundindex ('gunner/death1.wav');
sound_pain := gi.soundindex ('gunner/gunpain2.wav');
sound_pain2 := gi.soundindex ('gunner/gunpain1.wav');
sound_idle := gi.soundindex ('gunner/gunidle1.wav');
sound_open := gi.soundindex ('gunner/gunatck1.wav');
sound_search := gi.soundindex ('gunner/gunsrch1.wav');
sound_sight := gi.soundindex ('gunner/sight1.wav');
gi.soundindex ('gunner/gunatck2.wav');
gi.soundindex ('gunner/gunatck3.wav');
self.movetype := MOVETYPE_STEP;
self.solid := SOLID_BBOX;
self.s.modelindex := gi.modelindex ('models/monsters/gunner/tris.md2');
VectorSet (self.mins, -16, -16, -24);
VectorSet (self.maxs, 16, 16, 32);
self.health := 175;
self.gib_health := -70;
self.mass := 200;
self.pain := gunner_pain;
self.die := gunner_die;
self.monsterinfo.stand := gunner_stand;
self.monsterinfo.walk := gunner_walk;
self.monsterinfo.run := gunner_run;
self.monsterinfo.dodge := gunner_dodge;
self.monsterinfo.attack := gunner_attack;
self.monsterinfo.melee := nil;
self.monsterinfo.sight := gunner_sight;
self.monsterinfo.search := gunner_search;
gi.linkentity (self);
self.monsterinfo.currentmove := @gunner_move_stand;
Self.monsterinfo.scale := MODEL_SCALE;
walkmonster_start (self);
end;
end.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -