📄 g_turret.pas
字号:
{----------------------------------------------------------------------------}
{ }
{ File(s): m_infantry.h }
{ }
{ Initial conversion by : Ben Watt (ben@delphigamedev.com) }
{ Initial conversion on : 12-Feb-2002 }
{ }
{ This File contains part of convertion of Quake2 source to ObjectPascal. }
{ More information about this project can be found at: }
{ http://www.sulaco.co.za/quake2/ }
{ }
{ Copyright (C) 1997-2001 Id Software, Inc. }
{ }
{ This program is free software; you can redistribute it and/or }
{ modify it under the terms of the GNU General Public License }
{ as published by the Free Software Foundation; either version 2 }
{ of the License, or (at your option) any later version. }
{ }
{ This program is distributed in the hope that it will be useful, }
{ but WITHOUT ANY WARRANTY; without even the implied warranty of }
{ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. }
{ }
{ See the GNU General Public License for more details. }
{ }
{----------------------------------------------------------------------------}
{ Updated on : }
{ Updated by : }
{ }
{----------------------------------------------------------------------------}
{ * Still dependent (to compile correctly) on: }
{ 1.) g_local.h and game.h }
{----------------------------------------------------------------------------}
{ * TODO: }
{ 1.) test compilation with the above two units }
{----------------------------------------------------------------------------}
unit g_turret;
interface
{$I g_local.inc}
procedure AnglesNormalize(vec : vec3_t);
function SnapToEights(x : single): Single;
procedure turret_blocked(self, other : edict_t);
procedure turret_breach_fire(self : edict_t);
procedure turret_breach_think(self : edict_t);
procedure turret_breach_finish_init(self : edict_t);
procedure SP_turret_breach(self : edict_t);
procedure SP_turret_base(self : edict_t);
procedure turret_driver_die(self, inflictor, attacker : edict_t; damage : integer; point : vec3_t);
function FindTarget(self: edict_t): qboolean;
procedure turret_driver_think(self : edict_t);
procedure turret_driver_link(self : edict_t);
procedure SP_turret_driver(self : edict_t);
procedure AnglesNormalize(vec : vec3_t);
begin
while vec[0] > 360 do
vec[0] := vec[0] - 360;
while vec[0] < 0 do
vec[0] := vec[0] + 360;
while vec[1] > 360 do
vec[1] := vec[1] - 360;
while vec[1] < 0 do
vec[1] := vec[1] + 360;
end;
function SnapToEights(x : single): Single;
begin
x := x*8.0;
if x > 0.0 then
x := x+0.5
else
x := x-0.5;
Result := 0.125 * Int(x);
end;
procedure turret_blocked(self, other : edict_t);
var
attacker : edict_t;
begin
if other.takedamage then
begin
if self.teammaster.owner then
attacker := self.teammaster.owner;
else
attacker := self.teammaster;
T_Damage(other, self, attacker, vec3_origin, other.s.origin, vec3_origin, self.teammaster.dmg, 10, 0, MOD_CRUSH);
end;
end;
{QUAKED turret_breach (0 0 0) ?
This portion of the turret can change both pitch and yaw.
The model should be made with a flat pitch.
It (and the associated base) need to be oriented towards 0.
Use "angle" to set the starting angle.
"speed" default 50
"dmg" default 10
"angle" point this forward
"target" point this at an info_notnull at the muzzle tip
"minpitch" min acceptable pitch angle : default -30
"maxpitch" max acceptable pitch angle : default 30
"minyaw" min acceptable yaw angle : default 0
"maxyaw" max acceptable yaw angle : default 360
}
procedure turret_breach_fire(self : edict_t);
var
f, r, u : vec3_t;
start : vec3_t;
damage : integer;
speed : integer;
begin
AngleVectors(self.s.angles, f, r, u);
VectorMA(self.s.origin, self.move_origin[0], f, start);
VectorMA(start, self.move_origin[1], r, start);
VectorMA(start, self.move_origin[2], u, start);
damage := 100 + random() * 50;
speed := 550 + 50 * skill.value;
fire_rocket(self.teammaster.owner, start, f, damage, speed, 150, damage);
gi.positioned_sound(start, self, CHAN_WEAPON, gi.soundindex('weapons/rocklf1a.wav'), 1, ATTN_NORM, 0);
end;
procedure turret_breach_think(self : edict_t);
var
ent : edict_t;
current_angles : vec3_t;
delta : vec3_t;
dmin, dmax : single;
angle : single;
target_z : single;
diff : single;
target : vec3_t;
dir : vec3_t;
begin
VectorCopy(self.s.angles, current_angles);
AnglesNormalize(current_angles);
AnglesNormalize(self.move_angles);
if self.move_angles[PITCH] > 180 then
self.move_angles[PITCH] := self.move_angles[PITCH] - 360;
// clamp angles to mins & maxs
if self.move_angles[PITCH] > self.pos1[PITCH] then
self.move_angles[PITCH] := self.pos1[PITCH]
else
if self.move_angles[PITCH] < self.pos2[PITCH] then
self.move_angles[PITCH] := self.pos2[PITCH];
if (self.move_angles[YAW] < self.pos1[YAW]) or (self.move_angles[YAW] > self.pos2[YAW]) then
begin
dmin := fabs(self.pos1[YAW] - self.move_angles[YAW]);
if dmin < -180 then
dmin := dmin + 360
else
if dmin > 180 then
dmin := dmin - 360;
dmax := fabs(self.pos2[YAW] - self.move_angles[YAW]);
if dmax < -180 then
dmax := dmax + 360
else
if dmax > 180 then
dmax := dmax - 360;
if fabs(dmin) < fabs(dmax) then
self.move_angles[YAW] := self.pos1[YAW]
else
self.move_angles[YAW] := self.pos2[YAW];
end;
VectorSubtract(self.move_angles, current_angles, delta);
if delta[0] < -180 then
delta[0] := delta[0] + 360
else
if delta[0] > 180 then
delta[0] := delta[0] - 360;
if delta[1] < -180 then
delta[1] := delta[1] + 360
else
if delta[1] > 180 then
delta[1] := delta[1] - 360;
delta[2] := 0;
if delta[0] > (self.speed * FRAMETIME) then
delta[0] := self.speed * FRAMETIME;
if delta[0] < (-1 * self.speed * FRAMETIME) then
delta[0] := -1 * self->speed * FRAMETIME;
if delta[1] > (self.speed * FRAMETIME) then
delta[1] := self.speed * FRAMETIME;
if delta[1] < (-1 * self.speed * FRAMETIME) then
delta[1] := -1 * self.speed * FRAMETIME;
VectorScale(delta, 1.0/FRAMETIME, self.avelocity);
self.nextthink := level.time + FRAMETIME;
ent := self.teammaster;
while (ent <> nil) do
begin
ent.avelocity[1] := self.avelocity[1];
ent := ent.teamchain;
end;
// if we have adriver, adjust his velocities
if self.owner then
begin
// angular is easy, just copy ours
self.owner.avelocity[0] := self.avelocity[0];
self.owner.avelocity[1] := self.avelocity[1];
// x & y
angle := self.s.angles[1] + self.owner.move_origin[1];
angle := angle * (M_PI*2 / 360);
target[0] := SnapToEights(self.s.origin[0] + cos(angle) * self.owner.move_origin[0]);
target[1] := SnapToEights(self.s.origin[1] + sin(angle) * self.owner.move_origin[0]);
target[2] := self.owner.s.origin[2];
VectorSubtract(target, self.owner.s.origin, dir);
self.owner.velocity[0] := dir[0] * 1.0 / FRAMETIME;
self.owner.velocity[1] := dir[1] * 1.0 / FRAMETIME;
// z
angle := self.s.angles[PITCH] * (M_PI*2 / 360);
target_z := SnapToEights(self.s.origin[2] + self.owner.move_origin[0] * tan(angle) + self.owner.move_origin[2]);
diff := target_z - self.owner.s.origin[2];
self.owner.velocity[2] := diff * 1.0 / FRAMETIME;
if self.spawnflags and 65536 then
begin
turret_breach_fire(self);
self.spawnflags := self.spawnflags and 65536;
end;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -