X-Git-Url: http://git.xonotic.org/?a=blobdiff_plain;f=qcsrc%2Fserver%2Ft_teleporters.qc;h=2932ad68b143bed0b8d8cf342717592bc48eaa49;hb=845401fd312c66c059aaee1772ac5d79555ab4fc;hp=1705d8f8ea705edc6f71d4c5490bb32cd5d40c76;hpb=616650bb18362024afeed71fed91d33dc1708d09;p=xonotic%2Fxonotic-data.pk3dir.git diff --git a/qcsrc/server/t_teleporters.qc b/qcsrc/server/t_teleporters.qc index 1705d8f8e..af72d135a 100644 --- a/qcsrc/server/t_teleporters.qc +++ b/qcsrc/server/t_teleporters.qc @@ -13,28 +13,28 @@ void trigger_teleport_use() deathmax = (o) + player.maxs; \ if(telefragmin != telefragmax) \ { \ - if(deathmin_x > telefragmin_x) deathmin_x = telefragmin_x; \ - if(deathmin_y > telefragmin_y) deathmin_y = telefragmin_y; \ - if(deathmin_z > telefragmin_z) deathmin_z = telefragmin_z; \ - if(deathmax_x < telefragmax_x) deathmax_x = telefragmax_x; \ - if(deathmax_y < telefragmax_y) deathmax_y = telefragmax_y; \ - if(deathmax_z < telefragmax_z) deathmax_z = telefragmax_z; \ + if(deathmin.x > telefragmin.x) deathmin_x = telefragmin.x; \ + if(deathmin.y > telefragmin.y) deathmin_y = telefragmin.y; \ + if(deathmin.z > telefragmin.z) deathmin_z = telefragmin.z; \ + if(deathmax.x < telefragmax.x) deathmax_x = telefragmax.x; \ + if(deathmax.y < telefragmax.y) deathmax_y = telefragmax.y; \ + if(deathmax.z < telefragmax.z) deathmax_z = telefragmax.z; \ } \ deathradius = max(vlen(deathmin), vlen(deathmax)); \ for(head = findradius(o, deathradius); head; head = head.chain) \ if(head != player) \ if(head.takedamage) \ if(boxesoverlap(deathmin, deathmax, head.absmin, head.absmax)) - + float check_tdeath(entity player, vector org, vector telefragmin, vector telefragmax) { - if (player.classname == "player" && player.health >= 1) + if (IS_PLAYER(player) && player.health >= 1) { TDEATHLOOP(org) { - if not(teamplay && autocvar_g_telefrags_teamplay && head.team == player.team) - if(head.classname == "player") + if (!(teamplay && autocvar_g_telefrags_teamplay && head.team == player.team)) + if(IS_PLAYER(head)) if(head.health >= 1) return 1; } @@ -46,11 +46,11 @@ void tdeath(entity player, entity teleporter, entity telefragger, vector telefra { TDEATHLOOP(player.origin) { - if (player.classname == "player" && player.health >= 1) + if (IS_PLAYER(player) && player.health >= 1) { - if not(teamplay && autocvar_g_telefrags_teamplay && head.team == player.team) + if (!(teamplay && autocvar_g_telefrags_teamplay && head.team == player.team)) { - if(head.classname == "player") + if(IS_PLAYER(head)) if(head.health >= 1) ++tdeath_hit; Damage (head, teleporter, telefragger, 10000, DEATH_TELEFRAG, head.origin, '0 0 0'); @@ -67,14 +67,20 @@ void spawn_tdeath(vector v0, entity e, vector v) } .entity pusher; -#define TELEPORT_FLAG_SOUND 1 -#define TELEPORT_FLAG_PARTICLES 2 -#define TELEPORT_FLAG_TDEATH 4 -#define TELEPORT_FLAG_FORCE_TDEATH 8 +const float TELEPORT_FLAG_SOUND = 1; +const float TELEPORT_FLAG_PARTICLES = 2; +const float TELEPORT_FLAG_TDEATH = 4; +const float TELEPORT_FLAG_FORCE_TDEATH = 8; #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 +const float TELEPORT_NORMAL = 1; // play sounds/effects etc +const float TELEPORT_SIMPLE = 2; // only do teleport, nothing special + +void Reset_ArcBeam(entity player, vector forward); void TeleportPlayer(entity teleporter, entity player, vector to, vector to_angles, vector to_velocity, vector telefragmin, vector telefragmax, float tflags) { entity telefragger; @@ -87,12 +93,12 @@ void TeleportPlayer(entity teleporter, entity player, vector to, vector to_angle makevectors (to_angles); - if(player.classname == "player") // don't play sounds or show particles for anything that isn't a player, maybe change later to block only observers + 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(self.pushltime < time) // only show one teleport effect per teleporter per 0.2 seconds, for better fps { if(tflags & TELEPORT_FLAG_SOUND) - sound (player, CH_TRIGGER, "misc/teleport.wav", VOL_BASE, ATTN_NORM); + sound (player, CH_TRIGGER, "misc/teleport.wav", VOL_BASE, ATTEN_NORM); if(tflags & TELEPORT_FLAG_PARTICLES) { pointparticles(particleeffectnum("teleport"), player.origin, '0 0 0', 1); @@ -108,20 +114,22 @@ void TeleportPlayer(entity teleporter, entity player, vector to, vector to_angle setorigin (player, to); player.oldorigin = to; // don't undo the teleport by unsticking player.angles = to_angles; - player.fixangle = TRUE; + player.fixangle = true; player.velocity = to_velocity; BITXOR_ASSIGN(player.effects, EF_TELEPORT_BIT); + makevectors(player.angles); + Reset_ArcBeam(player, v_forward); UpdateCSQCProjectileAfterTeleport(player); - if(player.classname == "player") + if(IS_PLAYER(player)) { if(tflags & TELEPORT_FLAG_TDEATH) if(player.takedamage && player.deadflag == DEAD_NO && !g_race && !g_cts && (autocvar_g_telefrags || (tflags & TELEPORT_FLAG_FORCE_TDEATH))) tdeath(player, teleporter, telefragger, telefragmin, telefragmax); // player no longer is on ground - player.flags &~= FL_ONGROUND; + player.flags &= ~FL_ONGROUND; // reset tracking of oldvelocity for impact damage (sudden velocity changes) player.oldvelocity = player.velocity; @@ -131,10 +139,12 @@ 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; @@ -146,21 +156,21 @@ entity Simple_TeleportPlayer(entity teleporter, entity player) vector locout; entity e; float p; - + // Find the output teleporter if(teleporter.enemy) { e = teleporter.enemy; } else - { + { RandomSelection_Init(); for(e = world; (e = find(e, targetname, teleporter.target)); ) { p = 1; if(autocvar_g_telefrags_avoid) { - locout = e.origin + '0 0 1' * (1 - player.mins_z - 24); + locout = e.origin + '0 0 1' * (1 - player.mins.z - 24); if(check_tdeath(player, locout, '0 0 0', '0 0 0')) p = 0; } @@ -170,18 +180,18 @@ entity Simple_TeleportPlayer(entity teleporter, entity player) } if(!e) { sprint(player, "Teleport destination vanished. Sorry... please complain to the mapper.\n"); } - + makevectors(e.mangle); if(e.speed) if(vlen(player.velocity) > e.speed) player.velocity = normalize(player.velocity) * max(0, e.speed); - + if(autocvar_g_teleport_maxspeed) if(vlen(player.velocity) > autocvar_g_teleport_maxspeed) player.velocity = normalize(player.velocity) * max(0, autocvar_g_teleport_maxspeed); - locout = e.origin + '0 0 1' * (1 - player.mins_z - 24); + 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; @@ -194,39 +204,36 @@ void Teleport_Touch (void) if (self.active != ACTIVE_ACTIVE) return; - - if not(other.iscreature) + + if (!other.teleportable) return; - // for gameplay: vehicles can't teleport - if (other.vehicle_flags & VHF_ISVEHICLE) + if(other.vehicle) + if(!other.vehicle.teleportable) return; - - if(other.vehicle) - return; - - if(other.turrcaps_flags & TFL_TURRCAPS_ISTURRET) - return; - - if (other.deadflag != DEAD_NO) + + 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)) + if(((self.spawnflags & 4) == 0) == (self.team != other.team)) return; EXACTTRIGGER_TOUCH; - if(other.classname == "player") + if(IS_PLAYER(other)) RemoveGrapplingHook(other); - + entity e; e = Simple_TeleportPlayer(self, other); activator = other; s = self.target; self.target = string_null; SUB_UseTargets(); - if not(self.target) self.target = s; + if (!self.target) self.target = s; oldself = self; self = e; @@ -306,34 +313,42 @@ entity Teleport_Find(vector mi, vector ma) return world; } -entity teleport_first; +entity teleport_first; .entity teleport_next; void spawnfunc_trigger_teleport (void) { self.angles = '0 0 0'; EXACTTRIGGER_INIT; - - self.active = ACTIVE_ACTIVE; - + + self.active = ACTIVE_ACTIVE; + self.use = trigger_teleport_use; // 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) { + makevectors(pl.angles); + Reset_ArcBeam(pl, v_forward); UpdateCSQCProjectileAfterTeleport(pl); + { + entity oldself = self; + self = pl; + anticheat_fixangle(); + self = oldself; + } // "disown" projectiles after teleport if(pl.owner) if(pl.owner == pl.realowner) @@ -342,7 +357,7 @@ void WarpZone_PostTeleportPlayer_Callback(entity pl) 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") + if(IS_PLAYER(pl)) { // reset tracking of oldvelocity for impact damage (sudden velocity changes) pl.oldvelocity = pl.velocity;