From c99ff12a5db3bc53a19838d7a945931952047c66 Mon Sep 17 00:00:00 2001 From: div0 Date: Fri, 22 Aug 2008 11:01:02 +0000 Subject: [PATCH] exact triggers: jumppads, teleporters and race checkpoints now work EXACTLY as made in the map editor (not as bbox any more). This change might be desirable on other entity types too. Usage: - In the spawn functions, call EXACTTRIGGER_INIT; instead of InitTrigger(); - In the touch function, first do the classname checks, then call EXACTTRIGGER_TOUCH; (this will abort the touch function if it is a bad touch) git-svn-id: svn://svn.icculus.org/nexuiz/trunk@4142 f962a42d-fe04-0410-a3ab-8c8b0445ebaa --- data/qcsrc/server/miscfunctions.qc | 62 ++++++++++++++++++++++-------- data/qcsrc/server/race.qc | 30 ++++++++++++++- data/qcsrc/server/t_jumppads.qc | 4 +- data/qcsrc/server/t_teleporters.qc | 4 +- 4 files changed, 80 insertions(+), 20 deletions(-) diff --git a/data/qcsrc/server/miscfunctions.qc b/data/qcsrc/server/miscfunctions.qc index 0440e77af..8db63d41e 100644 --- a/data/qcsrc/server/miscfunctions.qc +++ b/data/qcsrc/server/miscfunctions.qc @@ -1140,20 +1140,48 @@ void precache() } } -#define WRITESPECTATABLE_MSG_ONE_VARNAME(varname,statement) \ - entity varname; \ - varname = msg_entity; \ - FOR_EACH_REALCLIENT(msg_entity) \ - if(msg_entity == varname || (msg_entity.classname == STR_SPECTATOR && msg_entity.enemy == varname)) \ - statement \ - msg_entity = varname -#define WRITESPECTATABLE_MSG_ONE(statement) \ - WRITESPECTATABLE_MSG_ONE_VARNAME(oldmsg_entity, statement) -#define WRITESPECTATABLE(msg,statement) \ - if(msg == MSG_ONE) \ - { \ - WRITESPECTATABLE_MSG_ONE(statement); \ - } \ - else \ - statement \ - float WRITESPECTATABLE_workaround = 0 +// sorry, but using \ in macros breaks line numbers +#define WRITESPECTATABLE_MSG_ONE_VARNAME(varname,statement) entity varname; varname = msg_entity; FOR_EACH_REALCLIENT(msg_entity) if(msg_entity == varname || (msg_entity.classname == STR_SPECTATOR && msg_entity.enemy == varname)) statement msg_entity = varname +#define WRITESPECTATABLE_MSG_ONE(statement) WRITESPECTATABLE_MSG_ONE_VARNAME(oldmsg_entity, statement) +#define WRITESPECTATABLE(msg,statement) if(msg == MSG_ONE) { WRITESPECTATABLE_MSG_ONE(statement); } else statement float WRITESPECTATABLE_workaround = 0 + +vector ExactTriggerHit_mins; +vector ExactTriggerHit_maxs; +float ExactTriggerHit_Recurse() +{ + float s; + entity se; + float f; + + tracebox('0 0 0', ExactTriggerHit_mins, ExactTriggerHit_maxs, '0 0 0', MOVE_NORMAL, world); + if not(trace_ent) + return 0; + if(trace_ent == self) + return 1; + + se = trace_ent; + s = se.solid; + se.solid = SOLID_NOT; + f = ExactTriggerHit_Recurse(); + se.solid = s; + + return f; +} + +float ExactTriggerHit() +{ + float f, s; + + s = self.solid; + self.solid = SOLID_BSP; + ExactTriggerHit_mins = other.absmin + '1 1 1'; + ExactTriggerHit_maxs = other.absmax - '1 1 1'; + f = ExactTriggerHit_Recurse(); + self.solid = s; + + return f; +} + +// WARNING: this kills the trace globals +#define EXACTTRIGGER_TOUCH if not(ExactTriggerHit()) return +#define EXACTTRIGGER_INIT InitSolidBSPTrigger(); self.solid = SOLID_TRIGGER diff --git a/data/qcsrc/server/race.qc b/data/qcsrc/server/race.qc index c1a58fb56..1fc65fda7 100644 --- a/data/qcsrc/server/race.qc +++ b/data/qcsrc/server/race.qc @@ -275,11 +275,37 @@ void race_ClearTime(entity e) }); } +void dumpsurface(entity e) +{ + float n, si, ni; + vector norm, vec; + print("Surfaces of ", etos(e), ":\n"); + + print("TEST = ", ftos(getsurfacenearpoint(e, '0 0 0')), "\n"); + + for(si = 0; ; ++si) + { + n = getsurfacenumpoints(e, si); + if(n <= 0) + break; + print(" Surface ", ftos(si), ":\n"); + norm = getsurfacenormal(e, si); + print(" Normal = ", vtos(norm), "\n"); + for(ni = 0; ni < n; ++ni) + { + vec = getsurfacepoint(e, si, ni); + print(" Point ", ftos(ni), " = ", vtos(vec), " (", ftos(norm * vec), ")\n"); + } + } +} + void checkpoint_touch() { if(other.classname != "player") return; + EXACTTRIGGER_TOUCH; + if(other.race_checkpoint == -1 || other.race_checkpoint == self.race_checkpoint) { other.race_checkpoint = race_NextCheckpoint(self.race_checkpoint); @@ -327,7 +353,9 @@ void spawnfunc_trigger_race_checkpoint() remove(self); return; } - InitTrigger(); + + EXACTTRIGGER_INIT; + self.use = checkpoint_use; if not(self.spawnflags & 1) self.touch = checkpoint_touch; diff --git a/data/qcsrc/server/t_jumppads.qc b/data/qcsrc/server/t_jumppads.qc index 6968698e9..ada452bdb 100644 --- a/data/qcsrc/server/t_jumppads.qc +++ b/data/qcsrc/server/t_jumppads.qc @@ -120,6 +120,8 @@ void trigger_push_touch() if (other.deadflag && other.classname == "player") return; + EXACTTRIGGER_TOUCH; + if(self.target) self.movedir = trigger_push_calculatevelocity(other.origin, self.enemy, self.height); @@ -239,7 +241,7 @@ void spawnfunc_trigger_push() if (self.angles != '0 0 0') SetMovedir (); - InitTrigger(); + EXACTTRIGGER_INIT; self.touch = trigger_push_touch; diff --git a/data/qcsrc/server/t_teleporters.qc b/data/qcsrc/server/t_teleporters.qc index 98be99170..a063efcf2 100644 --- a/data/qcsrc/server/t_teleporters.qc +++ b/data/qcsrc/server/t_teleporters.qc @@ -8,6 +8,8 @@ void Teleport_Touch (void) if (!other.flags & FL_CLIENT) // FIXME: Make missiles firable through the teleport too return; + EXACTTRIGGER_TOUCH; + sound (other, CHAN_TRIGGER, "misc/teleport.wav", VOL_BASE, ATTN_NORM); pointparticles(particleeffectnum("teleport"), other.origin, '0 0 0', 1); @@ -125,7 +127,7 @@ void spawnfunc_trigger_teleport (void) { self.angles = '0 0 0'; - InitTrigger(); + EXACTTRIGGER_INIT; self.think = teleport_findtarget; self.nextthink = time + 0.2; -- 2.39.2