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

📄 g_target.pas

📁 delphi编的不错的贪吃蛇
💻 PAS
📖 第 1 页 / 共 2 页
字号:
    T_RadiusDamage(self, activator, self^.dmg, nil, self^.dmg + 40, MOD_SPLASH);
end;

procedure SP_target_splash(self: edict_p);
begin
  self^.use := use_target_splash;
  G_SetMovedir(self^.s.angles, self^.movedir);

  if self^.count = 0 then
    self^.count := 32;

  self^.svflags := SVF_NOCLIENT;
end;


//==========================================================
{ QUAKED target_spawner (1 0 0) (-8 -8 -8) (8 8 8)
Set target to the type of entity you want spawned.
Useful for spawning monsters and gibs in the factory levels.

For monsters:
	Set direction to the facing you want it to have.

For gibs:
	Set direction if you want it moving and
	speed how fast it should be moving otherwise it
	will just be dropped
}

procedure use_target_spawner(self: edict_p; other: edict_p; activator: edict_p);
var
  ent: edict_p;
begin
  ent := g_utils.G_Spawn;
  ent^.classname := self^.target;
  VectorCopy(self^.s.origin, ent^.s.origin);
  VectorCopy(self^.s.angles, ent^.s.angles);
  ED_CallSpawn(ent);
  gi.unlinkentity(ent);
  KillBox(ent);
  gi.linkentity(ent);
  if self^.speed <> 0 then
    VectorCopy(self^.movedir, ent^.velocity);
end;

procedure SP_target_spawner(self: edict_p);
begin
  self^.use := use_target_spawner;
  self^.svflags := SVF_NOCLIENT;
  if self^.speed <> 0 then
  begin
    G_SetMovedir(self^.s.angles, self^.movedir);
    VectorScale(self^.movedir, self^.speed, self^.movedir);
  end;
end;


//==========================================================
{ QUAKED target_blaster (1 0 0) (-8 -8 -8) (8 8 8) NOTRAIL NOEFFECTS
Fires a blaster bolt in the set direction when triggered.

dmg		default is 15
speed	default is 1000
}
procedure use_target_blaster(self: edict_p; other: edict_p; activator: edict_p);
var
  effect: integer;
begin
  if (self^.spawnflags and 2) <> 0 then
    effect := 0
  else if (self^.spawnflags and 1) <> 0 then
    effect := EF_HYPERBLASTER
  else
    effect := EF_BLASTER;

  // WARNING in this call. Some types could be wrong
  fire_blaster(self, self^.s.origin, self^.movedir, self^.dmg, trunc(self^.speed), EF_BLASTER, qboolean(MOD_TARGET_BLASTER));
  gi.sound(self, CHAN_VOICE, self^.noise_index, 1, ATTN_NORM, 0);
end;

procedure SP_target_blaster(self: edict_p);
begin
  self^.use := use_target_blaster;
  G_SetMovedir(self^.s.angles, self^.movedir);
  self^.noise_index := gi.soundindex('weapons/laser2.wav');

  if self^.dmg = 0 then
    self^.dmg := 15
  else if self^.speed = 0 then
    self^.speed := 1000;

  self^.svflags := SVF_NOCLIENT;
end;


//==========================================================
{QUAKED target_crosslevel_trigger (.5 .5 .5) (-8 -8 -8) (8 8 8) trigger1 trigger2 trigger3 trigger4 trigger5 trigger6 trigger7 trigger8
Once this trigger is touched/used, any trigger_crosslevel_target with the same trigger number is automatically used when a level is started within the same unit.  It is OK to check multiple triggers.  Message, delay, target, and killtarget also work.
}
procedure trigger_crosslevel_trigger_use(self: edict_p; other: edict_p; activator: edict_p);
begin
  game.serverflags := game.serverflags or self^.spawnflags;
  G_FreeEdict(self);
end;

procedure SP_target_crosslevel_trigger(self: edict_p);
begin
  self^.svflags := SVF_NOCLIENT;
  self^.use 	:= trigger_crosslevel_trigger_use;
end;

{ QUAKED target_crosslevel_target (.5 .5 .5) (-8 -8 -8) (8 8 8) trigger1 trigger2 trigger3 trigger4 trigger5 trigger6 trigger7 trigger8
Triggered by a trigger_crosslevel elsewhere within a unit.  If multiple triggers are checked, all must be true.  Delay, target and
killtarget also work.

"delay"		delay before using targets if the trigger has been activated (default 1)
}
procedure target_crosslevel_target_think(self: edict_p);
begin
  if self^.spawnflags = (game.serverflags and SFL_CROSS_TRIGGER_MASK and self^.spawnflags) then
  begin
    G_UseTargets(self, self);
	G_FreeEdict(self);
  end;
end;

procedure SP_target_crosslevel_target(self: edict_p);
begin
  if self^.delay = 0 then
    self^.delay := 1;
  self^.svflags := SVF_NOCLIENT;

  self^.think := target_crosslevel_target_think;
  self^.nextthink := level.time + self^.delay;
end;


//==========================================================
{ QUAKED target_laser (0 .5 .8) (-8 -8 -8) (8 8 8) START_ON RED GREEN BLUE YELLOW ORANGE FAT
When triggered, fires a laser.  You can either set a target
or a direction.
}
procedure target_laser_think (self: edict_p);
var
  ignore:       edict_p;
  start:        vec3_t;
  EndVar:	vec3_t; // original variable name: end
  tr: 	  	trace_t;
  point:        vec3_t;
  last_movedir: vec3_t;
  count:        integer;
begin
  if (self^.spawnflags and $80000000) <> 0 then
    count := 8
  else
    count := 4;

  if self^.enemy <> nil then
  begin
    VectorCopy(self^.movedir, last_movedir);
    VectorMA(self^.enemy^.absmin, 0.5, self^.enemy^.size, point);
    VectorSubtract(point, self^.s.origin, self^.movedir);
    VectorNormalize(self^.movedir);
    if VectorCompare(self^.movedir, last_movedir) = 0 then
      self^.spawnflags := self^.spawnflags or $80000000;
  end;

  ignore := self;
  VectorCopy(self^.s.origin, start);
  VectorMA(start, 2048, self^.movedir, EndVar);
  while true do
  begin
    tr := gi.trace(@start, nil, nil, @EndVar, ignore, CONTENTS_SOLID or CONTENTS_MONSTER or CONTENTS_DEADMONSTER);

    if tr.ent = nil then
      break;

    // hurt it if we can
    if (edict_p(tr.ent)^.takedamage <> DAMAGE_NO) and ((edict_p(tr.ent)^.flags and FL_IMMUNE_LASER) = 0) then
      T_Damage(tr.ent, self, self^.activator, self^.movedir, tr.endpos, vec3_origin, self^.dmg, 1, DAMAGE_ENERGY, MOD_TARGET_LASER);

    // if we hit something that's not a monster or player or is immune to lasers, we're done
    if ((edict_p(tr.ent)^.svflags and SVF_MONSTER) = 0) and (edict_p(tr.ent)^.client = nil) then
    begin
      if (self^.spawnflags and $80000000) <> 0 then
      begin
        self^.spawnflags := self^.spawnflags and not $80000000;
        gi.WriteByte(svc_temp_entity);
        gi.WriteByte(Integer(TE_LASER_SPARKS)); // cast to Integer done
        gi.WriteByte(count);
        gi.WritePosition(tr.endpos);
        gi.WriteDir(tr.plane.normal);
        gi.WriteByte(self^.s.skinnum);
        gi.multicast(@tr.endpos, MULTICAST_PVS);
      end;
      break;
    end;

    ignore := tr.ent;
    VectorCopy(tr.endpos, start);
  end;

  VectorCopy(tr.endpos, self^.s.old_origin);

  self^.nextthink := level.time + FRAMETIME;
end;

procedure target_laser_on(self: edict_p);
begin
  if self^.activator = nil then
    self^.activator := self;

  self^.spawnflags := self^.spawnflags or $80000001;
  self^.svflags    := self^.svflags and not SVF_NOCLIENT;
  target_laser_think(self);
end;

procedure target_laser_off(self: edict_p);
begin
  self^.spawnflags := self^.spawnflags and not 1;
  self^.svflags    := self^.svflags or SVF_NOCLIENT;
  self^.nextthink  := 0;
end;

procedure target_laser_use(self: edict_p; other: edict_p; activator: edict_p);
begin
  self^.activator := activator;
  if (self^.spawnflags and 1) <> 0 then
    target_laser_off(self)
  else
    target_laser_on(self);
end;

procedure target_laser_start(self: edict_p);
var
  ent: edict_p;
begin
  self^.movetype     := MOVETYPE_NONE;
  self^.solid 	     := SOLID_NOT;
  self^.s.renderfx   := self^.s.renderfx or (RF_BEAM and RF_TRANSLUCENT);
  self^.s.modelindex := 1;			// must be non-zero

  // set the beam diameter
  if (self^.spawnflags and 64) <> 0 then
    self^.s.frame := 16
  else
    self^.s.frame := 4;

  // set the color
  if (self^.spawnflags and 2) <> 0 then
    self^.s.skinnum := $f2f2f0f0
  else if (self^.spawnflags and 4) <> 0 then
    self^.s.skinnum := $d0d1d2d3
  else if (self^.spawnflags and 8) <> 0 then
    self^.s.skinnum := $f3f3f1f1
  else if (self^.spawnflags and 16) <> 0 then
    self^.s.skinnum := $dcdddedf
  else if (self^.spawnflags and 32) <> 0 then
    self^.s.skinnum := $e0e1e2e3;

  if self^.enemy = nil then
  begin
    if self^.target <> nil then
    begin
      ent := G_Find(nil, FOFS_targetname, self^.target);
      if ent = nil then
        gi.dprintf('%s at %s: %s is a bad target'#10, self^.classname, vtos(self^.s.origin), self^.target);
      self^.enemy := ent;
    end
    else
    begin
      G_SetMovedir(self^.s.angles, self^.movedir);
    end;
  end;
  self^.use   := target_laser_use;
  self^.think := target_laser_think;

  if self^.dmg = 0 then
    self^.dmg := 1;

  VectorSet(self^.mins, -8, -8, -8);
  VectorSet(self^.maxs, 8, 8, 8);
  gi.linkentity(self);

  if (self^.spawnflags and 1) <> 0 then
    target_laser_on(self)
  else
    target_laser_off(self);
end;

procedure SP_target_laser(self: edict_p);
begin
  // let everything else get spawned before we start firing
  self^.think 	  := target_laser_start;
  self^.nextthink := level.time + 1;
end;


//==========================================================
{ QUAKED target_lightramp (0 .5 .8) (-8 -8 -8) (8 8 8) TOGGLE
speed		How many seconds the ramping will take
message		two letters; starting lightlevel and ending lightlevel
}
procedure target_lightramp_think(self: edict_p);
var
  style: array[0..1] of char;
  temp: single;
begin
  style[0] := chr(ord('a') + trunc(self^.movedir[0] + (level.time - self^.timestamp) / FRAMETIME * self^.movedir[2]));
  style[1] := #0;
  gi.configstring(CS_LIGHTS + self^.enemy^.style, style);

  if (level.time - self^.timestamp) < self^.speed then
  begin
    self^.nextthink := level.time + FRAMETIME;
  end
  else if (self^.spawnflags and 1) <> 0 then
  begin
    temp := self^.movedir[0];
    self^.movedir[0] := self^.movedir[1];
    self^.movedir[1] := temp;
    self^.movedir[2] := self^.movedir[2] * -1;
  end;
end;

procedure target_lightramp_use(self: edict_p; other: edict_p; activator: edict_p);
var
  e: edict_p;
begin
  if self^.enemy = nil then
  begin
    // check all the targets
    e := nil;
    while true do
    begin
      e := G_Find(e, FOFS_targetname, self^.target);
      if e = nil then
        break;
      if StrComp(e^.classname, 'light') <> 0 then
      begin
        gi.dprintf('%s at %s ', self^.classname, vtos(self^.s.origin));
        gi.dprintf('target %s (%s at %s) is not a light'#10, self^.target, e^.classname, vtos(e^.s.origin));
      end
      else
      begin
        self^.enemy := e;
      end;
    end;

    if self^.enemy = nil then
    begin
      gi.dprintf('%s target %s not found at %s'#10, self^.classname, self^.target, vtos(self^.s.origin));
      G_FreeEdict(self);
      exit;
    end;
  end;

  self^.timestamp := level.time;
  target_lightramp_think(self);
end;

procedure SP_target_lightramp(self: edict_p);
begin
  if (self^._message = nil)    or (StrLen(self^._message) <> 2) or
     (self^._message[0] < 'a') or (self^._message[0] > 'z')     or
     (self^._message[1] < 'a') or (self^._message[1] > 'z')     or
     (self^._message[0] = self^._message[1]) then
  begin
    gi.dprintf('target_lightramp has bad ramp (%s) at %s'#10, self^._message, vtos(self^.s.origin));
    G_FreeEdict(self);
    exit;
  end;

  if deathmatch^.Value <> 0 then
  begin
    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^.svflags := self^.svflags or SVF_NOCLIENT;
  self^.use 	:= target_lightramp_use;
  self^.think 	:= target_lightramp_think;

  self^.movedir[0] := ord(self^._message[0]) - ord('a');
  self^.movedir[1] := ord(self^._message[1]) - ord('a');
  self^.movedir[2] := (self^.movedir[1] - self^.movedir[0]) / (self^.speed / FRAMETIME);
end;

//==========================================================
{ QUAKED target_earthquake (1 0 0) (-8 -8 -8) (8 8 8)
When triggered, this initiates a level-wide earthquake.
All players and monsters are affected.
"speed"		severity of the quake (default:200)
"count"		duration of the quake (default:5)
}
procedure target_earthquake_think(self: edict_p);
var
  i: integer;
  e: edict_p;
begin
  if self^.last_move_time < level.time then
  begin
    gi.positioned_sound(@self^.s.origin, self, CHAN_AUTO, self^.noise_index, 1.0, ATTN_NONE, 0);
    self^.last_move_time := level.time + 0.5;
  end;

  for I := 1 to globals.num_edicts - 1 do
  begin
    e := @g_edicts^[I]; // cast must be done

    if not e^.inuse then
      Continue;

    if e^.client = nil then
      Continue;

    if e^.groundentity = nil then
      Continue;

    e^.groundentity := nil;
    e^.velocity[0] := e^.velocity[0] + crandom() * 150;
    e^.velocity[1] := e^.velocity[1] + crandom() * 150;
    e^.velocity[2] := self^.speed * (100.0 / e^.mass);
  end;

  if level.time < self^.timestamp then
    self^.nextthink := level.time + FRAMETIME;
end;

procedure target_earthquake_use(self: edict_p; other: edict_p; activator: edict_p);
begin
  self^.timestamp := level.time + self^.count;
  self^.nextthink := level.time + FRAMETIME;
  self^.activator := activator;
  self^.last_move_time := 0;
end;

procedure SP_target_earthquake(self: edict_p);
begin
  if self^.targetname = nil then
    gi.dprintf('untargeted %s at %s'#10, self^.classname, vtos(self^.s.origin));

  if self^.count = 0 then
    self^.count := 5;

  if self^.speed = 0 then
    self^.speed := 200;

  self^.svflags := self^.svflags or SVF_NOCLIENT;
  self^.think 	:= target_earthquake_think;
  self^.use 	:= target_earthquake_use;

  self^.noise_index := gi.soundindex('world/quake.wav');
end;

end.

⌨️ 快捷键说明

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