📄 m_actor.pas
字号:
gi.cprintf(other, PRINT_CHAT, '%s: %s!'#10, name, messages[rand() mod 3]);
Exit;
end;
n := rand() mod 3;
if n = 0 then
self^.monsterinfo.currentmove := @actor_move_pain1
else if n = 1 then
self^.monsterinfo.currentmove := @actor_move_pain2
else
self^.monsterinfo.currentmove := @actor_move_pain3;
end;
procedure actorMachineGun(self : edict_p);
var start, target : vec3_t;
fforward, right : vec3_t;
begin
AngleVectors(self^.s.angles, @fforward, @right, nil);
G_ProjectSource(self^.s.origin, monster_flash_offset[MZ2_ACTOR_MACHINEGUN_1], fforward, right, start);
if (self^.enemy <> nil) then
begin
if (self^.enemy^.health > 0) then
begin
VectorMA(self^.enemy^.s.origin, -0.2, self^.enemy^.velocity, target);
target[2] := target[2] + self^.enemy^.viewheight;
end
else
begin
VectorCopy(self^.enemy^.absmin, target);
target[2] := target[2] + (self^.enemy^.size[2] / 2);
end;
VectorSubtract(target, start, fforward);
VectorNormalize(fforward);
end
else
AngleVectors(self^.s.angles, @fforward, Nil, Nil);
monster_fire_bullet(self, start, fforward, 3, 4, DEFAULT_BULLET_HSPREAD, DEFAULT_BULLET_VSPREAD, MZ2_ACTOR_MACHINEGUN_1);
end;
procedure actor_dead(self : edict_p);
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 actor_die(self, inflictor, attacker : edict_p; damage : Integer; const point : vec3_t); cdecl;
var n : Integer;
begin
// check for gib
if self.health <= -80 then
begin
for n := 0 to (2 - 1) do
ThrowGib(self, 'models/objects/gibs/bone/tris.md2', damage, GIB_ORGANIC);
for n := 0 to (4 - 1) 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
self^.deadflag := DEAD_DEAD;
self^.takedamage := DAMAGE_YES;
n := rand() mod 2;
if n = 0 then
self^.monsterinfo.currentmove := @actor_move_death1
else
self^.monsterinfo.currentmove := @actor_move_death2;
end;
procedure actor_fire(self : edict_p);
begin
actorMachineGun(self);
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 actor_attack(self : edict_p); cdecl;
var n : Integer;
begin
self^.monsterinfo.currentmove := @actor_move_attack;
n := (rand() AND 15) + 3 + 7; // (rand() & 15) + 3 + 7
self^.monsterinfo.pausetime := level.time + n * FRAMETIME;
end;
procedure actor_use(self, other, activator : edict_p); cdecl;
var v : vec3_t;
begin
self^.movetarget := G_PickTarget(self.target);
self^.goalentity := self^.movetarget;
if (self^.movetarget = Nil) OR (StrCmp(self^.movetarget^.classname, 'target_actor') <> 0) then
begin
gi.dprintf('%s has bad target %s at %s'#10, self^.classname, self^.target, vtos(self^.s.origin));
self^.target := nil;
self^.monsterinfo.pausetime := 100000000;
self^.monsterinfo.stand(self);
Exit;
end;
VectorSubtract(self^.goalentity^.s.origin, self^.s.origin, v);
self^.s.angles[YAW] := vectoyaw(v);
self^.ideal_yaw := self^.s.angles[YAW];
self^.monsterinfo.walk(self);
self^.target := nil;
end;
// QUAKED misc_actor (1 .5 0) (-16 -16 -24) (16 16 32)
procedure SP_misc_actor(self : edict_p);
begin
if (deathmatch^.Value <> 0) then
begin
G_FreeEdict(self);
Exit;
end;
if (self^.targetname = Nil) then
begin
gi.dprintf('untargeted %s at %s'#10, self^.classname, vtos(self^.s.origin));
G_FreeEdict(self);
Exit;
end;
if (self.target = Nil) then
begin
gi.dprintf('%s with no target at %s'#10, self^.classname, vtos(self^.s.origin));
G_FreeEdict(self);
Exit;
end;
self^.movetype := MOVETYPE_STEP;
self^.solid := SOLID_BBOX;
self^.s.modelindex := gi.modelindex('players/male/tris.md2');
VectorSet(self^.mins, -16, -16, -24);
VectorSet(self^.maxs, 16, 16, 32);
if (self^.health = 0) then
self^.health := 100;
self^.mass := 200;
self^.pain := actor_pain;
self^.die := actor_die;
self^.monsterinfo.stand := actor_stand;
self^.monsterinfo.walk := actor_walk;
self^.monsterinfo.run := actor_run;
self^.monsterinfo.attack := actor_attack;
self^.monsterinfo.melee := nil;
self^.monsterinfo.sight := nil;
self^.monsterinfo.aiflags := (self^.monsterinfo.aiflags OR AI_GOOD_GUY);
gi.linkentity(self);
self^.monsterinfo.currentmove := @actor_move_stand;
self^.monsterinfo.scale := MODEL_SCALE;
walkmonster_start(self);
// actors always start in a dormant state, they *must* be used to get going
self^.use := actor_use;
end;
{ TODO: From here down }
{
QUAKED target_actor (.5 .3 0) (-8 -8 -8) (8 8 8) JUMP SHOOT ATTACK x HOLD BRUTAL
JUMP jump in set direction upon reaching this target
SHOOT take a single shot at the pathtarget
ATTACK attack pathtarget until it or actor is dead
"target" next target_actor
"pathtarget" target of any action to be taken at this point
"wait" amount of time actor should pause at this point
"message" actor will "say" this to the player
for JUMP only:
"speed" speed thrown forward (default 200)
"height" speed thrown upwards (default 200)
}
procedure target_actor_touch(self, other: edict_p; plane: cplane_p; surf: csurface_p); cdecl;
var v : vec3_t;
n : Integer;
ent : edict_p;
savetarget : PChar;
begin
if (other^.movetarget <> self) then
Exit;
if (other^.enemy <> nil) then
Exit;
other^.movetarget := nil;
other^.goalentity := other^.movetarget;
if (self^._message <> Nil) then
begin
for n := 1 to game.maxclients do
begin
ent := @g_edicts[n];
if ent^.inuse then
gi.cprintf(ent, PRINT_CHAT, '%s: %s'#10, actor_names[(Cardinal(other) - Cardinal(g_edicts)) MOD MAX_ACTOR_NAMES], self._message);
end;
end;
if (self^.spawnflags AND 1) <> 0 then //jump
begin
other^.velocity[0] := self^.movedir[0] * self^.speed;
other^.velocity[1] := self^.movedir[1] * self^.speed;
if (other^.groundentity <> Nil) then
begin
other^.groundentity := nil;
other^.velocity[2] := self^.movedir[2];
gi.sound(other, CHAN_VOICE, gi.soundindex('player/male/jump1.wav'), 1, ATTN_NORM, 0);
end;
end;
if (self^.spawnflags AND 2) <> 0 then //shoot
begin
end
else if (self^.spawnflags AND 4) <> 0 then //attack
begin
other^.enemy := G_PickTarget(self^.pathtarget);
if (other^.enemy <> Nil) then
begin
other^.goalentity := other^.enemy;
if (self^.spawnflags AND 32) <> 0 then
other^.monsterinfo.aiflags := (other^.monsterinfo.aiflags OR AI_BRUTAL);
if (self.spawnflags AND 16) <> 0 then
begin
other^.monsterinfo.aiflags := (other^.monsterinfo.aiflags OR AI_STAND_GROUND);
actor_stand(other);
end
else
actor_run(other);
end;
end;
if (((self^.spawnflags AND 6) = 0) AND (self^.pathtarget <> '')) then
begin
savetarget := self^.target;
self^.target := self^.pathtarget;
G_UseTargets(self, other);
self^.target := savetarget;
end;
other^.movetarget := G_PickTarget(self^.target);
if (other^.goalentity = Nil) then
other^.goalentity := other^.movetarget;
if ((other^.movetarget = Nil) AND (other^.enemy = Nil)) then
begin
other^.monsterinfo.pausetime := level.time + 100000000;
other^.monsterinfo.stand(other);
end
else if (other^.movetarget = other^.goalentity) then
begin
VectorSubtract(other^.movetarget^.s.origin, other^.s.origin, v);
other^.ideal_yaw := vectoyaw(v);
end;
end;
procedure SP_target_actor(self: edict_p);
begin
if (self^.targetname = nil) then
gi.dprintf('%s with no targetname at %s'#10, self^.classname, vtos(self^.s.origin));
self^.solid := SOLID_TRIGGER;
self^.touch := target_actor_touch;
VectorSet(self^.mins, -8, -8, -8);
VectorSet(self^.maxs, 8, 8, 8);
self^.svflags := SVF_NOCLIENT;
if (self^.spawnflags AND 1) <> 0 then
begin
if self^.speed = 0 then
self^.speed := 200;
if st.height = 0 then
st.height := 200;
if (self^.s.angles[YAW] = 0) then
self^.s.angles[YAW] := 360;
G_SetMovedir(self^.s.angles, self^.movedir);
self^.movedir[2] := st.height;
end;
gi.linkentity(self);
end;
end.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -