From 5de1b522522a77539a109a255619983b8a56673c Mon Sep 17 00:00:00 2001 From: Mario Date: Tue, 17 Mar 2015 02:00:13 +1100 Subject: [PATCH] Network impulse triggers --- qcsrc/client/main.qc | 1 + qcsrc/client/miscfunctions.qc | 4 +- qcsrc/client/miscfunctions.qh | 2 +- qcsrc/common/constants.qh | 2 +- qcsrc/common/triggers/trigger/impulse.qc | 200 ++++++++++++++--------- qcsrc/common/triggers/trigger/impulse.qh | 4 + qcsrc/common/triggers/trigger/include.qh | 1 + qcsrc/csqcmodellib/cl_player.qc | 2 +- 8 files changed, 137 insertions(+), 79 deletions(-) diff --git a/qcsrc/client/main.qc b/qcsrc/client/main.qc index 0b75058b4..f51674b0b 100644 --- a/qcsrc/client/main.qc +++ b/qcsrc/client/main.qc @@ -854,6 +854,7 @@ void CSQC_Ent_Update(float bIsNewEntity) case ENT_CLIENT_CORNER: ent_corner(); break; case ENT_CLIENT_KEYLOCK: ent_keylock(); break; case ENT_CLIENT_TRAIN: ent_train(); break; + case ENT_CLIENT_TRIGGER_IMPULSE: ent_trigger_impulse(); break; default: //error(strcat(_("unknown entity type in CSQC_Ent_Update: %d\n"), self.enttype)); diff --git a/qcsrc/client/miscfunctions.qc b/qcsrc/client/miscfunctions.qc index 95f94794b..683f455bf 100644 --- a/qcsrc/client/miscfunctions.qc +++ b/qcsrc/client/miscfunctions.qc @@ -459,11 +459,11 @@ void PolyDrawModel(entity e) break; } -void DrawCircleClippedPic(vector centre, float radius, string pic, float f, vector rgb, float a, float drawflag) +void DrawCircleClippedPic(vector centre, float radi, string pic, float f, vector rgb, float a, float drawflag) { float x, y, q, d; vector ringsize, v, t; - ringsize = radius * '1 1 0'; + ringsize = radi * '1 1 0'; x = cos(f * 2 * M_PI); y = sin(f * 2 * M_PI); diff --git a/qcsrc/client/miscfunctions.qh b/qcsrc/client/miscfunctions.qh index 142d00a23..9b97b88c2 100644 --- a/qcsrc/client/miscfunctions.qh +++ b/qcsrc/client/miscfunctions.qh @@ -154,7 +154,7 @@ void drawcolorcodedstring_aspect_expanding(vector pos, string text, vector sz, f float PolyDrawModelSurface(entity e, float i_s); void PolyDrawModel(entity e); -void DrawCircleClippedPic(vector centre, float radius, string pic, float f, vector rgb, float a, float drawflag); +void DrawCircleClippedPic(vector centre, float radi, string pic, float f, vector rgb, float a, float drawflag); const vector GETPLAYERORIGIN_ERROR = '1123581321 2357111317 3141592653'; // way out of bounds for anything on the map vector getplayerorigin(int pl); diff --git a/qcsrc/common/constants.qh b/qcsrc/common/constants.qh index 4c8d448dd..9e1355ba4 100644 --- a/qcsrc/common/constants.qh +++ b/qcsrc/common/constants.qh @@ -110,7 +110,7 @@ const int ENT_CLIENT_CONVEYOR = 64; const int ENT_CLIENT_DOOR = 65; const int ENT_CLIENT_TRAIN = 66; const int ENT_CLIENT_PLAT = 67; -// 68 +const int ENT_CLIENT_TRIGGER_IMPULSE = 68; const int ENT_CLIENT_SWAMP = 69; const int ENT_CLIENT_CORNER = 70; const int ENT_CLIENT_KEYLOCK = 71; diff --git a/qcsrc/common/triggers/trigger/impulse.qc b/qcsrc/common/triggers/trigger/impulse.qc index d4368812f..601988539 100644 --- a/qcsrc/common/triggers/trigger/impulse.qc +++ b/qcsrc/common/triggers/trigger/impulse.qc @@ -1,10 +1,9 @@ -#ifdef SVQC // targeted (directional) mode void trigger_impulse_touch1() { entity targ; - float pushdeltatime; - float str; + float pushdeltatime; + float str; if (self.active != ACTIVE_ACTIVE) return; @@ -14,37 +13,43 @@ void trigger_impulse_touch1() EXACTTRIGGER_TOUCH; - targ = find(world, targetname, self.target); - if(!targ) - { - objerror("trigger_force without a (valid) .target!\n"); - remove(self); - return; - } - - str = min(self.radius, vlen(self.origin - other.origin)); - - if(self.falloff == 1) - str = (str / self.radius) * self.strength; - else if(self.falloff == 2) - str = (1 - (str / self.radius)) * self.strength; - else - str = self.strength; - - pushdeltatime = time - other.lastpushtime; - if (pushdeltatime > 0.15) pushdeltatime = 0; - other.lastpushtime = time; - if(!pushdeltatime) return; - - other.velocity = other.velocity + normalize(targ.origin - self.origin) * str * pushdeltatime; - other.flags &= ~FL_ONGROUND; - UpdateCSQCProjectile(other); + targ = find(world, targetname, self.target); + if(!targ) + { + objerror("trigger_force without a (valid) .target!\n"); + remove(self); + return; + } + + str = min(self.radius, vlen(self.origin - other.origin)); + + if(self.falloff == 1) + str = (str / self.radius) * self.strength; + else if(self.falloff == 2) + str = (1 - (str / self.radius)) * self.strength; + else + str = self.strength; + + pushdeltatime = time - other.lastpushtime; + if (pushdeltatime > 0.15) pushdeltatime = 0; + other.lastpushtime = time; + if(!pushdeltatime) return; + +#ifdef CSQC + print("Touchie!\n"); +#endif + + other.velocity = other.velocity + normalize(targ.origin - self.origin) * str * pushdeltatime; + other.flags &= ~FL_ONGROUND; +#ifdef SVQC + UpdateCSQCProjectile(other); +#endif } // Directionless (accelerator/decelerator) mode void trigger_impulse_touch2() { - float pushdeltatime; + float pushdeltatime; if (self.active != ACTIVE_ACTIVE) return; @@ -54,21 +59,23 @@ void trigger_impulse_touch2() EXACTTRIGGER_TOUCH; - pushdeltatime = time - other.lastpushtime; - if (pushdeltatime > 0.15) pushdeltatime = 0; - other.lastpushtime = time; - if(!pushdeltatime) return; + pushdeltatime = time - other.lastpushtime; + if (pushdeltatime > 0.15) pushdeltatime = 0; + other.lastpushtime = time; + if(!pushdeltatime) return; - // div0: ticrate independent, 1 = identity (not 20) - other.velocity = other.velocity * pow(self.strength, pushdeltatime); - UpdateCSQCProjectile(other); + // div0: ticrate independent, 1 = identity (not 20) + other.velocity = other.velocity * pow(self.strength, pushdeltatime); +#ifdef SVQC + UpdateCSQCProjectile(other); +#endif } // Spherical (gravity/repulsor) mode void trigger_impulse_touch3() { - float pushdeltatime; - float str; + float pushdeltatime; + float str; if (self.active != ACTIVE_ACTIVE) return; @@ -78,34 +85,36 @@ void trigger_impulse_touch3() EXACTTRIGGER_TOUCH; - pushdeltatime = time - other.lastpushtime; - if (pushdeltatime > 0.15) pushdeltatime = 0; - other.lastpushtime = time; - if(!pushdeltatime) return; + pushdeltatime = time - other.lastpushtime; + if (pushdeltatime > 0.15) pushdeltatime = 0; + other.lastpushtime = time; + if(!pushdeltatime) return; - setsize(self, '-1 -1 -1' * self.radius,'1 1 1' * self.radius); + setsize(self, '-1 -1 -1' * self.radius,'1 1 1' * self.radius); str = min(self.radius, vlen(self.origin - other.origin)); - if(self.falloff == 1) - str = (1 - str / self.radius) * self.strength; // 1 in the inside - else if(self.falloff == 2) - str = (str / self.radius) * self.strength; // 0 in the inside - else - str = self.strength; + if(self.falloff == 1) + str = (1 - str / self.radius) * self.strength; // 1 in the inside + else if(self.falloff == 2) + str = (str / self.radius) * self.strength; // 0 in the inside + else + str = self.strength; - other.velocity = other.velocity + normalize(other.origin - self.origin) * str * pushdeltatime; - UpdateCSQCProjectile(other); + other.velocity = other.velocity + normalize(other.origin - self.origin) * str * pushdeltatime; +#ifdef SVQC + UpdateCSQCProjectile(other); +#endif } /*QUAKED spawnfunc_trigger_impulse (.5 .5 .5) ? -------- KEYS -------- target : If this is set, this points to the spawnfunc_target_position to which the player will get pushed. - If not, this trigger acts like a damper/accelerator field. + If not, this trigger acts like a damper/accelerator field. strength : This is how mutch force to add in the direction of .target each second - when .target is set. If not, this is hoe mutch to slow down/accelerate - someting cought inside this trigger. (1=no change, 0,5 half speed rougthly each tic, 2 = doubble) + when .target is set. If not, this is hoe mutch to slow down/accelerate + someting cought inside this trigger. (1=no change, 0,5 half speed rougthly each tic, 2 = doubble) radius : If set, act as a spherical device rather then a liniar one. @@ -115,32 +124,75 @@ falloff : 0 = none, 1 = liniar, 2 = inverted liniar Use a brush textured with common/origin in the trigger entity to determine the origin of the force in directional and sperical mode. For damper/accelerator mode this is not nessesary (and has no effect). */ +#ifdef SVQC +bool trigger_impulse_send(entity to, int sf) +{ + WriteByte(MSG_ENTITY, ENT_CLIENT_TRIGGER_IMPULSE); + + WriteCoord(MSG_ENTITY, self.radius); + WriteCoord(MSG_ENTITY, self.strength); + WriteByte(MSG_ENTITY, self.falloff); + WriteByte(MSG_ENTITY, self.active); + + trigger_common_write(true); + + return true; +} + +void trigger_impulse_link() +{ + Net_LinkEntity(self, 0, false, trigger_impulse_send); +} void spawnfunc_trigger_impulse() { self.active = ACTIVE_ACTIVE; EXACTTRIGGER_INIT; - if(self.radius) - { - if(!self.strength) self.strength = 2000 * autocvar_g_triggerimpulse_radial_multiplier; - setorigin(self, self.origin); - setsize(self, '-1 -1 -1' * self.radius,'1 1 1' * self.radius); - self.touch = trigger_impulse_touch3; - } - else - { - if(self.target) - { - if(!self.strength) self.strength = 950 * autocvar_g_triggerimpulse_directional_multiplier; - self.touch = trigger_impulse_touch1; - } - else - { - if(!self.strength) self.strength = 0.9; + if(self.radius) + { + if(!self.strength) self.strength = 2000 * autocvar_g_triggerimpulse_radial_multiplier; + setorigin(self, self.origin); + setsize(self, '-1 -1 -1' * self.radius,'1 1 1' * self.radius); + self.touch = trigger_impulse_touch3; + } + else + { + if(self.target) + { + if(!self.strength) self.strength = 950 * autocvar_g_triggerimpulse_directional_multiplier; + self.touch = trigger_impulse_touch1; + } + else + { + if(!self.strength) self.strength = 0.9; self.strength = pow(self.strength, autocvar_g_triggerimpulse_accel_power) * autocvar_g_triggerimpulse_accel_multiplier; - self.touch = trigger_impulse_touch2; - } - } + self.touch = trigger_impulse_touch2; + } + } + + trigger_impulse_link(); +} +#elif defined(CSQC) +void ent_trigger_impulse() +{ + self.radius = ReadCoord(); + self.strength = ReadCoord(); + self.falloff = ReadByte(); + self.active = ReadByte(); + + trigger_common_read(true); + + + self.classname = "trigger_impulse"; + self.solid = SOLID_TRIGGER; + self.entremove = trigger_remove_generic; + self.draw = trigger_draw_generic; + self.drawmask = MASK_NORMAL; + self.move_time = time; + + if(self.radius) { self.trigger_touch = trigger_impulse_touch3; } + else if(self.target) { self.trigger_touch = trigger_impulse_touch1; } + else { self.trigger_touch = trigger_impulse_touch2; } } #endif diff --git a/qcsrc/common/triggers/trigger/impulse.qh b/qcsrc/common/triggers/trigger/impulse.qh index 67d6361fb..a4c248dca 100644 --- a/qcsrc/common/triggers/trigger/impulse.qh +++ b/qcsrc/common/triggers/trigger/impulse.qh @@ -7,4 +7,8 @@ .float strength; .float lastpushtime; +#ifdef CSQC +void ent_trigger_impulse(); +#endif + #endif diff --git a/qcsrc/common/triggers/trigger/include.qh b/qcsrc/common/triggers/trigger/include.qh index 5c862b950..1601143ec 100644 --- a/qcsrc/common/triggers/trigger/include.qh +++ b/qcsrc/common/triggers/trigger/include.qh @@ -6,5 +6,6 @@ #include "secret.qh" #include "swamp.qh" #include "keylock.qh" +#include "impulse.qh" #endif diff --git a/qcsrc/csqcmodellib/cl_player.qc b/qcsrc/csqcmodellib/cl_player.qc index f16c5be85..1f5f2251f 100644 --- a/qcsrc/csqcmodellib/cl_player.qc +++ b/qcsrc/csqcmodellib/cl_player.qc @@ -244,7 +244,7 @@ void CSQCPlayer_SetCamera() v = v0; csqcplayer_status = CSQCPLAYERSTATUS_PREDICTED; CSQCPlayer_PredictTo(servercommandframe + 1, false); - CSQCPlayer_SetPredictionError(self.origin - o, self.velocity - v, pmove_onground - !!(self.pmove_flags & PMF_ONGROUND)); + CSQCPlayer_SetPredictionError(self.origin - o, self.velocity - v, pmove_onground - !!(self.flags & FL_ONGROUND)); self.origin = o; self.velocity = v; -- 2.39.2