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

📄 g_misc.pas

📁 delphi编的不错的贪吃蛇
💻 PAS
📖 第 1 页 / 共 4 页
字号:
    other.s.event := EV_OTHER_TELEPORT;
{$ENDIF}
  end;

  other.goalentity := next;
  other.movetarget := next;

  if self.wait<>0 then begin
    other.monsterinfo.pausetime := level.time + self.wait;
    other.monsterinfo.stand(other);
    exit;
  end;

  if other.movetarget=Nil then begin
    other.monsterinfo.pausetime := level.time + 100000000;
    other.monsterinfo.stand (other);
  end else begin
    VectorSubtract (other.goalentity.s.origin, other.s.origin, v);
    other.ideal_yaw := vectoyaw (v);
  end;
end;

procedure SP_path_corner(self: edict_p); cdecl;
begin
  if self.targetname=Nil then begin
    gi_dprintf('path_corner with no targetname at %s'#10, [vtos(self.s.origin)]);
    G_FreeEdict (self);
    exit;
  end;

  self.solid := SOLID_TRIGGER;
  self.touch := path_corner_touch;
  VectorSet (self.mins, -8, -8, -8);
  VectorSet (self.maxs, 8, 8, 8);
  self.svflags := self.svflags OR SVF_NOCLIENT;
  gi.linkentity (self);
end;


(*QUAKED point_combat (0.5 0.3 0) (-8 -8 -8) (8 8 8) Hold
Makes this the target of a monster and it will head here
when first activated before going after the activator.  If
hold is selected, it will stay here.
*)
procedure point_combat_touch(self, other: edict_p; plane: cplane_p; surf: csurface_p); cdecl;
Var activator: edict_p; savetarget: PChar;
begin
  if other.movetarget <> self then
    exit;

  if self.target<>Nil then begin
    other.target := self.target;
    other.movetarget := G_PickTarget(other.target);
    other.goalentity := other.movetarget;
    if other.goalentity=Nil then begin
      gi_dprintf('%s at %s target %s does not exist'#10, [self.classname, vtos(self.s.origin), self.target]);
      other.movetarget := self;
    end;
    self.target := Nil;
  end else if ((self.spawnflags AND 1)>0)
  and ((other.flags AND (FL_SWIM OR FL_FLY))>0) then begin
    other.monsterinfo.pausetime := level.time + 100000000;
    other.monsterinfo.aiflags := other.monsterinfo.aiflags OR AI_STAND_GROUND;
    other.monsterinfo.stand(other);
  end;

  if other.movetarget = self then begin
    other.target := Nil;
    other.movetarget := Nil;
    other.goalentity := other.enemy;
    other.monsterinfo.aiflags := other.monsterinfo.aiflags AND NOT AI_COMBAT_POINT;
  end;

  if self.pathtarget<>Nil then begin
    savetarget := self.target;
    self.target := self.pathtarget;
    if (other.enemy<>Nil) and (other.enemy.client<>Nil) then
      activator := other.enemy
    else if (other.oldenemy<>Nil) and (other.oldenemy.client<>Nil) then
      activator := other.oldenemy
    else if (other.activator<>Nil) and (other.activator.client<>Nil) then
      activator := other.activator
    else
      activator := other;
    G_UseTargets(self, activator);
    self.target := savetarget;
  end;
end;

procedure SP_point_combat(self: edict_p); cdecl;
begin
  if deathmatch.value<>0 then begin
    G_FreeEdict(self);
    exit;
  end;
  self.solid := SOLID_TRIGGER;
  self.touch := point_combat_touch;
  VectorSet(self.mins, -8, -8, -16);
  VectorSet(self.maxs, 8, 8, 16);
  self.svflags := SVF_NOCLIENT;
  gi.linkentity(self);
end;


(*QUAKED viewthing (0 .5 .8) (-8 -8 -8) (8 8 8)
Just for the debugging level.  Don't use
*)
{$IFDEF CTF}
Var
  robotron: Array[0..3] of Integer;
{$ENDIF}

procedure TH_viewthing(ent: edict_p); cdecl;
begin
  ent.s.frame := (ent.s.frame + 1) mod 7;
{$IFDEF CTF}
//  ent.s.frame := (ent.s.frame + 1) mod 9;
{$ENDIF}
  ent.nextthink := level.time + FRAMETIME;
{$IFDEF CTF}
//  exit;

  if ent.spawnflags<>0 then begin
    if ent.s.frame = 0 then begin
      ent.spawnflags := ((ent.spawnflags + 1) mod 4) + 1;
      ent.s.modelindex := robotron[ent.spawnflags - 1];
    end;
  end;
{$ENDIF}
end;

procedure SP_viewthing(ent: edict_p); cdecl;
begin
  gi.dprintf ('viewthing spawned'#10);

  ent.movetype := MOVETYPE_NONE;
  ent.solid := SOLID_BBOX;
  ent.s.renderfx := RF_FRAMELERP;
  VectorSet (ent.mins, -16, -16, -24);
  VectorSet (ent.maxs, 16, 16, 32);
{$IFDEF CTF}
//  ent.s.modelindex := gi.modelindex('models/player_y/tris.md2');
{$ENDIF}
  ent.s.modelindex := gi.modelindex('models/objects/banner/tris.md2');
  gi.linkentity(ent);
  ent.nextthink := level.time + 0.5;
  ent.think := TH_viewthing;
  exit; // CAK - what's the point of this???
end;


(*QUAKED info_null (0 0.5 0) (-4 -4 -4) (4 4 4)
Used as a positional target for spotlights, etc.
*)
procedure SP_info_null(self: edict_p); cdecl;
begin
  G_FreeEdict(self);
end;


(*QUAKED info_notnull (0 0.5 0) (-4 -4 -4) (4 4 4)
Used as a positional target for lightning.
*)
procedure SP_info_notnull(self: edict_p); cdecl;
begin
  VectorCopy(self.s.origin, self.absmin);
  VectorCopy(self.s.origin, self.absmax);
end;


(*QUAKED light (0 1 0) (-8 -8 -8) (8 8 8) START_OFF
Non-displayed light.
Default light value is 300.
Default style is 0.
If targeted, will toggle between on and off.
Default _cone value is 10 (used to set size of light for spotlights)
*)

const
  START_OFF = 1;

// CAK - static, so not in interface!!!
procedure light_use(self, other, activator: edict_p); cdecl;
begin
  if (self.spawnflags AND START_OFF)>0 then begin
    gi.configstring(CS_LIGHTS+self.style, 'm');
    self.spawnflags := self.spawnflags AND NOT START_OFF;
  end else begin
    gi.configstring(CS_LIGHTS+self.style, 'a');
    self.spawnflags := self.spawnflags OR START_OFF;
  end;
end;

procedure SP_light(self: edict_p); cdecl;
begin
  // no targeted lights in deathmatch, because they cause global messages
  if (self.targetname=Nil) or (deathmatch.value<>0) then begin
    G_FreeEdict(self);
    exit;
  end;

  if self.style >= 32 then begin
    self.use := light_use;
    if (self.spawnflags AND START_OFF)>0 then
      gi.configstring (CS_LIGHTS+self.style, 'a')
    else
      gi.configstring (CS_LIGHTS+self.style, 'm');
  end;
end;


(*QUAKED func_wall (0 .5 .8) ? TRIGGER_SPAWN TOGGLE START_ON ANIMATED ANIMATED_FAST
This is just a solid wall if not inhibited

TRIGGER_SPAWN  the wall will not be present until triggered
        it will then blink in to existance; it will
        kill anything that was in it's way

TOGGLE      only valid for TRIGGER_SPAWN walls
        this allows the wall to be turned on and off

START_ON    only valid for TRIGGER_SPAWN walls
        the wall will initially be present
*)

procedure func_wall_use(self, other, activator: edict_p); cdecl;
begin
  if self.solid = SOLID_NOT then begin
    self.solid := SOLID_BSP;
    self.svflags := self.svflags AND NOT SVF_NOCLIENT;
    KillBox (self);
  end else begin
    self.solid := SOLID_NOT;
    self.svflags := self.svflags OR SVF_NOCLIENT;
  end;
  gi.linkentity (self);

  if (self.spawnflags AND 2)=0 then
    self.use := Nil;
end;

procedure SP_func_wall(self: edict_p); cdecl;
begin
  self.movetype := MOVETYPE_PUSH;
  gi.setmodel(self, self.model);

  if (self.spawnflags AND 8)>0 then
    self.s.effects := self.s.effects OR EF_ANIM_ALL;
  if (self.spawnflags AND 16)>0 then
    self.s.effects := self.s.effects OR EF_ANIM_ALLFAST;

  // just a wall
  if (self.spawnflags AND 7) = 0 then begin
    self.solid := SOLID_BSP;
    gi.linkentity (self);
    exit;
  end;

  // it must be TRIGGER_SPAWN
  if (self.spawnflags AND 1)=0 then begin
//    gi.dprintf('func_wall missing TRIGGER_SPAWN'#10);
    self.spawnflags := self.spawnflags OR 1;
  end;

  // yell if the spawnflags are odd
  if (self.spawnflags AND 4)>0 then begin
    if (self.spawnflags AND 2)=0 then begin
      gi.dprintf('func_wall START_ON without TOGGLE'#10);
      self.spawnflags := self.spawnflags OR 2;
    end;
  end;

  self.use := func_wall_use;
  if (self.spawnflags AND 4)>0 then begin
    self.solid := SOLID_BSP;
  end else begin
    self.solid := SOLID_NOT;
    self.svflags := self.svflags OR SVF_NOCLIENT;
  end;
  gi.linkentity(self);
end;


(*QUAKED func_object (0 .5 .8) ? TRIGGER_SPAWN ANIMATED ANIMATED_FAST
This is solid bmodel that will fall if it's support it removed.
*)

procedure func_object_touch(self, other: edict_p; plane: cplane_p; surf: csurface_p); cdecl;
begin
  // only squash thing we fall on top of
  if plane=Nil then
    exit;
  if plane.normal[2] < 1.0 then
    exit;
  if other.takedamage = DAMAGE_NO then
    exit;
  T_Damage(other, self, self, vec3_origin, self.s.origin, vec3_origin, self.dmg, 1, 0, MOD_CRUSH);
end;

procedure func_object_release(self: edict_p); cdecl;
begin
  self.movetype := MOVETYPE_TOSS;
  self.touch := func_object_touch;
end;

procedure func_object_use(self, other, activator: edict_p); cdecl;
begin
  self.solid := SOLID_BSP;
  self.svflags := self.svflags AND NOT SVF_NOCLIENT;
  self.use := Nil;
  KillBox(self);
  func_object_release(self);
end;

procedure SP_func_object(self: edict_p); cdecl;
begin
  gi.setmodel (self, self.model);

  self.mins[0] := self.mins[0] + 1;
  self.mins[1] := self.mins[1] + 1;
  self.mins[2] := self.mins[2] + 1;
  self.maxs[0] := self.maxs[0] - 1;
  self.maxs[1] := self.maxs[1] - 1;
  self.maxs[2] := self.maxs[2] - 1;

  if self.dmg=0 then
    self.dmg := 100;

  if self.spawnflags = 0 then begin
    self.solid := SOLID_BSP;
    self.movetype := MOVETYPE_PUSH;
    self.think := func_object_release;
    self.nextthink := level.time + 2 * FRAMETIME;
  end else begin
    self.solid := SOLID_NOT;
    self.movetype := MOVETYPE_PUSH;
    self.use := func_object_use;
    self.svflags := self.svflags OR SVF_NOCLIENT;
  end;

  if (self.spawnflags AND 2)>0 then
    self.s.effects := self.s.effects OR EF_ANIM_ALL;
  if (self.spawnflags AND 4)>0 then
    self.s.effects := self.s.effects OR EF_ANIM_ALLFAST;

  self.clipmask := MASK_MONSTERSOLID;

  gi.linkentity(self);
end;


(*QUAKED func_explosive (0 .5 .8) ? Trigger_Spawn ANIMATED ANIMATED_FAST
Any brush that you want to explode or break apart.  If you want an
ex0plosion, set dmg and it will do a radius explosion of that amount
at the center of the bursh.

If targeted it will not be shootable.

health defaults to 100.

mass defaults to 75.  This determines how much debris is emitted when
it explodes.  You get one large chunk per 100 of mass (up to 8) and
one small chunk per 25 of mass (up to 16).  So 800 gives the most.
*)
procedure func_explosive_explode(self, inflictor, attacker: edict_p; damage: Integer; point: vec3_t); cdecl;
Var origin, chunkorigin, size: vec3_t; count, mass: Integer;
begin
  // bmodel origins are (0 0 0), we need to adjust that here
  VectorScale(self.size, 0.5, size);
  VectorAdd(self.absmin, size, origin);
  VectorCopy(origin, self.s.origin);

  self.takedamage := DAMAGE_NO;

  if self.dmg<>0 then
    T_RadiusDamage(self, attacker, self.dmg, Nil, self.dmg+40, MOD_EXPLOSIVE);

  VectorSubtract(self.s.origin, inflictor.s.origin, self.velocity);
  VectorNormalize(self.velocity);
  VectorScale(self.velocity, 150, self.velocity);

  // start chunks towards the center
  VectorScale (size, 0.5, size);

  mass := self.mass;
  if mass=0 then
    mass := 75;

  // big chunks
  if mass >= 100 then begin
    count := mass div 100;
    if count > 8 then
      count := 8;
    while count<>0 do begin
      dec(count);
      chunkorigin[0] := origin[0] + crandom() * size[0];
      chunkorigin[1] := origin[1] + crandom() * size[1];
      chunkorigin[2] := origin[2] + crandom() * size[2];
      ThrowDebris(self, 'models/objects/debris1/tris.md2', 1, chunkorigin);
    end;
  end;

  // small chunks
  count := mass div 25;
  if count > 16 then
    count := 16;
  while count<>0 do begin
    dec(count);
    chunkorigin[0] := origin[0] + crandom() * size[0];
    chunkorigin[1] := origin[1] + crandom() * size[1];
    chunkorigin[2] := origin[2] + crandom() * size[2];
    ThrowDebris (self, 'models/objects/debris2/tris.md2', 2, chunkorigin);
  end;

  G_UseTargets(self, attacker);

  if self.dmg<>0 then
    BecomeExplosion1(self)
  else
    G_FreeEdict(self);
end;

procedure func_explosive_use(self, other, activator: edict_p); cdecl;
begin
  func_explosive_explode (self, self, other, self.health, vec3_origin);
end;

procedure func_explosive_spawn(self, other, activator: edict_p); cdecl;
begin
  self.solid := SOLID_BSP;
  self.svflags := self.svflags AND NOT SVF_NOCLIENT;
  self.use := Nil;
  KillBox(self);
  gi.linkentity(self);
end;

procedure SP_func_explosive(self: edict_p); cdecl;
begin
  if deathmatch.value<>0 then begin  // auto-remove for deathmatch
    G_FreeEdict(self);
    exit;
  end;

  self.movetype := MOVETYPE_PUSH;

  gi.modelindex ('models/objects/debris1/tris.md2');
  gi.modelindex ('models/objects/debris2/tris.md2');

  gi.setmodel(self, self.model);

  if (self.spawnflags AND 1)>0 then begin
    self.svflags := self.svflags OR SVF_NOCLIENT;
    self.solid := SOLID_NOT;
    self.use := func_explosive_spawn;
  end else begin
    self.solid := SOLID_BSP;
    if self.targetname<>Nil then
      self.use := func_explosive_use;
  end;

  if (self.spawnflags AND 2)>0 then
    self.s.effects := self.s.effects OR EF_ANIM_ALL;
  if (self.spawnflags AND 4)>0 then
    self.s.effects := self.s.effects OR EF_ANIM_ALLFAST;

  if @self.use <> @func_explosive_use then begin
    if self.health=0 then
      self.health := 100;
    self.die := func_explosive_explode;
    self.takedamage := DAMAGE_YES;
  end;

  gi.linkentity(self);
end;


(*QUAKED misc_explobox (0 .5 .8) (-16 -16 0) (16 16 40)
Large exploding box.  You can override its mass (100),
health (80), and dmg (150).
*)

procedure barrel_touch(self, other: edict_p; plane: cplane_p; surf: csurface_p); cdecl;
Var ratio: Single; v: vec3_t;
begin
  if (other.groundentity=Nil) or (other.groundentity = self) then
    exit;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -