X-Git-Url: https://de.git.xonotic.org/?a=blobdiff_plain;f=qcsrc%2Fserver%2Ft_teleporters.qc;h=9a17d90c0c53bac0a71e9d2187f057f89add046a;hb=8db035f374df1c19ea24531f8a96f04625f5f559;hp=0adbd5196af1731fecf51774167e77816d161c1b;hpb=128c68b3e475d812ab3aa81a1aab0648a7d80505;p=xonotic%2Fxonotic-data.pk3dir.git diff --git a/qcsrc/server/t_teleporters.qc b/qcsrc/server/t_teleporters.qc index 0adbd5196..9a17d90c0 100644 --- a/qcsrc/server/t_teleporters.qc +++ b/qcsrc/server/t_teleporters.qc @@ -75,6 +75,11 @@ void spawn_tdeath(vector v0, entity e, vector v) #define TELEPORT_FLAGS_WARPZONE 0 #define TELEPORT_FLAGS_PORTAL (TELEPORT_FLAG_SOUND | TELEPORT_FLAG_PARTICLES | TELEPORT_FLAG_TDEATH | TELEPORT_FLAG_FORCE_TDEATH) #define TELEPORT_FLAGS_TELEPORTER (TELEPORT_FLAG_SOUND | TELEPORT_FLAG_PARTICLES | TELEPORT_FLAG_TDEATH) + +// types for .teleportable entity setting +#define TELEPORT_NORMAL 1 // play sounds/effects etc +#define TELEPORT_SIMPLE 2 // only do teleport, nothing special + void TeleportPlayer(entity teleporter, entity player, vector to, vector to_angles, vector to_velocity, vector telefragmin, vector telefragmax, float tflags) { entity telefragger; @@ -87,16 +92,19 @@ void TeleportPlayer(entity teleporter, entity player, vector to, vector to_angle makevectors (to_angles); - if(self.pushltime < time) // only show one teleport effect per teleporter per 0.2 seconds, for better fps + if(player.teleportable == TELEPORT_NORMAL) // don't play sounds or show particles for anything that isn't a player, maybe change later to block only observers { - if(tflags & TELEPORT_FLAG_SOUND) - sound (player, CH_TRIGGER, "misc/teleport.wav", VOL_BASE, ATTN_NORM); - if(tflags & TELEPORT_FLAG_PARTICLES) + if(self.pushltime < time) // only show one teleport effect per teleporter per 0.2 seconds, for better fps { - pointparticles(particleeffectnum("teleport"), player.origin, '0 0 0', 1); - pointparticles(particleeffectnum("teleport"), to + v_forward * 32, '0 0 0', 1); + if(tflags & TELEPORT_FLAG_SOUND) + sound (player, CH_TRIGGER, "misc/teleport.wav", VOL_BASE, ATTN_NORM); + if(tflags & TELEPORT_FLAG_PARTICLES) + { + pointparticles(particleeffectnum("teleport"), player.origin, '0 0 0', 1); + pointparticles(particleeffectnum("teleport"), to + v_forward * 32, '0 0 0', 1); + } + self.pushltime = time + 0.2; } - self.pushltime = time + 0.2; } // Relocate the player @@ -128,85 +136,96 @@ void TeleportPlayer(entity teleporter, entity player, vector to, vector to_angle { player.pusher = teleporter.owner; player.pushltime = time + autocvar_g_maxpushtime; + player.istypefrag = player.BUTTON_CHAT; } else { player.pushltime = 0; + player.istypefrag = 0; } player.lastteleporttime = time; } } -void Teleport_Touch (void) +entity Simple_TeleportPlayer(entity teleporter, entity player) { - entity oldself, e; - vector o; + vector locout; + entity e; float p; - string s; - - if (self.active != ACTIVE_ACTIVE) - return; - if not(other.iscreature) - return; - - // for gameplay: vehicles can't teleport - if (other.vehicle_flags & VHF_ISVEHICLE) - return; - - if (other.deadflag != DEAD_NO) - return; - - if(self.team) - if((self.spawnflags & 4 == 0) == (self.team != other.team)) - return; - - EXACTTRIGGER_TOUCH; - - makevectors(self.enemy.mangle); - - if(other.classname == "player") - RemoveGrapplingHook(other); - - if(self.enemy) + // Find the output teleporter + if(teleporter.enemy) { - e = self.enemy; + e = teleporter.enemy; } else - { + { RandomSelection_Init(); - for(e = world; (e = find(e, targetname, self.target)); ) + for(e = world; (e = find(e, targetname, teleporter.target)); ) { p = 1; if(autocvar_g_telefrags_avoid) { - o = e.origin + '0 0 1' * (1 - other.mins_z - 24); - if(check_tdeath(other, o, '0 0 0', '0 0 0')) + locout = e.origin + '0 0 1' * (1 - player.mins_z - 24); + if(check_tdeath(player, locout, '0 0 0', '0 0 0')) p = 0; } - if(e.cnt) - RandomSelection_Add(e, 0, string_null, e.cnt, p); - else - RandomSelection_Add(e, 0, string_null, 1, p); + RandomSelection_Add(e, 0, string_null, (e.cnt ? e.cnt : 1), p); } e = RandomSelection_chosen_ent; } - if(!e) - { - sprint(other, "Teleport destination vanished. Sorry... please complain to the mapper.\n"); - } + if(!e) { sprint(player, "Teleport destination vanished. Sorry... please complain to the mapper.\n"); } + + makevectors(e.mangle); if(e.speed) - if(vlen(other.velocity) > e.speed) - other.velocity = normalize(other.velocity) * max(0, e.speed); + if(vlen(player.velocity) > e.speed) + player.velocity = normalize(player.velocity) * max(0, e.speed); + if(autocvar_g_teleport_maxspeed) - if(vlen(other.velocity) > autocvar_g_teleport_maxspeed) - other.velocity = normalize(other.velocity) * max(0, autocvar_g_teleport_maxspeed); + if(vlen(player.velocity) > autocvar_g_teleport_maxspeed) + player.velocity = normalize(player.velocity) * max(0, autocvar_g_teleport_maxspeed); - o = e.origin + '0 0 1' * (1 - other.mins_z - 24); - TeleportPlayer(self, other, o, e.mangle, v_forward * vlen(other.velocity), '0 0 0', '0 0 0', TELEPORT_FLAGS_TELEPORTER); + locout = e.origin + '0 0 1' * (1 - player.mins_z - 24); + TeleportPlayer(teleporter, player, locout, e.mangle, v_forward * vlen(player.velocity), '0 0 0', '0 0 0', TELEPORT_FLAGS_TELEPORTER); + + return e; +} + +void Teleport_Touch (void) +{ + entity oldself; + string s; + + if (self.active != ACTIVE_ACTIVE) + return; + + if not(other.teleportable) + return; + + if(other.vehicle) + if(!other.vehicle.teleportable) + return; + + if(other.turrcaps_flags & TFL_TURRCAPS_ISTURRET) + return; + + if(other.deadflag != DEAD_NO) + return; + + if(self.team) + if((self.spawnflags & 4 == 0) == (self.team != other.team)) + return; + + EXACTTRIGGER_TOUCH; + + if(other.classname == "player") + RemoveGrapplingHook(other); + + entity e; + e = Simple_TeleportPlayer(self, other); activator = other; s = self.target; self.target = string_null; @@ -282,6 +301,17 @@ void teleport_findtarget (void) self.touch = Teleport_Touch; } +entity Teleport_Find(vector mi, vector ma) +{ + entity e; + for(e = world; (e = find(e, classname, "trigger_teleport")); ) + if(WarpZoneLib_BoxTouchesBrush(mi, ma, e, world)) + return e; + return world; +} + +entity teleport_first; +.entity teleport_next; void spawnfunc_trigger_teleport (void) { self.angles = '0 0 0'; @@ -295,19 +325,27 @@ void spawnfunc_trigger_teleport (void) // this must be called to spawn the teleport waypoints for bots InitializeEntity(self, teleport_findtarget, INITPRIO_FINDTARGET); - if (!self.target) + if (self.target == "") { objerror ("Teleporter with no target"); return; } + + self.teleport_next = teleport_first; + teleport_first = self; } void WarpZone_PostTeleportPlayer_Callback(entity pl) { UpdateCSQCProjectileAfterTeleport(pl); // "disown" projectiles after teleport + if(pl.owner) if(pl.owner == pl.realowner) + { + if(!(pl.flags & FL_PROJECTILE)) + print("A non-projectile got through a warpzone and its owner cleared. It's a ", pl.classname, ".\n"); pl.owner = world; + } if(pl.classname == "player") { // reset tracking of oldvelocity for impact damage (sudden velocity changes)