]> git.xonotic.org Git - xonotic/xonotic-data.pk3dir.git/blob - qcsrc/common/turrets/turret/ewheel.qc
Merge branch 'Mario/plasma_removal' into 'master'
[xonotic/xonotic-data.pk3dir.git] / qcsrc / common / turrets / turret / ewheel.qc
1 #include "ewheel.qh"
2
3 #ifdef SVQC
4
5 float autocvar_g_turrets_unit_ewheel_speed_fast;
6 float autocvar_g_turrets_unit_ewheel_speed_slow;
7 float autocvar_g_turrets_unit_ewheel_speed_slower;
8 float autocvar_g_turrets_unit_ewheel_speed_stop;
9 float autocvar_g_turrets_unit_ewheel_turnrate;
10
11 const int ewheel_anim_stop     = 0;
12 const int ewheel_anim_fwd_slow = 1;
13 const int ewheel_anim_fwd_fast = 2;
14 const int ewheel_anim_bck_slow = 3;
15 const int ewheel_anim_bck_fast = 4;
16
17 void ewheel_move_path(entity this)
18 {
19     // Are we close enough to a path node to switch to the next?
20     if(turret_closetotarget(this, this.pathcurrent.origin, 64))
21     {
22 #ifdef EWHEEL_FANCYPATH
23         if (this.pathcurrent.path_next == NULL)
24         {
25             // Path endpoint reached
26             pathlib_deletepath(this.pathcurrent.owner);
27             this.pathcurrent = NULL;
28
29             if (this.pathgoal)
30             {
31                 if (this.pathgoal.use)
32                     this.pathgoal.use(this.pathgoal, NULL, NULL);
33
34                 if (this.pathgoal.enemy)
35                 {
36                     this.pathcurrent = pathlib_astar(this, this.pathgoal.origin,this.pathgoal.enemy.origin);
37                     this.pathgoal = this.pathgoal.enemy;
38                 }
39             }
40             else
41                 this.pathgoal = NULL;
42         }
43         else
44             this.pathcurrent = this.pathcurrent.path_next;
45 #else
46         this.pathcurrent = this.pathcurrent.enemy;
47 #endif
48     }
49
50     if (this.pathcurrent)
51     {
52         this.moveto = this.pathcurrent.origin;
53         this.steerto = steerlib_attract2(this, this.moveto, 0.5, 500, 0.95);
54
55         movelib_move_simple(this, v_forward, (autocvar_g_turrets_unit_ewheel_speed_fast), 0.4);
56     }
57 }
58
59 void ewheel_move_enemy(entity this)
60 {
61     int newframe;
62
63     this.steerto = steerlib_arrive(this, this.enemy.origin,this.target_range_optimal);
64
65     this.moveto = this.origin + this.steerto * 128;
66
67     if (this.tur_dist_enemy > this.target_range_optimal)
68     {
69         if ( this.tur_head.spawnshieldtime < 1 )
70         {
71             newframe = ewheel_anim_fwd_fast;
72             movelib_move_simple(this, v_forward, (autocvar_g_turrets_unit_ewheel_speed_fast), 0.4);
73         }
74         else if (this.tur_head.spawnshieldtime < 2)
75         {
76             newframe = ewheel_anim_fwd_slow;
77             movelib_move_simple(this, v_forward, (autocvar_g_turrets_unit_ewheel_speed_slow), 0.4);
78         }
79         else
80         {
81             newframe = ewheel_anim_fwd_slow;
82             movelib_move_simple(this, v_forward, (autocvar_g_turrets_unit_ewheel_speed_slower), 0.4);
83         }
84     }
85     else if (this.tur_dist_enemy < this.target_range_optimal * 0.5)
86     {
87         newframe = ewheel_anim_bck_slow;
88         movelib_move_simple(this, v_forward * -1, (autocvar_g_turrets_unit_ewheel_speed_slow), 0.4);
89     }
90     else
91     {
92         newframe = ewheel_anim_stop;
93         movelib_brake_simple(this, (autocvar_g_turrets_unit_ewheel_speed_stop));
94     }
95
96     turrets_setframe(this, newframe, false);
97 }
98
99 void ewheel_move_idle(entity this)
100 {
101     if(this.frame != 0)
102     {
103         this.SendFlags |= TNSF_ANIM;
104         this.anim_start_time = time;
105     }
106
107     this.frame = 0;
108     if(this.velocity)
109         movelib_brake_simple(this, (autocvar_g_turrets_unit_ewheel_speed_stop));
110 }
111
112 void ewheel_findtarget(entity this)
113 {
114     entity e = find(NULL, targetname, this.target);
115     if (!e)
116     {
117         LOG_TRACE("Initital waypoint for ewheel does NOT exist, fix your map!");
118         this.target = "";
119     }
120
121     if (e.classname != "turret_checkpoint")
122         LOG_TRACE("Warning: not a turret path");
123     else
124     {
125
126 #ifdef EWHEEL_FANCYPATH
127         this.pathcurrent = pathlib_astar(this, this.origin, e.origin);
128         this.pathgoal = e;
129 #else
130         this.pathcurrent  = e;
131 #endif
132     }
133 }
134
135 spawnfunc(turret_ewheel) { if(!turret_initialize(this, TUR_EWHEEL)) delete(this); }
136
137 METHOD(EWheel, tr_think, void(EWheel thistur, entity it))
138 {
139     vector wish_angle, real_angle;
140
141     float vz = it.velocity_z;
142
143     it.angles_x = anglemods(it.angles_x);
144     it.angles_y = anglemods(it.angles_y);
145
146     fixedmakevectors(it.angles);
147
148     wish_angle = normalize(it.steerto);
149     wish_angle = vectoangles(wish_angle);
150     real_angle = wish_angle - it.angles;
151     real_angle = shortangle_vxy(real_angle, it.tur_head.angles);
152
153     it.tur_head.spawnshieldtime = fabs(real_angle_y);
154
155     float f = it.tur_head.aim_speed * frametime;
156     real_angle_y = bound(-f, real_angle_y, f);
157     it.angles_y = (it.angles_y + real_angle_y);
158
159     if(it.enemy)
160         ewheel_move_enemy(it);
161     else if(it.pathcurrent)
162         ewheel_move_path(it);
163     else
164         ewheel_move_idle(it);
165
166     it.velocity_z = vz;
167
168     if(it.velocity)
169         it.SendFlags |= TNSF_MOVE;
170 }
171
172 METHOD(EWheel, tr_death, void(EWheel this, entity it))
173 {
174     it.velocity = '0 0 0';
175
176 #ifdef EWHEEL_FANCYPATH
177     if (it.pathcurrent)
178         pathlib_deletepath(it.pathcurrent.owner);
179 #endif
180     it.pathcurrent = NULL;
181 }
182
183 METHOD(EWheel, tr_setup, void(EWheel this, entity it))
184 {
185     if(it.move_movetype == MOVETYPE_WALK)
186     {
187         it.velocity = '0 0 0';
188         it.enemy = NULL;
189
190         setorigin(it, it.pos1);
191
192         if (it.target != "")
193             InitializeEntity(it, ewheel_findtarget, INITPRIO_FINDTARGET);
194     }
195
196     it.iscreature                               = true;
197     it.teleportable                     = TELEPORT_NORMAL;
198     if(!it.damagedbycontents)
199         IL_PUSH(g_damagedbycontents, it);
200     it.damagedbycontents        = true;
201     set_movetype(it, MOVETYPE_WALK);
202     it.solid                                    = SOLID_SLIDEBOX;
203     it.takedamage                               = DAMAGE_AIM;
204     it.idle_aim                         = '0 0 0';
205     it.pos1                                     = it.origin;
206     it.target_select_flags      = TFL_TARGETSELECT_PLAYERS | TFL_TARGETSELECT_RANGELIMITS | TFL_TARGETSELECT_TEAMCHECK | TFL_TARGETSELECT_LOS;
207     it.target_validate_flags    = TFL_TARGETSELECT_PLAYERS | TFL_TARGETSELECT_RANGELIMITS | TFL_TARGETSELECT_TEAMCHECK | TFL_TARGETSELECT_LOS;
208     it.frame                                    = it.tur_head.frame = 1;
209     it.ammo_flags                               = TFL_AMMO_ENERGY | TFL_AMMO_RECHARGE | TFL_AMMO_RECIEVE;
210
211     it.tur_head.aim_speed = autocvar_g_turrets_unit_ewheel_turnrate;
212 }
213
214 #endif // SVQC
215 #ifdef CSQC
216
217 void ewheel_draw(entity this)
218 {
219     float dt;
220
221     dt = time - this.move_time;
222     this.move_time = time;
223     if(dt <= 0)
224         return;
225
226     fixedmakevectors(this.angles);
227     setorigin(this, this.origin + this.velocity * dt);
228     this.tur_head.angles += dt * this.tur_head.avelocity;
229
230     if(GetResource(this, RES_HEALTH) < 127)
231     if(random() < 0.05)
232         te_spark(this.origin + '0 0 40', randomvec() * 256 + '0 0 256', 16);
233 }
234
235 METHOD(EWheel, tr_setup, void(EWheel this, entity it))
236 {
237     it.gravity          = 1;
238     set_movetype(it, MOVETYPE_BOUNCE);
239     it.move_time                = time;
240     it.draw                     = ewheel_draw;
241 }
242
243 #endif // CSQC