]> de.git.xonotic.org Git - xonotic/xonotic-data.pk3dir.git/blob - qcsrc/server/tturrets/units/unit_ewheel.qc
Merge remote branch 'origin/master' into samual/hagar_secondary_autorelease
[xonotic/xonotic-data.pk3dir.git] / qcsrc / server / tturrets / units / unit_ewheel.qc
1 #define ewheel_amin_stop 0
2 #define ewheel_amin_fwd_slow 1
3 #define ewheel_amin_fwd_fast 2
4 #define ewheel_amin_bck_slow 3
5 #define ewheel_amin_bck_fast 4
6
7 void turret_ewheel_projectile_explode()
8 {
9 #ifdef TURRET_DEBUG
10     float d;
11
12     d = RadiusDamage (self, self.owner, self.owner.shot_dmg, 0, self.owner.shot_radius, world, self.owner.shot_force, DEATH_TURRET_EWHEEL, world);
13     self.owner.tur_dbg_dmg_t_h = self.owner.tur_dbg_dmg_t_h + d;
14     self.owner.tur_dbg_dmg_t_f = self.owner.tur_dbg_dmg_t_f + self.owner.shot_dmg;
15 #else
16     RadiusDamage (self, self.owner, self.owner.shot_dmg, 0, self.owner.shot_radius, world, self.owner.shot_force, DEATH_TURRET_EWHEEL, world);
17 #endif
18
19     remove (self);
20 }
21
22
23 void ewheel_attack()
24 {
25     entity proj;
26     float i;
27
28     for (i = 0; i < 1; ++i)
29     {
30         turret_do_updates(self);
31
32         sound (self, CH_WEAPON_A, "weapons/lasergun_fire.wav", VOL_BASE, ATTN_NORM);
33         pointparticles(particleeffectnum("laser_muzzleflash"), self.tur_shotorg, self.tur_shotdir_updated * 1000, 1);
34
35         proj                    = spawn ();
36         setorigin(proj, self.tur_shotorg);
37         proj.classname       = "ewheel bolt";
38         proj.owner           = self;
39         proj.bot_dodge       = FALSE;
40         proj.bot_dodgerating = self.shot_dmg;
41         proj.think           = turret_ewheel_projectile_explode;
42         proj.nextthink       = time + 9;
43         //proj.solid           = SOLID_TRIGGER;
44         proj.movetype        = MOVETYPE_FLYMISSILE;
45         proj.velocity        = normalize(self.tur_shotdir_updated + randomvec() * self.shot_spread) * self.shot_speed;
46         proj.touch           = turret_ewheel_projectile_explode;
47         proj.enemy           = self.enemy;
48         proj.flags           = FL_PROJECTILE | FL_NOTARGET;
49         PROJECTILE_MAKETRIGGER(proj);
50
51         CSQCProjectile(proj, TRUE, PROJECTILE_LASER, TRUE);
52
53         self.tur_head.frame += 2;
54
55         if (self.tur_head.frame > 3)
56             self.tur_head.frame = 0;
57     }
58
59 }
60 //#define EWHEEL_FANCYPATH
61 void ewheel_move_path()
62 {
63 #ifdef EWHEEL_FANCYPATH
64     // Are we close enougth to a path node to switch to the next?
65     if (vlen(self.origin  - self.pathcurrent.origin) < 64)
66         if (self.pathcurrent.path_next == world)
67         {
68             // Path endpoint reached
69             pathlib_deletepath(self.pathcurrent.owner);
70             self.pathcurrent = world;
71
72             if (self.pathgoal)
73             {
74                 if (self.pathgoal.use)
75                     self.pathgoal.use();
76
77                 if (self.pathgoal.enemy)
78                 {
79                     self.pathcurrent = pathlib_astar(self.pathgoal.origin,self.pathgoal.enemy.origin);
80                     self.pathgoal = self.pathgoal.enemy;
81                 }
82             }
83             else
84                 self.pathgoal = world;
85         }
86         else
87             self.pathcurrent = self.pathcurrent.path_next;
88
89 #else
90     if (vlen(self.origin - self.pathcurrent.origin) < 64)    
91         self.pathcurrent = self.pathcurrent.enemy;
92 #endif
93
94     if (self.pathcurrent)
95     {
96
97         self.moveto = self.pathcurrent.origin;
98         self.steerto = steerlib_attract2(self.moveto, 0.5, 500, 0.95);
99
100         movelib_move_simple(v_forward, autocvar_g_turrets_unit_ewheel_speed_fast, 0.4);
101     }
102 }
103
104 void  ewheel_move_enemy()
105 {
106
107     float newframe;
108     
109     self.steerto = steerlib_arrive(self.enemy.origin,self.target_range_optimal);
110
111     //self.steerto = steerlib_standoff(self.enemy.origin,self.target_range_optimal);
112     //self.steerto = steerlib_beamsteer(self.steerto,1024,64,68,256);
113     self.moveto  = self.origin + self.steerto * 128;
114
115     if (self.tur_dist_enemy > self.target_range_optimal)
116     {
117         if ( self.tur_head.spawnshieldtime < 1 )
118         {
119             newframe = ewheel_amin_fwd_fast;
120             movelib_move_simple(v_forward, autocvar_g_turrets_unit_ewheel_speed_fast, 0.4);
121         }
122         else if (self.tur_head.spawnshieldtime < 2)
123         {
124
125             newframe = ewheel_amin_fwd_slow;
126             movelib_move_simple(v_forward, autocvar_g_turrets_unit_ewheel_speed_slow, 0.4);
127        }
128         else
129         {
130             newframe = ewheel_amin_fwd_slow;
131             movelib_move_simple(v_forward, autocvar_g_turrets_unit_ewheel_speed_slower, 0.4);
132         }
133     }
134     else if (self.tur_dist_enemy < self.target_range_optimal * 0.5)
135     {
136         newframe = ewheel_amin_bck_slow;
137         movelib_move_simple(v_forward * -1, autocvar_g_turrets_unit_ewheel_speed_slow, 0.4);
138     }
139     else
140     {
141         newframe = ewheel_amin_stop;
142         movelib_beak_simple(autocvar_g_turrets_unit_ewheel_speed_stop);
143     }
144     
145     if(self.frame != newframe)
146     {
147         self.frame = newframe;
148         self.SendFlags |= TNSF_ANIM;
149         self.anim_start_time = time;
150     }
151 }
152
153
154 void ewheel_move_idle()
155 {
156     if(self.frame != 0)
157     {
158         self.SendFlags |= TNSF_ANIM;
159         self.anim_start_time = time;
160     }
161
162     self.frame = 0;
163     if (vlen(self.velocity))
164         movelib_beak_simple(autocvar_g_turrets_unit_ewheel_speed_stop);
165 }
166
167 void ewheel_postthink()
168 {
169     float vz;
170     vector wish_angle, real_angle;
171
172     vz = self.velocity_z;
173
174     self.angles_x = anglemods(self.angles_x);
175     self.angles_y = anglemods(self.angles_y);
176
177     fixedmakevectors(self.angles);
178
179     wish_angle = normalize(self.steerto);
180     wish_angle = vectoangles(wish_angle);
181     real_angle = wish_angle - self.angles;
182     real_angle = shortangle_vxy(real_angle, self.tur_head.angles);
183
184     self.tur_head.spawnshieldtime = fabs(real_angle_y);
185     real_angle_y  = bound(-self.tur_head.aim_speed, real_angle_y, self.tur_head.aim_speed);
186     self.angles_y = (self.angles_y + real_angle_y);
187
188     if(self.enemy)
189         ewheel_move_enemy();
190     else if(self.pathcurrent)
191         ewheel_move_path();
192     else
193         ewheel_move_idle();
194
195
196     self.velocity_z = vz;
197     
198     if(vlen(self.velocity))
199         self.SendFlags |= TNSF_MOVE;
200 }
201
202 void ewheel_respawnhook()
203 {
204     entity e;
205
206     // Respawn is called & first spawn to, to set team. need to make sure we do not move the initial spawn.
207     if(self.movetype != MOVETYPE_WALK)
208                 return;
209                 
210     self.velocity = '0 0 0';
211     self.enemy = world;
212
213     setorigin(self, self.pos1);
214
215     if (self.target != "")
216     {
217         e = find(world,targetname,self.target);
218         if (!e)
219         {
220             dprint("Initital waypoint for ewheel does NOT exsist, fix your map!\n");
221             self.target = "";
222         }
223
224         if (e.classname != "turret_checkpoint")
225             dprint("Warning: not a turrret path\n");
226         else
227         {
228
229 #ifdef EWHEEL_FANCYPATH
230             self.pathcurrent = WALKER_PATH(self.origin,e.origin);
231             self.pathgoal = e;
232 #else
233             self.pathcurrent  = e;
234 #endif
235         }
236     }
237 }
238
239 void ewheel_diehook()
240 {
241     self.velocity = '0 0 0';
242
243 #ifdef EWHEEL_FANCYPATH
244     if (self.pathcurrent)
245         pathlib_deletepath(self.pathcurrent.owner);
246 #endif
247     self.pathcurrent = world;
248 }
249
250 void turret_ewheel_dinit()
251 {
252     entity e;
253
254     if (self.netname == "")      
255         self.netname     = "eWheel Turret";
256
257     if (self.target != "")
258     {
259         e = find(world,targetname,self.target);
260         if (!e)
261         {
262             bprint("Warning! initital waypoint for ewheel does NOT exsist!\n");
263             self.target = "";
264         }
265
266         if (e.classname != "turret_checkpoint")
267             dprint("Warning: not a turrret path\n");
268         else
269             self.goalcurrent = e;
270     }
271
272     self.ammo_flags = TFL_AMMO_ENERGY | TFL_AMMO_RECHARGE | TFL_AMMO_RECIVE;
273     self.turrcaps_flags = TFL_TURRCAPS_PLAYERKILL | TFL_TURRCAPS_MOVE | TFL_TURRCAPS_ROAM ;
274     self.turret_respawnhook = ewheel_respawnhook;
275
276     self.turret_diehook = ewheel_diehook;
277
278     if (turret_stdproc_init("ewheel_std", "models/turrets/ewheel-base2.md3", "models/turrets/ewheel-gun1.md3", TID_EWHEEL) == 0)
279     {
280         remove(self);
281         return;
282     }
283
284     self.target_select_flags   = TFL_TARGETSELECT_PLAYERS | TFL_TARGETSELECT_RANGELIMTS | TFL_TARGETSELECT_TEAMCHECK | TFL_TARGETSELECT_LOS;
285     self.target_validate_flags = TFL_TARGETSELECT_PLAYERS | TFL_TARGETSELECT_RANGELIMTS | TFL_TARGETSELECT_TEAMCHECK | TFL_TARGETSELECT_LOS;
286
287     self.damage_flags          |= TFL_DMG_DEATH_NOGIBS;
288
289     self.iscreature = TRUE;
290     self.movetype   = MOVETYPE_WALK;
291     self.solid      = SOLID_SLIDEBOX;
292     self.takedamage = DAMAGE_AIM;
293
294     setsize(self, '-32 -32 0', '32 32 48');
295     self.idle_aim = '0 0 0';
296
297     self.pos1 = self.origin;
298
299     // Our fire routine
300     self.turret_firefunc  = ewheel_attack;
301     self.turret_postthink = ewheel_postthink;
302     self.tur_head.frame = 1;
303
304     // Convert from dgr / sec to dgr / tic
305     self.tur_head.aim_speed = autocvar_g_turrets_unit_ewheel_turnrate;
306     self.tur_head.aim_speed = self.tur_head.aim_speed / (1 / self.ticrate);
307
308     //setorigin(self,self.origin + '0 0 128');
309     if (self.target != "")
310     {
311         e = find(world,targetname,self.target);
312         if (!e)
313         {
314             dprint("Initital waypoint for ewheel does NOT exsist, fix your map!\n");
315             self.target = "";
316         }
317
318         if (e.classname != "turret_checkpoint")
319             dprint("Warning: not a turrret path\n");
320         else
321         {
322 #ifdef EWHEEL_FANCYPATH
323             self.pathcurrent = WALKER_PATH(self.origin, e.origin);
324             self.pathgoal = e;
325 #else
326             self.pathcurrent = e;
327 #endif
328         }
329     }
330 }
331
332 void spawnfunc_turret_ewheel()
333 {
334     g_turrets_common_precash();
335
336     precache_model ("models/turrets/ewheel-base2.md3");
337     precache_model ("models/turrets/ewheel-gun1.md3");
338
339     self.think = turret_ewheel_dinit;
340     self.nextthink = time + 0.5;
341 }