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

📄 g_target.pas

📁 雷神之锤2(Quake2)Delphi源码
💻 PAS
📖 第 1 页 / 共 3 页
字号:
  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 + -