Xonotic QuakeC
The free, fast arena FPS with crisp movement and a wide array of weapons
impulse.qc
Go to the documentation of this file.
1#include "impulse.qh"
2// targeted (directional) mode
4{
5 entity targ;
6 float pushdeltatime;
7 float str;
8
9 if (this.active != ACTIVE_ACTIVE)
10 return;
11
12 if (!isPushable(toucher))
13 return;
14
16
17 targ = find(NULL, targetname, this.target);
18 if(!targ)
19 {
20 objerror(this, "trigger_force without a (valid) .target!\n");
21 delete(this);
22 return;
23 }
24
25 // falloff is not supported because radius is always 0 in directional mode
26 str = this.strength;
27
28 pushdeltatime = time - toucher.lastpushtime;
29 if (pushdeltatime > IMPULSE_MAX_PUSHDELTATIME)
30 {
31 pushdeltatime = 0;
32 }
33 toucher.lastpushtime = time;
34 if(!pushdeltatime)
35 {
36 return;
37 }
38
40 {
41 float addspeed = str - toucher.velocity * normalize(targ.origin - this.origin);
42 if (addspeed > 0)
43 {
44 float accelspeed = min(IMPULSE_DIRECTIONAL_MAX_ACCEL_FACTOR * pushdeltatime * str, addspeed);
45 toucher.velocity += accelspeed * normalize(targ.origin - this.origin);
46 }
47 }
48 else
49 toucher.velocity += normalize(targ.origin - this.origin) * str * pushdeltatime;
50
52
53#ifdef SVQC
55#endif
56}
57
58// Directionless (accelerator/decelerator) mode
60{
61 float pushdeltatime;
62
63 if (this.active != ACTIVE_ACTIVE)
64 return;
65
66 if (!isPushable(toucher))
67 return;
68
70
71 pushdeltatime = time - toucher.lastpushtime;
72 if (pushdeltatime > IMPULSE_MAX_PUSHDELTATIME)
73 {
74 pushdeltatime = 0;
75 }
76 toucher.lastpushtime = time;
77 if(!pushdeltatime)
78 {
79 return;
80 }
81
82 // div0: ticrate independent, 1 = identity (not 20)
83 toucher.velocity *= this.strength ** pushdeltatime;
84
85#ifdef SVQC
87#endif
88}
89
90// Spherical (gravity/repulsor) mode
92{
93 float pushdeltatime;
94 float str;
95
96 if (this.active != ACTIVE_ACTIVE)
97 return;
98
99 if (!isPushable(toucher))
100 return;
101
103
104 pushdeltatime = time - toucher.lastpushtime;
105 if (pushdeltatime > IMPULSE_MAX_PUSHDELTATIME)
106 {
107 pushdeltatime = 0;
108 }
109 toucher.lastpushtime = time;
110 if(!pushdeltatime)
111 {
112 return;
113 }
114
115 setsize(this, '-1 -1 -1' * this.radius,'1 1 1' * this.radius);
116
117 str = min(this.radius, vlen(this.origin - toucher.origin));
118
119 if(this.falloff == FALLOFF_LINEAR)
120 str = (1 - str / this.radius) * this.strength; // 1 in the inside
121 else if(this.falloff == FALLOFF_LINEAR_INV)
122 str = (str / this.radius) * this.strength; // 0 in the inside
123 else
124 str = this.strength;
125
126 toucher.velocity += normalize(toucher.origin - this.origin) * str * pushdeltatime;
127
128#ifdef SVQC
130#endif
131}
132
133REGISTER_NET_LINKED(ENT_CLIENT_TRIGGER_IMPULSE)
134
135/*QUAKED spawnfunc_trigger_impulse (.5 .5 .5) ?
136Force field
137-------- KEYS --------
138target : If this is set, this points to the spawnfunc_target_position to which the player will get pushed.
139 If not, this trigger acts like a damper/accelerator field.
140
141strength : This is how much force to add in the direction of .target each second
142 when .target is set. If not, this is how much to slow down/accelerate
143 something cought inside this trigger. (1=no change, 0,5 half speed rougthly each tic, 2 = doubble)
144
145radius : If set, act as a spherical device rather then a linear one.
146
147falloff : 0 = none, 1 = liniar, 2 = inverted liniar
148
149-------- NOTES --------
150Use a brush textured with common/origin in the trigger entity to determine the origin of the force
151in directional and sperical mode. For damper/accelerator mode this is not nessesary (and has no effect).
152*/
153#ifdef SVQC
154bool trigger_impulse_send(entity this, entity to, int sf)
155{
156 WriteHeader(MSG_ENTITY, ENT_CLIENT_TRIGGER_IMPULSE);
157
163
164 trigger_common_write(this, true);
165
166 return true;
167}
168
173
174spawnfunc(trigger_impulse)
175{
176 this.active = ACTIVE_ACTIVE;
179
180 if(this.radius)
181 {
182 if(!this.strength)
183 {
185 }
186 setorigin(this, this.origin);
187 setsize(this, '-1 -1 -1' * this.radius,'1 1 1' * this.radius);
189 }
190 else
191 {
192 if(this.target)
193 {
194 if(!this.strength)
195 {
197 }
199 }
200 else
201 {
202 if(!this.strength)
203 {
205 }
208 }
209 }
210
212}
213#elif defined(CSQC)
214NET_HANDLE(ENT_CLIENT_TRIGGER_IMPULSE, bool isnew)
215{
216 this.spawnflags = ReadByte();
217 this.radius = ReadCoord();
218 this.strength = ReadCoord();
219 this.falloff = ReadByte();
220 this.active = ReadByte();
221
222 trigger_common_read(this, true);
223 return = true;
224
225 this.solid = SOLID_TRIGGER;
226 this.entremove = trigger_remove_generic;
227 this.move_time = time;
228
229 if (this.radius)
230 {
232 }
233 else if (this.target)
234 {
236 }
237 else
238 {
240 }
241}
242#endif
var entity(vector mins, vector maxs,.entity tofield) findbox_tofield_OrFallback
int spawnflags
Definition ammo.qh:15
void trigger_impulse_touch_directional(entity this, entity toucher)
Definition impulse.qc:3
bool trigger_impulse_send(entity this, entity to, int sf)
Definition impulse.qc:154
void trigger_impulse_link(entity this)
Definition impulse.qc:169
void trigger_impulse_touch_accel(entity this, entity toucher)
Definition impulse.qc:59
void trigger_impulse_touch_radial(entity this, entity toucher)
Definition impulse.qc:91
const float IMPULSE_MAX_PUSHDELTATIME
Definition impulse.qh:26
float strength
Definition impulse.qh:13
const float IMPULSE_DEFAULT_RADIAL_STRENGTH
Definition impulse.qh:22
float radius
Definition impulse.qh:11
const float IMPULSE_DEFAULT_DIRECTIONAL_STRENGTH
Definition impulse.qh:23
float autocvar_g_triggerimpulse_directional_multiplier
Definition impulse.qh:6
const int IMPULSE_DIRECTIONAL_SPEEDTARGET
Definition impulse.qh:20
float autocvar_g_triggerimpulse_radial_multiplier
Definition impulse.qh:7
const int FALLOFF_LINEAR
Definition impulse.qh:17
const float IMPULSE_DEFAULT_ACCEL_STRENGTH
Definition impulse.qh:24
float autocvar_g_triggerimpulse_accel_power
Definition impulse.qh:5
const int FALLOFF_LINEAR_INV
Definition impulse.qh:18
int falloff
Definition impulse.qh:12
float autocvar_g_triggerimpulse_accel_multiplier
Definition impulse.qh:4
const float IMPULSE_DIRECTIONAL_MAX_ACCEL_FACTOR
Definition impulse.qh:28
const float SOLID_TRIGGER
float effects
float time
const float EF_NODEPTHTEST
vector origin
float solid
void UpdateCSQCProjectile(entity e)
int active
Definition defs.qh:34
const int ACTIVE_ACTIVE
Definition defs.qh:37
WriteByte(chan, ent.angles.y/DEC_FACTOR)
#define NET_HANDLE(id, param)
Definition net.qh:15
const int MSG_ENTITY
Definition net.qh:156
#define WriteHeader(to, id)
Definition net.qh:265
#define REGISTER_NET_LINKED(id)
Definition net.qh:91
int ReadByte()
#define EXACTTRIGGER_TOUCH(e, t)
Definition common.qh:118
#define BITSET_ASSIGN(a, b)
Definition common.qh:107
entity find(entity start,.string field, string match)
float vlen(vector v)
void WriteCoord(float data, float dest, float desto)
float min(float f,...)
vector normalize(vector v)
float move_time
Definition movetypes.qh:77
#define UNSET_ONGROUND(s)
Definition movetypes.qh:18
#define NULL
Definition post.qh:14
#define objerror
Definition pre.qh:8
entity entity toucher
Definition self.qh:76
#define settouch(e, f)
Definition self.qh:77
#define spawnfunc(id)
Definition spawnfunc.qh:107
void trigger_link(entity this, bool(entity this, entity to, int sendflags) sendfunc)
Definition triggers.qc:104
bool isPushable(entity e)
Definition triggers.qc:3
void trigger_common_write(entity this, bool withtarget)
Definition triggers.qc:110
void trigger_remove_generic(entity this)
string targetname
Definition triggers.qh:56
void trigger_common_read(entity this, bool withtarget)
string target
Definition triggers.qh:55
void WarpZoneLib_ExactTrigger_Init(entity this, bool unsetmodel)
Definition util_server.qc:8