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

📄 g_turret.pas

📁 雷神之锤2(Quake2)Delphi源码
💻 PAS
📖 第 1 页 / 共 2 页
字号:
{----------------------------------------------------------------------------}
{                                                                            }
{ 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 + -