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;
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;
17 void ewheel_move_path(entity this)
19 // Are we close enough to a path node to switch to the next?
20 if(turret_closetotarget(this, this.pathcurrent.origin, 64))
22 #ifdef EWHEEL_FANCYPATH
23 if (this.pathcurrent.path_next == NULL)
25 // Path endpoint reached
26 pathlib_deletepath(this.pathcurrent.owner);
27 this.pathcurrent = NULL;
31 if (this.pathgoal.use)
32 this.pathgoal.use(this.pathgoal, NULL, NULL);
34 if (this.pathgoal.enemy)
36 this.pathcurrent = pathlib_astar(this, this.pathgoal.origin,this.pathgoal.enemy.origin);
37 this.pathgoal = this.pathgoal.enemy;
44 this.pathcurrent = this.pathcurrent.path_next;
46 this.pathcurrent = this.pathcurrent.enemy;
52 this.moveto = this.pathcurrent.origin;
53 this.steerto = steerlib_attract2(this, this.moveto, 0.5, 500, 0.95);
55 movelib_move_simple(this, v_forward, (autocvar_g_turrets_unit_ewheel_speed_fast), 0.4);
59 void ewheel_move_enemy(entity this)
63 this.steerto = steerlib_arrive(this, this.enemy.origin,this.target_range_optimal);
65 this.moveto = this.origin + this.steerto * 128;
67 if (this.tur_dist_enemy > this.target_range_optimal)
69 if ( this.tur_head.spawnshieldtime < 1 )
71 newframe = ewheel_anim_fwd_fast;
72 movelib_move_simple(this, v_forward, (autocvar_g_turrets_unit_ewheel_speed_fast), 0.4);
74 else if (this.tur_head.spawnshieldtime < 2)
76 newframe = ewheel_anim_fwd_slow;
77 movelib_move_simple(this, v_forward, (autocvar_g_turrets_unit_ewheel_speed_slow), 0.4);
81 newframe = ewheel_anim_fwd_slow;
82 movelib_move_simple(this, v_forward, (autocvar_g_turrets_unit_ewheel_speed_slower), 0.4);
85 else if (this.tur_dist_enemy < this.target_range_optimal * 0.5)
87 newframe = ewheel_anim_bck_slow;
88 movelib_move_simple(this, v_forward * -1, (autocvar_g_turrets_unit_ewheel_speed_slow), 0.4);
92 newframe = ewheel_anim_stop;
93 movelib_brake_simple(this, (autocvar_g_turrets_unit_ewheel_speed_stop));
96 turrets_setframe(this, newframe, false);
99 void ewheel_move_idle(entity this)
103 this.SendFlags |= TNSF_ANIM;
104 this.anim_start_time = time;
109 movelib_brake_simple(this, (autocvar_g_turrets_unit_ewheel_speed_stop));
112 void ewheel_findtarget(entity this)
114 entity e = find(NULL, targetname, this.target);
117 LOG_TRACE("Initital waypoint for ewheel does NOT exist, fix your map!");
121 if (e.classname != "turret_checkpoint")
122 LOG_TRACE("Warning: not a turret path");
126 #ifdef EWHEEL_FANCYPATH
127 this.pathcurrent = pathlib_astar(this, this.origin, e.origin);
130 this.pathcurrent = e;
135 spawnfunc(turret_ewheel) { if(!turret_initialize(this, TUR_EWHEEL)) delete(this); }
137 METHOD(EWheel, tr_think, void(EWheel thistur, entity it))
139 vector wish_angle, real_angle;
141 float vz = it.velocity_z;
143 it.angles_x = anglemods(it.angles_x);
144 it.angles_y = anglemods(it.angles_y);
146 fixedmakevectors(it.angles);
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);
153 it.tur_head.spawnshieldtime = fabs(real_angle_y);
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);
160 ewheel_move_enemy(it);
161 else if(it.pathcurrent)
162 ewheel_move_path(it);
164 ewheel_move_idle(it);
169 it.SendFlags |= TNSF_MOVE;
172 METHOD(EWheel, tr_death, void(EWheel this, entity it))
174 it.velocity = '0 0 0';
176 #ifdef EWHEEL_FANCYPATH
178 pathlib_deletepath(it.pathcurrent.owner);
180 it.pathcurrent = NULL;
183 METHOD(EWheel, tr_setup, void(EWheel this, entity it))
185 if(it.move_movetype == MOVETYPE_WALK)
187 it.velocity = '0 0 0';
190 setorigin(it, it.pos1);
193 InitializeEntity(it, ewheel_findtarget, INITPRIO_FINDTARGET);
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';
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;
211 it.tur_head.aim_speed = autocvar_g_turrets_unit_ewheel_turnrate;
217 void ewheel_draw(entity this)
221 dt = time - this.move_time;
222 this.move_time = time;
226 fixedmakevectors(this.angles);
227 setorigin(this, this.origin + this.velocity * dt);
228 this.tur_head.angles += dt * this.tur_head.avelocity;
230 if(GetResource(this, RES_HEALTH) < 127)
232 te_spark(this.origin + '0 0 40', randomvec() * 256 + '0 0 256', 16);
235 METHOD(EWheel, tr_setup, void(EWheel this, entity it))
238 set_movetype(it, MOVETYPE_BOUNCE);
240 it.draw = ewheel_draw;