📄 g_target.pas
字号:
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 + -