]> de.git.xonotic.org Git - xonotic/xonotic-data.pk3dir.git/blob - qcsrc/common/triggers/trigger/impulse.qc
Merge branch 'master' into Mario/qc_physics_prehax
[xonotic/xonotic-data.pk3dir.git] / qcsrc / common / triggers / trigger / impulse.qc
1 #ifdef SVQC
2 // targeted (directional) mode
3 void trigger_impulse_touch1()
4 {
5         entity targ;
6     float pushdeltatime;
7     float str;
8
9         if (self.active != ACTIVE_ACTIVE)
10                 return;
11
12         if (!isPushable(other))
13                 return;
14
15         EXACTTRIGGER_TOUCH;
16
17     targ = find(world, targetname, self.target);
18     if(!targ)
19     {
20         objerror("trigger_force without a (valid) .target!\n");
21         remove(self);
22         return;
23     }
24
25     str = min(self.radius, vlen(self.origin - other.origin));
26
27     if(self.falloff == 1)
28         str = (str / self.radius) * self.strength;
29     else if(self.falloff == 2)
30         str = (1 - (str / self.radius)) * self.strength;
31     else
32         str = self.strength;
33
34     pushdeltatime = time - other.lastpushtime;
35     if (pushdeltatime > 0.15) pushdeltatime = 0;
36     other.lastpushtime = time;
37     if(!pushdeltatime) return;
38
39     other.velocity = other.velocity + normalize(targ.origin - self.origin) * str * pushdeltatime;
40     other.flags &= ~FL_ONGROUND;
41     UpdateCSQCProjectile(other);
42 }
43
44 // Directionless (accelerator/decelerator) mode
45 void trigger_impulse_touch2()
46 {
47     float pushdeltatime;
48
49         if (self.active != ACTIVE_ACTIVE)
50                 return;
51
52         if (!isPushable(other))
53                 return;
54
55         EXACTTRIGGER_TOUCH;
56
57     pushdeltatime = time - other.lastpushtime;
58     if (pushdeltatime > 0.15) pushdeltatime = 0;
59     other.lastpushtime = time;
60     if(!pushdeltatime) return;
61
62     // div0: ticrate independent, 1 = identity (not 20)
63     other.velocity = other.velocity * pow(self.strength, pushdeltatime);
64     UpdateCSQCProjectile(other);
65 }
66
67 // Spherical (gravity/repulsor) mode
68 void trigger_impulse_touch3()
69 {
70     float pushdeltatime;
71     float str;
72
73         if (self.active != ACTIVE_ACTIVE)
74                 return;
75
76         if (!isPushable(other))
77                 return;
78
79         EXACTTRIGGER_TOUCH;
80
81     pushdeltatime = time - other.lastpushtime;
82     if (pushdeltatime > 0.15) pushdeltatime = 0;
83     other.lastpushtime = time;
84     if(!pushdeltatime) return;
85
86     setsize(self, '-1 -1 -1' * self.radius,'1 1 1' * self.radius);
87
88         str = min(self.radius, vlen(self.origin - other.origin));
89
90     if(self.falloff == 1)
91         str = (1 - str / self.radius) * self.strength; // 1 in the inside
92     else if(self.falloff == 2)
93         str = (str / self.radius) * self.strength; // 0 in the inside
94     else
95         str = self.strength;
96
97     other.velocity = other.velocity + normalize(other.origin - self.origin) * str * pushdeltatime;
98     UpdateCSQCProjectile(other);
99 }
100
101 /*QUAKED spawnfunc_trigger_impulse (.5 .5 .5) ?
102 -------- KEYS --------
103 target : If this is set, this points to the spawnfunc_target_position to which the player will get pushed.
104          If not, this trigger acts like a damper/accelerator field.
105
106 strength : This is how mutch force to add in the direction of .target each second
107            when .target is set. If not, this is hoe mutch to slow down/accelerate
108            someting cought inside this trigger. (1=no change, 0,5 half speed rougthly each tic, 2 = doubble)
109
110 radius   : If set, act as a spherical device rather then a liniar one.
111
112 falloff : 0 = none, 1 = liniar, 2 = inverted liniar
113
114 -------- NOTES --------
115 Use a brush textured with common/origin in the trigger entity to determine the origin of the force
116 in directional and sperical mode. For damper/accelerator mode this is not nessesary (and has no effect).
117 */
118
119 void spawnfunc_trigger_impulse()
120 {
121         self.active = ACTIVE_ACTIVE;
122
123         EXACTTRIGGER_INIT;
124     if(self.radius)
125     {
126         if(!self.strength) self.strength = 2000 * autocvar_g_triggerimpulse_radial_multiplier;
127         setorigin(self, self.origin);
128         setsize(self, '-1 -1 -1' * self.radius,'1 1 1' * self.radius);
129         self.touch = trigger_impulse_touch3;
130     }
131     else
132     {
133         if(self.target)
134         {
135             if(!self.strength) self.strength = 950 * autocvar_g_triggerimpulse_directional_multiplier;
136             self.touch = trigger_impulse_touch1;
137         }
138         else
139         {
140             if(!self.strength) self.strength = 0.9;
141                         self.strength = pow(self.strength, autocvar_g_triggerimpulse_accel_power) * autocvar_g_triggerimpulse_accel_multiplier;
142             self.touch = trigger_impulse_touch2;
143         }
144     }
145 }
146 #endif