vector org = targ.origin;
- if(STAT(Q3COMPAT))
- {
- org.z += targ.mins_z;
- org.z += 1; // off by 1!
- }
+ if(Q3COMPAT_COMMON || this.spawnflags & PUSH_STATIC)
+ org = (this.absmin + this.absmax) * 0.5;
+ bool already_pushed = false;
+ if(is_velocity_pad) // remember velocity jump pads
+ {
+ if(this == targ.last_pushed || (targ.last_pushed && !STAT(Q3COMPAT, targ))) // if q3compat is active overwrite last stored jump pad, otherwise ignore
+ {
+ already_pushed = true;
+ }
+ else
+ {
+ targ.last_pushed = this; // may be briefly out of sync between client and server if client prediction is toggled
+ }
+ }
+
if(this.enemy)
{
- targ.velocity = trigger_push_calculatevelocity(org, this.enemy, this.height, targ);
+ if(!is_velocity_pad)
+ {
+ targ.velocity = trigger_push_calculatevelocity(org, this.enemy, this.height, targ);
+ }
+ else
+ {
+ targ.velocity = trigger_push_velocity_calculatevelocity(this, org, this.enemy, this.speed, this.count, targ, already_pushed);
+ }
}
else if(this.target && this.target != "")
{
InitializeEntity(this, trigger_push_findtarget, INITPRIO_FINDTARGET);
}
- trigger_init(this);
+/*
+ * ENTITY PARAMETERS:
+ *
+ * target: this points to the target_position to which the player will jump.
+ * speed: XY speed for player-directional velocity pads - either sets or adds to the player's horizontal velocity.
+ * count: Z speed for player-directional velocity pads - either sets or adds to the player's vertical velocity.
+ */
+spawnfunc(trigger_push_velocity)
+{
++ EXACTTRIGGER_INIT;
++ BITSET_ASSIGN(this.effects, EF_NODEPTHTEST);
+
+ this.active = ACTIVE_ACTIVE;
+ this.use = trigger_push_use;
+ settouch(this, trigger_push_velocity_touch);
+
+ // normal push setup
+ if (!this.noise)
+ this.noise = "misc/jumppad.wav";
+ precache_sound (this.noise);
+
+ trigger_push_velocity_link(this); // link it now
+}
+
bool target_push_send(entity this, entity to, float sf)
{
const int PUSH_ONCE = BIT(0); // legacy, deactivate with relay instead
const int PUSH_SILENT = BIT(1); // not used?
+ const int PUSH_STATIC = BIT(12); // xonotic-only, Q3 already behaves like this by default
+#define PUSH_VELOCITY_PLAYERDIR_XY BIT(0)
+#define PUSH_VELOCITY_ADD_XY BIT(1)
+#define PUSH_VELOCITY_PLAYERDIR_Z BIT(2)
+#define PUSH_VELOCITY_ADD_Z BIT(3)
+#define PUSH_VELOCITY_BIDIRECTIONAL_XY BIT(4)
+#define PUSH_VELOCITY_BIDIRECTIONAL_Z BIT(5)
+#define PUSH_VELOCITY_CLAMP_NEGATIVE_ADDS BIT(6)
+
IntrusiveList g_jumppads;
STATIC_INIT(g_jumppads) { g_jumppads = IL_NEW(); }
string to_execute_next_frame;
void execute_next_frame()
{
- if(WarpZoneLib_ExactTrigger_Touch(it.last_pushed, it))
+#ifdef SVQC
+ IL_EACH(g_moveables, it.last_pushed,
+ {
- if(csqcplayer.last_pushed && WarpZoneLib_ExactTrigger_Touch(csqcplayer.last_pushed, csqcplayer))
++ if(!WarpZoneLib_ExactTrigger_Touch(it.last_pushed, it, false))
+ {
+ it.last_pushed = NULL;
+ }
+ });
+#elif defined(CSQC)
++ if(csqcplayer.last_pushed && !WarpZoneLib_ExactTrigger_Touch(csqcplayer.last_pushed, csqcplayer, false))
+ {
+ csqcplayer.last_pushed = NULL;
+ }
+#endif
+
if(to_execute_next_frame)
{
localcmd("\n", to_execute_next_frame, "\n");