]> de.git.xonotic.org Git - xonotic/xonotic-data.pk3dir.git/commitdiff
Implement XDF Compatibility: target_speed
authorJuhu <5894800-Juhu_@users.noreply.gitlab.com>
Fri, 22 Mar 2024 08:46:25 +0000 (08:46 +0000)
committerbones_was_here <bones_was_here@xonotic.au>
Fri, 22 Mar 2024 08:46:25 +0000 (08:46 +0000)
qcsrc/common/mapobjects/target/_mod.inc
qcsrc/common/mapobjects/target/_mod.qh
qcsrc/common/mapobjects/target/speed.qc [new file with mode: 0644]
qcsrc/common/mapobjects/target/speed.qh [new file with mode: 0644]

index f9cc536eda728e8e402121af6c5fe33a702cc179..9d97d66101451fa042925a756b13015da9fede91 100644 (file)
@@ -7,4 +7,5 @@
 #include <common/mapobjects/target/spawn.qc>
 #include <common/mapobjects/target/spawnpoint.qc>
 #include <common/mapobjects/target/speaker.qc>
+#include <common/mapobjects/target/speed.qc>
 #include <common/mapobjects/target/voicescript.qc>
index e3f4cede9912314c03bbd2cef0d9a5cc494e20b4..48c57c42d9f12b0090ece1df715229177569591f 100644 (file)
@@ -7,4 +7,5 @@
 #include <common/mapobjects/target/spawn.qh>
 #include <common/mapobjects/target/spawnpoint.qh>
 #include <common/mapobjects/target/speaker.qh>
+#include <common/mapobjects/target/speed.qh>
 #include <common/mapobjects/target/voicescript.qh>
diff --git a/qcsrc/common/mapobjects/target/speed.qc b/qcsrc/common/mapobjects/target/speed.qc
new file mode 100644 (file)
index 0000000..b42e080
--- /dev/null
@@ -0,0 +1,206 @@
+#include "speed.qh"
+
+// bones_was_here: TODO implement subscript support for vectors in gmqcc
+// or _something_ so code like this can be cheaper...
+#define ARRAY_AS_VECTOR(a) vec3((a)[0], (a)[1], (a)[2])
+#define VECTOR_TO_ARRAY(a, e) (a)[0] = (e).x, (a)[1] = (e).y, (a)[2] = (e).z
+vector target_speed_calculatevelocity(entity this, float speed, entity pushed_entity)
+{
+       bool is_percentage = boolean(this.spawnflags & SPEED_PERCENTAGE);
+       bool is_add = boolean(this.spawnflags & SPEED_ADD);
+       bool is_launcher = boolean(this.spawnflags & SPEED_LAUNCHER);
+
+       bool is_positive[3];
+       is_positive[0] = boolean(this.spawnflags & SPEED_POSITIVE_X);
+       is_positive[1] = boolean(this.spawnflags & SPEED_POSITIVE_Y);
+       is_positive[2] = boolean(this.spawnflags & SPEED_POSITIVE_Z);
+
+       bool is_negative[3];
+       is_negative[0] = boolean(this.spawnflags & SPEED_NEGATIVE_X);
+       is_negative[1] = boolean(this.spawnflags & SPEED_NEGATIVE_Y);
+       is_negative[2] = boolean(this.spawnflags & SPEED_NEGATIVE_Z);
+
+       // speed cannot be negative except when subtracting
+       if(!is_add)
+       {
+               speed = max(speed, 0);
+       }
+
+       float pushvel[3];
+       VECTOR_TO_ARRAY(pushvel, pushed_entity.velocity);
+
+       for(int i = 0; i < 3; ++i)
+       {
+               // launcher can only be either positive or negative not both
+               if(is_launcher && is_positive[i] && is_negative[i])
+               {
+                       is_positive[i] = is_negative[i] = false;
+               }
+
+               // ignore this direction
+               if(!is_positive[i] && !is_negative[i])
+               {
+                       pushvel[i] = 0;
+               }
+       }
+
+       float oldspeed = vlen(ARRAY_AS_VECTOR(pushvel));
+
+       // the speed field is used to specify the percentage of the current speed
+       if(is_percentage)
+       {
+               speed = oldspeed * speed / 100;
+       }
+
+       float launcherspeed = 0;
+
+       // do this properly when not playing a Q3 map, do not put this in the loop
+       if(!STAT(Q3COMPAT, pushed_entity))
+       {
+               launcherspeed += speed;
+
+               // add the add speed in the same variable
+               // as it goes in the same direction
+               if(is_add) launcherspeed += oldspeed;
+       }
+
+       for(int i = 0; i < 3; ++i)
+       {
+               if(((pushvel[i] != 0) || is_launcher) && (is_positive[i] != is_negative[i]))
+               {
+                       if(is_launcher)
+                       {
+                               // every direction weighs the same amount on launchers
+                               // movedir does not matter
+                               pushvel[i] = 1;
+
+                               // this does not belong inside the loop
+                               // only simulate this bug when playing a Q3 map
+                               if(STAT(Q3COMPAT, pushed_entity))
+                               {
+                                       launcherspeed += speed;
+
+                                       // add the add speed in the same variable
+                                       // as it goes in the same direction
+                                       if(is_add) launcherspeed += oldspeed;
+                               }
+                       }
+
+                       if(is_positive[i])
+                       {
+                               pushvel[i] = copysign(pushvel[i], 1);
+                       }
+                       else if(is_negative[i])
+                       {
+                               pushvel[i] = copysign(pushvel[i], -1);
+                       }
+               }
+       }
+
+       float oldvel[3];
+       VECTOR_TO_ARRAY(oldvel, pushed_entity.velocity);
+
+       if(is_launcher)
+       {
+               // launcher will always launch you in the correct direction
+               // even if speed is set to a negative value, fabs() is correct
+               VECTOR_TO_ARRAY(pushvel, normalize(ARRAY_AS_VECTOR(pushvel)) * fabs(launcherspeed));
+       }
+       else
+       {
+               if(!is_add)
+                       VECTOR_TO_ARRAY(pushvel, normalize(ARRAY_AS_VECTOR(pushvel)) * speed);
+               else
+                       VECTOR_TO_ARRAY(pushvel, normalize(ARRAY_AS_VECTOR(pushvel)) * speed + ARRAY_AS_VECTOR(oldvel));
+       }
+
+       for(int i = 0; i < 3; ++i)
+       {
+               // preserve unaffected directions
+               if(!is_positive[i] && !is_negative[i])
+               {
+                       pushvel[i] = oldvel[i];
+               }
+       }
+
+       return ARRAY_AS_VECTOR(pushvel);
+}
+#undef ARRAY_AS_VECTOR
+#undef VECTOR_TO_ARRAY
+
+REGISTER_NET_LINKED(ENT_CLIENT_TARGET_SPEED)
+
+void target_speed_use(entity this, entity actor, entity trigger)
+{
+       if(this.active != ACTIVE_ACTIVE)
+               return;
+
+       actor.velocity = target_speed_calculatevelocity(this, this.speed, actor);
+}
+
+void target_speed_reset(entity this)
+{
+       this.active = ACTIVE_ACTIVE;
+}
+
+#ifdef SVQC
+void target_speed_link(entity this);
+
+/*
+ * ENTITY PARAMETERS:
+ *
+ *   targetname:  Activating trigger points to this.
+ *   speed:       Speed value to set (default: 100).
+ */
+spawnfunc(target_speed)
+{
+       this.active = ACTIVE_ACTIVE;
+       this.setactive = generic_netlinked_setactive;
+       this.use = target_speed_use;
+       this.reset = target_speed_reset;
+
+       // support a 0 speed setting AND a default
+       string s = GetField_fullspawndata(this, "speed");
+       if (!s || s == "")
+               this.speed = 100;
+
+       target_speed_link(this);
+}
+
+bool target_speed_send(entity this, entity to, float sf)
+{
+       WriteHeader(MSG_ENTITY, ENT_CLIENT_TARGET_SPEED);
+
+       WriteShort(MSG_ENTITY, this.spawnflags);
+       WriteByte(MSG_ENTITY, this.active);
+       WriteString(MSG_ENTITY, this.targetname);
+       WriteCoord(MSG_ENTITY, this.speed);
+
+       return true;
+}
+
+void target_speed_link(entity this)
+{
+       Net_LinkEntity(this, false, 0, target_speed_send);
+}
+
+#elif defined(CSQC)
+
+void target_speed_remove(entity this)
+{
+       strfree(this.targetname);
+}
+
+NET_HANDLE(ENT_CLIENT_TARGET_SPEED, bool isnew)
+{
+       this.spawnflags = ReadShort();
+       this.active = ReadByte();
+       this.targetname = strzone(ReadString());
+       this.speed = ReadCoord();
+
+       this.use = target_speed_use;
+       this.entremove = target_speed_remove;
+
+       return true;
+}
+#endif
diff --git a/qcsrc/common/mapobjects/target/speed.qh b/qcsrc/common/mapobjects/target/speed.qh
new file mode 100644 (file)
index 0000000..6e85444
--- /dev/null
@@ -0,0 +1,12 @@
+#pragma once
+
+
+#define SPEED_PERCENTAGE BIT(0)
+#define SPEED_ADD        BIT(1)
+#define SPEED_POSITIVE_X BIT(2)
+#define SPEED_NEGATIVE_X BIT(3)
+#define SPEED_POSITIVE_Y BIT(4)
+#define SPEED_NEGATIVE_Y BIT(5)
+#define SPEED_POSITIVE_Z BIT(6)
+#define SPEED_NEGATIVE_Z BIT(7)
+#define SPEED_LAUNCHER   BIT(8)