]> de.git.xonotic.org Git - xonotic/xonotic-data.pk3dir.git/blob - qcsrc/common/turrets/unit/ewheel.qc
Merge branch 'master' into TimePath/global_self
[xonotic/xonotic-data.pk3dir.git] / qcsrc / common / turrets / unit / ewheel.qc
1 #ifdef REGISTER_TURRET
2 REGISTER_TURRET(
3 /* TUR_##id   */ EWHEEL,
4 /* function   */ t_ewheel,
5 /* spawnflags */ TUR_FLAG_PLAYER | TUR_FLAG_MOVE | TUR_FLAG_ROAM,
6 /* mins,maxs  */ '-32 -32 0', '32 32 48',
7 /* model      */ "ewheel-base2.md3",
8 /* head_model */ "ewheel-gun1.md3",
9 /* netname    */ "ewheel",
10 /* fullname   */ _("eWheel Turret")
11 );
12 #else
13 #ifdef SVQC
14 float autocvar_g_turrets_unit_ewheel_speed_fast;
15 float autocvar_g_turrets_unit_ewheel_speed_slow;
16 float autocvar_g_turrets_unit_ewheel_speed_slower;
17 float autocvar_g_turrets_unit_ewheel_speed_stop;
18 float autocvar_g_turrets_unit_ewheel_turnrate;
19
20 const float ewheel_anim_stop = 0;
21 const float ewheel_anim_fwd_slow = 1;
22 const float ewheel_anim_fwd_fast = 2;
23 const float ewheel_anim_bck_slow = 3;
24 const float ewheel_anim_bck_fast = 4;
25
26 //#define EWHEEL_FANCYPATH
27 void ewheel_move_path()
28 {SELFPARAM();
29 #ifdef EWHEEL_FANCYPATH
30     // Are we close enougth to a path node to switch to the next?
31     if (vlen(self.origin  - self.pathcurrent.origin) < 64)
32         if (self.pathcurrent.path_next == world)
33         {
34             // Path endpoint reached
35             pathlib_deletepath(self.pathcurrent.owner);
36             self.pathcurrent = world;
37
38             if (self.pathgoal)
39             {
40                 if (self.pathgoal.use)
41                     self.pathgoal.use();
42
43                 if (self.pathgoal.enemy)
44                 {
45                     self.pathcurrent = pathlib_astar(self.pathgoal.origin,self.pathgoal.enemy.origin);
46                     self.pathgoal = self.pathgoal.enemy;
47                 }
48             }
49             else
50                 self.pathgoal = world;
51         }
52         else
53             self.pathcurrent = self.pathcurrent.path_next;
54
55 #else
56     if (vlen(self.origin - self.pathcurrent.origin) < 64)
57         self.pathcurrent = self.pathcurrent.enemy;
58 #endif
59
60     if (self.pathcurrent)
61     {
62
63         self.moveto = self.pathcurrent.origin;
64         self.steerto = steerlib_attract2(self.moveto, 0.5, 500, 0.95);
65
66         movelib_move_simple(v_forward, (autocvar_g_turrets_unit_ewheel_speed_fast), 0.4);
67     }
68 }
69
70 void ewheel_move_enemy()
71 {SELFPARAM();
72     float newframe;
73
74     self.steerto = steerlib_arrive(self.enemy.origin,self.target_range_optimal);
75
76     self.moveto  = self.origin + self.steerto * 128;
77
78     if (self.tur_dist_enemy > self.target_range_optimal)
79     {
80         if ( self.tur_head.spawnshieldtime < 1 )
81         {
82             newframe = ewheel_anim_fwd_fast;
83             movelib_move_simple(v_forward, (autocvar_g_turrets_unit_ewheel_speed_fast), 0.4);
84         }
85         else if (self.tur_head.spawnshieldtime < 2)
86         {
87
88             newframe = ewheel_anim_fwd_slow;
89             movelib_move_simple(v_forward, (autocvar_g_turrets_unit_ewheel_speed_slow), 0.4);
90        }
91         else
92         {
93             newframe = ewheel_anim_fwd_slow;
94             movelib_move_simple(v_forward, (autocvar_g_turrets_unit_ewheel_speed_slower), 0.4);
95         }
96     }
97     else if (self.tur_dist_enemy < self.target_range_optimal * 0.5)
98     {
99         newframe = ewheel_anim_bck_slow;
100         movelib_move_simple(v_forward * -1, (autocvar_g_turrets_unit_ewheel_speed_slow), 0.4);
101     }
102     else
103     {
104         newframe = ewheel_anim_stop;
105         movelib_beak_simple((autocvar_g_turrets_unit_ewheel_speed_stop));
106     }
107
108     turrets_setframe(newframe, false);
109 }
110
111 void ewheel_move_idle()
112 {SELFPARAM();
113     if(self.frame != 0)
114     {
115         self.SendFlags |= TNSF_ANIM;
116         self.anim_start_time = time;
117     }
118
119     self.frame = 0;
120     if (vlen(self.velocity))
121         movelib_beak_simple((autocvar_g_turrets_unit_ewheel_speed_stop));
122 }
123
124 void spawnfunc_turret_ewheel() { SELFPARAM(); if(!turret_initialize(TUR_EWHEEL)) remove(self); }
125
126 float t_ewheel(float req)
127 {SELFPARAM();
128     switch(req)
129     {
130         case TR_ATTACK:
131         {
132             float i;
133             entity _mis;
134
135             for (i = 0; i < 1; ++i)
136             {
137                 turret_do_updates(self);
138
139                 _mis = turret_projectile(W_Sound("lasergun_fire"), 1, 0, DEATH_TURRET_EWHEEL, PROJECTILE_BLASTER, TRUE, TRUE);
140                 _mis.missile_flags = MIF_SPLASH;
141
142                 Send_Effect(EFFECT_BLASTER_MUZZLEFLASH, self.tur_shotorg, self.tur_shotdir_updated * 1000, 1);
143
144                 self.tur_head.frame += 2;
145
146                 if (self.tur_head.frame > 3)
147                     self.tur_head.frame = 0;
148             }
149
150             return true;
151         }
152         case TR_THINK:
153         {
154             float vz;
155             vector wish_angle, real_angle;
156
157             vz = self.velocity_z;
158
159             self.angles_x = anglemods(self.angles_x);
160             self.angles_y = anglemods(self.angles_y);
161
162             fixedmakevectors(self.angles);
163
164             wish_angle = normalize(self.steerto);
165             wish_angle = vectoangles(wish_angle);
166             real_angle = wish_angle - self.angles;
167             real_angle = shortangle_vxy(real_angle, self.tur_head.angles);
168
169             self.tur_head.spawnshieldtime = fabs(real_angle_y);
170             real_angle_y  = bound(-self.tur_head.aim_speed, real_angle_y, self.tur_head.aim_speed);
171             self.angles_y = (self.angles_y + real_angle_y);
172
173             if(self.enemy)
174                 ewheel_move_enemy();
175             else if(self.pathcurrent)
176                 ewheel_move_path();
177             else
178                 ewheel_move_idle();
179
180             self.velocity_z = vz;
181
182             if(vlen(self.velocity))
183                 self.SendFlags |= TNSF_MOVE;
184
185             return true;
186         }
187         case TR_DEATH:
188         {
189             self.velocity = '0 0 0';
190
191 #ifdef EWHEEL_FANCYPATH
192             if (self.pathcurrent)
193                 pathlib_deletepath(self.pathcurrent.owner);
194 #endif
195             self.pathcurrent = world;
196
197             return true;
198         }
199         case TR_SETUP:
200         {
201             entity e;
202
203             if(self.movetype == MOVETYPE_WALK)
204             {
205                 self.velocity = '0 0 0';
206                 self.enemy = world;
207
208                 setorigin(self, self.pos1);
209
210                 if (self.target != "")
211                 {
212                     e = find(world, targetname, self.target);
213                     if (!e)
214                     {
215                         LOG_TRACE("Initital waypoint for ewheel does NOT exsist, fix your map!\n");
216                         self.target = "";
217                     }
218
219                     if (e.classname != "turret_checkpoint")
220                         LOG_TRACE("Warning: not a turrret path\n");
221                     else
222                     {
223
224 #ifdef EWHEEL_FANCYPATH
225                         self.pathcurrent = WALKER_PATH(self.origin,e.origin);
226                         self.pathgoal = e;
227 #else
228                         self.pathcurrent  = e;
229 #endif
230                     }
231                 }
232             }
233
234             self.iscreature                             = true;
235             self.teleportable                   = TELEPORT_NORMAL;
236             self.damagedbycontents              = true;
237             self.movetype                               = MOVETYPE_WALK;
238             self.solid                                  = SOLID_SLIDEBOX;
239             self.takedamage                             = DAMAGE_AIM;
240             self.idle_aim                               = '0 0 0';
241             self.pos1                                   = self.origin;
242             self.target_select_flags    = TFL_TARGETSELECT_PLAYERS | TFL_TARGETSELECT_RANGELIMITS | TFL_TARGETSELECT_TEAMCHECK | TFL_TARGETSELECT_LOS;
243             self.target_validate_flags  = TFL_TARGETSELECT_PLAYERS | TFL_TARGETSELECT_RANGELIMITS | TFL_TARGETSELECT_TEAMCHECK | TFL_TARGETSELECT_LOS;
244             self.frame                                  = self.tur_head.frame = 1;
245             self.ammo_flags                             = TFL_AMMO_ENERGY | TFL_AMMO_RECHARGE | TFL_AMMO_RECIEVE;
246
247             // Convert from dgr / sec to dgr / tic
248             self.tur_head.aim_speed = (autocvar_g_turrets_unit_ewheel_turnrate);
249             self.tur_head.aim_speed = self.tur_head.aim_speed / (1 / self.ticrate);
250
251             return true;
252         }
253         case TR_PRECACHE:
254         {
255             precache_model ("models/turrets/ewheel-base2.md3");
256             precache_model ("models/turrets/ewheel-gun1.md3");
257             return true;
258         }
259     }
260
261     return true;
262 }
263
264 #endif // SVQC
265 #ifdef CSQC
266
267 void ewheel_draw()
268 {SELFPARAM();
269     float dt;
270
271     dt = time - self.move_time;
272     self.move_time = time;
273     if(dt <= 0)
274         return;
275
276     fixedmakevectors(self.angles);
277     setorigin(self, self.origin + self.velocity * dt);
278     self.tur_head.angles += dt * self.tur_head.move_avelocity;
279     self.angles_y = self.move_angles_y;
280
281     if (self.health < 127)
282     if(random() < 0.05)
283         te_spark(self.origin + '0 0 40', randomvec() * 256 + '0 0 256', 16);
284 }
285
286 float t_ewheel(float req)
287 {SELFPARAM();
288     switch(req)
289     {
290         case TR_SETUP:
291         {
292             self.gravity                = 1;
293             self.movetype               = MOVETYPE_BOUNCE;
294             self.move_movetype  = MOVETYPE_BOUNCE;
295             self.move_origin    = self.origin;
296             self.move_time              = time;
297             self.draw                   = ewheel_draw;
298
299             return true;
300         }
301         case TR_PRECACHE:
302         {
303             return true;
304         }
305     }
306
307     return true;
308 }
309
310 #endif // CSQC
311 #endif // REGISTER_TURRET