Git Repos / fte_dogmode / qc / triggers / teleport.qc
Last update to this file was on 2024-07-03 at 07:20.
Show teleport.qc
//==============================================================================
// TELEPORT TRIGGERS with added functions from Zerstrorer and Qmaster
// -- dumptruck_ds
//==============================================================================
//======================================================================
// constants
//======================================================================
#ifdef SSQC
const float TRIGGER_TELEPORT_ONLYPLAYER = 1;
const float TRIGGER_TELEPORT_SILENT = 2;
const float TRIGGER_TELEPORT_RANDOM = 4;
const float TRIGGER_TELEPORT_STEALTH = 8;
const float TRIGGER_TELEPORT_ONLYMONSTER = 16;
const float TRIGGER_TELEPORT_DD = 32;
#endif
//======================================================================
// forward declarations
//======================================================================
#ifdef SSQC
// tfog & tdeath
void() spawn_tfog_think;
void(vector org) spawn_tfog;
void() spawn_tdeath_touch;
void(vector org, entity death_owner) spawn_tdeath;
#endif
#ifdef SSQC
// trigger_teleport
entity() trigger_teleport_randomspot;
void() trigger_teleport_touch;
void() trigger_teleport_use;
void(entity e) trigger_teleport_init;
void() trigger_teleport;
#endif
//------------------------------------------------------------------------------
//======================================================================
// teleporter fog & teleporter death
//======================================================================
#ifdef SSQC
//----------------------------------------------------------------------
void() spawn_tfog_think =
{
local float v;
local string tmpstr;
v = random() * 5;
if (v < 1)
tmpstr = "misc/r_tele1.wav";
else if (v < 2)
tmpstr = "misc/r_tele2.wav";
else if (v < 3)
tmpstr = "misc/r_tele3.wav";
else if (v < 4)
tmpstr = "misc/r_tele4.wav";
else
tmpstr = "misc/r_tele5.wav";
sound (self, CHAN_VOICE, tmpstr, VOL_HIGH, ATTN_NORM);
remove (self);
};
//----------------------------------------------------------------------
void(vector org) spawn_tfog =
{
local entity s;
s = spawn ();
s.origin = org;
s.spawnflags = self.spawnflags; // dumptruck_ds
s.nextthink = time + 0.2;
s.think = spawn_tfog_think;
WriteByte (MSG_BROADCAST, SVC_TEMPENTITY);
WriteByte (MSG_BROADCAST, TE_TELEPORT);
WriteCoord (MSG_BROADCAST, org_x);
WriteCoord (MSG_BROADCAST, org_y);
WriteCoord (MSG_BROADCAST, org_z);
};
//----------------------------------------------------------------------
void() spawn_tdeath_touch =
{
if (other == self.owner)
return;
// frag anyone who teleports in on top of an invincible player
if (other.classtype == CT_PLAYER)
{
// 1998-07-26 Pentagram telefrag fix by Zoid/Maddes start
if (self.owner.classtype != CT_PLAYER)
{
// other monsters explode themselves
t_damage2 (self.owner, self, self, 50000);
return;
}
// 1998-07-26 Pentagram telefrag fix by Zoid/Maddes end
// 1998-07-26 Pentagram telefrag fix by Zoid/Maddes start
if (other.invincible_finished > time)
{
// player on spot has active pentagram
if (self.owner.invincible_finished > time)
{
// teleported player has active pentagram too
// can happen often in deathmatch 4
// and levels with more than one pentagram
self.classname = "teledeath3";
other.invincible_finished = 0;
// kill player on spot
t_damage2 (other, self, self, 50000);
/*
// 1998-07-26 only telefrag player on spot
// by Maddes
local entity other2;
other2 = self.owner;
self.owner = other;
other2.invincible_finished = 0;
// kill teleported player
T_Damage (other2, self, self, 50000);
*/
}
else
{
// 1998-07-26 Pentagram telefrag fix by
// Zoid/Maddes end
self.classname = "teledeath2";
// 1998-07-26 Pentagram telefrag fix by
// Zoid/Maddes start
t_damage2 (self.owner, self, self, 50000);
}
return;
}
/*
if (self.owner.classtype != CT_PLAYER)
{ // other monsters explode themselves
T_Damage (self.owner, self, self, 50000);
return;
}
*/
// 1998-07-26 Pentagram telefrag fix by Zoid/Maddes end
}
if (other.health)
t_damage2 (other, self, self, 50000);
};
//----------------------------------------------------------------------
void(vector org, entity death_owner) spawn_tdeath =
{
local entity death;
death = spawn ();
death.classname = "teledeath";
death.movetype = MOVETYPE_NONE;
death.solid = SOLID_TRIGGER;
death.angles = '0 0 0';
setsize (death, death_owner.mins - '1 1 1', death_owner.maxs + '1 1 1');
setorigin (death, org);
death.touch = spawn_tdeath_touch;
death.nextthink = time + 0.2;
death.think = sub_remove;
death.owner = death_owner;
// make sure even still objects get hit
force_retouch = 2;
};
#endif
//======================================================================
// trigger_teleport
//======================================================================
#ifdef SSQC
/*QUAKED trigger_teleport (.5 .5 .5) ? TRIGGER_TELEPORT_ONLYPLAYER TRIGGER_TELEPORT_SILENT TRIGGER_TELEPORT_RANDOM TRIGGER_TELEPORT_STEALTH X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
Any object touching this will be transported to the corresponding
info_teleport_destination entity. You must set the "target" field,
and create an object with a "targetname" field that matches.
If the trigger_teleport has a targetname, it will only teleport entities
when it has been fired.
TRIGGER_TELEPORT_SILENT(2) eliminates the teleporter ambient noise (good
for hidden monster teleporters.
TRIGGER_TELEPORT_RANDOM(4) causes the teleporter to send the player to a
random destination among the info_teleport_random markers in the level.
You MUST place a "count" field that is the number of info_teleport_random
entities you placed.
TRIGGER_TELEPORT_STEALTH(8) eliminates the particle flash and noise when
an entity is teleported.
TRIGGER_TELEPORT_ONLYMONSTER(16) will only teleport monsters
*/
//----------------------------------------------------------------------
// class trigger_teleport: base_trigger
// {
//--------------------------------------------------------------
// trigger_teleport_randomspot -- more Zerstrorer -- dumptruck_ds
// teleport_randomspot - returns a random spot to teleport to
// among all of the "info_teleport_random" entities in the level.
// self.count is the number of spots
//--------------------------------------------------------------
entity() trigger_teleport_randomspot =
{
local float rndm;
// local float rndm, num1;
local entity spot, first;
rndm = rint (random() * (self.count - 1));
spot = findfloat (world, classtype, CT_INFO_TELEPORT_RANDOM);
if (!spot)
dprint ("trigger_teleport_randomspot: "
"no random teleport points found!\n");
first = spot;
while (rndm > 0)
{
rndm = rndm - 1;
spot = findfloat (spot, classtype,
CT_INFO_TELEPORT_RANDOM);
}
if (spot == world)
{
dprint ("trigger_teleport_randomspot: "
"random spot found world!!\n");
spot = first;
}
return spot;
};
// end dumptruck_ds
//--------------------------------------------------------------
void() trigger_teleport_touch =
{
local entity t;
local vector org;
if (self.estate != STATE_ACTIVE)
return;
if (self.targetname != "")
if (self.nextthink < time)
// not fired yet
return;
if (self.spawnflags & TRIGGER_TELEPORT_ONLYPLAYER)
if (other.classtype != CT_PLAYER &&
other.classtype != CT_PROJECTILE_GRENADE)
return;
// is this going to work? dumptruck_ds
if (self.spawnflags & TRIGGER_TELEPORT_ONLYMONSTER)
if (other.classtype == CT_PLAYER)
return;
// from Copper -- dumptruck_ds
if (other.movetype == MOVETYPE_NOCLIP)
return;
// Supa, is this trigger waiting to be activated?
if (self.is_waiting == TRUE)
return;
// Special case
if (self.is_waiting != -1)
if (self.targetname != "")
if (self.nextthink < time)
// not fired yet
return;
// only teleport living creatures (and projectiles)
if (other.health <= 0 || (other.solid != SOLID_SLIDEBOX &&
other.solid != SOLID_BBOX))
return;
sub_usetargets ();
// put a tfog where the player was
// ### dhm - if stealth, don't spawn a fog
if (!(self.spawnflags & TRIGGER_TELEPORT_STEALTH))
spawn_tfog (other.origin);
// dhm - if this is a random teleporter, pick a random spot!
if (self.spawnflags & TRIGGER_TELEPORT_RANDOM)
{
t = trigger_teleport_randomspot ();
}
else if ((self.spawnflags & TRIGGER_TELEPORT_DD) &&
other.classtype == CT_PLAYER)
{
t = find (world, targetname, self.noise);
}
else
{
t = find (world, targetname, self.target);
}
if (!t)
objerror ("trigger_teleport_touch: couldn't "
"find target");
// put a tfog where the player was
/*
spawn_tfog (other.origin);
t = find (world, targetname, self.target);
if (!t)
objerror ("couldn't find target");
*/
// spawn a tfog flash in front of the destination
makevectors (t.mangle);
org = t.origin + 32 * v_forward;
// ### dhm - if stealth, don't spawn a fog
if (!(self.spawnflags & TRIGGER_TELEPORT_STEALTH))
spawn_tfog (org);
spawn_tdeath (t.origin, other);
// move the player and lock him down for a little while
if (!other.health)
{
other.origin = t.origin;
other.velocity = (v_forward * other.velocity_x) +
(v_forward * other.velocity_y);
return;
}
setorigin (other, t.origin);
other.angles = t.mangle;
if (other.classtype == CT_PLAYER)
{
// retrieves fog values from teleport destination,
// if any
fog_set_from_ent (other, t);
// turn this way immediately
other.fixangle = 1;
other.teleport_time = time + 0.7;
other.velocity = v_forward * PM_MAXSPEED;
// TODO CEV commented out the next line
// other.flags -= other.flags & FL_ONGROUND;
}
if ((self.spawnflags & TRIGGER_TELEPORT_ONLYMONSTER) &&
other.classtype != CT_PLAYER)
{
// turn this way immediately
other.fixangle = 1;
other.teleport_time = time + 0.7;
other.velocity = v_forward * 300;
if (other.flags & FL_ONGROUND)
other.flags -= other.flags & FL_ONGROUND;
}
};
//--------------------------------------------------------------
void() trigger_teleport_use =
{
self.nextthink = time + 0.2;
// make sure even still objects get hit
force_retouch = 2;
self.think = sub_null;
};
//--------------------------------------------------------------
void(entity e) trigger_teleport_init =
{
e.classname = "trigger_teleport";
e.classtype = CT_TRIGGER_TELEPORT;
base_trigger_init (e);
e.touch = trigger_teleport_touch;
e.use = trigger_teleport_use;
// find the destination
if (!e.target)
objerror ("trigger_teleport_init: no target");
if (!(e.spawnflags & TRIGGER_TELEPORT_SILENT))
{
precache_sound ("ambience/hum1.wav");
// volume was 0.5 -- CEV
ambientsound ((e.mins + e.maxs) * 0.5,
"ambience/hum1.wav", VOL_LOW, ATTN_STATIC);
}
sub_checkwaiting (e);
};
//--------------------------------------------------------------
void() trigger_teleport =
{
// new spawnflags for all entities -- iw
if (SUB_Inhibit())
return;
trigger_teleport_init (self);
};
// };
#endif
Return to the top of this page or return to the overview of this repo.
Log teleport.qc
Date | Commit Message | Author | + | - |
---|---|---|---|---|
2024-07-03 | pmove changes and fixes, improved climbing | cev | +3 | -5 |
2024-06-15 | Major update, committing as-is, will have bugs | cev | +12 | -2 |
2024-03-24 | 2nd pass refactor, rework QC class structure | cev | +109 | -76 |
2024-02-27 | Bullet projectile, pmove changes, misc | cev | +7 | -4 |
2024-02-18 | Client/player, projectiles, entrypoints refactor | cev | +5 | -4 |
2024-01-31 | Class based monster refactor & start projectiles | cev | +2 | -2 |
2024-01-09 | Continue OO / Class-based refactor | cev | +41 | -44 |
2023-12-09 | Start OO / class-based refactor, work on items | cev | +202 | -321 |
2023-11-16 | pmove bug fixes, moved q3 compat code, cleanup | cev | +493 |
Return to the top of this page or return to the overview of this repo.