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