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