X-Git-Url: http://de.git.xonotic.org/?p=xonotic%2Fxonotic-data.pk3dir.git;a=blobdiff_plain;f=qcsrc%2Flib%2Fwarpzone%2Fserver.qc;h=f1bd0e524e5bbd3c6cebaa2784c0c226579fa765;hp=0cd85cba62241a7080ce2fa54786c272c2444894;hb=87cbf00c7734cf2910502c217b5c5157511ba5ea;hpb=1e31381058a302273d1a3f907f1dd72885845b27 diff --git a/qcsrc/lib/warpzone/server.qc b/qcsrc/lib/warpzone/server.qc index 0cd85cba6..f1bd0e524 100644 --- a/qcsrc/lib/warpzone/server.qc +++ b/qcsrc/lib/warpzone/server.qc @@ -4,12 +4,12 @@ #if defined(CSQC) #elif defined(MENUQC) #elif defined(SVQC) - #include "../../common/constants.qh" - #include "../../common/triggers/subs.qh" - #include "../../common/util.qh" - #include "../../server/command/common.qh" - #include "../../server/constants.qh" - #include "../../server/defs.qh" + #include + #include + #include + #include + #include + #include #endif #ifdef WARPZONELIB_KEEPDEBUG @@ -28,19 +28,21 @@ .float warpzone_teleport_finishtime; .entity warpzone_teleport_zone; -void WarpZone_StoreProjectileData(entity e) -{ - e.warpzone_oldorigin = e.origin; - e.warpzone_oldvelocity = e.velocity; - e.warpzone_oldangles = e.angles; -} +#define WarpZone_StoreProjectileData(e_) MACRO_BEGIN { \ + entity e = e_; \ + e.warpzone_oldorigin = e.origin; \ + e.warpzone_oldvelocity = e.velocity; \ + e.warpzone_oldangles = e.angles; \ + } MACRO_END void WarpZone_TeleportPlayer(entity teleporter, entity player, vector to, vector to_angles, vector to_velocity) { - setorigin (player, to); // NOTE: this also aborts the move, when this is called by touch + setorigin(player, to); // NOTE: this also aborts the move, when this is called by touch +#ifdef SVQC player.oldorigin = to; // for DP's unsticking - player.angles = to_angles; player.fixangle = true; +#endif + player.angles = to_angles; player.velocity = to_velocity; BITXOR_ASSIGN(player.effects, EF_TELEPORT_BIT); @@ -51,14 +53,16 @@ void WarpZone_TeleportPlayer(entity teleporter, entity player, vector to, vector WarpZone_PostTeleportPlayer_Callback(player); } -bool WarpZone_Teleported_Send(entity to, int sf) -{SELFPARAM(); +#ifdef SVQC +bool WarpZone_Teleported_Send(entity this, entity to, int sf) +{ WriteHeader(MSG_ENTITY, ENT_CLIENT_WARPZONE_TELEPORTED); - WriteCoord(MSG_ENTITY, self.angles.x); - WriteCoord(MSG_ENTITY, self.angles.y); - WriteCoord(MSG_ENTITY, self.angles.z); + WriteCoord(MSG_ENTITY, this.angles.x); + WriteCoord(MSG_ENTITY, this.angles.y); + WriteCoord(MSG_ENTITY, this.angles.z); return true; } +#endif float WarpZone_Teleport(entity wz, entity player, float f0, float f1) { @@ -71,7 +75,7 @@ float WarpZone_Teleport(entity wz, entity player, float f0, float f1) o10 = o1 = WarpZone_TransformOrigin(wz, o0); v1 = WarpZone_TransformVelocity(wz, v0); if (!IS_NOT_A_CLIENT(player)) - a1 = WarpZone_TransformVAngles(wz, player.v_angle); + a1 = WarpZone_TransformVAngles(wz, PHYS_INPUT_ANGLES(player)); else a1 = WarpZone_TransformAngles(wz, a0); @@ -84,7 +88,7 @@ float WarpZone_Teleport(entity wz, entity player, float f0, float f1) { entity own; own = player.owner; - player.owner = world; + player.owner = NULL; tracebox(trace_endpos, player.mins, player.maxs, o1 - player.view_ofs + v1 * frametime * f1, MOVE_NORMAL, player); // this should get us through the warpzone player.owner = own; } @@ -124,12 +128,15 @@ float WarpZone_Teleport(entity wz, entity player, float f0, float f1) player.warpzone_teleport_finishtime = time; player.warpzone_teleport_zone = wz; +#ifdef SVQC // prevent further teleports back float dt = (o1 - o10) * v1 * (1 / (v1 * v1)); - if(dt < sys_frametime) - player.warpzone_teleport_finishtime += sys_frametime - dt; + if(dt < PHYS_INPUT_FRAMETIME) + player.warpzone_teleport_finishtime += PHYS_INPUT_FRAMETIME - dt; +#endif #ifndef WARPZONE_USE_FIXANGLE + #ifdef SVQC if(IS_VEHICLE(player) && player.owner) player = player.owner; // hax if(IS_PLAYER(player)) @@ -139,37 +146,46 @@ float WarpZone_Teleport(entity wz, entity player, float f0, float f1) entity ts = new(warpzone_teleported); setmodel(ts, MDL_Null); - ts.SendEntity = WarpZone_Teleported_Send; + setSendEntity(ts, WarpZone_Teleported_Send); ts.SendFlags = 0xFFFFFF; ts.drawonlytoclient = player; - ts.think = SUB_Remove_self; + setthink(ts, SUB_Remove); ts.nextthink = time + 1; ts.owner = player; ts.enemy = wz; ts.effects = EF_NODEPTHTEST; ts.angles = wz.warpzone_transform; } + #elif defined(CSQC) + setproperty(VF_CL_VIEWANGLES, WarpZone_TransformVAngles(wz, getpropertyvec(VF_CL_VIEWANGLES))); + //if(checkextension("DP_CSQC_ROTATEMOVES")) + //CL_RotateMoves(wz.warpzone_transform); + #endif #endif return 1; } -void WarpZone_Touch () -{SELFPARAM(); - if(other.classname == "trigger_warpzone") +void WarpZone_Touch(entity this, entity toucher) +{ + if(toucher.classname == "trigger_warpzone") return; - if(time <= other.warpzone_teleport_finishtime) // already teleported this frame + if(time <= toucher.warpzone_teleport_finishtime) // already teleported this frame return; // FIXME needs a better check to know what is safe to teleport and what not - if(other.movetype == MOVETYPE_NONE || other.movetype == MOVETYPE_FOLLOW || other.tag_entity) + if((toucher.move_movetype == MOVETYPE_NONE && toucher.move_movetype == MOVETYPE_NONE) || toucher.move_movetype == MOVETYPE_FOLLOW || toucher.move_movetype == MOVETYPE_FOLLOW || toucher.tag_entity +#ifdef CSQC + || tag_networkentity +#endif + ) return; - if(WarpZoneLib_ExactTrigger_Touch()) + if(WarpZoneLib_ExactTrigger_Touch(this, toucher)) return; - if(WarpZone_PlaneDist(self, other.origin + other.view_ofs) >= 0) // wrong side of the trigger_warpzone (don't teleport yet) + if(WarpZone_PlaneDist(this, toucher.origin + toucher.view_ofs) >= 0) // wrong side of the trigger_warpzone (don't teleport yet) return; float f; @@ -184,29 +200,28 @@ void WarpZone_Touch () // 24/(0.25/frametime) // 96*frametime float d; - d = 24 + max(vlen(other.mins), vlen(other.maxs)); - if(IS_NOT_A_CLIENT(other)) - f = -d / bound(frametime * d * 1, frametime * vlen(other.velocity), d); + d = 24 + max(vlen(toucher.mins), vlen(toucher.maxs)); + if(IS_NOT_A_CLIENT(toucher)) + f = -d / bound(frametime * d * 1, frametime * vlen(toucher.velocity), d); else f = -1; - if(WarpZone_Teleport(self, other, f, 0)) + if(WarpZone_Teleport(this, toucher, f, 0)) { +#ifdef SVQC string save1, save2; - activator = other; - - save1 = self.target; self.target = string_null; - save2 = self.target3; self.target3 = string_null; - SUB_UseTargets(); - if (!self.target) self.target = save1; - if (!self.target3) self.target3 = save2; - - setself(self.enemy); - save1 = self.target; self.target = string_null; - save2 = self.target2; self.target2 = string_null; - SUB_UseTargets(); - if (!self.target) self.target = save1; - if (!self.target2) self.target2 = save2; - setself(this); + + save1 = this.target; this.target = string_null; + save2 = this.target3; this.target3 = string_null; + SUB_UseTargets(this, toucher, toucher); // use toucher too? + if (!this.target) this.target = save1; + if (!this.target3) this.target3 = save2; + + save1 = this.target; this.target = string_null; + save2 = this.target2; this.target2 = string_null; + SUB_UseTargets(this.enemy, toucher, toucher); // use toucher too? + if (!this.target) this.target = save1; + if (!this.target2) this.target2 = save2; +#endif } else { @@ -214,100 +229,101 @@ void WarpZone_Touch () } } -bool WarpZone_Send(entity to, int sendflags) -{SELFPARAM(); +#ifdef SVQC +bool WarpZone_Send(entity this, entity to, int sendflags) +{ WriteHeader(MSG_ENTITY, ENT_CLIENT_WARPZONE); // we must send this flag for clientside to match properly too int f = 0; - if(self.warpzone_isboxy) + if(this.warpzone_isboxy) BITSET_ASSIGN(f, 1); - if(self.warpzone_fadestart) + if(this.warpzone_fadestart) BITSET_ASSIGN(f, 2); - if(self.origin != '0 0 0') + if(this.origin != '0 0 0') BITSET_ASSIGN(f, 4); WriteByte(MSG_ENTITY, f); // we need THESE to render the warpzone (and cull properly)... if(f & 4) { - WriteCoord(MSG_ENTITY, self.origin.x); - WriteCoord(MSG_ENTITY, self.origin.y); - WriteCoord(MSG_ENTITY, self.origin.z); + WriteCoord(MSG_ENTITY, this.origin.x); + WriteCoord(MSG_ENTITY, this.origin.y); + WriteCoord(MSG_ENTITY, this.origin.z); } - WriteShort(MSG_ENTITY, self.modelindex); - WriteCoord(MSG_ENTITY, self.mins.x); - WriteCoord(MSG_ENTITY, self.mins.y); - WriteCoord(MSG_ENTITY, self.mins.z); - WriteCoord(MSG_ENTITY, self.maxs.x); - WriteCoord(MSG_ENTITY, self.maxs.y); - WriteCoord(MSG_ENTITY, self.maxs.z); - WriteByte(MSG_ENTITY, bound(1, self.scale * 16, 255)); + WriteShort(MSG_ENTITY, this.modelindex); + WriteCoord(MSG_ENTITY, this.mins.x); + WriteCoord(MSG_ENTITY, this.mins.y); + WriteCoord(MSG_ENTITY, this.mins.z); + WriteCoord(MSG_ENTITY, this.maxs.x); + WriteCoord(MSG_ENTITY, this.maxs.y); + WriteCoord(MSG_ENTITY, this.maxs.z); + WriteByte(MSG_ENTITY, bound(1, this.scale * 16, 255)); // we need THESE to calculate the proper transform - WriteCoord(MSG_ENTITY, self.warpzone_origin.x); - WriteCoord(MSG_ENTITY, self.warpzone_origin.y); - WriteCoord(MSG_ENTITY, self.warpzone_origin.z); - WriteCoord(MSG_ENTITY, self.warpzone_angles.x); - WriteCoord(MSG_ENTITY, self.warpzone_angles.y); - WriteCoord(MSG_ENTITY, self.warpzone_angles.z); - WriteCoord(MSG_ENTITY, self.warpzone_targetorigin.x); - WriteCoord(MSG_ENTITY, self.warpzone_targetorigin.y); - WriteCoord(MSG_ENTITY, self.warpzone_targetorigin.z); - WriteCoord(MSG_ENTITY, self.warpzone_targetangles.x); - WriteCoord(MSG_ENTITY, self.warpzone_targetangles.y); - WriteCoord(MSG_ENTITY, self.warpzone_targetangles.z); + WriteCoord(MSG_ENTITY, this.warpzone_origin.x); + WriteCoord(MSG_ENTITY, this.warpzone_origin.y); + WriteCoord(MSG_ENTITY, this.warpzone_origin.z); + WriteCoord(MSG_ENTITY, this.warpzone_angles.x); + WriteCoord(MSG_ENTITY, this.warpzone_angles.y); + WriteCoord(MSG_ENTITY, this.warpzone_angles.z); + WriteCoord(MSG_ENTITY, this.warpzone_targetorigin.x); + WriteCoord(MSG_ENTITY, this.warpzone_targetorigin.y); + WriteCoord(MSG_ENTITY, this.warpzone_targetorigin.z); + WriteCoord(MSG_ENTITY, this.warpzone_targetangles.x); + WriteCoord(MSG_ENTITY, this.warpzone_targetangles.y); + WriteCoord(MSG_ENTITY, this.warpzone_targetangles.z); if(f & 2) { - WriteShort(MSG_ENTITY, self.warpzone_fadestart); - WriteShort(MSG_ENTITY, self.warpzone_fadeend); + WriteShort(MSG_ENTITY, this.warpzone_fadestart); + WriteShort(MSG_ENTITY, this.warpzone_fadeend); } return true; } -bool WarpZone_Camera_Send(entity to, int sendflags) -{SELFPARAM(); +bool WarpZone_Camera_Send(entity this, entity to, int sendflags) +{ int f = 0; WriteHeader(MSG_ENTITY, ENT_CLIENT_WARPZONE_CAMERA); - if(self.warpzone_fadestart) + if(this.warpzone_fadestart) BITSET_ASSIGN(f, 2); - if(self.origin != '0 0 0') + if(this.origin != '0 0 0') BITSET_ASSIGN(f, 4); WriteByte(MSG_ENTITY, f); // we need THESE to render the warpzone (and cull properly)... if(f & 4) { - WriteCoord(MSG_ENTITY, self.origin.x); - WriteCoord(MSG_ENTITY, self.origin.y); - WriteCoord(MSG_ENTITY, self.origin.z); + WriteCoord(MSG_ENTITY, this.origin.x); + WriteCoord(MSG_ENTITY, this.origin.y); + WriteCoord(MSG_ENTITY, this.origin.z); } - WriteShort(MSG_ENTITY, self.modelindex); - WriteCoord(MSG_ENTITY, self.mins.x); - WriteCoord(MSG_ENTITY, self.mins.y); - WriteCoord(MSG_ENTITY, self.mins.z); - WriteCoord(MSG_ENTITY, self.maxs.x); - WriteCoord(MSG_ENTITY, self.maxs.y); - WriteCoord(MSG_ENTITY, self.maxs.z); - WriteByte(MSG_ENTITY, bound(1, self.scale * 16, 255)); + WriteShort(MSG_ENTITY, this.modelindex); + WriteCoord(MSG_ENTITY, this.mins.x); + WriteCoord(MSG_ENTITY, this.mins.y); + WriteCoord(MSG_ENTITY, this.mins.z); + WriteCoord(MSG_ENTITY, this.maxs.x); + WriteCoord(MSG_ENTITY, this.maxs.y); + WriteCoord(MSG_ENTITY, this.maxs.z); + WriteByte(MSG_ENTITY, bound(1, this.scale * 16, 255)); // we need THESE to calculate the proper transform - WriteCoord(MSG_ENTITY, self.enemy.origin.x); - WriteCoord(MSG_ENTITY, self.enemy.origin.y); - WriteCoord(MSG_ENTITY, self.enemy.origin.z); - WriteCoord(MSG_ENTITY, self.enemy.angles.x); - WriteCoord(MSG_ENTITY, self.enemy.angles.y); - WriteCoord(MSG_ENTITY, self.enemy.angles.z); + WriteCoord(MSG_ENTITY, this.enemy.origin.x); + WriteCoord(MSG_ENTITY, this.enemy.origin.y); + WriteCoord(MSG_ENTITY, this.enemy.origin.z); + WriteCoord(MSG_ENTITY, this.enemy.angles.x); + WriteCoord(MSG_ENTITY, this.enemy.angles.y); + WriteCoord(MSG_ENTITY, this.enemy.angles.z); if(f & 2) { - WriteShort(MSG_ENTITY, self.warpzone_fadestart); - WriteShort(MSG_ENTITY, self.warpzone_fadeend); + WriteShort(MSG_ENTITY, this.warpzone_fadestart); + WriteShort(MSG_ENTITY, this.warpzone_fadeend); } return true; @@ -315,7 +331,7 @@ bool WarpZone_Camera_Send(entity to, int sendflags) #ifdef WARPZONELIB_KEEPDEBUG float WarpZone_CheckProjectileImpact(entity player) -{SELFPARAM(); +{ vector o0, v0; o0 = player.origin + player.view_ofs; @@ -348,27 +364,19 @@ float WarpZone_CheckProjectileImpact(entity player) player.velocity = player.warpzone_oldvelocity; if(WarpZone_Teleport(wz, player, 0, 1)) { - entity oldself; string save1, save2; - oldself = self; - self = wz; - other = player; - activator = player; - - save1 = self.target; self.target = string_null; - save2 = self.target3; self.target3 = string_null; - SUB_UseTargets(); - if (!self.target) self.target = save1; - if (!self.target3) self.target3 = save2; - - self = self.enemy; - save1 = self.target; self.target = string_null; - save2 = self.target2; self.target2 = string_null; - SUB_UseTargets(); - if (!self.target) self.target = save1; - if (!self.target2) self.target2 = save2; - self = oldself; + save1 = wz.target; wz.target = string_null; + save2 = wz.target3; wz.target3 = string_null; + SUB_UseTargets(wz, player, player); + if (!wz.target) wz.target = save1; + if (!wz.target3) wz.target3 = save2; + + save1 = wz.enemy.target; wz.enemy.target = string_null; + save2 = wz.enemy.target2; wz.enemy.target2 = string_null; + SUB_UseTargets(wz.enemy, player, player); + if (!wz.enemy.target) wz.enemy.target = save1; + if (!wz.enemy.target2) wz.enemy.target2 = save2; } else { @@ -380,10 +388,11 @@ float WarpZone_CheckProjectileImpact(entity player) #endif } #endif +#endif -float WarpZone_Projectile_Touch() -{SELFPARAM(); - if(other.classname == "trigger_warpzone") +float WarpZone_Projectile_Touch(entity this, entity toucher) +{ + if(toucher.classname == "trigger_warpzone") return true; // no further impacts if we teleported this frame! @@ -392,9 +401,10 @@ float WarpZone_Projectile_Touch() // engine now aborts moves on teleport, so this SHOULD not happen any more // but if this is called from TouchAreaGrid of the projectile moving, // then this won't do - if(time == self.warpzone_teleport_time) + if(time == this.warpzone_teleport_time) return true; +#ifdef SVQC #ifdef WARPZONELIB_KEEPDEBUG // this SEEMS to not happen at the moment, but if it did, it would be more reliable { @@ -424,9 +434,8 @@ float WarpZone_Projectile_Touch() save_ent = trace_ent; save_inopen = trace_inopen; save_inwater = trace_inwater; - float f; - if((f = WarpZone_CheckProjectileImpact(self)) != 0) - return (f > 0); + float f = WarpZone_CheckProjectileImpact(this); + if (f) return (f > 0); trace_dpstartcontents = save_dpstartcontents; trace_dphitcontents = save_dphitcontents; trace_dphitq3surfaceflags = save_dphitq3surfaceflags; @@ -443,122 +452,125 @@ float WarpZone_Projectile_Touch() } #endif - if(WarpZone_Projectile_Touch_ImpactFilter_Callback()) + if(WarpZone_Projectile_Touch_ImpactFilter_Callback(this, toucher)) return true; +#endif return false; } -void WarpZone_InitStep_FindOriginTarget() -{SELFPARAM(); - if(self.killtarget != "") +#ifdef SVQC + +void WarpZone_InitStep_FindOriginTarget(entity this) +{ + if(this.killtarget != "") { - self.aiment = find(world, targetname, self.killtarget); - if(self.aiment == world) + this.aiment = find(NULL, targetname, this.killtarget); + if(this.aiment == NULL) { error("Warp zone with nonexisting killtarget"); return; } - self.killtarget = string_null; + this.killtarget = string_null; } } -void WarpZonePosition_InitStep_FindTarget() -{SELFPARAM(); - if(self.target == "") +void WarpZonePosition_InitStep_FindTarget(entity this) +{ + if(this.target == "") { error("Warp zone position with no target"); return; } - self.enemy = find(world, targetname, self.target); - if(self.enemy == world) + this.enemy = find(NULL, targetname, this.target); + if(this.enemy == NULL) { error("Warp zone position with nonexisting target"); return; } - if(self.enemy.aiment) + if(this.enemy.aiment) { // already is positioned error("Warp zone position targeting already oriented warpzone"); return; } - self.enemy.aiment = self; + this.enemy.aiment = this; } -void WarpZoneCamera_Think() -{SELFPARAM(); - if(self.warpzone_save_origin != self.origin - || self.warpzone_save_angles != self.angles - || self.warpzone_save_eorigin != self.enemy.origin - || self.warpzone_save_eangles != self.enemy.angles) +void WarpZoneCamera_Think(entity this) +{ + if(this.warpzone_save_origin != this.origin + || this.warpzone_save_angles != this.angles + || this.warpzone_save_eorigin != this.enemy.origin + || this.warpzone_save_eangles != this.enemy.angles) { - WarpZone_Camera_SetUp(self, self.enemy.origin, self.enemy.angles); - self.warpzone_save_origin = self.origin; - self.warpzone_save_angles = self.angles; - self.warpzone_save_eorigin = self.enemy.origin; - self.warpzone_save_eangles = self.enemy.angles; + WarpZone_Camera_SetUp(this, this.enemy.origin, this.enemy.angles); + this.warpzone_save_origin = this.origin; + this.warpzone_save_angles = this.angles; + this.warpzone_save_eorigin = this.enemy.origin; + this.warpzone_save_eangles = this.enemy.angles; } - self.nextthink = time; + this.nextthink = time; } -void WarpZoneCamera_InitStep_FindTarget() -{SELFPARAM(); +void WarpZoneCamera_InitStep_FindTarget(entity this) +{ entity e; float i; - if(self.target == "") + if(this.target == "") { error("Camera with no target"); return; } - self.enemy = world; - for(e = world, i = 0; (e = find(e, targetname, self.target)); ) + this.enemy = NULL; + for(e = NULL, i = 0; (e = find(e, targetname, this.target)); ) if(random() * ++i < 1) - self.enemy = e; - if(self.enemy == world) + this.enemy = e; + if(this.enemy == NULL) { error("Camera with nonexisting target"); return; } warpzone_cameras_exist = 1; - WarpZone_Camera_SetUp(self, self.enemy.origin, self.enemy.angles); - self.SendFlags = 0xFFFFFF; - if(self.spawnflags & 1) + WarpZone_Camera_SetUp(this, this.enemy.origin, this.enemy.angles); + this.SendFlags = 0xFFFFFF; + if(this.spawnflags & 1) { - self.think = WarpZoneCamera_Think; - self.nextthink = time; + setthink(this, WarpZoneCamera_Think); + this.nextthink = time; } else - self.nextthink = 0; + this.nextthink = 0; } -void WarpZone_InitStep_UpdateTransform() -{SELFPARAM(); +void WarpZone_InitStep_UpdateTransform(entity this) +{ vector org, ang, norm, point; float area; vector tri, a, b, c, n; float i_s, i_t, n_t; string tex; - org = self.origin; + org = this.origin; if(org == '0 0 0') - org = 0.5 * (self.mins + self.maxs); + org = 0.5 * (this.mins + this.maxs); norm = point = '0 0 0'; area = 0; for(i_s = 0; ; ++i_s) { - tex = getsurfacetexture(self, i_s); + tex = getsurfacetexture(this, i_s); if (!tex) break; // this is beyond the last one if(tex == "textures/common/trigger" || tex == "trigger") continue; - n_t = getsurfacenumtriangles(self, i_s); + n_t = getsurfacenumtriangles(this, i_s); for(i_t = 0; i_t < n_t; ++i_t) { - tri = getsurfacetriangle(self, i_s, i_t); - a = getsurfacepoint(self, i_s, tri.x); - b = getsurfacepoint(self, i_s, tri.y); - c = getsurfacepoint(self, i_s, tri.z); + tri = getsurfacetriangle(this, i_s, i_t); + a = getsurfacepoint(this, i_s, tri.x); + b = getsurfacepoint(this, i_s, tri.y); + c = getsurfacepoint(this, i_s, tri.z); n = cross(c - a, b - a); area = area + vlen(n); norm = norm + n; @@ -569,34 +581,34 @@ void WarpZone_InitStep_UpdateTransform() { norm = norm * (1 / area); point = point * (1 / (3 * area)); - if(vlen(norm) < 0.99) + if(vdist(norm, <, 0.99)) { - LOG_INFO("trigger_warpzone near ", vtos(self.aiment.origin), " is nonplanar. BEWARE.\n"); + LOG_INFO("trigger_warpzone near ", vtos(this.aiment.origin), " is nonplanar. BEWARE.\n"); area = 0; // no autofixing in this case } norm = normalize(norm); } ang = '0 0 0'; - if(self.aiment) + if(this.aiment) { - org = self.aiment.origin; - ang = self.aiment.angles; + org = this.aiment.origin; + ang = this.aiment.angles; if(area > 0) { org = org - ((org - point) * norm) * norm; // project to plane makevectors(ang); if(norm * v_forward < 0) { - LOG_INFO("Position target of trigger_warpzone near ", vtos(self.aiment.origin), " points into trigger_warpzone. BEWARE.\n"); + LOG_INFO("Position target of trigger_warpzone near ", vtos(this.aiment.origin), " points into trigger_warpzone. BEWARE.\n"); norm = -1 * norm; } ang = vectoangles2(norm, v_up); // keep rotation, but turn exactly against plane ang.x = -ang.x; if(norm * v_forward < 0.99) - LOG_INFO("trigger_warpzone near ", vtos(self.aiment.origin), " has been turned to match plane orientation (", vtos(self.aiment.angles), " -> ", vtos(ang), "\n"); - if(vlen(org - self.aiment.origin) > 0.5) - LOG_INFO("trigger_warpzone near ", vtos(self.aiment.origin), " has been moved to match the plane (", vtos(self.aiment.origin), " -> ", vtos(org), ").\n"); + LOG_INFO("trigger_warpzone near ", vtos(this.aiment.origin), " has been turned to match plane orientation (", vtos(this.aiment.angles), " -> ", vtos(ang), "\n"); + if(vdist(org - this.aiment.origin, >, 0.5)) + LOG_INFO("trigger_warpzone near ", vtos(this.aiment.origin), " has been moved to match the plane (", vtos(this.aiment.origin), " -> ", vtos(org), ").\n"); } } else if(area > 0) @@ -608,68 +620,68 @@ void WarpZone_InitStep_UpdateTransform() else error("cannot infer origin/angles for this warpzone, please use a killtarget or a trigger_warpzone_position"); - self.warpzone_origin = org; - self.warpzone_angles = ang; + this.warpzone_origin = org; + this.warpzone_angles = ang; } -void WarpZone_InitStep_ClearTarget() -{SELFPARAM(); - if(self.enemy) - self.enemy.enemy = world; - self.enemy = world; +void WarpZone_InitStep_ClearTarget(entity this) +{ + if(this.enemy) + this.enemy.enemy = NULL; + this.enemy = NULL; } entity warpzone_first; .entity warpzone_next; -void WarpZone_InitStep_FindTarget() -{SELFPARAM(); +void WarpZone_InitStep_FindTarget(entity this) +{ float i; entity e, e2; - if(self.enemy) + if(this.enemy) return; // this way only one of the two ents needs to target - if(self.target != "") + if(this.target != "") { - self.enemy = self; // so the if(!e.enemy) check also skips self, saves one IF + this.enemy = this; // so the if(!e.enemy) check also skips this, saves one IF - e2 = world; - for(e = world, i = 0; (e = find(e, targetname, self.target)); ) + e2 = NULL; + for(e = NULL, i = 0; (e = find(e, targetname, this.target)); ) if(!e.enemy) - if(e.classname == self.classname) // possibly non-warpzones may use the same targetname! + if(e.classname == this.classname) // possibly non-warpzones may use the same targetname! if(random() * ++i < 1) e2 = e; if(!e2) { - self.enemy = world; + this.enemy = NULL; error("Warpzone with non-existing target"); return; } - self.enemy = e2; - e2.enemy = self; + this.enemy = e2; + e2.enemy = this; } } -void WarpZone_Think(); -void WarpZone_InitStep_FinalizeTransform() -{SELFPARAM(); - if(!self.enemy || self.enemy.enemy != self) +void WarpZone_Think(entity this); +void WarpZone_InitStep_FinalizeTransform(entity this) +{ + if(!this.enemy || this.enemy.enemy != this) { error("Invalid warp zone detected. Killed."); return; } warpzone_warpzones_exist = 1; - WarpZone_SetUp(self, self.warpzone_origin, self.warpzone_angles, self.enemy.warpzone_origin, self.enemy.warpzone_angles); - self.touch = WarpZone_Touch; - self.SendFlags = 0xFFFFFF; - if(self.spawnflags & 1) + WarpZone_SetUp(this, this.warpzone_origin, this.warpzone_angles, this.enemy.warpzone_origin, this.enemy.warpzone_angles); + settouch(this, WarpZone_Touch); + this.SendFlags = 0xFFFFFF; + if(this.spawnflags & 1) { - self.think = WarpZone_Think; - self.nextthink = time; + setthink(this, WarpZone_Think); + this.nextthink = time; } else - self.nextthink = 0; + this.nextthink = 0; } float warpzone_initialized; @@ -680,8 +692,8 @@ entity warpzone_camera_first; spawnfunc(misc_warpzone_position) { // "target", "angles", "origin" - self.warpzone_next = warpzone_position_first; - warpzone_position_first = self; + this.warpzone_next = warpzone_position_first; + warpzone_position_first = this; } spawnfunc(trigger_warpzone_position) { @@ -697,186 +709,163 @@ spawnfunc(trigger_warpzone) // the map, with another killtarget to designate its // orientation - if(!self.scale) - self.scale = self.modelscale; - if(!self.scale) - self.scale = 1; + if(!this.scale) + this.scale = this.modelscale; + if(!this.scale) + this.scale = 1; string m; - m = self.model; - WarpZoneLib_ExactTrigger_Init(); + m = this.model; + WarpZoneLib_ExactTrigger_Init(this); if(m != "") { precache_model(m); - _setmodel(self, m); // no precision needed + _setmodel(this, m); // no precision needed } - setorigin(self, self.origin); - if(self.scale) - setsize(self, self.mins * self.scale, self.maxs * self.scale); + setorigin(this, this.origin); + if(this.scale) + setsize(this, this.mins * this.scale, this.maxs * this.scale); else - setsize(self, self.mins, self.maxs); - self.SendEntity = WarpZone_Send; - self.SendFlags = 0xFFFFFF; - BITSET_ASSIGN(self.effects, EF_NODEPTHTEST); - self.warpzone_next = warpzone_first; - warpzone_first = self; + setsize(this, this.mins, this.maxs); + setSendEntity(this, WarpZone_Send); + this.SendFlags = 0xFFFFFF; + BITSET_ASSIGN(this.effects, EF_NODEPTHTEST); + this.warpzone_next = warpzone_first; + warpzone_first = this; } spawnfunc(func_camera) { - if(!self.scale) - self.scale = self.modelscale; - if(!self.scale) - self.scale = 1; - if(self.model != "") + if(!this.scale) + this.scale = this.modelscale; + if(!this.scale) + this.scale = 1; + if(this.model != "") { - precache_model(self.model); - _setmodel(self, self.model); // no precision needed + precache_model(this.model); + _setmodel(this, this.model); // no precision needed } - setorigin(self, self.origin); - if(self.scale) - setsize(self, self.mins * self.scale, self.maxs * self.scale); + setorigin(this, this.origin); + if(this.scale) + setsize(this, this.mins * this.scale, this.maxs * this.scale); else - setsize(self, self.mins, self.maxs); - if(!self.solid) - self.solid = SOLID_BSP; - else if(self.solid < 0) - self.solid = SOLID_NOT; - self.SendEntity = WarpZone_Camera_Send; - self.SendFlags = 0xFFFFFF; - self.warpzone_next = warpzone_camera_first; - warpzone_camera_first = self; + setsize(this, this.mins, this.maxs); + if(!this.solid) + this.solid = SOLID_BSP; + else if(this.solid < 0) + this.solid = SOLID_NOT; + setSendEntity(this, WarpZone_Camera_Send); + this.SendFlags = 0xFFFFFF; + this.warpzone_next = warpzone_camera_first; + warpzone_camera_first = this; } void WarpZones_Reconnect() -{SELFPARAM(); - for(setself(warpzone_first); self; setself(self.warpzone_next)) - WarpZone_InitStep_ClearTarget(); - for(setself(warpzone_first); self; setself(self.warpzone_next)) - WarpZone_InitStep_FindTarget(); - for(setself(warpzone_camera_first); self; setself(self.warpzone_next)) - WarpZoneCamera_InitStep_FindTarget(); - for(setself(warpzone_first); self; setself(self.warpzone_next)) - WarpZone_InitStep_FinalizeTransform(); - setself(this); +{ + for(entity e = warpzone_first; e; e = e.warpzone_next) + WarpZone_InitStep_ClearTarget(e); + for(entity e = warpzone_first; e; e = e.warpzone_next) + WarpZone_InitStep_FindTarget(e); + for(entity e = warpzone_camera_first; e; e = e.warpzone_next) + WarpZoneCamera_InitStep_FindTarget(e); + for(entity e = warpzone_first; e; e = e.warpzone_next) + WarpZone_InitStep_FinalizeTransform(e); } -void WarpZone_Think() -{SELFPARAM(); - if(self.warpzone_save_origin != self.origin - || self.warpzone_save_angles != self.angles - || self.warpzone_save_eorigin != self.enemy.origin - || self.warpzone_save_eangles != self.enemy.angles) - { - WarpZone_InitStep_UpdateTransform(); - setself(self.enemy); - WarpZone_InitStep_UpdateTransform(); - setself(this); - WarpZone_InitStep_FinalizeTransform(); - setself(self.enemy); - WarpZone_InitStep_FinalizeTransform(); - setself(this); - self.warpzone_save_origin = self.origin; - self.warpzone_save_angles = self.angles; - self.warpzone_save_eorigin = self.enemy.origin; - self.warpzone_save_eangles = self.enemy.angles; - } - self.nextthink = time; +void WarpZone_Think(entity this) +{ + if(this.warpzone_save_origin != this.origin + || this.warpzone_save_angles != this.angles + || this.warpzone_save_eorigin != this.enemy.origin + || this.warpzone_save_eangles != this.enemy.angles) + { + WarpZone_InitStep_UpdateTransform(this); + WarpZone_InitStep_UpdateTransform(this.enemy); + WarpZone_InitStep_FinalizeTransform(this); + WarpZone_InitStep_FinalizeTransform(this.enemy); + this.warpzone_save_origin = this.origin; + this.warpzone_save_angles = this.angles; + this.warpzone_save_eorigin = this.enemy.origin; + this.warpzone_save_eangles = this.enemy.angles; + } + this.nextthink = time; } void WarpZone_StartFrame() -{SELFPARAM(); - entity e; - if(warpzone_initialized == 0) - { - warpzone_initialized = 1; - for(setself(warpzone_first); self; setself(self.warpzone_next)) - WarpZone_InitStep_FindOriginTarget(); - for(setself(warpzone_position_first); self; setself(self.warpzone_next)) - WarpZonePosition_InitStep_FindTarget(); - for(setself(warpzone_first); self; setself(self.warpzone_next)) - WarpZone_InitStep_UpdateTransform(); - setself(this); +{ + if (!warpzone_initialized) + { + warpzone_initialized = true; + for(entity e = warpzone_first; e; e = e.warpzone_next) + WarpZone_InitStep_FindOriginTarget(e); + for(entity e = warpzone_position_first; e; e = e.warpzone_next) + WarpZonePosition_InitStep_FindTarget(e); + for(entity e = warpzone_first; e; e = e.warpzone_next) + WarpZone_InitStep_UpdateTransform(e); WarpZones_Reconnect(); WarpZone_PostInitialize_Callback(); } - entity oldother; - oldother = other; - for(e = world; (e = nextent(e)); ) + FOREACH_ENTITY_FLOAT(pure_data, false, { - if(warpzone_warpzones_exist) { WarpZone_StoreProjectileData(e); } + if(warpzone_warpzones_exist) + WarpZone_StoreProjectileData(it); - if(IS_REAL_CLIENT(e)) + if(IS_OBSERVER(it) || it.solid == SOLID_NOT) + if(IS_CLIENT(it)) // we don't care about it being a bot { - if(e.solid == SOLID_NOT) // not spectating? - if(e.movetype == MOVETYPE_NOCLIP || e.movetype == MOVETYPE_FLY || e.movetype == MOVETYPE_FLY_WORLDONLY) // not spectating? (this is to catch observers) - { - other = e; // player - - // warpzones - if(warpzone_warpzones_exist) { - setself(WarpZone_Find(e.origin + e.mins, e.origin + e.maxs)); - if(self) - if(!WarpZoneLib_ExactTrigger_Touch()) - if(WarpZone_PlaneDist(self, e.origin + e.view_ofs) <= 0) - WarpZone_Teleport(self, e, -1, 0); } // NOT triggering targets by this! - - // teleporters - setself(Teleport_Find(e.origin + e.mins, e.origin + e.maxs)); - if(self) - if(!WarpZoneLib_ExactTrigger_Touch()) - Simple_TeleportPlayer(self, other); // NOT triggering targets by this! + // warpzones + if (warpzone_warpzones_exist) { + entity e = WarpZone_Find(it.origin + it.mins, it.origin + it.maxs); + if (e) + if (!WarpZoneLib_ExactTrigger_Touch(e, it)) + if (WarpZone_PlaneDist(e, it.origin + it.view_ofs) <= 0) + WarpZone_Teleport(e, it, -1, 0); // NOT triggering targets by this! } - } - if(IS_NOT_A_CLIENT(e)) - { - if(warpzone_warpzones_exist) - for (; (e = nextent(e)); ) - WarpZone_StoreProjectileData(e); - break; + // teleporters + if(it.teleportable) + { + entity ent = Teleport_Find(it.origin + it.mins, it.origin + it.maxs); + if (ent) + if (!WarpZoneLib_ExactTrigger_Touch(ent, it)) + Simple_TeleportPlayer(ent, it); // NOT triggering targets by this! + } } - } - setself(this); - other = oldother; + }); } .float warpzone_reconnecting; -float visible_to_some_client(entity ent) +bool visible_to_some_client(entity ent) { - entity e; - for(e = nextent(world); !IS_NOT_A_CLIENT(e); e = nextent(e)) - if(IS_PLAYER(e) && IS_REAL_CLIENT(e)) - if(checkpvs(e.origin + e.view_ofs, ent)) - return 1; - return 0; + FOREACH_CLIENT(IS_PLAYER(it) && IS_REAL_CLIENT(it) && checkpvs(it.origin + it.view_ofs, ent), + { + return true; + }); + return false; } -void trigger_warpzone_reconnect_use() -{SELFPARAM(); - entity e; - e = self; +void trigger_warpzone_reconnect_use(entity this, entity actor, entity trigger) +{ // NOTE: this matches for target, not targetname, but of course // targetname must be set too on the other entities - for(setself(warpzone_first); self; setself(self.warpzone_next)) - self.warpzone_reconnecting = ((e.target == "" || self.target == e.target) && !((e.spawnflags & 1) && (visible_to_some_client(self) || visible_to_some_client(self.enemy)))); - for(setself(warpzone_camera_first); self; setself(self.warpzone_next)) - self.warpzone_reconnecting = ((e.target == "" || self.target == e.target) && !((e.spawnflags & 1) && visible_to_some_client(self))); - for(setself(warpzone_first); self; setself(self.warpzone_next)) - if(self.warpzone_reconnecting) - WarpZone_InitStep_ClearTarget(); - for(setself(warpzone_first); self; setself(self.warpzone_next)) - if(self.warpzone_reconnecting) - WarpZone_InitStep_FindTarget(); - for(setself(warpzone_camera_first); self; setself(self.warpzone_next)) - if(self.warpzone_reconnecting) - WarpZoneCamera_InitStep_FindTarget(); - for(setself(warpzone_first); self; setself(self.warpzone_next)) - if(self.warpzone_reconnecting || self.enemy.warpzone_reconnecting) - WarpZone_InitStep_FinalizeTransform(); - setself(e); + for(entity e = warpzone_first; e; e = e.warpzone_next) + e.warpzone_reconnecting = ((this.target == "" || e.target == this.target) && !((this.spawnflags & 1) && (visible_to_some_client(e) || visible_to_some_client(e.enemy)))); + for(entity e = warpzone_camera_first; e; e = e.warpzone_next) + e.warpzone_reconnecting = ((this.target == "" || e.target == this.target) && !((this.spawnflags & 1) && visible_to_some_client(e))); + for(entity e = warpzone_first; e; e = e.warpzone_next) + if(e.warpzone_reconnecting) + WarpZone_InitStep_ClearTarget(e); + for(entity e = warpzone_first; e; e = e.warpzone_next) + if(e.warpzone_reconnecting) + WarpZone_InitStep_FindTarget(e); + for(entity e = warpzone_camera_first; e; e = e.warpzone_next) + if(e.warpzone_reconnecting) + WarpZoneCamera_InitStep_FindTarget(e); + for(entity e = warpzone_first; e; e = e.warpzone_next) + if(e.warpzone_reconnecting || e.enemy.warpzone_reconnecting) + WarpZone_InitStep_FinalizeTransform(e); } spawnfunc(trigger_warpzone_reconnect) { - self.use = trigger_warpzone_reconnect_use; + this.use = trigger_warpzone_reconnect_use; } spawnfunc(target_warpzone_reconnect) @@ -884,15 +873,17 @@ spawnfunc(target_warpzone_reconnect) spawnfunc_trigger_warpzone_reconnect(this); // both names make sense here :( } -void WarpZone_PlayerPhysics_FixVAngle() -{SELFPARAM(); +void WarpZone_PlayerPhysics_FixVAngle(entity this) +{ #ifndef WARPZONE_DONT_FIX_VANGLE - if(IS_REAL_CLIENT(self)) - if(self.v_angle.z <= 360) // if not already adjusted - if(time - self.ping * 0.001 < self.warpzone_teleport_time) + if(IS_REAL_CLIENT(this)) + if(this.v_angle.z <= 360) // if not already adjusted + if(time - this.ping * 0.001 < this.warpzone_teleport_time) { - self.v_angle = WarpZone_TransformVAngles(self.warpzone_teleport_zone, self.v_angle); - self.v_angle_z += 720; // mark as adjusted + this.v_angle = WarpZone_TransformVAngles(this.warpzone_teleport_zone, this.v_angle); + this.v_angle_z += 720; // mark as adjusted } #endif } + +#endif