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

📄 g_target.pas

📁 delphi编的不错的贪吃蛇
💻 PAS
📖 第 1 页 / 共 3 页
字号:
  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;
  // dummy vars for trace() call
  dummy_vec_1:  vec3_t;
  dummy_vec_2:  vec3_t;
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
    //????
    // call could not be done because args 2 and 3 must be vec3_t and C source pass NULL
    // use dummy structs for arg 2 and 3
    FillChar(dummy_vec_1, sizeof(vec3_t), 0);
    FillChar(dummy_vec_2, sizeof(vec3_t), 0);
    tr := gi.trace(start, dummy_vec_1, dummy_vec_2, EndVar, ignore, CONTENTS_SOLID or CONTENTS_MONSTER or CONTENTS_DEADMONSTER);

    if tr.ent = nil then
      break;

    // hurt it if we can
    // cast to Integer must be done in takendamage
    if (Integer(tr.ent^.takedamage) and (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 ((tr.ent^.svflags and SVF_MONSTER) = 0) and (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
      //???? FOPS(targetname) translated as FOFS_targetname
      // I'm not sure...
      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: char;
begin
//???? incompatibility between char and single expression
//  style[0] := 'a' + 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 false {deathmatch^.value} 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;

  //???? no idea how tranlate: single := single - char
  //self^.movedir[0] := self^._message[0] - 'a';
  //self^.movedir[1] := self^._message[1] - '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;

  e := Pointer(Integer(g_edicts) + Integer(i)); // cast must be done
  Inc(e);
  for i:=1 to globals.num_edicts - 1 do
  begin
    if not e^.inuse then
    begin
      Inc(e);
      continue;
    end;
    if e^.client = nil then
    begin
      Inc(e);
      continue;
    end;
    if e^.groundentity = nil then
    begin
      Inc(e);
      continue;
    end;

    e^.groundentity := nil;
    e^.velocity[0] := e^.velocity[0] + crandom() * 150;
    e^.velocity[1] := e^.velocity[1] + crandom() * 150;
    e^.velocity[2] := 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 + -