📄 g_turret.pas
字号:
end;
end;
procedure turret_breach_finish_init(self : edict_t);
begin
// get and save info for muzzle location
if not(self.target) then
gi.dprintf('%s at %s needs a target', [self.classname, vtos(self.s.origin)]);
else
begin
self.target_ent := G_PickTarget(self.target);
VectorSubtract(self.target_ent.s.origin, self.s.origin, self.move_origin);
G_FreeEdict(self.target_ent);
end
self.teammaster.dmg := self.dmg;
self.think := turret_breach_think;
self.think(self);
end;
procedure SP_turret_breach(self : edict_t);
begin
self.solid := SOLID_BSP;
self.movetype := MOVETYPE_PUSH;
gi.setmodel(self, self.model);
if not(self.speed) then
self.speed := 50;
if not(self.dmg) then
self.dmg := 10;
if not(st.minpitch) then
st.minpitch := -30;
if not(st.maxpitch) then
st.maxpitch := 30;
if not(st.maxyaw) then
st.maxyaw := 360;
self.pos1[PITCH] := -1 * st.minpitch;
self.pos1[YAW] := st.minyaw;
self.pos2[PITCH] := -1 * st.maxpitch;
self.pos2[YAW] := st.maxyaw;
self.ideal_yaw := self.s.angles[YAW];
self.move_angles[YAW] := self.ideal_yaw;
self.blocked := turret_blocked;
self.think := turret_breach_finish_init;
self.nextthink := level.time + FRAMETIME;
gi.linkentity(self);
end;
{QUAKED turret_base (0 0 0) ?
This portion of the turret changes yaw only.
MUST be teamed with a turret_breach.
}
procedure SP_turret_base(self : edict_t);
begin
self.solid := SOLID_BSP;
self.movetype := MOVETYPE_PUSH;
gi.setmodel(self, self.model);
self.blocked := turret_blocked;
gi.linkentity(self);
end;
{QUAKED turret_driver (1 .5 0) (-16 -16 -24) (16 16 32)
Must NOT be on the team with the rest of the turret parts.
Instead it must target the turret_breach.
}
procedure turret_driver_die(self, inflictor, attacker : edict_t; damage : integer; point : vec3_t);
var
ent : edict_t;
begin
// level the gun
self.target_ent.move_angles[0] := 0;
// remove the driver from the end of them team chain
ent := self.target_ent.teammaster;
while (ent.teamchain <> self) do
begin
ent := ent.teamchain;
end;
ent.teamchain := nil;
self.teammaster := nil;
self.flags := self.flags and FL_TEAMSLAVE;
self.target_ent.owner := nil;
self.target_ent.teammaster.owner := nil;
infantry_die(self, inflictor, attacker, damage);
end;
function FindTarget(self: edict_t): qboolean;
procedure turret_driver_think(self : edict_t);
var
target : vec3_t;
dir : vec3_t;
reaction_time : vec3_t;
begin
self.nextthink := level.time + FRAMETIME;
if (self.enemy and not(self.enemy.inuse or self.enemy.health <= 0)) then
self.enemy := nil;
if not(self.enemy) then
begin
if not(FindTarget(self)) then
exit;
self.monsterinfo.trail_time := level.time;
self.monsterinfo.aiflags := self.monsterinfo.aiflags and AI_LOST_SIGHT;
end
else
begin
if visible(self, self.enemy) then
begin
if (self.monsterinfo.aiflags and AI_LOST_SIGHT) then
begin
self.monsterinfo.trail_time := level.time;
self.monsterinfo.aiflags := self.monsterinfo.aiflags and AI_LOST_SIGHT;
end;
end
else
begin
self.monsterinfo.aiflags := self.monsterinfo.aiflags or AI_LOST_SIGHT;
exit;
end;
end;
// let the turret know where we want it to aim
VectorCopy(self.enemy.s.origin, target);
target[2] := target[2] + self.enemy.viewheight;
VectorSubtract(target, self.target_ent.s.origin, dir);
vectoangles(dir, self.target_ent.move_angles);
// decide if we should shoot
if level.time < self.monsterinfo.attack_finished then
exit;
reaction_time := (3 - skill->value) * 1.0;
if (level.time - self.monsterinfo.trail_time) < reaction_time then
exit;
self.monsterinfo.attack_finished := level.time + reaction_time + 1.0;
//FIXME how do we really want to pass this along?
self.target_ent.spawnflags := self.target_ent.spawnflags or 65536;
end;
procedure turret_driver_link(self : edict_t);
var
vec : vec3_t;
ent : edict_t;
begin
self.think := turret_driver_think;
self.nextthink := level.time + FRAMETIME;
self.target_ent := G_PickTarget(self.target);
self.target_ent.owner := self;
self.target_ent.teammaster.owner := self;
VectorCopy(self.target_ent.s.angles, self.s.angles);
vec[0] := self.target_ent.s.origin[0] - self.s.origin[0];
vec[1] := self.target_ent.s.origin[1] - self.s.origin[1];
vec[2] := 0;
self.move_origin[0] := VectorLength(vec);
VectorSubtract(self.s.origin, self.target_ent.s.origin, vec);
vectoangles(vec, vec);
AnglesNormalize(vec);
self.move_origin[1] := vec[1];
self.move_origin[2] := self.s.origin[2] - self.target_ent.s.origin[2];
// add the driver to the end of them team chain
ent := self.target_ent.teammaster;
while (ent.teamchain <> nil) do
begin
ent := ent.teamchain;
end;
ent.teamchain := self;
self.teammaster := self.target_ent.teammaster;
self.flags := self.flags or FL_TEAMSLAVE;
end;
procedure SP_turret_driver(self : edict_t);
begin
if deathmatch.value then
begin
G_FreeEdict(self);
exit;
end;
self.movetype := MOVETYPE_PUSH;
self.solid := SOLID_BBOX;
self.s.modelindex := gi.modelindex('models/monsters/infantry/tris.md2');
VectorSet(self.mins, -16, -16, -24);
VectorSet(self.maxs, 16, 16, 32);
self.health := 100;
self.gib_health := 0;
self.mass := 200;
self.viewheight := 24;
self.die := turret_driver_die;
self.monsterinfo.stand := infantry_stand;
self.flags := self.flags or FL_NO_KNOCKBACK;
level.total_monsters := level.total_monsters + 1;
self.svflags := self.svflags or SVF_MONSTER;
self.s.renderfx := self.s.renderfx or RF_FRAMELERP;
self.takedamage := DAMAGE_AIM;
self.use := monster_use;
self.clipmask := MASK_MONSTERSOLID;
VectorCopy(self.s.origin, self.s.old_origin);
self.monsterinfo.aiflags := self.monsterinfo.aiflags or (AI_STAND_GROUND or AI_DUCKED);
if st.item then
begin
self.item := FindItemByClassname(st.item);
if not(self.item) then
gi.dprintf('%s at %s has bad item: %s\n', [self.classname, vtos(self.s.origin), st.item]);
end;
self.think := turret_driver_link;
self.nextthink := level.time + FRAMETIME;
gi.linkentity(self);
end;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -