From: Juhu <5894800-Juhu_@users.noreply.gitlab.com> Date: Fri, 22 Mar 2024 08:46:25 +0000 (+0000) Subject: Implement XDF Compatibility: target_speed X-Git-Url: https://git.rm.cloudns.org/?a=commitdiff_plain;h=e88e1e15090f826fe3ac9b006e89eca0d1ecfe68;p=xonotic%2Fxonotic-data.pk3dir.git Implement XDF Compatibility: target_speed --- diff --git a/qcsrc/common/mapobjects/target/_mod.inc b/qcsrc/common/mapobjects/target/_mod.inc index f9cc536ed..9d97d6610 100644 --- a/qcsrc/common/mapobjects/target/_mod.inc +++ b/qcsrc/common/mapobjects/target/_mod.inc @@ -7,4 +7,5 @@ #include #include #include +#include #include diff --git a/qcsrc/common/mapobjects/target/_mod.qh b/qcsrc/common/mapobjects/target/_mod.qh index e3f4cede9..48c57c42d 100644 --- a/qcsrc/common/mapobjects/target/_mod.qh +++ b/qcsrc/common/mapobjects/target/_mod.qh @@ -7,4 +7,5 @@ #include #include #include +#include #include diff --git a/qcsrc/common/mapobjects/target/speed.qc b/qcsrc/common/mapobjects/target/speed.qc new file mode 100644 index 000000000..b42e0802b --- /dev/null +++ b/qcsrc/common/mapobjects/target/speed.qc @@ -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 index 000000000..6e8544439 --- /dev/null +++ b/qcsrc/common/mapobjects/target/speed.qh @@ -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)