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