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