]> git.xonotic.org Git - xonotic/xonotic-data.pk3dir.git/blob - qcsrc/common/turrets/util.qc
Add an intrusive list for entities that are damaged by contents (liquids etc)
[xonotic/xonotic-data.pk3dir.git] / qcsrc / common / turrets / util.qc
1 #include "util.qh"
2 /*
3 * Update this.tur_shotorg by getting up2date bone info
4 * NOTICE this func overwrites the global v_forward, v_right and v_up vectors.
5 */
6 float turret_tag_fire_update(entity this)
7 {
8         if(!this.tur_head)
9         {
10                 LOG_DEBUG("Call to turret_tag_fire_update with this.tur_head missing!");
11                 this.tur_shotorg = '0 0 0';
12                 return false;
13         }
14
15         this.tur_shotorg = gettaginfo(this.tur_head, gettagindex(this.tur_head, "tag_fire"));
16         v_forward = normalize(v_forward);
17
18         return true;
19 }
20
21 /*
22 * Railgun-like beam, but has thickness and suppots slowing of target
23 */
24 void FireImoBeam(entity this, vector start, vector end, vector smin, vector smax,
25                                   float bforce, float f_dmg, float f_velfactor, int deathtype)
26
27 {
28         vector hitloc, force, endpoint, dir;
29         entity ent;
30
31         dir = normalize(end - start);
32         force = dir * bforce;
33
34         // go a little bit into the wall because we need to hit this wall later
35         end = end + dir;
36
37         // trace multiple times until we hit a wall, each obstacle will be made unsolid.
38         // note down which entities were hit so we can damage them later
39         while (1)
40         {
41                 tracebox(start, smin, smax, end, false, this);
42
43                 // if it is NULL we can't hurt it so stop now
44                 if (trace_ent == NULL || trace_fraction == 1)
45                         break;
46
47                 if (trace_ent.solid == SOLID_BSP)
48                         break;
49
50                 // make the entity non-solid so we can hit the next one
51                 trace_ent.railgunhit = true;
52                 trace_ent.railgunhitloc = end;
53                 trace_ent.railgunhitsolidbackup = trace_ent.solid;
54
55                 // stop if this is a wall
56
57                 // make the entity non-solid
58                 trace_ent.solid = SOLID_NOT;
59         }
60
61         endpoint = trace_endpos;
62
63         // find all the entities the railgun hit and restore their solid state
64         ent = findfloat(NULL, railgunhit, true);
65         while (ent)
66         {
67                 // restore their solid type
68                 ent.solid = ent.railgunhitsolidbackup;
69                 ent = findfloat(ent, railgunhit, true);
70         }
71
72         // find all the entities the railgun hit and hurt them
73         ent = findfloat(NULL, railgunhit, true);
74         while (ent)
75         {
76                 // get the details we need to call the damage function
77                 hitloc = ent.railgunhitloc;
78                 ent.railgunhitloc = '0 0 0';
79                 ent.railgunhitsolidbackup = SOLID_NOT;
80                 ent.railgunhit = false;
81
82                 // apply the damage
83                 if (ent.takedamage)
84                 {
85                         Damage (ent, this, this, f_dmg, deathtype, hitloc, force);
86                         ent.velocity = ent.velocity * f_velfactor;
87                         //ent.alpha = 0.25 + random() * 0.75;
88                 }
89
90                 // advance to the next entity
91                 ent = findfloat(ent, railgunhit, true);
92         }
93         trace_endpos = endpoint;
94 }
95
96 #ifdef TURRET_DEBUG
97 void marker_think(entity this, )
98 {
99         if(this.cnt)
100         if(this.cnt < time)
101         {
102                 setthink(this, SUB_Remove);
103                 this.nextthink = time;
104                 return;
105         }
106
107         this.frame += 1;
108         if(this.frame > 29)
109                 this.frame = 0;
110
111         this.nextthink = time;
112 }
113
114 void mark_error(vector where,float lifetime)
115 {
116         entity err = new(error_marker);
117         setmodel(err, MDL_MARKER);
118         setorigin(err, where);
119         set_movetype(err, MOVETYPE_NONE);
120         setthink(err, marker_think);
121         err.nextthink = time;
122         err.skin = 0;
123         if(lifetime)
124                 err.cnt = lifetime + time;
125 }
126
127 void mark_info(vector where,float lifetime)
128 {
129         entity err = spawn(info_marker);
130         setmodel(err, MDL_MARKER);
131         setorigin(err, where);
132         set_movetype(err, MOVETYPE_NONE);
133         setthink(err, marker_think);
134         err.nextthink = time;
135         err.skin = 1;
136         if(lifetime)
137                 err.cnt = lifetime + time;
138 }
139
140 entity mark_misc(vector where,float lifetime)
141 {
142         entity err = spawn(mark_misc);
143         setmodel(err, MDL_MARKER);
144         setorigin(err, where);
145         set_movetype(err, MOVETYPE_NONE);
146         setthink(err, marker_think);
147         err.nextthink = time;
148         err.skin = 3;
149         if(lifetime)
150                 err.cnt = lifetime + time;
151         return err;
152 }
153
154 MODEL(TUR_C512, "models/turrets/c512.md3");
155
156 /*
157 * Paint a v_color colord circle on target onwho
158 * that fades away over f_time
159 */
160 void paint_target(entity onwho, float f_size, vector v_color, float f_time)
161 {
162         entity e;
163
164         e = spawn();
165         setmodel(e, MDL_TUR_C512); // precision set above
166         e.scale = (f_size/512);
167         //setsize(e, '0 0 0', '0 0 0');
168         //setattachment(e,onwho,"");
169         setorigin(e, onwho.origin + '0 0 1');
170         e.alpha = 0.15;
171         set_movetype(e, MOVETYPE_FLY);
172
173         e.velocity = (v_color * 32); // + '0 0 1' * 64;
174
175         e.colormod = v_color;
176         SUB_SetFade(e,time,f_time);
177 }
178
179 void paint_target2(entity onwho, float f_size, vector v_color, float f_time)
180 {
181         entity e;
182
183         e = spawn();
184         setmodel(e, MDL_TUR_C512); // precision set above
185         e.scale = (f_size/512);
186         setsize(e, '0 0 0', '0 0 0');
187
188         setorigin(e, onwho.origin + '0 0 1');
189         e.alpha = 0.15;
190         set_movetype(e, MOVETYPE_FLY);
191
192         e.velocity = (v_color * 32); // + '0 0 1' * 64;
193         e.avelocity_x = -128;
194
195         e.colormod = v_color;
196         SUB_SetFade(e,time,f_time);
197 }
198
199 void paint_target3(vector where, float f_size, vector v_color, float f_time)
200 {
201         entity e;
202         e = spawn();
203         setmodel(e, MDL_TUR_C512); // precision set above
204         e.scale = (f_size/512);
205         setsize(e, '0 0 0', '0 0 0');
206         setorigin(e, where + '0 0 1');
207         set_movetype(e, MOVETYPE_NONE);
208         e.velocity = '0 0 0';
209         e.colormod = v_color;
210         SUB_SetFade(e,time,f_time);
211 }
212 #endif