4 CLASS(EWheelAttack, PortoLaunch)
5 /* flags */ ATTRIB(EWheelAttack, spawnflags, int, WEP_TYPE_OTHER);
6 /* impulse */ ATTRIB(EWheelAttack, impulse, int, 5);
7 /* refname */ ATTRIB(EWheelAttack, netname, string, "turret_ewheel");
8 /* wepname */ ATTRIB(EWheelAttack, message, string, _("eWheel"));
10 REGISTER_WEAPON(EWHEEL, NEW(EWheelAttack));
12 //#define EWHEEL_FANCYPATH
15 /* spawnflags */ ATTRIB(EWheel, spawnflags, int, TUR_FLAG_PLAYER | TUR_FLAG_MOVE | TUR_FLAG_ROAM);
16 /* mins */ ATTRIB(EWheel, mins, vector, '-32 -32 0');
17 /* maxs */ ATTRIB(EWheel, maxs, vector, '32 32 48');
18 /* modelname */ ATTRIB(EWheel, mdl, string, "ewheel-base2.md3");
19 /* model */ ATTRIB(EWheel, model, string, strzone(strcat("models/turrets/", this.mdl)));
20 /* head_model */ ATTRIB(EWheel, head_model, string, strzone(strcat("models/turrets/", "ewheel-gun1.md3")));
21 /* netname */ ATTRIB(EWheel, netname, string, "ewheel");
22 /* fullname */ ATTRIB(EWheel, turret_name, string, _("eWheel Turret"));
23 ATTRIB(EWheel, m_weapon, Weapon, WEP_EWHEEL);
25 REGISTER_TURRET(EWHEEL, NEW(EWheel));
31 void turret_initparams(entity);
32 METHOD(EWheelAttack, wr_think, bool(entity thiswep, bool fire1, bool fire2)) {
34 bool isPlayer = IS_PLAYER(self);
36 if (!isPlayer || weapon_prepareattack(false, WEP_CVAR_PRI(electro, refire))) {
38 turret_initparams(self);
39 W_SetupShot_Dir(self, v_forward, false, 0, W_Sound("electro_fire"), CH_WEAPON_B, 0);
40 self.tur_shotdir_updated = w_shotdir;
41 self.tur_shotorg = w_shotorg;
43 weapon_thinkf(WFRAME_FIRE1, WEP_CVAR_PRI(electro, animtime), w_ready);
46 turret_do_updates(self);
48 entity missile = turret_projectile(SND(LASERGUN_FIRE), 1, 0, DEATH_TURRET_EWHEEL, PROJECTILE_BLASTER, true, true);
49 missile.missile_flags = MIF_SPLASH;
51 Send_Effect(EFFECT_BLASTER_MUZZLEFLASH, self.tur_shotorg, self.tur_shotdir_updated * 1000, 1);
54 self.tur_head.frame += 2;
56 if (self.tur_head.frame > 3)
57 self.tur_head.frame = 0;
63 float autocvar_g_turrets_unit_ewheel_speed_fast;
64 float autocvar_g_turrets_unit_ewheel_speed_slow;
65 float autocvar_g_turrets_unit_ewheel_speed_slower;
66 float autocvar_g_turrets_unit_ewheel_speed_stop;
67 float autocvar_g_turrets_unit_ewheel_turnrate;
69 const float ewheel_anim_stop = 0;
70 const float ewheel_anim_fwd_slow = 1;
71 const float ewheel_anim_fwd_fast = 2;
72 const float ewheel_anim_bck_slow = 3;
73 const float ewheel_anim_bck_fast = 4;
75 void ewheel_move_path()
77 #ifdef EWHEEL_FANCYPATH
78 // Are we close enougth to a path node to switch to the next?
79 if (vlen(self.origin - self.pathcurrent.origin) < 64)
80 if (self.pathcurrent.path_next == world)
82 // Path endpoint reached
83 pathlib_deletepath(self.pathcurrent.owner);
84 self.pathcurrent = world;
88 if (self.pathgoal.use)
91 if (self.pathgoal.enemy)
93 self.pathcurrent = pathlib_astar(self.pathgoal.origin,self.pathgoal.enemy.origin);
94 self.pathgoal = self.pathgoal.enemy;
98 self.pathgoal = world;
101 self.pathcurrent = self.pathcurrent.path_next;
104 if (vlen(self.origin - self.pathcurrent.origin) < 64)
105 self.pathcurrent = self.pathcurrent.enemy;
108 if (self.pathcurrent)
111 self.moveto = self.pathcurrent.origin;
112 self.steerto = steerlib_attract2(self.moveto, 0.5, 500, 0.95);
114 movelib_move_simple(v_forward, (autocvar_g_turrets_unit_ewheel_speed_fast), 0.4);
118 void ewheel_move_enemy()
122 self.steerto = steerlib_arrive(self.enemy.origin,self.target_range_optimal);
124 self.moveto = self.origin + self.steerto * 128;
126 if (self.tur_dist_enemy > self.target_range_optimal)
128 if ( self.tur_head.spawnshieldtime < 1 )
130 newframe = ewheel_anim_fwd_fast;
131 movelib_move_simple(v_forward, (autocvar_g_turrets_unit_ewheel_speed_fast), 0.4);
133 else if (self.tur_head.spawnshieldtime < 2)
136 newframe = ewheel_anim_fwd_slow;
137 movelib_move_simple(v_forward, (autocvar_g_turrets_unit_ewheel_speed_slow), 0.4);
141 newframe = ewheel_anim_fwd_slow;
142 movelib_move_simple(v_forward, (autocvar_g_turrets_unit_ewheel_speed_slower), 0.4);
145 else if (self.tur_dist_enemy < self.target_range_optimal * 0.5)
147 newframe = ewheel_anim_bck_slow;
148 movelib_move_simple(v_forward * -1, (autocvar_g_turrets_unit_ewheel_speed_slow), 0.4);
152 newframe = ewheel_anim_stop;
153 movelib_beak_simple((autocvar_g_turrets_unit_ewheel_speed_stop));
156 turrets_setframe(newframe, false);
159 void ewheel_move_idle()
163 self.SendFlags |= TNSF_ANIM;
164 self.anim_start_time = time;
168 if (vlen(self.velocity))
169 movelib_beak_simple((autocvar_g_turrets_unit_ewheel_speed_stop));
172 void spawnfunc_turret_ewheel() { SELFPARAM(); if(!turret_initialize(TUR_EWHEEL)) remove(self); }
174 METHOD(EWheel, tr_think, void(EWheel thistur))
178 vector wish_angle, real_angle;
180 vz = self.velocity_z;
182 self.angles_x = anglemods(self.angles_x);
183 self.angles_y = anglemods(self.angles_y);
185 fixedmakevectors(self.angles);
187 wish_angle = normalize(self.steerto);
188 wish_angle = vectoangles(wish_angle);
189 real_angle = wish_angle - self.angles;
190 real_angle = shortangle_vxy(real_angle, self.tur_head.angles);
192 self.tur_head.spawnshieldtime = fabs(real_angle_y);
193 real_angle_y = bound(-self.tur_head.aim_speed, real_angle_y, self.tur_head.aim_speed);
194 self.angles_y = (self.angles_y + real_angle_y);
198 else if(self.pathcurrent)
203 self.velocity_z = vz;
205 if(vlen(self.velocity))
206 self.SendFlags |= TNSF_MOVE;
208 METHOD(EWheel, tr_death, void(EWheel this, entity it))
210 it.velocity = '0 0 0';
212 #ifdef EWHEEL_FANCYPATH
213 if (self.pathcurrent)
214 pathlib_deletepath(it.pathcurrent.owner);
216 it.pathcurrent = NULL;
218 METHOD(EWheel, tr_setup, void(EWheel this, entity it))
222 if(it.movetype == MOVETYPE_WALK)
224 it.velocity = '0 0 0';
227 setorigin(it, it.pos1);
231 e = find(world, targetname, it.target);
234 LOG_TRACE("Initital waypoint for ewheel does NOT exsist, fix your map!\n");
238 if (e.classname != "turret_checkpoint")
239 LOG_TRACE("Warning: not a turrret path\n");
243 #ifdef EWHEEL_FANCYPATH
244 it.pathcurrent = WALKER_PATH(it.origin,e.origin);
253 it.iscreature = true;
254 it.teleportable = TELEPORT_NORMAL;
255 it.damagedbycontents = true;
256 it.movetype = MOVETYPE_WALK;
257 it.solid = SOLID_SLIDEBOX;
258 it.takedamage = DAMAGE_AIM;
259 it.idle_aim = '0 0 0';
261 it.target_select_flags = TFL_TARGETSELECT_PLAYERS | TFL_TARGETSELECT_RANGELIMITS | TFL_TARGETSELECT_TEAMCHECK | TFL_TARGETSELECT_LOS;
262 it.target_validate_flags = TFL_TARGETSELECT_PLAYERS | TFL_TARGETSELECT_RANGELIMITS | TFL_TARGETSELECT_TEAMCHECK | TFL_TARGETSELECT_LOS;
263 it.frame = it.tur_head.frame = 1;
264 it.ammo_flags = TFL_AMMO_ENERGY | TFL_AMMO_RECHARGE | TFL_AMMO_RECIEVE;
266 // Convert from dgr / sec to dgr / tic
267 it.tur_head.aim_speed = (autocvar_g_turrets_unit_ewheel_turnrate);
268 it.tur_head.aim_speed = it.tur_head.aim_speed / (1 / it.ticrate);
278 dt = time - self.move_time;
279 self.move_time = time;
283 fixedmakevectors(self.angles);
284 setorigin(self, self.origin + self.velocity * dt);
285 self.tur_head.angles += dt * self.tur_head.move_avelocity;
286 self.angles_y = self.move_angles_y;
288 if (self.health < 127)
290 te_spark(self.origin + '0 0 40', randomvec() * 256 + '0 0 256', 16);
293 METHOD(EWheel, tr_setup, void(EWheel this, entity it))
296 it.movetype = MOVETYPE_BOUNCE;
297 it.move_movetype = MOVETYPE_BOUNCE;
298 it.move_origin = it.origin;
300 it.draw = ewheel_draw;