From ac38273555d889fd76fc39766d12000f13a7fb67 Mon Sep 17 00:00:00 2001 From: tzork Date: Fri, 27 Mar 2009 09:36:50 +0000 Subject: [PATCH] Better walker and ewheel. Better fix for NaN angles (fixed turret_stdproc_track) Fix unhanded damage type 0 on turret blow up Support TFL_SHOOT_CUSTOM Fix broken support units with TFL_TARGETSELECT_NOTURRETS Fix idle_aim / defend aim Fix missed body damage on support units Fix in turret_tag_setup/turret_tag_fire_update for mangled md3 tags Make tesla use te_csqc_lightningarc. Restructure tela to conform a bit better. Removed some un/rarely used crap Updated units for above changes. Fix harmless warning in pathlib git-svn-id: svn://svn.icculus.org/nexuiz/trunk@6319 f962a42d-fe04-0410-a3ab-8c8b0445ebaa --- data/qcsrc/server/pathlib.qc | 25 +- .../server/tturrets/include/turrets_early.qh | 6 +- .../server/tturrets/system/system_damage.qc | 4 +- .../server/tturrets/system/system_main.qc | 318 +++++----- .../server/tturrets/system/system_misc.qc | 44 +- .../server/tturrets/units/unit_ewheel.qc | 376 ++++++++---- data/qcsrc/server/tturrets/units/unit_flac.qc | 4 +- .../tturrets/units/unit_fusionreactor.qc | 2 +- .../server/tturrets/units/unit_hellion.qc | 3 +- data/qcsrc/server/tturrets/units/unit_hk.qc | 3 +- .../server/tturrets/units/unit_machinegun.qc | 3 +- data/qcsrc/server/tturrets/units/unit_mlrs.qc | 4 +- .../server/tturrets/units/unit_phaser.qc | 3 +- .../server/tturrets/units/unit_plasma.qc | 37 +- .../tturrets/units/unit_targettrigger.qc | 3 +- .../server/tturrets/units/unit_tessla.qc | 87 ++- .../server/tturrets/units/unit_walker.qc | 570 +++++++++--------- 17 files changed, 824 insertions(+), 668 deletions(-) diff --git a/data/qcsrc/server/pathlib.qc b/data/qcsrc/server/pathlib.qc index 606ab49ce..64aa9067e 100644 --- a/data/qcsrc/server/pathlib.qc +++ b/data/qcsrc/server/pathlib.qc @@ -9,6 +9,8 @@ #define medium spawnshieldtime +//#define DEBUGPATHING + entity openlist; entity closedlist; entity scraplist; @@ -24,6 +26,10 @@ float pathlib_merge_cnt; float pathlib_recycle_cnt; float pathlib_searched_cnt; +#ifdef DEBUGPATHING + +#endif + float pathlib_bestopen_seached; float pathlib_bestcash_hits; float pathlib_bestcash_saved; @@ -42,7 +48,7 @@ entity goal_node; entity best_open_node; .float is_path_node; -//#define DEBUGPATHING + #ifdef DEBUGPATHING float edge_show(vector point,float fsize); void mark_error(vector where,float lifetime); @@ -900,14 +906,15 @@ entity pathlib_astar(vector from,vector to) if not(scraplist) scraplist = spawn(); - pathlib_closed_cnt = 0; - pathlib_open_cnt = 0; - pathlib_made_cnt = 0; - pathlib_merge_cnt = 0; - pathlib_searched_cnt = 0; - pathlib_bestcash_hits = 0; - pathlib_bestcash_saved = 0; - pathlib_recycle_cnt = 0; + pathlib_closed_cnt = 0; + pathlib_open_cnt = 0; + pathlib_made_cnt = 0; + pathlib_merge_cnt = 0; + pathlib_searched_cnt = 0; + pathlib_bestopen_seached = 0; + pathlib_bestcash_hits = 0; + pathlib_bestcash_saved = 0; + pathlib_recycle_cnt = 0; pathlib_gridsize = 128; pathlib_movecost = pathlib_gridsize; diff --git a/data/qcsrc/server/tturrets/include/turrets_early.qh b/data/qcsrc/server/tturrets/include/turrets_early.qh index eca0ade7b..7c5bf6674 100644 --- a/data/qcsrc/server/tturrets/include/turrets_early.qh +++ b/data/qcsrc/server/tturrets/include/turrets_early.qh @@ -448,11 +448,11 @@ wkacked to save mem. * Stuff to plug into requierd but unused callbacks. */ /// Always return 1 -float turret_stdproc_true(); +//float turret_stdproc_true(); /// Always return 0 -float turret_stdproc_false(); +//float turret_stdproc_false(); /// Always return nothing at all -void turret_stdproc_nothing(); +//void turret_stdproc_nothing(); /* * Target selection diff --git a/data/qcsrc/server/tturrets/system/system_damage.qc b/data/qcsrc/server/tturrets/system/system_damage.qc index 4c18d52fe..3a505754d 100644 --- a/data/qcsrc/server/tturrets/system/system_damage.qc +++ b/data/qcsrc/server/tturrets/system/system_damage.qc @@ -180,7 +180,7 @@ void turret_stdproc_die() } // Go boom - RadiusDamage (self,self, min(self.ammo,50),min(self.ammo,50) * 0.25,250,world,min(self.ammo,50)*5,0,world); + RadiusDamage (self,self, min(self.ammo,50),min(self.ammo,50) * 0.25,250,world,min(self.ammo,50)*5,DEATH_TURRET,world); if(self.damage_flags & TFL_DMG_DEATH_NORESPAWN) { @@ -336,5 +336,3 @@ void turret_stdproc_damage (entity inflictor, entity attacker, float damage, flo baseent.think = turret_stdproc_die; } } - - diff --git a/data/qcsrc/server/tturrets/system/system_main.qc b/data/qcsrc/server/tturrets/system/system_main.qc index 9f5981c6c..f690cbe8b 100644 --- a/data/qcsrc/server/tturrets/system/system_main.qc +++ b/data/qcsrc/server/tturrets/system/system_main.qc @@ -1,13 +1,5 @@ #define cvar_base "g_turrets_unit_" -#define cvar_gets(s_base,s_add) strcat(s_base,s_add) -/* -string cvar_gets(string s_base,string s_add) -{ - return strcat(s_base,s_add); -} -*/ - void load_unit_settings(entity ent,string unitname,float is_reload) { @@ -31,43 +23,48 @@ void load_unit_settings(entity ent,string unitname,float is_reload) { ent.enemy = world; ent.tur_head.avelocity = '0 0 0'; - ent.tur_head.angles = ent.angles; + + if (ent.turrcaps_flags & TFL_TURRCAPS_HEADATTACHED) + ent.tur_head.angles = '0 0 0'; + else + ent.tur_head.angles = ent.angles; } - ent.health = cvar(cvar_gets(sbase,"_health")) * ent.turret_scale_health; - ent.respawntime = cvar(cvar_gets(sbase,"_respawntime")) * ent.turret_scale_respawn; - - ent.shot_dmg = cvar(cvar_gets(sbase,"_shot_dmg")) * ent.turret_scale_damage; - ent.shot_refire = cvar(cvar_gets(sbase,"_shot_refire")) * ent.turret_scale_refire; - ent.shot_radius = cvar(cvar_gets(sbase,"_shot_radius")) * ent.turret_scale_damage; - ent.shot_speed = cvar(cvar_gets(sbase,"_shot_speed")); - ent.shot_spread = cvar(cvar_gets(sbase,"_shot_spread")); - ent.shot_force = cvar(cvar_gets(sbase,"_shot_force")) * ent.turret_scale_damage; - ent.shot_volly = cvar(cvar_gets(sbase,"_shot_volly")); - ent.shot_volly_refire = cvar(cvar_gets(sbase,"_shot_volly_refire")) * ent.turret_scale_refire; - - ent.target_range = cvar(cvar_gets(sbase,"_target_range")) * ent.turret_scale_range; - ent.target_range_min = cvar(cvar_gets(sbase,"_target_range_min")) * ent.turret_scale_range; - ent.target_range_fire = cvar(cvar_gets(sbase,"_target_range_fire")) * ent.turret_scale_range; - ent.target_range_optimal = cvar(cvar_gets(sbase,"_target_range_optimal")) * ent.turret_scale_range; - - ent.target_select_rangebias = cvar(cvar_gets(sbase,"_target_select_rangebias")); - ent.target_select_samebias = cvar(cvar_gets(sbase,"_target_select_samebias")); - ent.target_select_anglebias = cvar(cvar_gets(sbase,"_target_select_anglebias")); - ent.target_select_playerbias = cvar(cvar_gets(sbase,"_target_select_playerbias")); + + ent.health = cvar(strcat(sbase,"_health")) * ent.turret_scale_health; + ent.respawntime = cvar(strcat(sbase,"_respawntime")) * ent.turret_scale_respawn; + + ent.shot_dmg = cvar(strcat(sbase,"_shot_dmg")) * ent.turret_scale_damage; + ent.shot_refire = cvar(strcat(sbase,"_shot_refire")) * ent.turret_scale_refire; + ent.shot_radius = cvar(strcat(sbase,"_shot_radius")) * ent.turret_scale_damage; + ent.shot_speed = cvar(strcat(sbase,"_shot_speed")); + ent.shot_spread = cvar(strcat(sbase,"_shot_spread")); + ent.shot_force = cvar(strcat(sbase,"_shot_force")) * ent.turret_scale_damage; + ent.shot_volly = cvar(strcat(sbase,"_shot_volly")); + ent.shot_volly_refire = cvar(strcat(sbase,"_shot_volly_refire")) * ent.turret_scale_refire; + + ent.target_range = cvar(strcat(sbase,"_target_range")) * ent.turret_scale_range; + ent.target_range_min = cvar(strcat(sbase,"_target_range_min")) * ent.turret_scale_range; + ent.target_range_fire = cvar(strcat(sbase,"_target_range_fire")) * ent.turret_scale_range; + ent.target_range_optimal = cvar(strcat(sbase,"_target_range_optimal")) * ent.turret_scale_range; + + ent.target_select_rangebias = cvar(strcat(sbase,"_target_select_rangebias")); + ent.target_select_samebias = cvar(strcat(sbase,"_target_select_samebias")); + ent.target_select_anglebias = cvar(strcat(sbase,"_target_select_anglebias")); + ent.target_select_playerbias = cvar(strcat(sbase,"_target_select_playerbias")); //ent.target_select_fov = cvar(cvar_gets(sbase,"_target_select_fov")); - ent.ammo_max = cvar(cvar_gets(sbase,"_ammo_max")) * ent.turret_scale_ammo; - ent.ammo_recharge = cvar(cvar_gets(sbase,"_ammo_recharge")) * ent.turret_scale_ammo; + ent.ammo_max = cvar(strcat(sbase,"_ammo_max")) * ent.turret_scale_ammo; + ent.ammo_recharge = cvar(strcat(sbase,"_ammo_recharge")) * ent.turret_scale_ammo; - ent.aim_firetolerance_dist = cvar(cvar_gets(sbase,"_aim_firetolerance_dist")); - ent.aim_speed = cvar(cvar_gets(sbase,"_aim_speed")) * ent.turret_scale_aim; - ent.aim_maxrot = cvar(cvar_gets(sbase,"_aim_maxrot")); - ent.aim_maxpitch = cvar(cvar_gets(sbase,"_aim_maxpitch")); + ent.aim_firetolerance_dist = cvar(strcat(sbase,"_aim_firetolerance_dist")); + ent.aim_speed = cvar(strcat(sbase,"_aim_speed")) * ent.turret_scale_aim; + ent.aim_maxrot = cvar(strcat(sbase,"_aim_maxrot")); + ent.aim_maxpitch = cvar(strcat(sbase,"_aim_maxpitch")); - ent.track_type = cvar(cvar_gets(sbase,"_track_type")); - ent.track_accel_pitch = cvar(cvar_gets(sbase,"_track_accel_pitch")); - ent.track_accel_rot = cvar(cvar_gets(sbase,"_track_accel_rot")); - ent.track_blendrate = cvar(cvar_gets(sbase,"_track_blendrate")); + ent.track_type = cvar(strcat(sbase,"_track_type")); + ent.track_accel_pitch = cvar(strcat(sbase,"_track_accel_pitch")); + ent.track_accel_rot = cvar(strcat(sbase,"_track_accel_rot")); + ent.track_blendrate = cvar(strcat(sbase,"_track_blendrate")); if(is_reload) if(ent.turret_respawnhook) @@ -75,6 +72,7 @@ void load_unit_settings(entity ent,string unitname,float is_reload) } +/* float turret_stdproc_true() { return 1; @@ -85,10 +83,12 @@ float turret_stdproc_false() return 0; } + void turret_stdproc_nothing() { return; } +*/ /** ** updates enemy distances, predicted impact point/time @@ -102,21 +102,6 @@ void turret_do_updates(entity t_turret) oldself = self; self = t_turret; - if (self.turrcaps_flags & TFL_TURRCAPS_HEADATTACHED) - { - self.tur_head.angles_x = self.tur_head.angles_x * -1; - self.angles_x = self.angles_x * -1; - makevectors(self.tur_head.angles + self.angles); - self.tur_head.angles_x = self.tur_head.angles_x * -1; - self.angles_x = self.angles_x * -1; - } - else - { - self.tur_head.angles_x = self.tur_head.angles_x * -1; - makevectors(self.tur_head.angles); - self.tur_head.angles_x = self.tur_head.angles_x * -1; - } - enemy_pos = real_origin(self.enemy); turret_tag_fire_update(); @@ -222,149 +207,133 @@ vector turret_fovsearch_random() //.entity aim_mark; void turret_stdproc_track() { - vector wish_angle; // This is where we want to aim - - vector real_angle; // This is where we can aim + vector target_angle; // This is where we want to aim + vector move_angle; // This is where we can aim float f_tmp; if (self.track_flags == TFL_TRACK_NO) return; - if(!self.tur_active) - { - wish_angle = self.idle_aim - ('1 0 0' * self.aim_maxpitch); - } + target_angle = self.idle_aim - ('1 0 0' * self.aim_maxpitch); else if (self.enemy == world) { if(time > self.lip) if (self.turrcaps_flags & TFL_TURRCAPS_HEADATTACHED) - wish_angle = self.idle_aim + self.angles; + target_angle = self.idle_aim + self.angles; else - wish_angle = self.idle_aim; + target_angle = self.idle_aim; else - wish_angle = vectoangles(normalize(self.tur_aimpos - self.tur_head.origin)); + target_angle = vectoangles(normalize(self.tur_aimpos - self.tur_shotorg)); } else { // Find the direction - /* - if (self.turrcaps_flags & TFL_TURRCAPS_HEADATTACHED) - wish_angle = normalize(self.tur_aimpos - self.tur_shotorg); - else - */ - wish_angle = normalize(self.tur_aimpos - self.tur_shotorg); - wish_angle = vectoangles(wish_angle); // And make a angle + target_angle = normalize(self.tur_aimpos - self.tur_shotorg); + target_angle = vectoangles(target_angle); // And make a angle } - self.tur_head.angles_x = anglemods(self.tur_head.angles_x); - self.tur_head.angles_y = anglemods(self.tur_head.angles_y); + self.tur_head.angles_x = safeangle(self.tur_head.angles_x); + self.tur_head.angles_y = safeangle(self.tur_head.angles_y); // Find the diffrence between where we currently aim and where we want to aim + vector a_off; + + if (self.turrcaps_flags & TFL_TURRCAPS_HEADATTACHED) { - real_angle = wish_angle - (self.angles + self.tur_head.angles); - real_angle = shortangle_v(real_angle,(self.angles + self.tur_head.angles)); + move_angle = target_angle - (self.angles + self.tur_head.angles); + move_angle = shortangle_vxy(move_angle,(self.angles + self.tur_head.angles)); + a_off = '0 0 0'; + } else { - real_angle = wish_angle - self.tur_head.angles; - real_angle = shortangle_v(real_angle,self.tur_head.angles); + move_angle = target_angle - self.tur_head.angles; + move_angle = shortangle_vxy(move_angle,self.tur_head.angles); + a_off = self.angles; } - // Limit pitch - if (self.track_flags & TFL_TRACK_PITCH) - real_angle_x = bound(self.aim_maxpitch * -1,real_angle_x,self.aim_maxpitch); - - // Limit rot - if (self.track_flags & TFL_TRACK_ROT) - real_angle_y = bound(self.aim_maxrot * -1,real_angle_y,self.aim_maxrot); - switch(self.track_type) { case TFL_TRACKTYPE_STEPMOTOR: - - /* - setorigin(self.aim_mark,self.tur_aimpos); - wish_angle = normalize(self.tur_aimpos - self.tur_shotorg_updated); - real_angle = vectoangles(wish_angle); - self.tur_head.angles = real_angle; - return; - */ f_tmp = self.aim_speed * self.ticrate; // dgr/sec -> dgr/tic - - // Limit turning speed - real_angle_x = bound((-1 * f_tmp),real_angle_x, f_tmp); - real_angle_y = bound((-1 * f_tmp),real_angle_y, f_tmp); - - // Limit pich and rot. if (self.track_flags & TFL_TRACK_PITCH) - self.tur_head.angles_x = bound((-1 * self.aim_maxpitch),self.tur_head.angles_x + real_angle_x,self.aim_maxpitch); + { + self.tur_head.angles_x += bound(-f_tmp,move_angle_x, f_tmp); + if(self.tur_head.angles_x + a_off_x > self.aim_maxpitch) + self.tur_head.angles_x = a_off_x + self.aim_maxpitch; + + if(self.tur_head.angles_x + a_off_x < -self.aim_maxpitch) + self.tur_head.angles_x = a_off_x - self.aim_maxpitch; + } if (self.track_flags & TFL_TRACK_ROT) - self.tur_head.angles_y = bound((-1 * self.aim_maxrot),self.tur_head.angles_y + real_angle_y,self.aim_maxrot); + { + self.tur_head.angles_y += bound(-f_tmp, move_angle_y, f_tmp); + if((self.tur_head.angles_y - a_off_y) > self.aim_maxrot) + self.tur_head.angles_y = a_off_y + self.aim_maxrot; + + if((self.tur_head.angles_y - a_off_y) < -self.aim_maxrot) + self.tur_head.angles_y = a_off_y - self.aim_maxrot; + } return; + case TFL_TRACKTYPE_FLUIDINERTIA: + f_tmp = self.aim_speed * self.ticrate; // dgr/sec -> dgr/tic + move_angle_x = bound(-self.aim_speed, move_angle_x * self.track_accel_pitch * f_tmp,self.aim_speed); + move_angle_y = bound(-self.aim_speed, move_angle_y * self.track_accel_rot * f_tmp,self.aim_speed); + move_angle = (self.tur_head.avelocity * self.track_blendrate) + (move_angle * (1 - self.track_blendrate)); break; case TFL_TRACKTYPE_FLUIDPRECISE: - real_angle_y = bound(self.aim_speed * -1,real_angle_y ,self.aim_speed); - real_angle_x = bound(self.aim_speed * -1,real_angle_x ,self.aim_speed); - - break; - - case TFL_TRACKTYPE_FLUIDINERTIA: - - f_tmp = self.aim_speed * self.ticrate; - - real_angle_y = bound(self.aim_speed * -1,real_angle_y * self.track_accel_rot * f_tmp,self.aim_speed); - real_angle_x = bound(self.aim_speed * -1,real_angle_x * self.track_accel_pitch * f_tmp,self.aim_speed); - real_angle = (self.tur_head.avelocity * self.track_blendrate) + (real_angle * (1 - self.track_blendrate)); - - self.tur_head.avelocity_z = real_angle_z; + move_angle_y = bound(-self.aim_speed, move_angle_y, self.aim_speed); + move_angle_x = bound(-self.aim_speed, move_angle_x, self.aim_speed); break; } - // Limit pitch + // pitch if (self.track_flags & TFL_TRACK_PITCH) { - self.tur_head.avelocity_x = real_angle_x; - if (self.tur_head.angles_x > 360) + self.tur_head.avelocity_x = move_angle_x; + if((self.tur_head.angles_x + self.tur_head.avelocity_x * self.ticrate) + a_off_x > self.aim_maxpitch) { - self.tur_head.angles_x -= floor(self.tur_head.angles_x / 360) * 360; - //self.tur_head.angles_x = self.aim_maxpitch; - //self.tur_head.avelocity_x = 0; + self.tur_head.avelocity_x = 0; + self.tur_head.angles_x = a_off_x + self.aim_maxpitch; } - else if (self.tur_head.angles_x < -360) + if((self.tur_head.angles_x + self.tur_head.avelocity_x * self.ticrate) + a_off_x < -self.aim_maxpitch) { - self.tur_head.angles_x += floor(self.tur_head.angles_x / 360) * 360; - //self.tur_head.angles_x = (self.aim_maxpitch * -1); - //self.tur_head.avelocity_x = 0; + self.tur_head.avelocity_x = 0; + self.tur_head.angles_x = a_off_x - self.aim_maxpitch; } + } - // Limit rot + // rot if (self.track_flags & TFL_TRACK_ROT) { - self.tur_head.avelocity_y = real_angle_y; - if (self.tur_head.angles_y > 360) + self.tur_head.avelocity_y = move_angle_y; + + if(((self.tur_head.angles_y + self.tur_head.avelocity_y * self.ticrate)- a_off_y) > self.aim_maxrot) { - self.tur_head.angles_y -= floor(self.tur_head.angles_y / 360) * 360; - //self.tur_head.angles_y = self.aim_maxrot; - //self.tur_head.avelocity_y = 0; + self.tur_head.avelocity_y = 0; + self.tur_head.angles_y = a_off_y + self.aim_maxrot; } - else if (self.tur_head.angles_y < -360) + + if(((self.tur_head.angles_y + self.tur_head.avelocity_y * self.ticrate) - a_off_y) < -self.aim_maxrot) { - self.tur_head.angles_y += floor(self.tur_head.angles_y / 360) * 360; - //self.tur_head.angles_y = (self.aim_maxrot * -1); - //self.tur_head.avelocity_y = 0; + self.tur_head.avelocity_y = 0; + self.tur_head.angles_y = a_off_y - self.aim_maxrot; } + } + } + /* + = implemented - = not implemented @@ -400,7 +369,7 @@ float turret_stdproc_firecheck() if((self.shoot_flags & TFL_SHOOT_VOLLYALWAYS) && (self.volly_counter != self.shot_volly)) return 1; - // + // Lack of zombies makes shooting dead things unnecessary :P if (self.firecheck_flags & TFL_FIRECHECK_DEAD) if (self.enemy.deadflag != DEAD_NO) return 0; @@ -506,7 +475,8 @@ float turret_validate_target(entity e_turret,entity e_target,float validate_flag // enemy turrets if (validate_flags & TFL_TARGETSELECT_NOTURRETS) if (e_target.turret_firefunc || e_target.owner.tur_head == e_target) - return -9; + if(e_target.team != e_turret.team) // Dont break support units. + return -9; // Missile if (e_target.flags & FL_PROJECTILE) @@ -691,7 +661,7 @@ void turret_think() // Inactive turrets needs to run the think loop, // So they can handle animation and wake up if need be. - if(!self.tur_active) + if not (self.tur_active) { turret_stdproc_track(); return; @@ -700,7 +670,7 @@ void turret_think() //This is just wrong :| if(self.deadflag != DEAD_NO) { - dprint("Warning:dead turret running the think function!\n"); + dprint("WARNING: dead turret running the think function!\n"); return; } @@ -727,6 +697,24 @@ void turret_think() } self.enemy = world; } + else if(self.shoot_flags & TFL_SHOOT_CUSTOM) + { + // This one is doing something oddball. assume its handles what needs to be handled. + + // Predict? + if not((self.aim_flags & TFL_AIM_NO)) + self.tur_aimpos = turret_stdproc_aim_generic(); + + // Turn & pitch? + if (!self.track_flags & TFL_TRACK_NO) + turret_stdproc_track(); + + turret_do_updates(self); + + // Fire? + if (self.turret_firecheckfunc()) + turret_fire(); + } else { // Special case for volly always. if it fired once it must compleate the volly. @@ -737,7 +725,6 @@ void turret_think() if not((self.aim_flags & TFL_AIM_NO)) self.tur_aimpos = turret_stdproc_aim_generic(); - // Turn & pitch if (!self.track_flags & TFL_TRACK_NO) turret_stdproc_track(); @@ -777,20 +764,11 @@ void turret_think() else self.lip = time + cvar("g_turrets_aimidle_delay"); // Keep track of the last time we had a target. - - /* - turret_do_updates(self); - if (self.turret_firecheckfunc() > 0) - turret_fire(); - */ - - //turret_do_updates(self); - // Predict or whatnot + // Predict? if not((self.aim_flags & TFL_AIM_NO)) self.tur_aimpos = turret_stdproc_aim_generic(); - //turret_do_updates(self); - // Turn & pitch + // Turn & pitch? if (!self.track_flags & TFL_TRACK_NO) turret_stdproc_track(); @@ -798,13 +776,11 @@ void turret_think() // Fire? if (self.turret_firecheckfunc()) turret_fire(); - - - } // do any per-turret stuff - self.turret_postthink(); + if(self.turret_postthink) + self.turret_postthink(); } void turret_fire() @@ -1132,18 +1108,27 @@ float turret_stdproc_init (string cvar_base_name) } } - // Put pices in place - if (!(self.turrcaps_flags & TFL_TURRCAPS_HEADATTACHED)) + if not (self.turrcaps_flags & TFL_TURRCAPS_HEADATTACHED) setorigin(self.tur_head,self.origin); - // In target defense mode, aim on the spot to defens when idle. - if (self.tur_defend) - self.idle_aim = self.tur_head.angles + angleofs(self.tur_head,self.tur_defend); + // In target defend mode, aim on the spot to defend when idle. + if(self.turrcaps_flags & TFL_TURRCAPS_HEADATTACHED) + { + if (self.tur_defend) + self.idle_aim = self.tur_head.angles + angleofs(self.tur_head,self.tur_defend); + else + self.idle_aim = '0 0 0'; + } else - self.idle_aim = self.angles; + { + if (self.tur_defend) + self.idle_aim = self.tur_head.angles + angleofs(self.tur_head,self.tur_defend); + else + self.idle_aim = self.angles; + } - if (!(self.turrcaps_flags & TFL_TURRCAPS_HEADATTACHED)) + if not (self.turrcaps_flags & TFL_TURRCAPS_HEADATTACHED) self.tur_head.angles = self.idle_aim; if (!self.health) @@ -1171,7 +1156,8 @@ float turret_stdproc_init (string cvar_base_name) self.turret_score_target = turret_stdproc_targetscore_support; self.turret_firecheckfunc = turret_stdproc_firecheck; self.turret_firefunc = turret_stdproc_fire; - self.turret_postthink = turret_stdproc_nothing; + //self.turret_postthink = turret_stdproc_nothing; + self.event_damage = turret_stdproc_damage; self.tur_head.event_damage = turret_stdproc_damage; } else @@ -1179,10 +1165,10 @@ float turret_stdproc_init (string cvar_base_name) self.turret_score_target = turret_stdproc_targetscore_generic; self.turret_firecheckfunc = turret_stdproc_firecheck; self.turret_firefunc = turret_stdproc_fire; - self.turret_postthink = turret_stdproc_nothing; + //self.turret_postthink = turret_stdproc_nothing; self.event_damage = turret_stdproc_damage; self.tur_head.event_damage = turret_stdproc_damage; - self.turret_addtarget = turret_stdproc_false; + //self.turret_addtarget = turret_stdproc_false; } self.use = turret_stdproc_use; diff --git a/data/qcsrc/server/tturrets/system/system_misc.qc b/data/qcsrc/server/tturrets/system/system_misc.qc index a5e2e42e7..20bea1eae 100644 --- a/data/qcsrc/server/tturrets/system/system_misc.qc +++ b/data/qcsrc/server/tturrets/system/system_misc.qc @@ -1,6 +1,20 @@ -//--// Some supptort routines //--// +//--// Some support routines //--// -#define anglemods(a) (a - floor(a / 360) * 360) +#define anglemodss(a) (a - floor(a / 360) * 360) +float(float v) anglemods = +{ + v = v - 360 * floor(v / 360); + return v; +}; +float safeangle(float a) +{ + if((a > -361) && (a < 361)) + return a; + + a -= (360 * floor(a / 360)); + + return a; +} float shortangle_f(float ang1,float ang2) { @@ -29,6 +43,16 @@ vector shortangle_v(vector ang1,vector ang2) return vtmp; } +vector shortangle_vxy(vector ang1,vector ang2) +{ + vector vtmp; + + vtmp_x = shortangle_f(ang1_x,ang2_x); + vtmp_y = shortangle_f(ang1_y,ang2_y); + + return vtmp; +} + // Get real origin vector real_origin(entity ent) { @@ -235,15 +259,20 @@ vector angleofs3(vector from,vector from_a, entity to) return v_res; } -float turret_tag_setup(float linked) +float turret_tag_setup() { - // Laters dooz - if (linked) + if(!self.tur_head) + { + dprint("Call to turret_tag_setup with self.tur_head missing!\n"); + self.tur_shotorg = '0 0 0'; return 0; + } setorigin(self.tur_head,gettaginfo(self,gettagindex(self,"tag_head"))); self.tur_shotorg = gettaginfo(self.tur_head,gettagindex(self.tur_head,"tag_fire")); + v_forward = normalize(v_forward); + return 1; } @@ -251,11 +280,14 @@ float turret_tag_fire_update() { if(!self.tur_head) { + dprint("Call to turret_tag_fire_update with self.tur_head missing!\n"); self.tur_shotorg = '0 0 0'; - return 1; + return 0; } self.tur_shotorg = gettaginfo(self.tur_head,gettagindex(self.tur_head,"tag_fire")); + v_forward = normalize(v_forward); + //dprint("update: tur_shotorg: ",vtos(self.tur_shotorg)," origin:", vtos(self.tur_head.origin), " angels: ", vtos(self.tur_head.angles),"\n"); return 1; diff --git a/data/qcsrc/server/tturrets/units/unit_ewheel.qc b/data/qcsrc/server/tturrets/units/unit_ewheel.qc index 3cdce87af..4968fec5f 100644 --- a/data/qcsrc/server/tturrets/units/unit_ewheel.qc +++ b/data/qcsrc/server/tturrets/units/unit_ewheel.qc @@ -4,7 +4,7 @@ void turret_ewheel_projectile_explode() org2 = findbetterlocation (self.origin, 8); pointparticles(particleeffectnum("laser_impact"), org2, trace_plane_normal * 1000, 1); - + //w_deathtypestring = "saw the eweel. to late."; #ifdef TURRET_DEBUG float d; @@ -61,183 +61,277 @@ void ewheel_attack() } -#define EWHEEL_MASS 25 -#define EWHEEL_MAXSPEED 800 -#define EWHEEL_ACCEL_SLOW 100 -#define EWHEEL_ACCEL_FAST 350 -#define EWHEEL_BREAK_SLOW 150 -#define EWHEEL_BREAK_FAST 250 -#define EWHEEL_DRAG 0.25 - -void ewheel_enemymove() +float ewheel_moveverb_path(float eval) { - vector wish_angle,real_angle,steer,avoid; - float turn_limit,angle_ofs; + switch (eval) + { + case VCM_EVAL: - //steer = steerlib_attract2(point,0.5,2000,0.95); - steer = steerlib_pull(self.enemy.origin); - avoid = steerlib_traceavoid(0.3,350); + if (self.pathcurrent) + return verb.verb_static_value; - wish_angle = normalize(avoid * 0.5 + steer); - wish_angle = vectoangles(wish_angle); - real_angle = wish_angle - self.angles; + return VS_CALL_NO; + break; - if (real_angle_x > self.angles_x) - { - if (real_angle_x >= 180) - real_angle_x -= 360; - } - else - { - if (real_angle_x <= -180) - real_angle_x += 360; - } + case VCM_DO: + // Do we have a path? + if not(self.pathcurrent) + return VS_CALL_NO; + else + { + // Are we close enougth to a path node to switch to the next? + if (vlen(self.origin - self.pathcurrent.origin) < 32) + if (self.pathcurrent.path_next == world) + { + // Path endpoint reached + pathlib_deletepath(self.pathcurrent.owner); + self.pathcurrent = world; + + if (self.pathgoal) + { + if (self.pathgoal.use) + self.pathgoal.use(); + + if (self.pathgoal.enemy) + { + self.pathcurrent = pathlib_astar(self.pathgoal.origin,self.pathgoal.enemy.origin); + self.pathgoal = self.pathgoal.enemy; + } + } + else + self.pathgoal = world; + } + else + self.pathcurrent = self.pathcurrent.path_next; + } - if (real_angle_y > self.tur_head.angles_y) - { - if (real_angle_y >= 180) - real_angle_y -= 360; + + if (self.pathcurrent) + { + switch (self.waterlevel) + { + case 0: + case 1: + case 2: + case 3: + } + + self.moveto = self.pathcurrent.origin; + self.steerto = steerlib_attract2(self.moveto,0.5,500,0.95); + + self.frame += 1; + movelib_move_simple(v_forward,cvar("g_turrets_unit_ewheel_speed_slow"),0.4); + + return VS_CALL_YES_DOING; + } + else + return VS_CALL_YES_DONE; + + break; + + case VCM_REMOVE: + + if (self.pathcurrent) + pathlib_deletepath(self.pathcurrent.owner); + + self.pathcurrent = world; + + return VS_CALL_YES_DONE; + + break; } - else + + return VS_CALL_YES_DONE; +} + +float ewheel_moveverb_enemy(float eval) +{ + switch (eval) { - if (real_angle_y <= -180) - real_angle_y += 360; - } + case VCM_EVAL: + if(self.enemy) + return verb.verb_static_value; - turn_limit = cvar("g_turrets_unit_ewheel_turnrate"); - // Convert from dgr / sec to dgr / tic - turn_limit = turn_limit / (1 / self.ticrate); - angle_ofs = fabs(real_angle_y); - real_angle_y = bound(turn_limit * -1,real_angle_y,turn_limit); - self.angles_y = (self.angles_y + real_angle_y); + return VS_CALL_NO; - // Simulate banking - self.angles_z = bound(-45,real_angle_y * -2,45); + break; - if (self.frame > 40) - self.frame = 1; + case VCM_DO: - makevectors(self.angles); - if (self.tur_dist_aimpos > self.target_range_optimal) - { - if ( angle_ofs < 1 ) + self.moveto = self.enemy.origin; + self.steerto = steerlib_arrive(self.enemy.origin,self.target_range_optimal); + + if (self.tur_dist_enemy > self.target_range_optimal) { - self.frame += 2; - movelib_move(v_forward * EWHEEL_ACCEL_FAST,EWHEEL_MAXSPEED,EWHEEL_DRAG,EWHEEL_MASS,0); + if ( self.tur_head.spawnshieldtime < 1 ) + { + self.frame += 2; + movelib_move_simple(v_forward ,cvar("g_turrets_unit_ewheel_speed_fast"),0.4); + } + else if (self.tur_head.spawnshieldtime < 2) + { + self.frame += 1; + movelib_move_simple(v_forward,cvar("g_turrets_unit_ewheel_speed_slow"),0.4); + } + else + { + self.frame += 1; + movelib_move_simple(v_forward,cvar("g_turrets_unit_ewheel_speed_slower"),0.4); + } } - else if (angle_ofs < 2) + else if (self.tur_dist_enemy < self.target_range_min) { - self.frame += 1; - movelib_move(v_forward * EWHEEL_ACCEL_SLOW,EWHEEL_MAXSPEED,EWHEEL_DRAG,EWHEEL_MASS,EWHEEL_BREAK_SLOW); + self.frame -= 1; + movelib_move_simple(v_forward * -1,cvar("g_turrets_unit_ewheel_speed_slow"),0.4); } else { - movelib_move('0 0 0',EWHEEL_MAXSPEED,EWHEEL_DRAG,EWHEEL_MASS,EWHEEL_BREAK_FAST); + movelib_beak_simple(cvar("g_turrets_unit_ewheel_speed_stop")); } + + return VS_CALL_YES_DOING; } - else - movelib_move('0 0 0',EWHEEL_MAXSPEED,EWHEEL_DRAG,EWHEEL_MASS,EWHEEL_BREAK_FAST); + + + return VS_CALL_YES_DONE; } -void ewheel_roammove() +float ewheel_moveverb_runaway(float eval) { - movelib_move(v_forward,EWHEEL_MAXSPEED,0,EWHEEL_MASS,EWHEEL_BREAK_SLOW); - self.angles_z = 0; + switch (eval) + { + case VCM_EVAL: + if(self.enemy) + if(self.health < 50) + return verb.verb_static_value; - /* - vector wish_angle,real_angle,steer,avoid; - float turn_limit,angle_ofs; - float dist; + return VS_CALL_NO; + break; - return; + case VCM_DO: + self.steerto = (steerlib_push(self.enemy.origin) * 0.7) + (steerlib_traceavoid_flat(0.3, 500, '0 0 128') * 0.3); + self.moveto = self.origin + self.steerto * 1000; - dist = vlen(self.origin - self.pos1); + self.frame += 2; + movelib_move_simple(v_forward ,cvar("g_turrets_unit_ewheel_speed_fast"),0.4); - //steer = steerlib_attract2(point,0.5,2000,0.95); - steer = steerlib_pull(self.pos1); - avoid = steerlib_traceavoid(0.3,350); + return VS_CALL_YES_DOING; - wish_angle = normalize(avoid * 0.5 + steer); - wish_angle = vectoangles(wish_angle); - real_angle = wish_angle - self.angles; + break; + } - real_angle_y = shortangle_f(real_angle_y,self.angles_y); + return VS_CALL_YES_DONE; +} - turn_limit = cvar("g_turrets_unit_ewheel_turnrate"); - // Convert from dgr/sec to dgr/tic - turn_limit = turn_limit / (1 / self.ticrate); - angle_ofs = fabs(real_angle_y); +float ewheel_moveverb_idle(float eval) +{ + switch (eval) + { + case VCM_EVAL: + if(self.enemy) + return VS_CALL_NO; - real_angle_y = bound(turn_limit * -1,real_angle_y,turn_limit); - self.angles_y = (self.angles_y + real_angle_y); + return verb.verb_static_value; - self.angles_z = bound(-12,real_angle_y * -1,12); + break; - if(self.frame > 40) - self.frame = 1; + case VCM_DO: + self.moveto = self.origin; - makevectors(self.angles); - float lspeed; - lspeed = vlen(self.velocity); + if(vlen(self.velocity)) + movelib_beak_simple(cvar("g_turrets_unit_ewheel_speed_stop")); - if((dist < 64)||(self.phase < time)) - { - movelib_move('0 0 0',150,0,50,200); - self.pos1 = self.origin + v_forward * 256 + randomvec() * 128; - self.pos1_z = self.origin_z; - self.phase = time + 5; + return VS_CALL_YES_DOING; } - else if(dist < 128) - { - self.frame += 1; - if(lspeed > 100) - movelib_move(v_forward * 50,150,0,50,50); - else - movelib_move(v_forward * 100,150,0,50,0); - } - else - { - self.frame += 1; - if(angle_ofs > 10) - movelib_move(v_forward * 50,150,0,50,50); - else - movelib_move(v_forward * 250,150,0,50,0); - } - */ + + return VS_CALL_YES_DONE; } void ewheel_postthink() { - if (self.enemy) - ewheel_enemymove(); - else - ewheel_roammove(); + float vz; + vector wish_angle,real_angle; -} + vz = self.velocity_z; + self.angles_x = anglemods(self.angles_x); + self.angles_y = anglemods(self.angles_y); + + self.angles_x *= -1; + makevectors(self.angles); + self.angles_x *= -1; + + wish_angle = normalize(self.steerto); + wish_angle = vectoangles(wish_angle); + real_angle = wish_angle - self.angles; + real_angle = shortangle_vxy(real_angle,self.tur_head.angles); + + self.tur_head.spawnshieldtime = fabs(real_angle_y); + real_angle_y = bound(self.tur_head.aim_speed * -1,real_angle_y,self.tur_head.aim_speed); + self.angles_y = (self.angles_y + real_angle_y); + + // Simulate banking + self.angles_z = bound(-45,real_angle_y * -2.5,45); + + verbstack_pop(self.verbs_move); + + if (self.frame > 40) + self.frame = 1; + + if (self.frame < 1) + self.frame = 40; + + + self.velocity_z = vz; +} void ewheel_respawnhook() { + entity e; + setorigin(self,self.pos1); + + if (self.target != "") + { + e = find(world,targetname,self.target); + if (!e) + { + dprint("Initital waypoint for ewheel does NOT exsist, fix your map!\n"); + self.target = ""; + } + + if (e.classname != "turret_checkpoint") + dprint("Warning: not a turrret path\n"); + else + { + self.pathcurrent = WALKER_PATH(self.origin,e.origin); + self.pathgoal = e; + } + } } void ewheel_diehook() { -} + turret_trowgib2(self.origin,self.velocity + v_up * 400,'-0.6 -0.2 -02',self,time + random() * 2 +3); + + if (self.pathcurrent) + pathlib_deletepath(self.pathcurrent.owner); + + self.pathcurrent = world; + + if (self.damage_flags & TFL_DMG_DEATH_NORESPAWN) + { + verbstack_flush(self.verbs_move); + remove(self.verbs_move); + } -float ewheel_firecheck() -{ - bprint("Firecheck\n"); - return 1; } void turret_ewheel_dinit() { entity e; - if (self.netname == "") self.netname = "Ewheel Turret"; - - // self.ticrate = 0.05; + if (self.netname == "") self.netname = "eWheel Turret"; if (self.target != "") { @@ -261,28 +355,23 @@ void turret_ewheel_dinit() self.turret_respawnhook = ewheel_respawnhook; self.turret_diehook = ewheel_diehook; - self.ticrate = 0.05; if (turret_stdproc_init("ewheel_std") == 0) { remove(self); return; } - //self.turret_firecheckfunc = ewheel_firecheck; - self.target_select_flags = TFL_TARGETSELECT_PLAYERS | TFL_TARGETSELECT_RANGELIMTS | TFL_TARGETSELECT_TEAMCHECK | TFL_TARGETSELECT_LOS; + self.target_select_flags = TFL_TARGETSELECT_PLAYERS | TFL_TARGETSELECT_RANGELIMTS | TFL_TARGETSELECT_TEAMCHECK | TFL_TARGETSELECT_LOS; self.target_validate_flags = TFL_TARGETSELECT_PLAYERS | TFL_TARGETSELECT_RANGELIMTS | TFL_TARGETSELECT_TEAMCHECK | TFL_TARGETSELECT_LOS; - self.damage_flags |= TFL_DMG_DEATH_NOGIBS; + self.damage_flags |= TFL_DMG_DEATH_NOGIBS; - //self.flags = FL_CLIENT; self.iscreature = TRUE; self.movetype = MOVETYPE_WALK; - self.gravity = 0.01; self.solid = SOLID_SLIDEBOX; self.takedamage = DAMAGE_AIM; setmodel(self,"models/turrets/ewheel-base.md3"); setmodel(self.tur_head,"models/turrets/ewheel-gun1.md3"); - setattachment(self.tur_head,self,"tag_head"); self.pos1 = self.origin; @@ -293,8 +382,35 @@ void turret_ewheel_dinit() self.turret_firefunc = ewheel_attack; self.turret_postthink = ewheel_postthink; self.tur_head.frame = 1; -} + self.verbs_move = spawn(); + verbstack_push(self.verbs_move, ewheel_moveverb_idle, WVM_IDLE, 0); + verbstack_push(self.verbs_move, ewheel_moveverb_enemy, WVM_ENEMY, 0); + verbstack_push(self.verbs_move, ewheel_moveverb_path, WVM_PATH, 0); + verbstack_push(self.verbs_move, ewheel_moveverb_runaway,WVM_PANIC, 0); + + // Convert from dgr / sec to dgr / tic + self.tur_head.aim_speed = cvar("g_turrets_unit_ewheel_turnrate"); + self.tur_head.aim_speed = self.tur_head.aim_speed / (1 / self.ticrate); + + if (self.target != "") + { + e = find(world,targetname,self.target); + if (!e) + { + dprint("Initital waypoint for ewheel does NOT exsist, fix your map!\n"); + self.target = ""; + } + + if (e.classname != "turret_checkpoint") + dprint("Warning: not a turrret path\n"); + else + { + self.pathcurrent = WALKER_PATH(self.origin,e.origin); + self.pathgoal = e; + } + } +} void spawnfunc_turret_ewheel() { diff --git a/data/qcsrc/server/tturrets/units/unit_flac.qc b/data/qcsrc/server/tturrets/units/unit_flac.qc index 55198b9ff..6c2329fed 100644 --- a/data/qcsrc/server/tturrets/units/unit_flac.qc +++ b/data/qcsrc/server/tturrets/units/unit_flac.qc @@ -45,6 +45,8 @@ void turret_flac_projectile_explode() // FIXME: tur_impacttime is not accurate enougth, this is a dirty hakk to make flac work. + //w_deathtypestring = "got caught in the flack."; + if(self.enemy != world) if(self.cnt < time) if(vlen(self.origin - self.enemy.origin) > self.owner.shot_radius * 0.25) @@ -100,7 +102,7 @@ void turret_flac_dinit() setmodel(self,"models/turrets/base.md3"); setmodel(self.tur_head,"models/turrets/flac.md3"); - if (!turret_tag_setup(0)) + if (!turret_tag_setup()) dprint("Warning: Turret ",self.classname, " faild to initialize md3 tags\n"); // Our fire routine diff --git a/data/qcsrc/server/tturrets/units/unit_fusionreactor.qc b/data/qcsrc/server/tturrets/units/unit_fusionreactor.qc index 32b369936..3a76f6e14 100644 --- a/data/qcsrc/server/tturrets/units/unit_fusionreactor.qc +++ b/data/qcsrc/server/tturrets/units/unit_fusionreactor.qc @@ -58,7 +58,7 @@ void turret_fusionreactor_dinit() setmodel(self,"models/turrets/base.md3"); setmodel(self.tur_head,"models/turrets/reactor.md3"); - //if(!turret_tag_setup(0)) + //if(!turret_tag_setup()) // dprint("Warning: Turret ",self.classname, " faild to initialize md3 tags\n"); self.tur_head.scale = 0.75; diff --git a/data/qcsrc/server/tturrets/units/unit_hellion.qc b/data/qcsrc/server/tturrets/units/unit_hellion.qc index add5f912e..30882f465 100644 --- a/data/qcsrc/server/tturrets/units/unit_hellion.qc +++ b/data/qcsrc/server/tturrets/units/unit_hellion.qc @@ -159,6 +159,7 @@ void turret_hellion_missile_explode() WriteCoord (MSG_BROADCAST, org2_y); WriteCoord (MSG_BROADCAST, org2_z); + //w_deathtypestring = "could not dodge the twin missiles."; self.event_damage = SUB_Null; d = RadiusDamage (self, self.owner, self.owner.shot_dmg, 0, self.owner.shot_radius, world, self.owner.shot_force, DEATH_TURRET, world); @@ -196,7 +197,7 @@ void turret_hellion_dinit() setmodel(self,"models/turrets/base.md3"); setmodel(self.tur_head,"models/turrets/hellion.md3"); - if (!turret_tag_setup(0)) + if (!turret_tag_setup()) dprint("Warning: Turret ",self.classname, " faild to initialize md3 tags\n"); // Our fire routine diff --git a/data/qcsrc/server/tturrets/units/unit_hk.qc b/data/qcsrc/server/tturrets/units/unit_hk.qc index 976917265..0d1aa91d5 100644 --- a/data/qcsrc/server/tturrets/units/unit_hk.qc +++ b/data/qcsrc/server/tturrets/units/unit_hk.qc @@ -363,6 +363,7 @@ void turret_hk_missile_explode() if ((other == self.owner)||(other == self.owner.tur_head)) return; + //w_deathtypestring = "got hunted to extinction"; //vector org2; sound (self, CHAN_PROJECTILE, "weapons/rocket_impact.wav", VOL_BASE, ATTN_NORM); org2 = findbetterlocation (self.origin, 16); @@ -443,7 +444,7 @@ void turret_hk_dinit() setmodel(self,"models/turrets/base.md3"); setmodel(self.tur_head,"models/turrets/hk.md3"); - if (!turret_tag_setup(0)) + if (!turret_tag_setup()) dprint("Warning: Turret ",self.classname, " faild to initialize md3 tags\n"); // Our fire routine diff --git a/data/qcsrc/server/tturrets/units/unit_machinegun.qc b/data/qcsrc/server/tturrets/units/unit_machinegun.qc index e145d5234..fcb381bbe 100644 --- a/data/qcsrc/server/tturrets/units/unit_machinegun.qc +++ b/data/qcsrc/server/tturrets/units/unit_machinegun.qc @@ -11,6 +11,7 @@ void turret_machinegun_attack() sound (self, CHAN_WEAPON, "weapons/uzi_fire.wav", VOL_BASE, ATTN_NORM); fireBallisticBullet (self.tur_shotorg, self.tur_shotdir_updated,self.shot_spread, self.shot_speed, 5, self.shot_dmg, 0, self.shot_force, DEATH_TURRET, 0, 1, cvar("g_balance_uzi_bulletconstant")); + //w_deathtypestring = "had an alergic reaction due to 10 kilos of led"; te_smallflash(self.tur_shotorg); // trailparticles(self,particleeffectnum("EF_MGTURRETTRAIL"),self.tur_shotorg_updated,trace_endpos); @@ -52,7 +53,7 @@ void turret_machinegun_std_init() setmodel(self,"models/turrets/base.md3"); setmodel(self.tur_head,"models/turrets/machinegun.md3"); - if (!turret_tag_setup(0)) + if (!turret_tag_setup()) dprint("Warning: Turret ",self.classname, " faild to initialize md3 tags\n"); // Our fire routine diff --git a/data/qcsrc/server/tturrets/units/unit_mlrs.qc b/data/qcsrc/server/tturrets/units/unit_mlrs.qc index 3ee8f0230..465cf4300 100644 --- a/data/qcsrc/server/tturrets/units/unit_mlrs.qc +++ b/data/qcsrc/server/tturrets/units/unit_mlrs.qc @@ -77,7 +77,7 @@ void turret_mlrs_rocket_explode() sound (self, CHAN_PROJECTILE, "weapons/rocket_impact.wav", VOL_BASE, ATTN_NORM); org2 = findbetterlocation (self.origin, 16); pointparticles(particleeffectnum("rocket_explode"), org2, '0 0 0', 1); - + //w_deathtypestring = "dident escape the rocket barrage"; #ifdef TURRET_DEBUG float d; @@ -117,7 +117,7 @@ void turret_mlrs_dinit() setmodel(self,"models/turrets/base.md3"); setmodel(self.tur_head,"models/turrets/mlrs.md3"); - if (!turret_tag_setup(0)) + if (!turret_tag_setup()) dprint("Warning: Turret ",self.classname, " faild to initialize md3 tags\n"); // Our fire routine diff --git a/data/qcsrc/server/tturrets/units/unit_phaser.qc b/data/qcsrc/server/tturrets/units/unit_phaser.qc index d01f038d9..eb992024b 100644 --- a/data/qcsrc/server/tturrets/units/unit_phaser.qc +++ b/data/qcsrc/server/tturrets/units/unit_phaser.qc @@ -60,6 +60,7 @@ void beam_think() entity oldself; oldself = self; self = self.owner; + //w_deathtypestring = "was phased out of existence"; FireImoBeam ( self.tur_shotorg, self.tur_shotorg + self.tur_shotdir_updated * self.target_range_fire, '-1 -1 -1' * self.shot_radius, @@ -124,7 +125,7 @@ void turret_phaser_dinit() setmodel(self,"models/turrets/base.md3"); setmodel(self.tur_head,"models/turrets/phaser.md3"); - if (!turret_tag_setup(0)) + if (!turret_tag_setup()) dprint("Warning: Turret ",self.classname, " faild to initialize md3 tags\n"); self.turret_firecheckfunc = turret_phaser_firecheck; diff --git a/data/qcsrc/server/tturrets/units/unit_plasma.qc b/data/qcsrc/server/tturrets/units/unit_plasma.qc index cfc2804eb..ad749c81e 100644 --- a/data/qcsrc/server/tturrets/units/unit_plasma.qc +++ b/data/qcsrc/server/tturrets/units/unit_plasma.qc @@ -9,30 +9,11 @@ void turret_plasma_projectile_explode(); void turret_plasma_postthink() { - - if (self.tur_head.frame != 0) self.tur_head.frame = self.tur_head.frame + 1; if (self.tur_head.frame > 5) self.tur_head.frame = 0; - - setsize(self,self.mins,self.maxs); - setsize(self.tur_head,self.tur_head.mins,self.tur_head.maxs); - - /* - float h; - h = self.health / self.tur_health; - if(h<0.95) - { - if( (0.5 + random()) > h) - { - //bprint("Spark!\n"); - //void(vector org, vector vel, float howmany) te_spark = #411; - te_spark(0.5 * (self.absmin + self.absmax) + (randomvec() * 64),randomvec() * 256,(1 - h) * 50); - } - } - */ } void turret_plasma_dual_postthink() @@ -48,15 +29,12 @@ void turret_plasma_attack() { entity proj; - turret_tag_fire_update(); - sound (self, CHAN_WEAPON, "weapons/hagar_fire.wav", VOL_BASE, ATTN_NORM); pointparticles(particleeffectnum("laser_muzzleflash"), self.tur_shotorg, self.tur_shotdir_updated * 1000, 1); proj = spawn (); setorigin(proj, self.tur_shotorg); setsize(proj, '-1 -1 -1', '1 1 1'); - //setmodel(proj, "models/elaser.mdl"); // precision set above proj.classname = "plasmabomb"; proj.owner = self; proj.bot_dodge = TRUE; @@ -82,8 +60,6 @@ void turret_plasma_dual_attack() { entity proj; - //turret_tag_fire_update(); - sound (self, CHAN_WEAPON, "weapons/hagar_fire.wav", VOL_BASE, ATTN_NORM); proj = spawn (); setorigin(proj, self.tur_shotorg); @@ -124,7 +100,7 @@ void turret_plasma_projectile_explode() WriteByte (MSG_BROADCAST, 155); self.event_damage = SUB_Null; - + //w_deathtypestring = "ate to much plasma"; #ifdef TURRET_DEBUG float d; @@ -147,9 +123,9 @@ void turret_plasma_std_init() self.ammo_flags = TFL_AMMO_ENERGY | TFL_AMMO_RECHARGE | TFL_AMMO_RECIVE; // How to aim - //self.aim_flags = TFL_AIM_LEAD | TFL_AIM_SHOTTIMECOMPENSATE;// | TFL_AIM_ZPREDICT | TFL_AIM_GROUND2; + //self.aim_flags = TFL_AIM_LEAD | TFL_AIM_SHOTTIMECOMPENSATE | TFL_AIM_ZPREDICT | TFL_AIM_GROUND2; self.aim_flags = TFL_AIM_LEAD | TFL_AIM_SHOTTIMECOMPENSATE | TFL_AIM_GROUND2; - self.turrcaps_flags = TFL_TURRCAPS_RADIUSDMG | TFL_TURRCAPS_MEDPROJ | TFL_TURRCAPS_PLAYERKILL;// | TFL_TURRCAPS_MISSILEKILL; + self.turrcaps_flags = TFL_TURRCAPS_RADIUSDMG | TFL_TURRCAPS_MEDPROJ | TFL_TURRCAPS_PLAYERKILL | TFL_TURRCAPS_MISSILEKILL; if (turret_stdproc_init("plasma_std") == 0) { @@ -158,8 +134,9 @@ void turret_plasma_std_init() } self.damage_flags |= TFL_DMG_HEADSHAKE; + //self.firecheck_flags |= (TFL_FIRECHECK_AFF | TFL_FIRECHECK_VERIFIED); - // self.firecheck_flags |= TFL_FIRECHECK_AFF; + self.firecheck_flags |= TFL_FIRECHECK_AFF; //self.target_select_flags |= TFL_TARGETSELECT_FOV; //self.target_select_fov = 45; @@ -167,7 +144,7 @@ void turret_plasma_std_init() setmodel(self,"models/turrets/base.md3"); setmodel(self.tur_head,"models/turrets/plasma.md3"); - if (!turret_tag_setup(0)) + if (!turret_tag_setup()) dprint("Warning: Turret ",self.classname, " faild to initialize md3 tags\n"); // Our fireing routine @@ -204,7 +181,7 @@ void turret_plasma_dual_init() setmodel(self.tur_head,"models/turrets/plasmad.md3"); - if (!turret_tag_setup(0)) + if (!turret_tag_setup()) dprint("Warning: Turret ",self.classname, " faild to initialize md3 tags\n"); // Our fireing routine diff --git a/data/qcsrc/server/tturrets/units/unit_targettrigger.qc b/data/qcsrc/server/tturrets/units/unit_targettrigger.qc index 321fe4f6e..ee3dab320 100644 --- a/data/qcsrc/server/tturrets/units/unit_targettrigger.qc +++ b/data/qcsrc/server/tturrets/units/unit_targettrigger.qc @@ -14,7 +14,8 @@ void turret_targettrigger_touch() if (e.turrcaps_flags & TFL_TURRCAPS_RECIVETARGETS) { self = e; - e.turret_addtarget(other,oldself); + if(e.turret_addtarget) + e.turret_addtarget(other,oldself); } e = find(e, targetname, oldself.target); diff --git a/data/qcsrc/server/tturrets/units/unit_tessla.qc b/data/qcsrc/server/tturrets/units/unit_tessla.qc index f76998d52..54606efc8 100644 --- a/data/qcsrc/server/tturrets/units/unit_tessla.qc +++ b/data/qcsrc/server/tturrets/units/unit_tessla.qc @@ -17,9 +17,8 @@ entity toast(entity from, float range, float damage) if ((e.toasted != 1) && (e != from)) if (turret_validate_target(self,e,self.target_validate_flags) > 0) { - - traceline(from.origin,e.origin,0,from); - if (trace_fraction > 0.9) + traceline(from.origin,e.origin,MOVE_WORLDONLY,from); + if (trace_fraction == 1.0) { d = vlen(e.origin - from.origin); if (d < dd) @@ -35,7 +34,7 @@ entity toast(entity from, float range, float damage) if (etarget) { te_smallflash(etarget.origin); - te_lightning1(world,from.origin,etarget.origin); + te_csqc_lightningarc(from.origin,etarget.origin); Damage(etarget,self,self,damage,DEATH_TURRET,etarget.origin,'0 0 0'); etarget.toasted = 1; } @@ -43,20 +42,34 @@ entity toast(entity from, float range, float damage) return etarget; } +float turret_tesla_firecheck() +{ + if not (turret_stdproc_firecheck()) + return 0; + + self.target_select_flags = TFL_TARGETSELECT_PLAYERS | TFL_TARGETSELECT_MISSILES | + TFL_TARGETSELECT_RANGELIMTS | TFL_TARGETSELECT_TEAMCHECK; + + self.enemy = turret_select_target(); + + if(self.enemy) + return 1; + + return 0; + +} + void turret_tesla_fire() { entity e,t; float d,r,i; - if (cvar("g_turrets_nofire") != 0) - return; - - if (self.attack_finished_single > time) return; + //w_deathtypestring = "discoverd how a tesla coil works"; d = self.shot_dmg; r = self.target_range; e = spawn(); - setorigin(e,self.origin + self.tur_shotorg); + setorigin(e,self.tur_shotorg); self.target_validate_flags = TFL_TARGETSELECT_PLAYERS | TFL_TARGETSELECT_MISSILES | @@ -71,11 +84,10 @@ void turret_tesla_fire() TFL_TARGETSELECT_TEAMCHECK; self.attack_finished_single = time + self.shot_refire; - self.ammo = self.ammo - self.shot_dmg; - for (i = 0;i < 10;i = i + 1) + for (i = 0; i < 10; ++i) { d *= 0.5; - r *= 0.75; + r *= 0.85; t = toast(t,r,d); if (t == world) break; } @@ -90,15 +102,30 @@ void turret_tesla_fire() void turret_tesla_postthink() { - turret_tesla_fire(); + if not (self.tur_active) + { + self.tur_head.avelocity = '0 0 0'; + return; + } - self.tur_head.frame = self.tur_head.frame + 1; + if(self.ammo < self.shot_dmg) + { + self.tur_head.avelocity = '0 9 0' * (self.ammo / self.shot_dmg); + } + else + { + self.tur_head.avelocity = '0 90 0' * (self.ammo / self.shot_dmg); - if (self.tur_head.frame >= 11) - self.tur_head.frame = 0; + if(self.attack_finished_single > time) + return; - if (self.tur_head.avelocity == '0 0 0') - self.tur_head.avelocity = '0 35 0'; + float f; + f = (self.ammo / self.ammo_max); + f = f*f; + if(f > random()) + if(random() < 0.1) + te_csqc_lightningarc(self.tur_shotorg,self.tur_shotorg + (randomvec() * 350)); + } } @@ -106,13 +133,16 @@ void turret_tesla_dinit() { if (self.netname == "") self.netname = "Tesla Coil"; - self.turrcaps_flags = TFL_TURRCAPS_HITSCAN | TFL_TURRCAPS_PLAYERKILL | TFL_TURRCAPS_MISSILEKILL; - self.target_select_flags = TFL_TARGETSELECT_NO; - self.firecheck_flags = TFL_FIRECHECK_REFIRE; - self.shoot_flags = TFL_SHOOT_CUSTOM; - self.ammo_flags = TFL_AMMO_ENERGY | TFL_AMMO_RECHARGE | TFL_AMMO_RECIVE; - self.aim_flags = TFL_AIM_NO; - self.track_flags = TFL_TRACK_NO; + self.turrcaps_flags = TFL_TURRCAPS_HITSCAN | TFL_TURRCAPS_PLAYERKILL | TFL_TURRCAPS_MISSILEKILL; + + self.target_select_flags = TFL_TARGETSELECT_PLAYERS | TFL_TARGETSELECT_MISSILES | + TFL_TARGETSELECT_RANGELIMTS | TFL_TARGETSELECT_TEAMCHECK; + + self.firecheck_flags = TFL_FIRECHECK_REFIRE | TFL_FIRECHECK_OWM_AMMO; + self.shoot_flags = TFL_SHOOT_CUSTOM; + self.ammo_flags = TFL_AMMO_ENERGY | TFL_AMMO_RECHARGE | TFL_AMMO_RECIVE; + self.aim_flags = TFL_AIM_NO; + self.track_flags = TFL_TRACK_NO; if (turret_stdproc_init("tesla_std") == 0) { @@ -126,11 +156,12 @@ void turret_tesla_dinit() self.target_validate_flags = TFL_TARGETSELECT_PLAYERS | TFL_TARGETSELECT_MISSILES | TFL_TARGETSELECT_RANGELIMTS | TFL_TARGETSELECT_TEAMCHECK; - if (!turret_tag_setup(0)) + if (!turret_tag_setup()) dprint("Warning: Turret ",self.classname, " faild to initialize md3 tags\n"); - self.turret_firefunc = turret_stdproc_nothing; - self.turret_postthink = turret_tesla_postthink; + self.turret_firefunc = turret_tesla_fire; + self.turret_postthink = turret_tesla_postthink; + self.turret_firecheckfunc = turret_tesla_firecheck; } /*QUAKED turret_tesla (0 .5 .8) ? diff --git a/data/qcsrc/server/tturrets/units/unit_walker.qc b/data/qcsrc/server/tturrets/units/unit_walker.qc index f6b1cefda..8c47d0116 100644 --- a/data/qcsrc/server/tturrets/units/unit_walker.qc +++ b/data/qcsrc/server/tturrets/units/unit_walker.qc @@ -1,16 +1,16 @@ -#define ANIM_NO 0 -#define ANIM_REVERSE 1 -#define ANIM_WALK 2 -#define ANIM_RUN 3 -#define ANIM_STRAFE_L 4 -#define ANIM_STRAFE_R 5 -#define ANIM_TURN 6 -#define ANIM_JUMP 7 -#define ANIM_LAND 8 -#define ANIM_PAIN 9 -#define ANIM_MEELE 10 -#define ANIM_SWIM 11 -#define ANIM_ROAM 12 +#define ANIM_NO 0 +#define ANIM_REVERSE 1 +#define ANIM_WALK 2 +#define ANIM_RUN 3 +#define ANIM_STRAFE_L 4 +#define ANIM_STRAFE_R 5 +#define ANIM_TURN 6 +#define ANIM_JUMP 7 +#define ANIM_LAND 8 +#define ANIM_PAIN 9 +#define ANIM_MEELE 10 +#define ANIM_SWIM 11 +#define ANIM_ROAM 12 #define WVM_IDLE_UP 25 #define WVM_IDLE 50 @@ -19,11 +19,12 @@ #define WVM_ENEMY 2000 #define WVM_STOP 3000 #define WVM_DODGE 4000 +#define WVM_PANIC 10000 #define walker_verbs_move verbs_move -#define WVA_MINIGUN 1 -#define WVA_ROCKET 10 -#define WVA_MEELE 20 +#define WVA_MINIGUN 100 +#define WVA_ROCKET 500 +#define WVA_MEELE 1000 #define walker_verbs_attack verbs_attack #define WVI_IDLE 1 @@ -31,7 +32,6 @@ #define walker_verbs_idle verbs_idle .float animflag; -.entity wkr_props; .entity wkr_spawn; #define WALKER_MIN '-70 -70 5' @@ -41,6 +41,9 @@ float walker_firecheck() { + if (self.animflag == ANIM_MEELE) + return 0; + return turret_stdproc_firecheck(); } @@ -51,6 +54,7 @@ void walker_meele_do_dmg() makevectors(self.angles); where = self.origin + v_forward * 128; + //w_deathtypestring = "tried to hug the cute spider thingy."; e = findradius(where,64); while (e) { @@ -62,16 +66,13 @@ void walker_meele_do_dmg() } } -.vector moveto; -.vector steerto; void walker_animate() { - vector wish_angle,real_angle; - float vz; + vector real_angle; + float vz; - wish_angle = self.steerto; - real_angle = wish_angle - self.angles; - vz = self.velocity_z; + real_angle = vectoangles(self.steerto) - self.angles; + vz = self.velocity_z; if (self.tur_head.frame != 0) self.tur_head.frame = self.tur_head.frame +1; @@ -81,27 +82,30 @@ void walker_animate() switch (self.animflag) { + case ANIM_NO: - if(self.frame != 0) + if (self.frame != 0) self.frame = 0; movelib_beak_simple(cvar("g_turrets_unit_walker_speed_stop")); + break; case ANIM_REVERSE: if ((self.frame < 5) || (self.frame > 25)) - self.frame = 5; + self.frame = 25; - self.frame = self.frame +1; + self.frame = self.frame -1; movelib_move_simple(v_forward * -1 ,cvar("g_turrets_unit_walker_speed_walk"),0.6); - if (self.frame > 25) - self.frame = 5; + if (self.frame < 5) + self.frame = 25; + break; case ANIM_TURN: - if (self.frame < 30) + if ((self.frame < 30) || (self.frame > 55)) self.frame = 30; self.frame = self.frame + 1; @@ -125,6 +129,7 @@ void walker_animate() if (self.frame > 25) self.frame = 5; + break; case ANIM_ROAM: @@ -133,26 +138,30 @@ void walker_animate() self.frame = self.frame +1; - self.angles_y += bound(-15,shortangle_f(real_angle_y,self.angles_y),15); + self.angles_y += bound(-5,shortangle_f(real_angle_y,self.angles_y),5); movelib_move_simple(v_forward ,cvar("g_turrets_unit_walker_speed_roam"),0.5); if (self.frame > 25) self.frame = 5; + break; case ANIM_SWIM: - if (self.frame < 142) + if ((self.frame < 142) || (self.frame > 151)) self.frame = 142; self.frame = self.frame +1; + self.angles_y += bound(-10,shortangle_f(real_angle_y,self.angles_y),10); self.angles_x += bound(-10,shortangle_f(real_angle_x,self.angles_x),10); + movelib_move_simple(v_forward, cvar("g_turrets_unit_walker_speed_swim"),0.3); vz = self.velocity_z + sin(time * 4) * 8; if (self.frame > 151) self.frame = 146; + break; case ANIM_RUN: @@ -165,10 +174,11 @@ void walker_animate() if (self.frame > 25) self.frame = 5; + break; case ANIM_STRAFE_L: - if (self.frame < 30) + if ((self.frame < 30) || (self.frame > 55)) self.frame = 30; self.frame = self.frame + 1; @@ -180,7 +190,7 @@ void walker_animate() break; case ANIM_STRAFE_R: - if (self.frame < 60) + if ((self.frame < 60) || (self.frame > 65)) self.frame = 60; self.frame = self.frame + 1; @@ -193,7 +203,7 @@ void walker_animate() break; case ANIM_JUMP: - if (self.frame < 95) + if ((self.frame < 95) || (self.frame > 100)) self.frame = 95; self.velocity += '0 0 1' * cvar("g_turrets_unit_walker_speed_jump"); @@ -204,7 +214,7 @@ void walker_animate() break; case ANIM_LAND: - if (self.frame < 100) + if ((self.frame < 100) || (self.frame > 107)) self.frame = 100; self.frame = self.frame + 1; @@ -215,7 +225,7 @@ void walker_animate() break; case ANIM_PAIN: - if (self.frame < 60) + if ((self.frame < 60) || (self.frame > 95)) self.frame = 90; self.frame = self.frame + 1; @@ -226,11 +236,11 @@ void walker_animate() break; case ANIM_MEELE: - movelib_beak_simple(250); - - if (self.frame < 123) + if ((self.frame < 123) || (self.frame > 140)) self.frame = 123; + movelib_beak_simple(cvar("g_turrets_unit_walker_speed_stop")); + self.frame = self.frame + 2; if (self.frame == 133) @@ -242,9 +252,10 @@ void walker_animate() self.frame = 0; } } + self.velocity_z = vz; - if(self.flags & FL_ONGROUND) + if (self.flags & FL_ONGROUND) movelib_groundalign4point(300,100); } @@ -254,7 +265,7 @@ void walker_rocket_explode() { vector org2; - if(self.event_damage != SUB_Null) + if (self.event_damage != SUB_Null) { self.event_damage = SUB_Null; self.think = walker_rocket_explode; @@ -266,7 +277,7 @@ void walker_rocket_explode() org2 = findbetterlocation (self.origin, 16); pointparticles(particleeffectnum("rocket_explode"), org2, '0 0 0', 1); - + //w_deathtypestring = "got blasted to oblivion"; RadiusDamage (self, self.owner, cvar("g_turrets_unit_walker_std_rocket_dmg"), 0, cvar("g_turrets_unit_walker_std_rocket_radius"), world, cvar("g_turrets_unit_walker_std_rocket_force"), DEATH_TURRET, world); remove (self); @@ -280,7 +291,7 @@ void walker_rocket_damage (entity inflictor, entity attacker, float damage, floa walker_rocket_explode(); } -#define WALKER_ROCKET_MOVE movelib_move_simple(newdir,1000,cvar("g_turrets_unit_walker_std_rocket_tunrate")); UpdateCSQCProjectile(self) +#define WALKER_ROCKET_MOVE movelib_move_simple(newdir,cvar("g_turrets_unit_walker_std_rocket_speed"),cvar("g_turrets_unit_walker_std_rocket_tunrate")); UpdateCSQCProjectile(self) void walker_rocket_loop(); void walker_rocket_think() { @@ -316,11 +327,11 @@ void walker_rocket_think() } if (self.shot_dmg != 1337) - if (random() < 0.01) - { - walker_rocket_loop(); - return; - } + if (random() < 0.01) + { + walker_rocket_loop(); + return; + } m_speed = vlen(self.velocity) + cvar("g_turrets_unit_walker_std_rocket_speed_add"); @@ -361,7 +372,6 @@ void walker_rocket_loop3() return; } - newdir = steerlib_pull(self.tur_shotorg); WALKER_ROCKET_MOVE; @@ -386,6 +396,7 @@ void walker_rocket_loop2() self.think = walker_rocket_loop3; return; } + newdir = steerlib_pull(self.tur_shotorg); WALKER_ROCKET_MOVE; } @@ -446,7 +457,7 @@ void walker_fire_rocket(vector org) rocket.solid = SOLID_BBOX; rocket.tur_health = time + 9; - CSQCProjectile(rocket, FALSE, PROJECTILE_ROCKET, FALSE); // no culling, has fly sound + CSQCProjectile(rocket, FALSE, PROJECTILE_ROCKET, FALSE); // no culling, has fly sound } void rv_think() @@ -455,7 +466,7 @@ void rv_think() vector org; entity oldself; - if(self.owner.deadflag != DEAD_NO) + if (self.owner.deadflag != DEAD_NO) { remove(self); return; @@ -483,300 +494,280 @@ void rv_think() self = oldself; } -/* -void walker_move() -{ - vector major,minor,f,b,l,r; - float lf,lb,lr,ll,bl,tl; - - if(self.animflag == ANIM_MEELE) - return; - - tl = vlen(self.origin - self.moveto); - switch(self.waterlevel) - { - case 0: - self.animflag = ANIM_WALK; - case 1: - case 2: - if(self.animflag == ANIM_WALK) - self.animflag = ANIM_WALK; - else - self.animflag = ANIM_SWIM; - break; - case 3: - self.animflag = ANIM_SWIM; - } - - if(self.animflag == ANIM_SWIM) - { - self.steerto = vectoangles(steerlib_attract2(self.moveto,0.5,500,0.95)); - return; - } - - if(tl < 250) - { - self.animflag = ANIM_WALK; - } - else - { - self.animflag = ANIM_RUN; - } - - self.steerto = vectoangles(steerlib_attract2(self.moveto,0.5,500,0.95)); - f = self.origin + v_forward; - lf = vlen(self.moveto - f); - bl = lf; - major = v_forward; - minor = major; - - b = self.origin - v_forward; - lb = vlen(self.moveto - b); - if(bl > lb) - { - minor = major; - major = v_forward * -1; - bl = lb; - } - - r = self.origin + v_right; - lr = vlen(self.moveto - r); - if(bl > lr) - { - - minor = major; - major = v_right; - bl = lr; - self.steerto = vectoangles(v_right); - self.animflag = ANIM_STRAFE_R; - - } - - l = self.origin - v_right; - ll = vlen(self.moveto - l); - if(bl > ll) - { - - minor = major; - major = v_right * -1; - bl = ll; - self.steerto = vectoangles(v_right*-1); - self.animflag = ANIM_STRAFE_L; - - } - -} -*/ - float walker_moveverb_path(float eval) { - if(eval) + switch (eval) { - if(self.animflag == ANIM_MEELE) + case VCM_EVAL: + + if (self.animflag == ANIM_MEELE) return VS_CALL_NO; - if(self.pathcurrent) + if (self.pathcurrent) return verb.verb_static_value; return VS_CALL_NO; - } - - // Do we have a path? - if not(self.pathcurrent) - { - return VS_CALL_NO; - } - else - { - // Are we close enougth to a path node to switch to the next? - if (vlen(self.origin - self.pathcurrent.origin) < 64) - if (self.pathcurrent.path_next == world) - { - // Path endpoint reached - pathlib_deletepath(self.pathcurrent.owner); - self.pathcurrent = world; + break; - if(self.pathgoal) + case VCM_DO: + // Do we have a path? + if not(self.pathcurrent) + { + return VS_CALL_NO; + } + else + { + // Are we close enougth to a path node to switch to the next? + if (vlen(self.origin - self.pathcurrent.origin) < 64) + if (self.pathcurrent.path_next == world) { - if(self.pathgoal.use) - self.pathgoal.use(); + // Path endpoint reached + pathlib_deletepath(self.pathcurrent.owner); + self.pathcurrent = world; - if(self.pathgoal.enemy) + if (self.pathgoal) { - self.pathcurrent = WALKER_PATH(self.pathgoal.origin,self.pathgoal.enemy.origin); - self.pathgoal = self.pathgoal.enemy; + if (self.pathgoal.use) + self.pathgoal.use(); + + if (self.pathgoal.enemy) + { + self.pathcurrent = WALKER_PATH(self.pathgoal.origin,self.pathgoal.enemy.origin); + self.pathgoal = self.pathgoal.enemy; + } } + else + self.pathgoal = world; } else - self.pathgoal = world; - } - else - self.pathcurrent = self.pathcurrent.path_next; - } + self.pathcurrent = self.pathcurrent.path_next; + } - if (self.pathcurrent) - { - switch(self.waterlevel) + if (self.pathcurrent) { + switch (self.waterlevel) + { case 0: self.animflag = ANIM_WALK; case 1: case 2: - if(self.animflag == ANIM_WALK) + if (self.animflag == ANIM_WALK) self.animflag = ANIM_WALK; else self.animflag = ANIM_SWIM; break; case 3: self.animflag = ANIM_SWIM; + } + + self.moveto = self.pathcurrent.origin; + self.steerto = steerlib_attract2(self.moveto,0.5,500,0.95); + + return VS_CALL_YES_DOING; } + else + return VS_CALL_YES_DONE; - self.moveto = self.pathcurrent.origin; - self.steerto = vectoangles(steerlib_attract2(self.moveto,0.5,500,0.95)); + break; + + case VCM_REMOVE: + + if (self.pathcurrent) + pathlib_deletepath(self.pathcurrent.owner); + + self.pathcurrent = world; - return VS_CALL_YES_DOING; - } - else return VS_CALL_YES_DONE; + + break; + } + + return VS_CALL_YES_DONE; } float walker_moveverb_enemy(float eval) { - if(eval) + switch (eval) { - if(self.animflag == ANIM_MEELE) + case VCM_EVAL: + + if (self.animflag == ANIM_MEELE) return VS_CALL_NO; - if(self.enemy == world) + if (self.enemy == world) return VS_CALL_NO; - if(tracewalk(self.enemy, self.origin, self.mins, self.maxs, self.enemy.origin, MOVE_NORMAL)) + if (tracewalk(self.enemy, self.origin, self.mins, self.maxs, self.enemy.origin, MOVE_NORMAL)) return verb.verb_static_value; return VS_CALL_NO; - } - switch(self.waterlevel) - { + break; + + case VCM_DO: + switch (self.waterlevel) + { case 0: - if(self.tur_dist_enemy > 500) + if (self.tur_dist_enemy > 500) self.animflag = ANIM_RUN; else self.animflag = ANIM_WALK; case 1: case 2: - if(self.animflag == ANIM_WALK) + if (self.animflag != ANIM_SWIM) self.animflag = ANIM_WALK; else self.animflag = ANIM_SWIM; break; case 3: self.animflag = ANIM_SWIM; - } + } - self.moveto = self.enemy.origin; - self.steerto = vectoangles(steerlib_attract2(self.moveto,0.5,500,0.95)); + self.moveto = self.enemy.origin; + self.steerto = steerlib_attract2(self.moveto,0.5,500,0.95); - return VS_CALL_YES_DOING; + return VS_CALL_YES_DOING; + break; + } + + return VS_CALL_YES_DONE; } float walker_moveverb_idle_pause(float eval) { - if(eval) + switch (eval) { - if(self.animflag == ANIM_MEELE) + case VCM_EVAL: + + if (self.animflag == ANIM_MEELE) return VS_CALL_NO; return verb.verb_static_value; + break; - } + case VCM_DO: + + self.moveto = self.origin; + self.steerto = v_forward; + self.animflag = ANIM_NO; - self.moveto = self.origin; - self.steerto = v_forward; - self.animflag = ANIM_NO; + return VS_CALL_YES_DOING; + break; + } - return VS_CALL_YES_DOING; + return VS_CALL_YES_DONE; } float walker_moveverb_idle_roam(float eval) { - if(eval) + switch (eval) { - if(self.animflag == ANIM_MEELE) + case VCM_EVAL: + + if (self.animflag == ANIM_MEELE) return VS_CALL_NO; return verb.verb_static_value; - } + break; + + case VCM_DO: + if(verb.wait < time) + { + trace_fraction = 0; + while(trace_fraction != 1.0) + { + self.moveto = self.origin + (v_forward * 256); + self.moveto += v_right * (random() * 256); + self.moveto -= v_right * (random() * 256); + + tracebox(self.origin+'0 0 64',self.mins,self.maxs,self.moveto + '0 0 64',MOVE_NORMAL,self); + } + verb.wait = time + 10; + } + else + { + if(verb.wait - time < 9) + if(vlen(self.moveto - self.origin) < 32) + { + verbstack_push(self.walker_verbs_move, walker_moveverb_idle_pause, WVM_IDLE + WVM_IDLE_UP, random() * (verb.wait - time)); + self.animflag = ANIM_NO; + return VS_CALL_REMOVE; + } + } - vector v; - v_x = (random() * 32) - (random() * 32); - v_y = (random() * 32) - (random() * 32); - v = self.origin + v_forward * 64 + v; - self.pos1 = self.pos1 * 0.9 + v * 0.1; + self.steerto = steerlib_attract(self.moveto,256); + te_lightning1(self,self.origin + '0 0 64',self.moveto + '0 0 64'); - self.moveto = self.origin + v_forward * 10; - v = self.angles; - v_y += random() * 15; - v_y -= random() * 15; - self.steerto = v; - switch(self.waterlevel) - { + switch (self.waterlevel) + { case 0: self.animflag = ANIM_ROAM; case 1: case 2: - if(self.animflag != ANIM_SWIM) + if (self.animflag != ANIM_SWIM) self.animflag = ANIM_ROAM; break; case 3: self.animflag = ANIM_SWIM; + } + + return VS_CALL_YES_DOING; + + break; } - return VS_CALL_YES_DOING; + return VS_CALL_YES_DONE; } float walker_moveverb_idle(float eval) { - if(eval) + switch (eval) { - if(self.animflag == ANIM_MEELE) + case VCM_EVAL: + + if (self.animflag == ANIM_MEELE) return VS_CALL_NO; return verb.verb_static_value; - } - if(verb.wait < time) - { - verb.wait = random() * 10; + break; - if(random() < 0.5) - verbstack_push(self.walker_verbs_move, walker_moveverb_idle_pause, WVM_IDLE + WVM_IDLE_UP, verb.wait); - else - verbstack_push(self.walker_verbs_move, walker_moveverb_idle_roam, WVM_IDLE + WVM_IDLE_UP, verb.wait); + case VCM_DO: - verb.wait += time; + //if (random() < 0.5) + verbstack_push(self.walker_verbs_move, walker_moveverb_idle_pause, WVM_IDLE + WVM_IDLE_UP, random() * 5); + //else + // verbstack_push(self.walker_verbs_move, walker_moveverb_idle_roam, WVM_IDLE + WVM_IDLE_UP, random() * 15); + + return VS_CALL_YES_DOING; + + break; } - return VS_CALL_YES_DOING; + return VS_CALL_YES_DONE; } + float walker_attackverb_meele(float eval) { - if(eval) + switch (eval) { - if(cvar("g_turrets_nofire")) + case VCM_EVAL: + + vector wish_angle; + + if (cvar("g_turrets_nofire")) return VS_CALL_NO; - if(self.animflag == ANIM_SWIM || self.animflag == ANIM_MEELE) + if (self.animflag == ANIM_SWIM || self.animflag == ANIM_MEELE) return VS_CALL_NO; - if(!self.enemy) + if (!self.enemy) return VS_CALL_NO; - vector wish_angle; wish_angle = angleofs(self,self.enemy); if (self.tur_dist_enemy < cvar("g_turrets_unit_walker_std_meele_range")) @@ -784,20 +775,28 @@ float walker_attackverb_meele(float eval) return verb.verb_static_value; return VS_CALL_NO; - } - self.moveto = self.enemy.origin; - self.steerto = vectoangles(steerlib_attract2(self.moveto,0.5,500,0.95)); + break; + + case VCM_DO: - self.animflag = ANIM_MEELE; + self.moveto = self.enemy.origin; + self.steerto = steerlib_attract2(self.moveto,0.5,500,0.95); + self.animflag = ANIM_MEELE; - return VS_CALL_YES_DOING; + return VS_CALL_YES_DOING; + + break; + } + + return VS_CALL_YES_DONE; } float walker_attackverb_rockets(float eval) { - if(eval) + switch (eval) { + case VCM_EVAL: if (self.tur_head.attack_finished_single > time) return VS_CALL_NO; @@ -814,19 +813,27 @@ float walker_attackverb_rockets(float eval) return VS_CALL_NO; return verb.verb_static_value; - } - entity rv; - rv = spawn(); - rv.think = rv_think; - rv.nextthink = time; - rv.cnt = 4; - rv.owner = self; + break; - self.tur_head.attack_finished_single = time + cvar("g_turrets_unit_walker_std_rocket_refire"); + case VCM_DO: - return VS_CALL_YES_DONE; + entity rv; + + rv = spawn(); + rv.think = rv_think; + rv.nextthink = time; + rv.cnt = 4; + rv.owner = self; + self.tur_head.attack_finished_single = time + cvar("g_turrets_unit_walker_std_rocket_refire"); + + return VS_CALL_YES_DONE; + + break; + } + + return VS_CALL_YES_DONE; } void walker_postthink() @@ -846,33 +853,30 @@ void walker_attack() { entity flash; - //turret_do_updates(self); - - self.tur_head.frame = self.tur_head.frame + 1; - + //w_deathtypestring = "was miniguned"; sound (self, CHAN_WEAPON, "weapons/uzi_fire.wav", VOL_BASE, ATTN_NORM); - fireBallisticBullet (self.tur_shotorg, self.tur_shotdir_updated,self.shot_spread, self.shot_speed, 5, self.shot_dmg, 0, self.shot_force, DEATH_TURRET, 0, 1, cvar("g_balance_uzi_bulletconstant")); - //te_smallflash(self.tur_shotorg_updated); - - if (!(self.uzi_bulletcounter & 3)) + if (self.uzi_bulletcounter == 2) { - //trailparticles(self,particleeffectnum("EF_MGTURRETTRAIL"),self.tur_shotorg_updated,trace_endpos); - // te_lightning1(self,self.tur_shotorg_updated,trace_endpos); flash = spawn(); - setmodel(flash, "models/uziflash.md3"); // precision set below + + setmodel(flash, "models/uziflash.md3"); setattachment(flash, self.tur_head, "tag_fire"); - flash.scale = 3; - flash.think = W_Uzi_Flash_Go; + + flash.scale = 3; + flash.think = W_Uzi_Flash_Go; flash.nextthink = time + 0.02; - flash.frame = 2; - flash.angles_z = flash.v_angle_z + random() * 180; - flash.alpha = 1; - flash.effects = EF_ADDITIVE | EF_FULLBRIGHT | EF_LOWPRECISION; + flash.frame = 2; + flash.angles_z = flash.v_angle_z + random() * 180; + flash.alpha = 1; + flash.effects = EF_ADDITIVE | EF_FULLBRIGHT | EF_LOWPRECISION; + + self.uzi_bulletcounter = self.uzi_bulletcounter = 0; } self.uzi_bulletcounter = self.uzi_bulletcounter + 1; + self.tur_head.frame = self.tur_head.frame + 1; } @@ -882,8 +886,8 @@ void walker_respawnhook() entity e; self.origin = self.wkr_spawn.origin; - self.wkr_props.solid = SOLID_BBOX; - self.wkr_props.alpha = 1; + //self.wkr_props.solid = SOLID_BBOX; + //self.wkr_props.alpha = 1; self.angles = self.wkr_spawn.angles; vtmp = self.wkr_spawn.origin; @@ -910,18 +914,22 @@ void walker_respawnhook() } void walker_diehook() { - if(self.pathcurrent) + turret_trowgib2(self.origin,self.velocity + v_up * 200,'-0.6 -0.2 -02',self,time + random() * 1); + turret_trowgib2(self.origin + '0 0 64',self.velocity + v_forward * 150 + v_up * 150,'-0.2 -0.2 -02',self.tur_head,time + random() * 2 + 3); + + if (self.pathcurrent) pathlib_deletepath(self.pathcurrent.owner); self.pathcurrent = world; - self.wkr_props.solid = SOLID_NOT; - self.wkr_props.alpha = -1; - - if(self.damage_flags & TFL_DMG_DEATH_NORESPAWN) + if (self.damage_flags & TFL_DMG_DEATH_NORESPAWN) { - remove(self.wkr_props); remove(self.wkr_spawn); + + verbstack_flush(self.walker_verbs_move); + verbstack_flush(self.walker_verbs_attack); + verbstack_flush(self.walker_verbs_idle); + remove(self.walker_verbs_move); remove(self.walker_verbs_attack); remove(self.walker_verbs_idle); @@ -935,15 +943,13 @@ void turret_walker_dinit() entity e; if (self.netname == "") self.netname = "Walker Turret"; - - self.wkr_props = spawn(); self.wkr_spawn = spawn(); self.ammo_flags = TFL_AMMO_BULLETS | TFL_AMMO_RECHARGE | TFL_AMMO_RECIVE; self.turrcaps_flags = TFL_TURRCAPS_PLAYERKILL | TFL_TURRCAPS_MOVE | TFL_TURRCAPS_HEADATTACHED; self.aim_flags = TFL_AIM_LEAD; - if(cvar("g_antilag_bullets")) + if (cvar("g_antilag_bullets")) self.turrcaps_flags |= TFL_TURRCAPS_HITSCAN; else self.aim_flags |= TFL_AIM_SHOTTIMECOMPENSATE; @@ -963,7 +969,7 @@ void turret_walker_dinit() self.walker_verbs_attack = spawn(); self.walker_verbs_idle = spawn(); - verbstack_push(self.walker_verbs_move, walker_moveverb_idle, WVM_IDLE, 0); + verbstack_push(self.walker_verbs_move, walker_moveverb_idle, WVM_IDLE, 0); verbstack_push(self.walker_verbs_move, walker_moveverb_enemy, WVM_ENEMY, 0); verbstack_push(self.walker_verbs_move, walker_moveverb_path, WVM_PATH, 0); @@ -972,10 +978,9 @@ void turret_walker_dinit() self.damage_flags |= TFL_DMG_DEATH_NOGIBS; - self.target_select_flags = TFL_TARGETSELECT_PLAYERS | TFL_TARGETSELECT_RANGELIMTS | TFL_TARGETSELECT_TEAMCHECK | TFL_TARGETSELECT_LOS; - self.target_validate_flags = TFL_TARGETSELECT_PLAYERS | TFL_TARGETSELECT_RANGELIMTS | TFL_TARGETSELECT_TEAMCHECK | TFL_TARGETSELECT_LOS; + //self.target_select_flags = TFL_TARGETSELECT_PLAYERS | TFL_TARGETSELECT_RANGELIMTS | TFL_TARGETSELECT_TEAMCHECK | TFL_TARGETSELECT_LOS; + //self.target_validate_flags = TFL_TARGETSELECT_PLAYERS | TFL_TARGETSELECT_RANGELIMTS | TFL_TARGETSELECT_TEAMCHECK | TFL_TARGETSELECT_LOS; - //self.flags = FL_CLIENT; self.iscreature = TRUE; self.movetype = MOVETYPE_WALK; self.solid = SOLID_SLIDEBOX; @@ -983,16 +988,14 @@ void turret_walker_dinit() setmodel(self,"models/turrets/walker_body.md3"); setmodel(self.tur_head,"models/turrets/walker_head_minigun.md3"); - setmodel(self.wkr_props,"models/turrets/walker_props.md3"); setmodel(self.wkr_spawn,"models/turrets/walker_spawn.md3"); - setorigin(self.wkr_spawn,self.origin); + setattachment(self.tur_head,self,"tag_head"); - setattachment(self.wkr_props,self,"tag_head"); self.wkr_spawn.angles = self.angles; self.wkr_spawn.solid = SOLID_NOT; - traceline(self.wkr_spawn.origin + '0 0 16', self.wkr_spawn.origin - '0 0 10000', MOVE_WORLDONLY, self); + traceline(self.origin + '0 0 16', self.origin - '0 0 10000', MOVE_WORLDONLY, self); setorigin(self.wkr_spawn,trace_endpos + '0 0 4'); setorigin(self,self.wkr_spawn.origin); @@ -1020,21 +1023,20 @@ void turret_walker_dinit() self.pathgoal = e; } } - - //self.solid = SOLID_NOT; - } void spawnfunc_turret_walker() { g_turrets_common_precash(); + precache_model ("models/turrets/walker_head_minigun.md3"); precache_model ("models/turrets/walker_body.md3"); precache_model ("models/turrets/walker_props.md3"); precache_model ("models/turrets/walker_spawn.md3"); precache_model ( "models/turrets/rocket.md3"); precache_sound ( "weapons/rocket_impact.wav" ); + self.think = turret_walker_dinit; self.nextthink = time + 0.5; } -- 2.39.2