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;
42 other.velocity = other.velocity + normalize(targ.origin - self.origin) * str * pushdeltatime;
43 other.flags &= ~FL_ONGROUND;
45 UpdateCSQCProjectile(other);
49 // Directionless (accelerator/decelerator) mode
50 void trigger_impulse_touch2()
54 if (self.active != ACTIVE_ACTIVE)
57 if (!isPushable(other))
62 pushdeltatime = time - other.lastpushtime;
63 if (pushdeltatime > 0.15) pushdeltatime = 0;
64 other.lastpushtime = time;
65 if(!pushdeltatime) return;
67 // div0: ticrate independent, 1 = identity (not 20)
68 other.velocity = other.velocity * pow(self.strength, pushdeltatime);
70 UpdateCSQCProjectile(other);
74 // Spherical (gravity/repulsor) mode
75 void trigger_impulse_touch3()
80 if (self.active != ACTIVE_ACTIVE)
83 if (!isPushable(other))
88 pushdeltatime = time - other.lastpushtime;
89 if (pushdeltatime > 0.15) pushdeltatime = 0;
90 other.lastpushtime = time;
91 if(!pushdeltatime) return;
93 setsize(self, '-1 -1 -1' * self.radius,'1 1 1' * self.radius);
95 str = min(self.radius, vlen(self.origin - other.origin));
98 str = (1 - str / self.radius) * self.strength; // 1 in the inside
99 else if(self.falloff == 2)
100 str = (str / self.radius) * self.strength; // 0 in the inside
104 other.velocity = other.velocity + normalize(other.origin - self.origin) * str * pushdeltatime;
106 UpdateCSQCProjectile(other);
110 /*QUAKED spawnfunc_trigger_impulse (.5 .5 .5) ?
111 -------- KEYS --------
112 target : If this is set, this points to the spawnfunc_target_position to which the player will get pushed.
113 If not, this trigger acts like a damper/accelerator field.
115 strength : This is how mutch force to add in the direction of .target each second
116 when .target is set. If not, this is hoe mutch to slow down/accelerate
117 someting cought inside this trigger. (1=no change, 0,5 half speed rougthly each tic, 2 = doubble)
119 radius : If set, act as a spherical device rather then a liniar one.
121 falloff : 0 = none, 1 = liniar, 2 = inverted liniar
123 -------- NOTES --------
124 Use a brush textured with common/origin in the trigger entity to determine the origin of the force
125 in directional and sperical mode. For damper/accelerator mode this is not nessesary (and has no effect).
128 bool trigger_impulse_send(entity to, int sf)
130 WriteByte(MSG_ENTITY, ENT_CLIENT_TRIGGER_IMPULSE);
132 WriteCoord(MSG_ENTITY, self.radius);
133 WriteCoord(MSG_ENTITY, self.strength);
134 WriteByte(MSG_ENTITY, self.falloff);
135 WriteByte(MSG_ENTITY, self.active);
137 trigger_common_write(true);
142 void trigger_impulse_link()
144 Net_LinkEntity(self, 0, false, trigger_impulse_send);
147 void spawnfunc_trigger_impulse()
149 self.active = ACTIVE_ACTIVE;
154 if(!self.strength) self.strength = 2000 * autocvar_g_triggerimpulse_radial_multiplier;
155 setorigin(self, self.origin);
156 setsize(self, '-1 -1 -1' * self.radius,'1 1 1' * self.radius);
157 self.touch = trigger_impulse_touch3;
163 if(!self.strength) self.strength = 950 * autocvar_g_triggerimpulse_directional_multiplier;
164 self.touch = trigger_impulse_touch1;
168 if(!self.strength) self.strength = 0.9;
169 self.strength = pow(self.strength, autocvar_g_triggerimpulse_accel_power) * autocvar_g_triggerimpulse_accel_multiplier;
170 self.touch = trigger_impulse_touch2;
174 trigger_impulse_link();
177 void ent_trigger_impulse()
179 self.radius = ReadCoord();
180 self.strength = ReadCoord();
181 self.falloff = ReadByte();
182 self.active = ReadByte();
184 trigger_common_read(true);
187 self.classname = "trigger_impulse";
188 self.solid = SOLID_TRIGGER;
189 self.entremove = trigger_remove_generic;
190 self.draw = trigger_draw_generic;
191 self.drawmask = MASK_NORMAL;
192 self.move_time = time;
194 if(self.radius) { self.trigger_touch = trigger_impulse_touch3; }
195 else if(self.target) { self.trigger_touch = trigger_impulse_touch1; }
196 else { self.trigger_touch = trigger_impulse_touch2; }