From: TimePath Date: Thu, 27 Aug 2015 00:48:56 +0000 (+1000) Subject: Use temp entities for casings instead of the delayed removal shared entity hack X-Git-Tag: xonotic-v0.8.2~2018^2 X-Git-Url: https://git.rm.cloudns.org/?a=commitdiff_plain;h=5c249b1433c3268e3b2fb25d30acac141f8347f7;p=xonotic%2Fxonotic-data.pk3dir.git Use temp entities for casings instead of the delayed removal shared entity hack --- diff --git a/qcsrc/client/casings.qc b/qcsrc/client/casings.qc deleted file mode 100644 index 61d7f10ba..000000000 --- a/qcsrc/client/casings.qc +++ /dev/null @@ -1,155 +0,0 @@ -#include "casings.qh" -#include "_all.qh" - -#include "../common/movetypes/movetypes.qh" -#include "../common/weapons/all.qh" -#include "prandom.qh" -#include "rubble.qh" - -#include "../common/util.qh" - -.float cnt; -.float alpha; -.int state; - -entityclass(Casing); -class(Casing) .bool silent; - -void Casing_Delete() -{ - remove(self); -} - -void Casing_Draw() -{ - if(self.move_flags & FL_ONGROUND) - { - self.move_angles_x = 0; - self.move_angles_z = 0; - self.flags &= ~FL_ONGROUND; - } - - Movetype_Physics_MatchTicrate(autocvar_cl_casings_ticrate, autocvar_cl_casings_sloppy); - if(wasfreed(self)) - return; // deleted by touch function - - self.renderflags = 0; - self.alpha = bound(0, self.cnt - time, 1); - - if(self.alpha < ALPHA_MIN_VISIBLE) - { - Casing_Delete(); - self.drawmask = 0; - } -} - -void Casing_Touch() -{ - if(trace_dphitq3surfaceflags & Q3SURFACEFLAG_NOIMPACT) - { - Casing_Delete(); - return; - } - - if(!self.silent) - if(!trace_ent || trace_ent.solid == SOLID_BSP) - { - if(vlen(self.velocity) > 50) - { - if(time >= self.nextthink) - { - string s; - int f = floor(prandom() * 3) + 1; - - switch(self.state) - { - case 1: - s = W_Sound(strcat("casings", itos(f))); - break; - default: - s = W_Sound(strcat("brass", itos(f))); - break; - } - - sound (self, CH_SHOTS, s, VOL_BASE, ATTEN_LARGE); - } - } - } - - self.nextthink = time + 0.2; -} - -void Casing_Damage(float thisdmg, int hittype, vector org, vector thisforce) -{ - if(thisforce.z < 0) - thisforce.z = 0; - self.move_velocity = self.move_velocity + thisforce + '0 0 100'; - self.move_flags &= ~FL_ONGROUND; -} - -void Ent_Casing(float isNew) -{ - entity casing; - - casing = RubbleNew("casing"); - casing.state = ReadByte(); - casing.silent = (casing.state & 0x80); - casing.state = (casing.state & 0x7F); - casing.origin_x = ReadCoord(); - casing.origin_y = ReadCoord(); - casing.origin_z = ReadCoord(); - setorigin(casing, casing.origin); - casing.velocity = decompressShortVector(ReadShort()); - casing.angles_x = ReadByte() * 360 / 256; - casing.angles_y = ReadByte() * 360 / 256; - casing.angles_z = ReadByte() * 360 / 256; - casing.drawmask = MASK_NORMAL; - - if(autocvar_cl_casings && isNew) { - casing.draw = Casing_Draw; - casing.move_origin = casing.origin; - casing.move_velocity = casing.velocity + 2 * prandomvec(); - casing.move_angles = casing.angles; - casing.move_avelocity = '0 250 0' + 100 * prandomvec(); - casing.move_movetype = MOVETYPE_BOUNCE; - casing.move_touch = Casing_Touch; - casing.move_time = time; - casing.event_damage = Casing_Damage; - casing.solid = SOLID_TRIGGER; - - switch(casing.state) - { - case 1: - setmodel(casing, "models/casing_shell.mdl"); - casing.cnt = time + autocvar_cl_casings_shell_time; - break; - default: - setmodel(casing, "models/casing_bronze.iqm"); - casing.cnt = time + autocvar_cl_casings_bronze_time; - break; - } - - setsize(casing, '0 0 -1', '0 0 -1'); - - RubbleLimit("casing", autocvar_cl_casings_maxcount, Casing_Delete); - } - else - { - entity oldself = self; - self = casing; - Casing_Delete(); // yes, this IS stupid, but I don't need to duplicate all the read* stuff then - self = oldself; - } -} - -void Casings_Precache() -{ - precache_model("models/casing_shell.mdl"); - precache_model("models/casing_bronze.iqm"); - precache_sound(W_Sound("brass1")); - precache_sound(W_Sound("brass2")); - precache_sound(W_Sound("brass3")); - precache_sound(W_Sound("casings1")); - precache_sound(W_Sound("casings2")); - precache_sound(W_Sound("casings3")); -} diff --git a/qcsrc/client/casings.qh b/qcsrc/client/casings.qh deleted file mode 100644 index dafe66a55..000000000 --- a/qcsrc/client/casings.qh +++ /dev/null @@ -1,8 +0,0 @@ -#ifndef CASINGS_H -#define CASINGS_H - -void Casings_Precache(); - -void Ent_Casing(float isNew); - -#endif diff --git a/qcsrc/client/controlpoint.qc b/qcsrc/client/controlpoint.qc index a579f93aa..3b8901cf3 100644 --- a/qcsrc/client/controlpoint.qc +++ b/qcsrc/client/controlpoint.qc @@ -1,7 +1,9 @@ #include "controlpoint.qh" #include "gibs.qh" #include "teamradar.qh" +#include "../common/movetypes/movetypes.qh" +.float alpha; bool cpicon_precached; .int count; .float pain_finished; diff --git a/qcsrc/client/damage.qc b/qcsrc/client/damage.qc index 05d9dfe6f..5eff455c2 100644 --- a/qcsrc/client/damage.qc +++ b/qcsrc/client/damage.qc @@ -2,7 +2,6 @@ #include "_all.qh" #include "gibs.qh" -#include "prandom.qh" #include "../common/vehicles/all.qh" diff --git a/qcsrc/client/gibs.qc b/qcsrc/client/gibs.qc index 298e9d5e6..bdde3b698 100644 --- a/qcsrc/client/gibs.qc +++ b/qcsrc/client/gibs.qc @@ -1,7 +1,6 @@ #include "gibs.qh" #include "_all.qh" -#include "prandom.qh" #include "rubble.qh" #include "../common/constants.qh" diff --git a/qcsrc/client/main.qc b/qcsrc/client/main.qc index da485708e..2309426ce 100644 --- a/qcsrc/client/main.qc +++ b/qcsrc/client/main.qc @@ -1,7 +1,6 @@ #include "main.qh" #include "_all.qh" -#include "casings.qh" #include "controlpoint.qh" #include "csqcmodel_hooks.qh" #include "damage.qh" @@ -15,7 +14,6 @@ #include "mapvoting.qh" #include "modeleffects.qh" #include "particles.qh" -#include "prandom.qh" #include "scoreboard.qh" #include "shownames.qh" #include "sortlist.qh" @@ -164,7 +162,6 @@ void CSQC_Init(void) Projectile_Precache(); Hook_Precache(); GibSplash_Precache(); - Casings_Precache(); Tuba_Precache(); CSQCPlayer_Precache(); @@ -867,7 +864,6 @@ void CSQC_Ent_Update(float bIsNewEntity) case ENT_CLIENT_PROJECTILE: Ent_Projectile(); break; case ENT_CLIENT_GIBSPLASH: Ent_GibSplash(bIsNewEntity); break; case ENT_CLIENT_DAMAGEINFO: Ent_DamageInfo(bIsNewEntity); break; - case ENT_CLIENT_CASING: Ent_Casing(bIsNewEntity); break; case ENT_CLIENT_INIT: Ent_Init(); break; case ENT_CLIENT_SCORES_INFO: Ent_ScoresInfo(); break; case ENT_CLIENT_MAPVOTE: Ent_MapVote(); break; diff --git a/qcsrc/client/mutators/events.qh b/qcsrc/client/mutators/events.qh index 86be898d9..9516fd25e 100644 --- a/qcsrc/client/mutators/events.qh +++ b/qcsrc/client/mutators/events.qh @@ -40,9 +40,10 @@ MUTATOR_HOOKABLE(UpdateCrosshair, EV_NO_ARGS); /** * Called when a temp entity is parsed - * NOTE: hooks MUST start with `if (MUTATOR_RETURNVALUE) return false;` - * NOTE: hooks MUST start with `if (!ReadMutatorEquals(mutator_argv_int_0, name_of_mutator)) return false;` - * NOTE: return true if you handled the command, return false to continue handling + * NOTE: hooks MUST start with: + * if (MUTATOR_RETURNVALUE) return; + * if (!ReadMutatorEquals(mutator_argv_int_0, name_of_mutator)) return; + * return = true; */ #define EV_CSQC_Parse_TempEntity(i, o) \ /** mutator id */ i(int, mutator_argv_int_0) \ @@ -51,9 +52,9 @@ MUTATOR_HOOKABLE(CSQC_Parse_TempEntity, EV_CSQC_Parse_TempEntity); /** * Called when a shared entity is updated - * NOTE: hooks MUST start with `if (MUTATOR_RETURNVALUE) return false;` - * NOTE: hooks MUST start with `if (!ReadMutatorEquals(mutator_argv_int_0, name_of_mutator)) return false;` - * NOTE: return true if you handled the command, return false to continue handling + * if (MUTATOR_RETURNVALUE) return; + * if (!ReadMutatorEquals(mutator_argv_int_0, name_of_mutator)) return; + * return = true; */ #define EV_CSQC_Ent_Update(i, o) \ /** mutator id */ i(int, mutator_argv_int_0) \ diff --git a/qcsrc/client/prandom.qc b/qcsrc/client/prandom.qc deleted file mode 100644 index 12e4e0ea5..000000000 --- a/qcsrc/client/prandom.qc +++ /dev/null @@ -1,52 +0,0 @@ -#include "prandom.qh" -#include "_all.qh" - -#include "../warpzonelib/mathlib.qh" - -// prandom - PREDICTABLE random number generator (not seeded yet) - -#ifdef USE_PRANDOM -float prandom_seed; -float prandom() -{ - float c; - c = crc16(false, strcat(ftos(prandom_seed), ftos(prandom_seed + M_PI))); - prandom_seed = c; - -#ifdef USE_PRANDOM_DEBUG - dprint("RANDOM -> ", ftos(c), "\n"); -#endif - - return c / 65536; // in [0..1[ -} - -vector prandomvec() -{ - vector v; - - do - { - v.x = prandom(); - v.y = prandom(); - v.z = prandom(); - } - while(v * v > 1); - - return v; -} - -void psrandom(float seed) -{ - prandom_seed = seed; -#ifdef USE_PRANDOM_DEBUG - dprint("SRANDOM ", ftos(seed), "\n"); -#endif -} - -#ifdef USE_PRANDOM_DEBUG -void prandom_debug() -{ - dprint("Current random seed = ", ftos(prandom_seed), "\n"); -} -#endif -#endif diff --git a/qcsrc/client/prandom.qh b/qcsrc/client/prandom.qh deleted file mode 100644 index a7653a505..000000000 --- a/qcsrc/client/prandom.qh +++ /dev/null @@ -1,24 +0,0 @@ -#ifndef PRANDOM_H -#define PRANDOM_H - -// prandom - PREDICTABLE random number generator - -#define USE_PRANDOM - -#ifdef USE_PRANDOM -float prandom(); -vector prandomvec(); - -void psrandom(float seed); -#ifdef USE_PRANDOM_DEBUG -void prandom_debug(); -#else -#define prandom_debug() -#endif -#else -#define prandom random -#define prandomvec randomvec -#define psrandom(x) -#define prandom_debug() -#endif -#endif diff --git a/qcsrc/client/progs.src b/qcsrc/client/progs.src index 1b5471b94..6941d86da 100644 --- a/qcsrc/client/progs.src +++ b/qcsrc/client/progs.src @@ -8,7 +8,6 @@ announcer.qc bgmscript.qc -casings.qc controlpoint.qc csqcmodel_hooks.qc damage.qc @@ -26,7 +25,6 @@ movelib.qc noise.qc particles.qc player_skeleton.qc -prandom.qc rubble.qc scoreboard.qc shownames.qc diff --git a/qcsrc/common/constants.qh b/qcsrc/common/constants.qh index 707840188..a85f09e1b 100644 --- a/qcsrc/common/constants.qh +++ b/qcsrc/common/constants.qh @@ -83,7 +83,6 @@ const int ENT_CLIENT_RADARLINK = 11; // flags [startorigin] [endorigin] [startco const int ENT_CLIENT_PROJECTILE = 12; const int ENT_CLIENT_GIBSPLASH = 13; const int ENT_CLIENT_DAMAGEINFO = 14; -const int ENT_CLIENT_CASING = 15; const int ENT_CLIENT_INIT = 16; const int ENT_CLIENT_MAPVOTE = 17; const int ENT_CLIENT_CLIENTDATA = 18; diff --git a/qcsrc/common/mutators/all.inc b/qcsrc/common/mutators/all.inc index ffdc453f1..1d02fc371 100644 --- a/qcsrc/common/mutators/all.inc +++ b/qcsrc/common/mutators/all.inc @@ -1,3 +1,4 @@ +#include "mutator/casings.qc" #include "mutator/damagetext.qc" #include "mutator/itemstime.qc" #include "mutator/waypoints/waypointsprites.qc" diff --git a/qcsrc/common/mutators/mutator/casings.qc b/qcsrc/common/mutators/mutator/casings.qc new file mode 100644 index 000000000..a9a86f81f --- /dev/null +++ b/qcsrc/common/mutators/mutator/casings.qc @@ -0,0 +1,177 @@ +#include "../../util.qh" + +#ifdef CSQC +#include "../../movetypes/movetypes.qh" +#include "../../../client/rubble.qh" +#endif + +REGISTER_MUTATOR(casings, true); + +#ifdef SVQC +void SpawnCasing(vector vel, float randomvel, vector ang, vector avel, float randomavel, int casingtype, entity casingowner) +{ + vector org = self.origin + self.view_ofs + self.weaponentity.spawnorigin.x * v_forward - self.weaponentity.spawnorigin.y * v_right + self.weaponentity.spawnorigin.z * v_up; + + if (!sound_allowed(MSG_BROADCAST, casingowner)) + casingtype |= 0x80; + + WriteByte(MSG_ALL, SVC_TEMPENTITY); + WriteMutator(MSG_ALL, casings); + WriteByte(MSG_ALL, casingtype); + WriteCoord(MSG_ALL, org.x); + WriteCoord(MSG_ALL, org.y); + WriteCoord(MSG_ALL, org.z); + WriteShort(MSG_ALL, compressShortVector(vel)); // actually compressed velocity + WriteByte(MSG_ALL, ang.x * 256 / 360); + WriteByte(MSG_ALL, ang.y * 256 / 360); + WriteByte(MSG_ALL, ang.z * 256 / 360); +} +#endif + +#ifdef CSQC +entityclass(Casing); +class(Casing) .float alpha; +class(Casing) .bool silent; +class(Casing) .int state; +class(Casing) .float cnt; + +void Casing_Delete() +{ + remove(self); +} + +void Casing_Draw() +{ + if (self.move_flags & FL_ONGROUND) + { + self.move_angles_x = 0; + self.move_angles_z = 0; + self.flags &= ~FL_ONGROUND; + } + + Movetype_Physics_MatchTicrate(autocvar_cl_casings_ticrate, autocvar_cl_casings_sloppy); + if (wasfreed(self)) + return; // deleted by touch function + + self.renderflags = 0; + self.alpha = bound(0, self.cnt - time, 1); + + if (self.alpha < ALPHA_MIN_VISIBLE) + { + Casing_Delete(); + self.drawmask = 0; + } +} + +void Casing_Touch() +{ + if (trace_dphitq3surfaceflags & Q3SURFACEFLAG_NOIMPACT) + { + Casing_Delete(); + return; + } + + if (!self.silent) + if (!trace_ent || trace_ent.solid == SOLID_BSP) + { + if (vlen(self.velocity) > 50) + { + if (time >= self.nextthink) + { + string s; + int f = floor(prandom() * 3) + 1; + + switch (self.state) + { + case 1: + s = W_Sound(strcat("casings", itos(f))); + break; + default: + s = W_Sound(strcat("brass", itos(f))); + break; + } + + sound (self, CH_SHOTS, s, VOL_BASE, ATTEN_LARGE); + } + } + } + + self.nextthink = time + 0.2; +} + +void Casing_Damage(float thisdmg, int hittype, vector org, vector thisforce) +{ + if (thisforce.z < 0) + thisforce.z = 0; + self.move_velocity = self.move_velocity + thisforce + '0 0 100'; + self.move_flags &= ~FL_ONGROUND; +} + +MUTATOR_HOOKFUNCTION(casings, CSQC_Parse_TempEntity) +{ + if (MUTATOR_RETURNVALUE) return; + if (!ReadMutatorEquals(mutator_argv_int_0, casings)) return; + return = true; + + int _state = ReadByte(); + vector org; + org_x = ReadCoord(); + org_y = ReadCoord(); + org_z = ReadCoord(); + vector vel = decompressShortVector(ReadShort()); + vector ang; + ang_x = ReadByte() * 360 / 256; + ang_y = ReadByte() * 360 / 256; + ang_z = ReadByte() * 360 / 256; + + if (!autocvar_cl_casings) return; + + Casing casing = RubbleNew("casing"); + casing.silent = (_state & 0x80); + casing.state = (_state & 0x7F); + casing.origin = org; + setorigin(casing, casing.origin); + casing.velocity = vel; + casing.angles = ang; + casing.drawmask = MASK_NORMAL; + + casing.draw = Casing_Draw; + casing.move_origin = casing.origin; + casing.move_velocity = casing.velocity + 2 * prandomvec(); + casing.move_angles = casing.angles; + casing.move_avelocity = '0 250 0' + 100 * prandomvec(); + casing.move_movetype = MOVETYPE_BOUNCE; + casing.move_touch = Casing_Touch; + casing.move_time = time; + casing.event_damage = Casing_Damage; + casing.solid = SOLID_TRIGGER; + + switch (casing.state) + { + case 1: + setmodel(casing, "models/casing_shell.mdl"); + casing.cnt = time + autocvar_cl_casings_shell_time; + break; + default: + setmodel(casing, "models/casing_bronze.iqm"); + casing.cnt = time + autocvar_cl_casings_bronze_time; + break; + } + + setsize(casing, '0 0 -1', '0 0 -1'); + + RubbleLimit("casing", autocvar_cl_casings_maxcount, Casing_Delete); +} + +STATIC_INIT(Casings) +{ + precache_model("models/casing_shell.mdl"); + precache_model("models/casing_bronze.iqm"); + precache_sound(W_Sound("brass1")); + precache_sound(W_Sound("brass2")); + precache_sound(W_Sound("brass3")); + precache_sound(W_Sound("casings1")); + precache_sound(W_Sound("casings2")); + precache_sound(W_Sound("casings3")); +} +#endif diff --git a/qcsrc/lib/_all.inc b/qcsrc/lib/_all.inc index 5a55b538b..108790668 100644 --- a/qcsrc/lib/_all.inc +++ b/qcsrc/lib/_all.inc @@ -5,6 +5,7 @@ #include "Lazy.qh" #include "Nil.qh" #include "OO.qh" +#include "prandom.qc" #include "Progname.qh" #include "Registry.qh" #include "test.qc" diff --git a/qcsrc/lib/prandom.qc b/qcsrc/lib/prandom.qc new file mode 100644 index 000000000..8b1f8d938 --- /dev/null +++ b/qcsrc/lib/prandom.qc @@ -0,0 +1,51 @@ +#include "prandom.qh" + +#include "../warpzonelib/mathlib.qh" + +// prandom - PREDICTABLE random number generator (not seeded yet) + +#ifdef USE_PRANDOM +float prandom_seed; +float prandom() +{ + float c; + c = crc16(false, strcat(ftos(prandom_seed), ftos(prandom_seed + M_PI))); + prandom_seed = c; + +#ifdef USE_PRANDOM_DEBUG + dprint("RANDOM -> ", ftos(c), "\n"); +#endif + + return c / 65536; // in [0..1[ +} + +vector prandomvec() +{ + vector v; + + do + { + v.x = prandom(); + v.y = prandom(); + v.z = prandom(); + } + while(v * v > 1); + + return v; +} + +void psrandom(float seed) +{ + prandom_seed = seed; +#ifdef USE_PRANDOM_DEBUG + dprint("SRANDOM ", ftos(seed), "\n"); +#endif +} + +#ifdef USE_PRANDOM_DEBUG +void prandom_debug() +{ + dprint("Current random seed = ", ftos(prandom_seed), "\n"); +} +#endif +#endif diff --git a/qcsrc/lib/prandom.qh b/qcsrc/lib/prandom.qh new file mode 100644 index 000000000..a7653a505 --- /dev/null +++ b/qcsrc/lib/prandom.qh @@ -0,0 +1,24 @@ +#ifndef PRANDOM_H +#define PRANDOM_H + +// prandom - PREDICTABLE random number generator + +#define USE_PRANDOM + +#ifdef USE_PRANDOM +float prandom(); +vector prandomvec(); + +void psrandom(float seed); +#ifdef USE_PRANDOM_DEBUG +void prandom_debug(); +#else +#define prandom_debug() +#endif +#else +#define prandom random +#define prandomvec randomvec +#define psrandom(x) +#define prandom_debug() +#endif +#endif diff --git a/qcsrc/server/g_casings.qc b/qcsrc/server/g_casings.qc deleted file mode 100644 index b9ad94e3f..000000000 --- a/qcsrc/server/g_casings.qc +++ /dev/null @@ -1,38 +0,0 @@ -#include "_all.qh" - -#include "../common/util.qh" - -float Casing_SendEntity(entity to, int sf) -{ - WriteByte(MSG_ENTITY, ENT_CLIENT_CASING); - WriteByte(MSG_ENTITY, self.state); // actually type - WriteCoord(MSG_ENTITY, self.origin.x); - WriteCoord(MSG_ENTITY, self.origin.y); - WriteCoord(MSG_ENTITY, self.origin.z); - WriteShort(MSG_ENTITY, self.oldorigin.x); // acrually compressed velocity - WriteByte(MSG_ENTITY, self.angles.x * 256 / 360); - WriteByte(MSG_ENTITY, self.angles.y * 256 / 360); - WriteByte(MSG_ENTITY, self.angles.z * 256 / 360); - return true; -} - -void SpawnCasing(vector vel, float randomvel, vector ang, vector avel, float randomavel, int casingtype, entity casingowner) -{ - entity e; - vector org; - - org = self.origin + self.view_ofs + self.weaponentity.spawnorigin.x * v_forward - self.weaponentity.spawnorigin.y * v_right + self.weaponentity.spawnorigin.z * v_up; - - if(!sound_allowed(MSG_BROADCAST, casingowner)) - casingtype |= 0x80; - - e = spawn(); - e.state = casingtype; - setorigin(e, org); - e.velocity = vel; - e.angles = ang; - e.oldorigin_x = compressShortVector(e.velocity); - - Net_LinkEntity(e, true, 0.2, Casing_SendEntity); - // 0.2s should be enough time for all clients to receive this ent once, do the gibbage and be done with it -} diff --git a/qcsrc/server/progs.src b/qcsrc/server/progs.src index 61ec76196..9dd0fae9b 100644 --- a/qcsrc/server/progs.src +++ b/qcsrc/server/progs.src @@ -19,7 +19,6 @@ cl_player.qc controlpoint.qc csqceffects.qc ent_cs.qc -g_casings.qc g_damage.qc g_hook.qc // g_lights.qc // TODO: was never used