1 // targeted (directional) mode
2 void trigger_impulse_touch1()
8 if (self.active != ACTIVE_ACTIVE)
11 if (!isPushable(other))
16 targ = find(world, targetname, self.target);
19 objerror("trigger_force without a (valid) .target!\n");
24 str = min(self.radius, vlen(self.origin - other.origin));
27 str = (str / self.radius) * self.strength;
28 else if(self.falloff == 2)
29 str = (1 - (str / self.radius)) * self.strength;
33 pushdeltatime = time - other.lastpushtime;
34 if (pushdeltatime > 0.15) pushdeltatime = 0;
35 other.lastpushtime = time;
36 if(!pushdeltatime) return;
38 if(self.spawnflags & 64)
40 float addspeed = str - other.velocity * normalize(targ.origin - self.origin);
43 float accelspeed = min(8 * pushdeltatime * str, addspeed);
44 other.velocity += accelspeed * normalize(targ.origin - self.origin);
48 other.velocity = other.velocity + normalize(targ.origin - self.origin) * str * pushdeltatime;
49 other.flags &= ~FL_ONGROUND;
51 UpdateCSQCProjectile(other);
55 // Directionless (accelerator/decelerator) mode
56 void trigger_impulse_touch2()
60 if (self.active != ACTIVE_ACTIVE)
63 if (!isPushable(other))
68 pushdeltatime = time - other.lastpushtime;
69 if (pushdeltatime > 0.15) pushdeltatime = 0;
70 other.lastpushtime = time;
71 if(!pushdeltatime) return;
73 // div0: ticrate independent, 1 = identity (not 20)
74 other.velocity = other.velocity * pow(self.strength, pushdeltatime);
76 UpdateCSQCProjectile(other);
80 // Spherical (gravity/repulsor) mode
81 void trigger_impulse_touch3()
86 if (self.active != ACTIVE_ACTIVE)
89 if (!isPushable(other))
94 pushdeltatime = time - other.lastpushtime;
95 if (pushdeltatime > 0.15) pushdeltatime = 0;
96 other.lastpushtime = time;
97 if(!pushdeltatime) return;
99 setsize(self, '-1 -1 -1' * self.radius,'1 1 1' * self.radius);
101 str = min(self.radius, vlen(self.origin - other.origin));
103 if(self.falloff == 1)
104 str = (1 - str / self.radius) * self.strength; // 1 in the inside
105 else if(self.falloff == 2)
106 str = (str / self.radius) * self.strength; // 0 in the inside
110 other.velocity = other.velocity + normalize(other.origin - self.origin) * str * pushdeltatime;
112 UpdateCSQCProjectile(other);
116 REGISTER_NET_LINKED(ENT_CLIENT_TRIGGER_IMPULSE)
118 /*QUAKED spawnfunc_trigger_impulse (.5 .5 .5) ?
119 -------- KEYS --------
120 target : If this is set, this points to the spawnfunc_target_position to which the player will get pushed.
121 If not, this trigger acts like a damper/accelerator field.
123 strength : This is how mutch force to add in the direction of .target each second
124 when .target is set. If not, this is hoe mutch to slow down/accelerate
125 someting cought inside this trigger. (1=no change, 0,5 half speed rougthly each tic, 2 = doubble)
127 radius : If set, act as a spherical device rather then a liniar one.
129 falloff : 0 = none, 1 = liniar, 2 = inverted liniar
131 -------- NOTES --------
132 Use a brush textured with common/origin in the trigger entity to determine the origin of the force
133 in directional and sperical mode. For damper/accelerator mode this is not nessesary (and has no effect).
136 bool trigger_impulse_send(entity to, int sf)
138 WriteHeader(MSG_ENTITY, ENT_CLIENT_TRIGGER_IMPULSE);
140 WriteCoord(MSG_ENTITY, self.radius);
141 WriteCoord(MSG_ENTITY, self.strength);
142 WriteByte(MSG_ENTITY, self.falloff);
143 WriteByte(MSG_ENTITY, self.active);
145 trigger_common_write(true);
150 void trigger_impulse_link()
152 //Net_LinkEntity(self, 0, false, trigger_impulse_send);
155 spawnfunc(trigger_impulse)
157 self.active = ACTIVE_ACTIVE;
162 if(!self.strength) self.strength = 2000 * autocvar_g_triggerimpulse_radial_multiplier;
163 setorigin(self, self.origin);
164 setsize(self, '-1 -1 -1' * self.radius,'1 1 1' * self.radius);
165 self.touch = trigger_impulse_touch3;
171 if(!self.strength) self.strength = 950 * autocvar_g_triggerimpulse_directional_multiplier;
172 self.touch = trigger_impulse_touch1;
176 if(!self.strength) self.strength = 0.9;
177 self.strength = pow(self.strength, autocvar_g_triggerimpulse_accel_power) * autocvar_g_triggerimpulse_accel_multiplier;
178 self.touch = trigger_impulse_touch2;
182 trigger_impulse_link();
185 NET_HANDLE(ENT_CLIENT_TRIGGER_IMPULSE, bool isnew)
187 self.radius = ReadCoord();
188 self.strength = ReadCoord();
189 self.falloff = ReadByte();
190 self.active = ReadByte();
192 trigger_common_read(true);
195 self.classname = "trigger_impulse";
196 self.solid = SOLID_TRIGGER;
197 self.entremove = trigger_remove_generic;
198 self.draw = trigger_draw_generic;
199 self.drawmask = MASK_NORMAL;
200 self.move_time = time;
202 if(self.radius) { self.trigger_touch = trigger_impulse_touch3; }
203 else if(self.target) { self.trigger_touch = trigger_impulse_touch1; }
204 else { self.trigger_touch = trigger_impulse_touch2; }