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