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