📄 g_target.pas
字号:
end;
if ent^._message = nil then
begin
gi_dprintf('%s with no message at %s'#10, [ent^.classname, vtos(ent^.s.origin)]);
G_FreeEdict(ent);
exit;
end;
ent^.use := @Use_Target_Help;
end;
//==========================================================
{ QUAKED target_secret (1 0 1) (-8 -8 -8) (8 8 8)
Counts a secret found.
These are single use targets.
}
procedure use_target_secret(ent: edict_p; other: edict_p; activator: edict_p);
begin
gi.sound(ent, CHAN_VOICE, ent^.noise_index, 1, ATTN_NORM, 0);
Inc(level.found_secrets);
G_UseTargets(ent, activator);
G_FreeEdict(ent);
end;
procedure SP_target_secret(ent: edict_p);
begin
//????
if {deathmatch^.value} false then
begin // auto-remove for deathmatch}
G_FreeEdict(ent);
exit;
end;
ent^.use := @use_target_secret;
if st.noise = nil then
st.noise := 'misc/secret.wav';
ent^.noise_index := gi.soundindex(st.noise);
ent^.svflags := SVF_NOCLIENT;
Inc(level.total_secrets);
// map bug hack
if (Q_stricmp(level.mapname, 'mine3') = 0) and (ent^.s.origin[0] = 280) and
(ent^.s.origin[1] = -2048) and (ent^.s.origin[2] = -624) then
begin
ent^._message := 'You have found a secret area.';
end;
end;
//==========================================================
{QUAKED target_goal (1 0 1) (-8 -8 -8) (8 8 8)
Counts a goal completed.
These are single use targets.
}
procedure use_target_goal(ent: edict_p; other: edict_p; activator: edict_p);
begin
gi.sound(ent, CHAN_VOICE, ent^.noise_index, 1, ATTN_NORM, 0);
Inc(level.found_goals);
if level.found_goals = level.total_goals then
gi.configstring(CS_CDTRACK, '0');
G_UseTargets(ent, activator);
G_FreeEdict(ent);
end;
procedure SP_target_goal(ent: edict_p);
begin
//????
if {deathmatch^.value} false then
begin // auto-remove for deathmatch}
G_FreeEdict(ent);
exit;
end;
ent^.use := @use_target_goal;
if st.noise = nil then
st.noise := 'misc/secret.wav';
ent^.noise_index := gi.soundindex(st.noise);
ent^.svflags := SVF_NOCLIENT;
Inc(level.total_goals);
end;
//==========================================================
{ QUAKED target_explosion (1 0 0) (-8 -8 -8) (8 8 8)
Spawns an explosion temporary entity when used.
"delay" wait this long before going off
"dmg" how much radius damage should be done, defaults to 0
}
procedure target_explosion_explode(self: edict_p);
var
save: Single;
begin
gi.WriteByte(svc_temp_entity);
gi.WriteByte(Integer(TE_EXPLOSION1)); // cast from temp_event_t to Integer must be done
gi.WritePosition(self^.s.origin);
gi.multicast(self^.s.origin, MULTICAST_PHS);
T_RadiusDamage(self, self^.activator, self^.dmg, nil, self^.dmg + 40, MOD_EXPLOSIVE);
save := self^.delay;
self^.delay := 0;
G_UseTargets(self, self^.activator);
self^.delay := save;
end;
procedure use_target_explosion(self: edict_p; other: edict_p; activator: edict_p);
begin
self^.activator := activator;
if self^.delay = 0 then
begin
target_explosion_explode(self);
exit;
end;
self^.think := @target_explosion_explode;
self^.nextthink := level.time + self^.delay;
end;
procedure SP_target_explosion(ent: edict_p);
begin
ent^.use := @use_target_explosion;
ent^.svflags := SVF_NOCLIENT;
end;
//==========================================================
{ QUAKED target_changelevel (1 0 0) (-8 -8 -8) (8 8 8)
Changes level to "map" when fired
}
procedure use_target_changelevel(self: edict_p; other: edict_p; activator: edict_p);
begin
if level.intermissiontime <> 0 then
exit; // allready activated
//????
if ({not deathmatch^.value} false) and ({not coop^.value} false) then
begin
if g_edicts[1].health <= 0 then
exit;
end;
// if noexit, do a ton of damage to other
//????
if false {deathmatch^.value and (0 = (Integer(dmflags^.value) and DF_ALLOW_EXIT) and (other <> world)} then
begin
T_Damage(other, self, self, vec3_origin, other^.s.origin, vec3_origin, 10 * other^.max_health, 1000, 0, MOD_EXIT);
exit;
end;
// if multiplayer, let everyone know who hit the exit
//????
if {deathmatch^.value} false then
begin
// cast to interger must be done for mask operation
if (Integer(activator) and Integer(activator^.client)) <> 0 then
gi_bprintf(PRINT_HIGH, '%s exited the level.'#10, [activator^.client^.pers.netname]);
end;
// if going to a new unit, clear cross triggers
if Pos('*', self^.map) <> 0 then
game.serverflags := game.serverflags and not SFL_CROSS_TRIGGER_MASK;
BeginIntermission(self);
end;
procedure SP_target_changelevel(ent: edict_p);
begin
if ent^.map = nil then
begin
gi_dprintf('target_changelevel with no map at %s'#10, [vtos(ent^.s.origin)]);
G_FreeEdict(ent);
exit;
end;
// ugly hack because *SOMEBODY* screwed up their map
if (Q_stricmp(level.mapname, 'fact1') = 0) and (Q_stricmp(ent^.map, 'fact3') = 0) then
ent^.map := 'fact3$secret1';
ent^.use := @use_target_changelevel;
ent^.svflags := SVF_NOCLIENT;
end;
//==========================================================
{ QUAKED target_splash (1 0 0) (-8 -8 -8) (8 8 8)
Creates a particle splash effect when used.
Set "sounds" to one of the following:
1) sparks
2) blue water
3) brown water
4) slime
5) lava
6) blood
"count" how many pixels in the splash
"dmg" if set, does a radius damage at this location when it splashes
useful for lava/sparks
}
procedure use_target_splash(self: edict_p; other: edict_p; activator: edict_p);
begin
gi.WriteByte(svc_temp_entity);
gi.WriteByte(Integer(TE_SPLASH));
gi.WriteByte(self^.count);
gi.WritePosition(self^.s.origin);
gi.WriteDir(self^.movedir);
gi.WriteByte(self^.sounds);
gi.multicast(self^.s.origin, MULTICAST_PVS);
if self^.dmg <> 0 then
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 ED_CallSpawn(ent: edict_p);
begin
//???? where is this funtion's implementation?
end;
procedure use_target_spawner(self: edict_p; other: edict_p; activator: edict_p);
var
ent: edict_p;
begin
ent := 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, 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;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -