Minor: Cleanups and comments, adjusted configs.
+#ifdef TURRET_DEBUG
void mark_error(vector where,float lifetime);
void mark_info(vector where,float lifetime);
entity mark_misc(vector where,float lifetime);
-
+#endif
void pathlib_showpath(entity start)
{
void __showpath2_think()
{
- mark_info(self.origin,1);
+ #ifdef TURRET_DEBUG
+ mark_info(self.origin,1);
+ #endif
if(self.path_next)
{
self.path_next.think = __showpath2_think;
node = pathlib_nodeatpoint(where);
if(node)
{
+ #ifdef TURRET_DEBUG
mark_error(where, 60);
+ #endif
return node;
}
/// Dont aim.
#define TFL_AIM_NO 1
/// Go for ground, not direct hit
-#define TFL_AIM_GROUND 2
+//#define TFL_AIM_GROUND 2
/// Go for ground, not direct hit, but only if target is on ground.
#define TFL_AIM_GROUND2 4
/// Use balistic aim. FIXME: not implemented
#define TFL_AIM_INFRONT 64
/// Aim slightly behind target
#define TFL_AIM_BEHIND 128
-/// blend real and predicted z positions. (fake bounce prediction)
-#define TFL_AIM_ZEASE 256
+/// blend real and predicted z positions. (fake bounce prediction)
+// #define TFL_AIM_ZEASE 256
/// Try to do real prediction of targets z pos at impact.
#define TFL_AIM_ZPREDICT 512
/// Simply aim at target's current location
/// on/off toggle.
.float tur_active;
-// Aim from this point,
-//.vector tur_aimorg;
-
/// and shoot from here. (can be non constant, think MLRS)
.vector tur_shotorg;
.float target_range;
/// Dont consider targets closer then
.float target_range_min;
-// Engage fire routine on targets within
-//.float target_range_fire; // no practical use aymore, work with target_range insted.
/// Targets closer to this are prefered
.float target_range_optimal;
*/
/// Maximum offset between impact and aim spot to fire
.float aim_firetolerance_dist;
-// Maximum angular offset between head and aimspot to fire
-//.float aim_firetolerance_angle;
/// How fast can i rotate/pitch (per second in stepmotor mode, base force in smooth modes)
.float aim_speed;
/// cant aim higher/lower then this
.void() turret_firefunc;
/// prefire checks go here. return 1 to go bang, 0 not to.
.float() turret_firecheckfunc;
-// Execure BEFORE main ai loop. return 0 to cancel any following proccessing.
-//.float() turret_prethink;
/// Execure AFTER main AI loop
.void() turret_postthink;
/// Add a target
.float(entity e_target,entity e_sender) turret_addtarget;
-//.float call_diehook;
-//.float call_respwnhook;
.void() turret_diehook;
.void() turret_respawnhook;
.float(float event_id) turret_eventhook;
*/
-/*
-* Some turrets need other aimsystems then other.
-* This should return the place to aim at, not acctualy turn or
-* pitch anyting.
-*
-* use turret_stdproc_aim* or Make your own.
-* Make sure you update tur_enemy_dist and tur_enemy_adist
-* with the apropriate info, if you do.
-
-removed.
-*/
-// function used to aim, usualy turret_stdproc_aim_generic
-//.vector() turret_aim;
-
-/*
-* This is where the acctual turret turning should take place
-* Use turret_stdproc_track or make your own.
-wkacked to save mem.
-*/
-// Function used to turn and pitch the .tur_head usualy turret_stdproc_track
-//.void() turret_track;
/*
* Target selection, preferably but not nessesarely
/// Function to use for target evaluation. usualy turret_stdproc_targetscore_generic
.float(entity e_turret, entity e_target) turret_score_target;
-/*
-* Damage, death and respawn.
-*/
-//void turret_gibs_precash();
-// generalized so save mem (on fields)
-// Function to handle incomming damage. usualy turret_stdproc_damage
-//.void(entity inflictor, entity attacker, float damage, float deathtype, vector hitloc, vector vforce) turret_damagefunc;
-// Function to handle the event of death. usualy turret_stdproc_die
-//.void() turret_diefunc;
-// Function that handles rebirth. usualy turret_stdproc_respawn
-//.void() turret_spawnfunc;
-
-/*
-* Stuff to plug into requierd but unused callbacks.
-*/
-/// Always return 1
-//float turret_stdproc_true();
-/// Always return 0
-//float turret_stdproc_false();
-/// Always return nothing at all
-//void turret_stdproc_nothing();
/*
* Target selection
*/
-// noting uses the following atm.
-// "closeer is beter" selection
-//float turret_stdproc_targetscore_close(entity e_turret, entity e_target);
-// "further is beter" selection
-//float turret_stdproc_targetscore_far(entity e_turret, entity e_target);
-// only target_range_optimal
-//float turret_stdproc_targetscore_optimal(entity e_turret, entity e_target);
-// defendpos
-//float turret_stdproc_targetscore_defend(entity e_turret, entity e_target);
-/// Generic fairly smart bias-aware target selection.
+/// Generic, fairly smart, bias-aware target selection.
float turret_stdproc_targetscore_generic(entity e_turret, entity e_target);
/// Experimental supportunits targetselector
float turret_stdproc_targetscore_support(entity e_turret,entity e_target);
* Aim functions
*/
/// Generic aimer guided by self.aim_flags
-vector turret_stdproc_aim_generic()
-// Straight line, current location
-//vector turret_stdproc_aim_simple()
+vector turret_stdproc_aim_generic();
/*
* Turret turning & pitch
/// updates aim org, shot org, shot dir and enemy org for selected turret
void turret_do_updates(entity e_turret);
-//.vector tur_aimorg_updated; // creates to much aim issues. using tur_shotorg_updated insted.
-//.vector tur_shotorg_updated; // DP8815 fixes gettaginfo, no longer needed.
.vector tur_shotdir_updated;
void turrets_precash();
supports:
TFL_AIM_NO
-TFL_AIM_GROUND
+TFL_AIM_GROUND2
TFL_AIM_LEAD
TFL_AIM_SHOTTIMECOMPENSATE
TFL_AIM_INFRONT
TFL_AIM_BEHIND
-TFL_AIM_ZEASE
not supported:
TFL_AIM_BALISTIC
+
+removed
+TFL_AIM_ZEASE
+TFL_AIM_GROUND
*/
vector turret_stdproc_aim_generic()
{
if(self.aim_flags & TFL_AIM_SIMPLE)
return real_origin(self.enemy);
- // Keep track of when we can shoot the next time and
- // try to predict where the target will be then, so we can put our aimpoint there.
- // + sys_frametime, becouse spawned REMOVE THIS IF sv_gameplayfix_delayprojectiles are 0!
- // projectiles dont move during the first tic of their life.
- //if (self.turrcaps_flags & TFL_TURRCAPS_HITSCAN)
- // mintime = max(self.attack_finished_single - time,0) + sys_frametime;
- //else
-
- mintime = max(self.attack_finished_single - time,0) + sys_frametime;
+ mintime = max(self.attack_finished_single - time,0) + sys_frametime ;
// Baseline
pre_pos = real_origin(self.enemy);
// Lead?
if (self.aim_flags & TFL_AIM_LEAD)
- if (self.aim_flags & TFL_AIM_SHOTTIMECOMPENSATE) // Need to conpensate for shot traveltime
- {
- // FIXME: this cant be the best way to do this..
- prep = pre_pos;
- for(i = 0; i < 4; ++i)
- {
- distance = vlen(prep - self.tur_shotorg);
- impact_time = distance / self.shot_speed;
- prep = pre_pos + self.enemy.velocity * impact_time;
- }
-
-
- // tnx to Rudolf "div0" Polzer for this solution.
- // hmm tobad it dont work.
- /*
- vector q;
- q = solve_quadratic(self.enemy.velocity*self.enemy.velocity - self.shot_speed*self.shot_speed, 2*(pre_pos*self.enemy.velocity), pre_pos * pre_pos);
- if(q_x > 0)
- impact_time = q_x;
- else
- impact_time = q_y;
- */
-
- prep = pre_pos + (self.enemy.velocity * (impact_time + mintime));
-
- if(self.aim_flags & TFL_AIM_ZPREDICT)
- if not(self.enemy.flags & FL_ONGROUND)
- if(self.enemy.movetype == MOVETYPE_WALK || self.enemy.movetype == MOVETYPE_TOSS || self.enemy.movetype == MOVETYPE_BOUNCE)
- {
- float vz;
- prep_z = pre_pos_z;
- vz = self.enemy.velocity_z;
- for(i = 0; i < impact_time; i += sys_frametime)
- {
- vz = vz - (sv_gravity * sys_frametime);
- prep_z = prep_z + vz * sys_frametime;
- }
- }
- pre_pos = prep;
- }
- else
- pre_pos = pre_pos + self.enemy.velocity * mintime;
-
- // Smooth out predict-Z?
- /*
- if (self.aim_flags & TFL_AIM_ZEASE)
- if (self.enemy.flags & FL_CLIENT)
- {
- vector v;
- v = real_origin(self.enemy);
- pre_pos_z = (pre_pos_z + v_z) * 0.5;
+ {
+ if (self.aim_flags & TFL_AIM_SHOTTIMECOMPENSATE) // Need to conpensate for shot traveltime
+ {
+ // FIXME: this cant be the best way to do this..
+ prep = pre_pos;
+ for(i = 0; i < 4; ++i)
+ {
+ distance = vlen(prep - self.tur_shotorg);
+ impact_time = distance / self.shot_speed;
+ prep = pre_pos + self.enemy.velocity * impact_time;
+ }
+
+ prep = pre_pos + (self.enemy.velocity * (impact_time + mintime));
+
+ if(self.aim_flags & TFL_AIM_ZPREDICT)
+ if not(self.enemy.flags & FL_ONGROUND)
+ if(self.enemy.movetype == MOVETYPE_WALK || self.enemy.movetype == MOVETYPE_TOSS || self.enemy.movetype == MOVETYPE_BOUNCE)
+ {
+ float vz;
+ prep_z = pre_pos_z;
+ vz = self.enemy.velocity_z;
+ for(i = 0; i < impact_time; i += sys_frametime)
+ {
+ vz = vz - (sv_gravity * sys_frametime);
+ prep_z = prep_z + vz * sys_frametime;
+ }
+ }
+ pre_pos = prep;
+ }
+ else
+ pre_pos = pre_pos + self.enemy.velocity * mintime;
}
- */
-
+
if(self.aim_flags & TFL_AIM_GROUND2)
{
//tracebox(pre_pos + '0 0 32',self.enemy.mins,self.enemy.maxs,pre_pos -'0 0 64',MOVE_WORLDONLY,self.enemy);
pre_pos = trace_endpos;
}
- /*
- // This turret should hit the ground neer a target rather the do a direct hit
- if (self.aim_flags & TFL_AIM_GROUND)
- {
- traceline(pre_pos + '0 0 8',pre_pos - '0 0 10000',MOVE_WORLDONLY,self.enemy);
- pre_pos = trace_endpos;
- }
- */
-
return pre_pos;
}
gib = spawn();
gib.classname = "turret_gib";
- setmodel(gib,smodel);
- setorigin(gib,v_from);
- SUB_SetFade(gib,time + f_lifetime,2);
+ setmodel(gib, smodel);
+ setorigin(gib, v_from);
+ SUB_SetFade(gib,time + f_lifetime, 2);
gib.solid = SOLID_BBOX;
-
gib.movetype = MOVETYPE_BOUNCE;
gib.takedamage = DAMAGE_YES;
gib.event_damage = turret_gib_damage;
burn.effects = EF_LOWPRECISION;//|EF_FLAME;
setattachment(burn,gib,"");
setorigin(burn,(gib.mins + gib.maxs) * 0.5);
- SUB_SetFade(burn,time + (f_lifetime * 0.5) ,2);
+ SUB_SetFade(burn,time + (f_lifetime * 0.5), 2);
}
}
s = strcat("models/turrets/head-gib",ftos(i));
s = strcat(s,".md3");
- // bprint("s:",s,"\n");
- setmodel(gib,s);
+ setmodel(gib, s);
setorigin(gib,self.origin);
SUB_SetFade(gib,time + 5,2);
gib.solid = SOLID_BBOX;
-
gib.movetype = MOVETYPE_BOUNCE;
gib.gravity = 0.5;
gib.damageforcescale = 2;
makevectors(self.angles);
if (random() > 0.5)
{
- turret_trowgib(self.origin, '0 0 0','1 1 1',"models/turrets/base-gib2.md3",min(self.respawntime,20),1,1);
+ turret_trowgib(self.origin, '0 0 0', '1 1 1', "models/turrets/base-gib2.md3", min(self.respawntime, 20), 1, 1);
+
+ t_dir = (v_up * 700) + (randomvec() * 300);
+ turret_trowgib(self.origin, t_dir, '1 1 1', "models/turrets/base-gib3.md3", min(self.respawntime, 10), 1, 1);
+
t_dir = (v_up * 700) + (randomvec() * 300);
- turret_trowgib(self.origin, t_dir,'1 1 1',"models/turrets/base-gib3.md3",min(self.respawntime,10),1,1);
- t_dir = (v_up * 700) + (randomvec() * 300);
- turret_trowgib(self.origin, t_dir,'1 1 1',"models/turrets/base-gib4.md3",min(self.respawntime,10),1,1);
+ turret_trowgib(self.origin, t_dir, '1 1 1', "models/turrets/base-gib4.md3", min(self.respawntime, 10), 1, 1);
}
else
{
- turret_trowgib(self.origin, '0 0 0','1 1 1',"models/turrets/base-gib1.md3",min(self.respawntime,20),1,1);
+ turret_trowgib(self.origin, '0 0 0', '1 1 1', "models/turrets/base-gib1.md3", min(self.respawntime, 20), 1, 1);
}
// Blow the top part up into the air
- turret_trowgib2( self.origin + (v_up * 50),
- v_up * 150 + randomvec() * 50,
- '0.2 0.2 0.2',
- self.tur_head,time + 0.5 + (random() * 0.5));
+ turret_trowgib2( self.origin + (v_up * 50), v_up * 150 + randomvec() * 50, '0.2 0.2 0.2', self.tur_head,time + 0.5 + (random() * 0.5));
}
// Go boom
}
else
{
- // Setup respawn
+ // Setup respawn
self.nextthink = time + self.respawntime;
- //self.think = self.turret_spawnfunc;
self.think = turret_stdproc_respawn;
+
if (self.turret_diehook)
self.turret_diehook();
}
-
}
+var const float SUB_NullFloat();
void turret_stdproc_respawn()
{
// Make sure all parts belong to the same team since
// this function doubles as "teamchange" function.
- self.tur_head.team = self.team;
-
- /*
- COLOR_TEAM1 = 4; // red
- COLOR_TEAM2 = 13; // blue
- COLOR_TEAM3 = 12; // yellow
- COLOR_TEAM4 = 9; // pink
- */
-
- self.colormod = '0 0 0';
+ self.tur_head.team = self.team;
+ self.colormod = '0 0 0';
switch(self.team)
{
}
self.deadflag = DEAD_NO;
- self.effects = 0;
+ self.effects = EF_LOWPRECISION;
self.tur_head.effects = self.effects;
-
self.solid = SOLID_BBOX;
-
- self.alpha = 1;
+ self.alpha = 1;
self.tur_head.alpha = self.alpha;
- self.customizeentityforclient = SUB_True;
- self.tur_head.customizeentityforclient = SUB_True;
+
+ self.customizeentityforclient = SUB_NullFloat;
+ self.tur_head.customizeentityforclient = SUB_NullFloat;
- self.takedamage = DAMAGE_AIM;
+ self.takedamage = DAMAGE_AIM;
self.event_damage = turret_stdproc_damage;
self.avelocity = '0 0 0';
}
*/
-void load_unit_settings(entity ent,string unitname,float is_reload)
+void load_unit_settings(entity ent, string unitname, float is_reload)
{
string sbase;
- // dprint("Reloading turret ",e_turret.netname,"\n");
-
if (ent == world)
return;
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_range_fire = cvar(strcat(sbase,"_target_range_fire")) * ent.turret_scale_range;
ent.target_select_rangebias = cvar(strcat(sbase,"_target_select_rangebias"));
ent.target_select_samebias = cvar(strcat(sbase,"_target_select_samebias"));
if(is_reload)
if(ent.turret_respawnhook)
ent.turret_respawnhook();
-
-}
-
-/*
-float turret_stdproc_true()
-{
- return 1;
}
-float turret_stdproc_false()
-{
- return 0;
-}
-
-
-void turret_stdproc_nothing()
-{
- return;
-}
-*/
/**
** updates enemy distances, predicted impact point/time
**/
void turret_do_updates(entity t_turret)
{
- vector enemy_pos,oldpos;
+ vector enemy_pos, oldpos;
entity oldself;
oldself = self;
turret_tag_fire_update();
- self.tur_shotdir_updated = normalize(v_forward);
-
+ self.tur_shotdir_updated = v_forward;
self.tur_dist_enemy = vlen(self.tur_shotorg - enemy_pos);
self.tur_dist_aimpos = vlen(self.tur_shotorg - self.tur_aimpos);
if(trace_ent == self.enemy)
self.tur_dist_impact_to_aimpos = 0;
else
- self.tur_dist_impact_to_aimpos = vlen(trace_endpos - self.tur_aimpos);// - (vlen(self.enemy.maxs - self.enemy.mins)*0.5);
+ self.tur_dist_impact_to_aimpos = vlen(trace_endpos - self.tur_aimpos);
- self.tur_impactent = trace_ent;
- self.tur_impacttime = vlen(self.tur_shotorg - trace_endpos) / self.shot_speed;
}
else
- tracebox(self.tur_shotorg, '-1 -1 -1','1 1 1',self.tur_shotorg + (self.tur_shotdir_updated * self.tur_dist_aimpos),MOVE_NORMAL,self);
- //traceline(self.tur_shotorg, self.tur_shotorg + (self.tur_shotdir_updated * self.tur_dist_aimpos),MOVE_NORMAL,self);
-
- self.tur_dist_impact_to_aimpos = vlen(trace_endpos - self.tur_aimpos) - (vlen(self.enemy.maxs - self.enemy.mins)*0.5);
- self.tur_impactent = trace_ent;
- self.tur_impacttime = vlen(self.tur_shotorg - trace_endpos) / self.shot_speed;
-
+ tracebox(self.tur_shotorg, '-1 -1 -1','1 1 1', self.tur_shotorg + (self.tur_shotdir_updated * self.tur_dist_aimpos),MOVE_NORMAL,self);
+
+ self.tur_dist_impact_to_aimpos = vlen(trace_endpos - self.tur_aimpos) - (vlen(self.enemy.maxs - self.enemy.mins) * 0.5);
+ self.tur_impactent = trace_ent;
+ self.tur_impacttime = vlen(self.tur_shotorg - trace_endpos) / self.shot_speed;
self = oldself;
}
** Handles head rotation according to
** the units .track_type and .track_flags
**/
-//.entity aim_mark;
void turret_stdproc_track()
{
vector target_angle; // This is where we want to aim
}
else
{
- // Find the direction
- target_angle = normalize(self.tur_aimpos - self.tur_shotorg);
- target_angle = vectoangles(target_angle); // And make a angle
+ target_angle = vectoangles(normalize(self.tur_aimpos - self.tur_shotorg));
}
-
- self.tur_head.angles_x = safeangle(self.tur_head.angles_x);
- self.tur_head.angles_y = safeangle(self.tur_head.angles_y);
+
+ self.tur_head.angles_x = anglemods(self.tur_head.angles_x);
+ self.tur_head.angles_y = anglemods(self.tur_head.angles_y);
// Find the diffrence between where we currently aim and where we want to aim
move_angle = target_angle - (self.angles + self.tur_head.angles);
move_angle = shortangle_vxy(move_angle,(self.angles + self.tur_head.angles));
-
-
-
switch(self.track_type)
{
case TFL_TRACKTYPE_STEPMOTOR:
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_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;
self.tur_head.avelocity_x = 0;
self.tur_head.angles_x = self.aim_maxpitch;
}
+
if((self.tur_head.angles_x + self.tur_head.avelocity_x * self.ticrate) < -self.aim_maxpitch)
{
self.tur_head.avelocity_x = 0;
- self.tur_head.angles_x = self.aim_maxpitch;
+ self.tur_head.angles_x = -self.aim_maxpitch;
}
-
}
// rot
if((self.tur_head.angles_y + self.tur_head.avelocity_y * self.ticrate) < -self.aim_maxrot)
{
self.tur_head.avelocity_y = 0;
- self.tur_head.angles_y = self.aim_maxrot;
+ self.tur_head.angles_y = -self.aim_maxrot;
}
-
}
-
}
// Ready?
if (self.firecheck_flags & TFL_FIRECHECK_REFIRE)
- if (self.attack_finished_single >= time) return 0;
+ if (self.attack_finished_single > time) return 0;
// Special case: volly fire turret that has to fire a full volly if a shot was fired.
if (self.shoot_flags & TFL_SHOOT_VOLLYALWAYS)
if (self.firecheck_flags & TFL_FIRECHECK_OTHER_AMMO)
if (self.enemy.ammo >= self.enemy.ammo_max)
return 0;
+
+ // Target of opertunity?
+ if(turret_validate_target(self, self.tur_impactent, self.target_validate_flags) > 0)
+ {
+ self.enemy = self.tur_impactent;
+ return 1;
+ }
if (self.firecheck_flags & TFL_FIRECHECK_DISTANCES)
{
- // Not close enougth?
- //if (self.tur_dist_aimpos > self.target_range_fire) return 0;
-
// To close?
if (self.tur_dist_aimpos < self.target_range_min)
- return 0;
+ if(turret_validate_target(self, self.tur_impactent, self.target_validate_flags) > 0)
+ return 1; // Target of opertunity?
+ else
+ return 0;
}
// Try to avoid FF?
if (self.tur_dist_impact_to_aimpos > self.aim_firetolerance_dist)
return 0;
- //if (self.tur_impactent != self.enemy)
-
// Volly status
if (self.shot_volly > 1)
if (self.volly_counter == self.shot_volly)
** Evaluate a entity for target valitity based on validate_flags
** NOTE: the caller must check takedamage before calling this, to inline this check.
**/
-float turret_validate_target(entity e_turret,entity e_target,float validate_flags)
+float turret_validate_target(entity e_turret, entity e_target, float validate_flags)
{
vector v_tmp;
}
// Can we even aim this thing?
- tvt_thadv = angleofs3(e_turret.tur_head.origin,e_turret.angles + e_turret.tur_head.angles ,e_target);
- //tvt_thadv = angleofs(e_turret.angles,e_target);
-
-
-
- tvt_tadv = shortangle_vxy(angleofs(e_turret,e_target),e_turret.angles);
+ tvt_thadv = angleofs3(e_turret.tur_head.origin, e_turret.angles + e_turret.tur_head.angles, e_target);
+ tvt_tadv = shortangle_vxy(angleofs(e_turret, e_target), e_turret.angles);
tvt_thadf = vlen(tvt_thadv);
tvt_tadf = vlen(tvt_tadv);
float score; // target looper entity score
entity e_enemy; // currently best scoreing target
float m_score; // currently best scoreing target's score
- float f;
m_score = 0;
if(self.enemy)
else
self.enemy = world;
- e = findradius(self.origin,self.target_range);
+ e = findradius(self.origin, self.target_range);
// Nothing to aim at?
- if (!e) return world;
+ if (!e)
+ return world;
while (e)
{
if(e.takedamage)
{
- f = turret_validate_target(self,e,self.target_select_flags);
- if (f > 0)
+ if (turret_validate_target(self, e, self.target_select_flags) > 0)
{
score = self.turret_score_target(self,e);
if ((score > m_score) && (score > 0))
if not (g_onslaught)
if (self.target)
{
- e = find(world,targetname,self.target);
+ e = find(world, targetname,self.target);
if (e != world)
self.team = e.team;
}
// Handle ammo
if not (self.spawnflags & TSF_NO_AMMO_REGEN)
if (self.ammo < self.ammo_max)
- self.ammo = min(self.ammo + self.ammo_recharge,self.ammo_max);
-
+ self.ammo = min(self.ammo + self.ammo_recharge, self.ammo_max);
// Inactive turrets needs to run the think loop,
// So they can handle animation and wake up if need be.
return;
}
- //This is just wrong :| and unlikely to ever happen.
- /*
- if(self.deadflag != DEAD_NO)
- {
- dprint("WARNING: dead turret running the think function!\n");
- return;
- }
- */
-
// This is typicaly used for zaping every target in range
// turret_fusionreactor uses this to recharge friendlys.
if (self.shoot_flags & TFL_SHOOT_HITALLVALID)
// Check if we have a vailid enemy, and try to find one if we dont.
- // g_turrets_targetscan_maxdelay forces a target re-scan this often
+ // g_turrets_targetscan_maxdelay forces a target re-scan at least this often
float do_target_scan;
if((self.target_select_time + cvar("g_turrets_targetscan_maxdelay")) < time)
do_target_scan = 1;
// Old target (if any) invalid?
- if (turret_validate_target(self,self.enemy,self.target_validate_flags) <= 0)
- do_target_scan = 1;
+ if (turret_validate_target(self, self.enemy, self.target_validate_flags) <= 0)
+ {
+ self.enemy = world;
+ do_target_scan = 1;
+ }
// But never more often then g_turrets_targetscan_mindelay!
if (self.target_select_time + cvar("g_turrets_targetscan_mindelay") > time)
turret_fire();
}
- // do any per-turret stuff
+ // do any custom per-turret stuff
if(self.turret_postthink)
self.turret_postthink();
}
if (cvar("g_turrets_nofire") != 0)
return;
- /*
- // unlikely to ever happen.
- if (self.deadflag != DEAD_NO)
- return;
-
- if not (self.tur_active)
- return;
- */
-
self.turret_firefunc();
self.attack_finished_single = time + self.shot_refire;
/*
When .used a turret switch team to activator.team.
- If activator is world, the turrets goes inactive.
+ If activator is world, the turret go inactive.
*/
void turret_stdproc_use()
{
- dprint("Turret ",self.netname, " used by ",activator.classname,"\n");
+ dprint("Turret ",self.netname, " used by ", activator.classname, "\n");
self.team = activator.team;
{
entity e, ee;
- // Are turrets allowed atm?
+ // Are turrets allowed?
if (cvar("g_turrets") == 0)
return 0;
self.team = 14; // Assume turrets are on the defending side if not explicitly set otehrwize
}
else if not (teamplay)
- self.team = MAX_SHOT_DISTANCE; // Group all turrets into the same team iso they dont kill eachother.
+ self.team = MAX_SHOT_DISTANCE; // Group all turrets into the same team, so they dont kill eachother.
else if(g_onslaught && self.targetname)
{
e = find(world,target,self.targetname);
}
}
else if(!self.team)
- self.team = MAX_SHOT_DISTANCE; // Group all turrets into the same team iso they dont kill eachother.
+ self.team = MAX_SHOT_DISTANCE; // Group all turrets into the same team, so they dont kill eachother.
/*
* Try to guess some reasonaly defaults
* as possible beforehand.
*/
if (self.turrcaps_flags & TFL_TURRCAPS_SUPPORT)
- if not (self.ticrate) self.ticrate = 0.2; // Support units generaly dont need to have a high speed ai-loop
+ self.ticrate = 0.2; // Support units generaly dont need to have a high speed ai-loop
else
- if not (self.ticrate) self.ticrate = 0.1; // 10 fps for normal turrets
+ self.ticrate = 0.1; // 10 fps for normal turrets
- self.ticrate = bound(sys_frametime,self.ticrate,60); // keep it sane
+ self.ticrate = bound(sys_frametime, self.ticrate, 60); // keep it sane
// General stuff
if (self.netname == "")
if not (self.respawntime)
self.respawntime = 60;
- self.respawntime = max(-1,self.respawntime);
+ self.respawntime = max(-1, self.respawntime);
if not (self.health)
self.health = 1000;
- self.tur_health = max(1,self.health);
+ self.tur_health = max(1, self.health);
if not (self.turrcaps_flags)
self.turrcaps_flags = TFL_TURRCAPS_RADIUSDMG | TFL_TURRCAPS_MEDPROJ | TFL_TURRCAPS_PLAYERKILL;
- if (!self.damage_flags)
+ if not (self.damage_flags)
self.damage_flags = TFL_DMG_YES | TFL_DMG_RETALIATE | TFL_DMG_AIMSHAKE;
// Shot stuff.
if not (self.shot_refire)
self.shot_refire = 1;
- self.shot_refire = bound(0.01,self.shot_refire,9999);
+ self.shot_refire = bound(0.01, self.shot_refire, 9999);
if not (self.shot_dmg)
self.shot_dmg = self.shot_refire * 50;
- self.shot_dmg = max(1,self.shot_dmg);
+ self.shot_dmg = max(1, self.shot_dmg);
if not (self.shot_radius)
self.shot_radius = self.shot_dmg * 0.5;
- self.shot_radius = max(1,self.shot_radius);
+ self.shot_radius = max(1, self.shot_radius);
if not (self.shot_speed)
self.shot_speed = 2500;
- self.shot_speed = max(1,self.shot_speed);
+ self.shot_speed = max(1, self.shot_speed);
if not (self.shot_spread)
self.shot_spread = 0.0125;
- self.shot_spread = bound(0.0001,self.shot_spread,500);
+ self.shot_spread = bound(0.0001, self.shot_spread, 500);
if not (self.shot_force)
self.shot_force = self.shot_dmg * 0.5 + self.shot_radius * 0.5;
- self.shot_force = bound(0.001,self.shot_force,MAX_SHOT_DISTANCE * 0.5);
+ self.shot_force = bound(0.001, self.shot_force, 5000);
if not (self.shot_volly)
self.shot_volly = 1;
- self.shot_volly = bound(1,self.shot_volly,floor(self.ammo_max / self.shot_dmg));
+ self.shot_volly = bound(1, self.shot_volly, floor(self.ammo_max / self.shot_dmg));
if not (self.shot_volly_refire)
self.shot_volly_refire = self.shot_refire * self.shot_volly;
- self.shot_volly_refire = bound(self.shot_refire,self.shot_volly_refire,60);
+ self.shot_volly_refire = bound(self.shot_refire, self.shot_volly_refire, 60);
if not (self.firecheck_flags)
self.firecheck_flags = TFL_FIRECHECK_WORLD | TFL_FIRECHECK_DEAD | TFL_FIRECHECK_DISTANCES |
// Range stuff.
if not (self.target_range)
self.target_range = self.shot_speed * 0.5;
- self.target_range = bound(0,self.target_range,MAX_SHOT_DISTANCE);
+ self.target_range = bound(0, self.target_range, MAX_SHOT_DISTANCE);
if not (self.target_range_min)
self.target_range_min = self.shot_radius * 2;
- self.target_range_min = bound(0,self.target_range_min,MAX_SHOT_DISTANCE);
-
- //if (!self.target_range_fire)
- // self.target_range_fire = self.target_range * 0.8;
- //self.target_range_fire = bound(0,self.target_range_fire,MAX_SHOT_DISTANCE);
+ self.target_range_min = bound(0, self.target_range_min, MAX_SHOT_DISTANCE);
if not (self.target_range_optimal)
self.target_range_optimal = self.target_range * 0.5;
- self.target_range_optimal = bound(0,self.target_range_optimal,MAX_SHOT_DISTANCE);
+ self.target_range_optimal = bound(0, self.target_range_optimal, MAX_SHOT_DISTANCE);
// Aim stuff.
if not (self.aim_maxrot)
self.aim_maxrot = 90;
- self.aim_maxrot = bound(0,self.aim_maxrot,360);
+ self.aim_maxrot = bound(0, self.aim_maxrot, 360);
if not (self.aim_maxpitch)
self.aim_maxpitch = 20;
- self.aim_maxpitch = bound(0,self.aim_maxpitch,90);
+ self.aim_maxpitch = bound(0, self.aim_maxpitch, 90);
if not (self.aim_speed)
self.aim_speed = 36;
- self.aim_speed = bound(0.1,self.aim_speed, 1000);
+ self.aim_speed = bound(0.1, self.aim_speed, 1000);
if not (self.aim_firetolerance_dist)
self.aim_firetolerance_dist = 5 + (self.shot_radius * 2);
- self.aim_firetolerance_dist = bound(0.1,self.aim_firetolerance_dist,MAX_SHOT_DISTANCE);
+ self.aim_firetolerance_dist = bound(0.1, self.aim_firetolerance_dist, MAX_SHOT_DISTANCE);
if not (self.aim_flags)
{
self.aim_flags |= TFL_AIM_GROUND2;
}
- // Sill the most tested (and aim-effective)
if not (self.track_type)
self.track_type = TFL_TRACKTYPE_STEPMOTOR;
if (self.track_type != TFL_TRACKTYPE_STEPMOTOR)
{
- // Fluid / Ineria mode. Looks mutch nicer, bit experimental &
- // Can inmapt aim preformance alot.
- // needs a bit diffrent aimspeed
+ // Fluid / Ineria mode. Looks mutch nicer.
+ // Can reduce aim preformance alot, needs a bit diffrent aimspeed
if not (self.aim_speed)
self.aim_speed = 180;
- self.aim_speed = bound(0.1,self.aim_speed, 1000);
+ self.aim_speed = bound(0.1, self.aim_speed, 1000);
if not (self.track_accel_pitch)
self.track_accel_pitch = 0.5;
// Target selection stuff.
if not (self.target_select_rangebias)
self.target_select_rangebias = 1;
- self.target_select_rangebias = bound(-10,self.target_select_rangebias,10);
+ self.target_select_rangebias = bound(-10, self.target_select_rangebias, 10);
if not (self.target_select_samebias)
self.target_select_samebias = 1;
- self.target_select_samebias = bound(-10,self.target_select_samebias,10);
+ self.target_select_samebias = bound(-10, self.target_select_samebias, 10);
if not (self.target_select_anglebias)
self.target_select_anglebias = 1;
- self.target_select_anglebias = bound(-10,self.target_select_anglebias,10);
+ self.target_select_anglebias = bound(-10, self.target_select_anglebias, 10);
if not (self.target_select_missilebias)
self.target_select_missilebias = -10;
- self.target_select_missilebias = bound(-10,self.target_select_missilebias,10);
- self.target_select_playerbias = bound(-10,self.target_select_playerbias,10);
+ self.target_select_missilebias = bound(-10, self.target_select_missilebias, 10);
+ self.target_select_playerbias = bound(-10, self.target_select_playerbias, 10);
if not (self.target_select_flags)
{
// Ammo stuff
if not (self.ammo_max)
self.ammo_max = self.shot_dmg * 10;
- self.ammo_max = max(self.shot_dmg,self.ammo_max);
+ self.ammo_max = max(self.shot_dmg, self.ammo_max);
if not (self.ammo)
self.ammo = self.shot_dmg * 5;
- self.ammo = bound(0,self.ammo,self.ammo_max);
+ self.ammo = bound(0,self.ammo, self.ammo_max);
if not (self.ammo_recharge)
self.ammo_recharge = self.shot_dmg * 0.5;
- self.ammo_recharge = max(0,self.ammo_recharge);
+ self.ammo_recharge = max(0 ,self.ammo_recharge);
// Convert the recharge from X per sec to X per ticrate
self.ammo_recharge = self.ammo_recharge * self.ticrate;
self.tur_head.team = self.team;
self.tur_head.owner = self;
- setmodel(self,base);
- setmodel(self.tur_head,head);
+ setmodel(self, base);
+ setmodel(self.tur_head, head);
- setsize(self,'-32 -32 0','32 32 64');
- setsize(self.tur_head,'0 0 0','0 0 0');
+ setsize(self, '-32 -32 0', '32 32 64');
+ setsize(self.tur_head, '0 0 0', '0 0 0');
- setorigin(self.tur_head,'0 0 0');
+ setorigin(self.tur_head, '0 0 0');
setattachment(self.tur_head, self, "tag_head");
if (!self.health)
// In target defend mode, aim on the spot to defend when idle.
if (self.tur_defend)
- self.idle_aim = self.tur_head.angles + angleofs(self.tur_head,self.tur_defend);
+ self.idle_aim = self.tur_head.angles + angleofs(self.tur_head, self.tur_defend);
else
self.idle_aim = '0 0 0';
-//--// Some support routines //--//
-
-#define anglemodss(a) (a - floor(a / 360) * 360)
-
-float(float v) anglemods =
+/*
+* Return a angle within +/- 360.
+*/
+float anglemods(float v)
{
v = v - 360 * floor(v / 360);
- return v;
-}
-
-float safeangle(float a)
-{
- if((a >= -360) && (a <= 360))
- return a;
-
-
- a -= (360 * floor(a / 360));
-
- return a;
+
+ if(v >= 180)
+ return v - 360;
+ else if(v <= -180)
+ return v + 360;
+ else
+ return v;
}
-float shortangle_f(float ang1,float ang2)
+/*
+* Return the short angle
+*/
+float shortangle_f(float ang1, float ang2)
{
if(ang1 > ang2)
{
return ang1;
}
-vector shortangle_v(vector ang1,vector ang2)
+vector shortangle_v(vector ang1, vector ang2)
{
vector vtmp;
return vtmp;
}
-vector shortangle_vxy(vector ang1,vector ang2)
+vector shortangle_vxy(vector ang1, vector ang2)
{
vector vtmp;
return vtmp;
}
-// Get real origin
+
+/*
+* Get "real" origin, in worldspace, even if ent is attached to something else.
+*/
vector real_origin(entity ent)
{
entity e;
e = ent.tag_entity;
while(e)
{
- // v = v + e.origin;
v = v + ((e.absmin + e.absmax) * 0.5);
e = e.tag_entity;
}
- //v = v + ent.origin;
v = v + ((ent.absmin + ent.absmax) * 0.5);
return v;
}
-// Plug this into wherever precache is done.
-void g_turrets_common_precash()
-{
- precache_model ("models/turrets/c512.md3");
- precache_model ("models/marker.md3");
-}
-
-void SUB_Remove();
-void marker_think()
-{
- if(self.cnt)
- if(self.cnt < time)
- {
- self.think = SUB_Remove;
- self.nextthink = time;
- return;
- }
-
- self.frame += 1;
- if(self.frame > 29)
- self.frame = 0;
-
- self.nextthink = time;
-}
-
-void mark_error(vector where,float lifetime)
-{
- entity err;
-
- err = spawn();
- err.classname = "error_marker";
- setmodel(err,"models/marker.md3");
- setorigin(err,where);
- err.movetype = MOVETYPE_NONE;
- err.think = marker_think;
- err.nextthink = time;
- err.skin = 0;
- if(lifetime)
- err.cnt = lifetime + time;
-}
-
-void mark_info(vector where,float lifetime)
-{
- entity err;
-
- err = spawn();
- err.classname = "info_marker";
- setmodel(err,"models/marker.md3");
- setorigin(err,where);
- err.movetype = MOVETYPE_NONE;
- err.think = marker_think;
- err.nextthink = time;
- err.skin = 1;
- if(lifetime)
- err.cnt = lifetime + time;
-}
-
-entity mark_misc(vector where,float lifetime)
-{
- entity err;
-
- err = spawn();
- err.classname = "mark_misc";
- setmodel(err,"models/marker.md3");
- setorigin(err,where);
- err.movetype = MOVETYPE_NONE;
- err.think = marker_think;
- err.nextthink = time;
- err.skin = 3;
- if(lifetime)
- err.cnt = lifetime + time;
- return err;
-}
-
-/*
-* Paint a v_color colord circle on target onwho
-* that fades away over f_time
-*/
-void paint_target(entity onwho, float f_size, vector v_color, float f_time)
-{
- entity e;
-
- e = spawn();
- setmodel(e, "models/turrets/c512.md3"); // precision set above
- e.scale = (f_size/512);
- //setsize(e, '0 0 0', '0 0 0');
- //setattachment(e,onwho,"");
- setorigin(e,onwho.origin + '0 0 1');
- e.alpha = 0.15;
- e.movetype = MOVETYPE_FLY;
-
- e.velocity = (v_color * 32); // + '0 0 1' * 64;
-
- e.colormod = v_color;
- SUB_SetFade(e,time,f_time);
-}
-
-void paint_target2(entity onwho, float f_size, vector v_color, float f_time)
-{
- entity e;
-
- e = spawn();
- setmodel(e, "models/turrets/c512.md3"); // precision set above
- e.scale = (f_size/512);
- setsize(e, '0 0 0', '0 0 0');
-
- setorigin(e,onwho.origin + '0 0 1');
- e.alpha = 0.15;
- e.movetype = MOVETYPE_FLY;
-
- e.velocity = (v_color * 32); // + '0 0 1' * 64;
- e.avelocity_x = -128;
-
- e.colormod = v_color;
- SUB_SetFade(e,time,f_time);
-}
-
-void paint_target3(vector where, float f_size, vector v_color, float f_time)
-{
- entity e;
- e = spawn();
- setmodel(e, "models/turrets/c512.md3"); // precision set above
- e.scale = (f_size/512);
- setsize(e, '0 0 0', '0 0 0');
- setorigin(e,where+ '0 0 1');
- e.movetype = MOVETYPE_NONE;
- e.velocity = '0 0 0';
- e.colormod = v_color;
- SUB_SetFade(e,time,f_time);
-}
-
/*
* Return the angle between two enteties
*/
vector angleofs(entity from, entity to)
{
vector v_res;
-
- // makevectors(from.angles);
+
v_res = normalize(to.origin - from.origin);
v_res = vectoangles(v_res);
v_res = v_res - from.angles;
- if (v_res_x < 0) v_res_x += 360;
- if (v_res_x > 180) v_res_x -= 360;
-
- if (v_res_y < 0) v_res_y += 360;
- if (v_res_y > 180) v_res_y -= 360;
-
- return v_res;
-}
-
-vector angleofs2(entity from, vector to)
-{
- vector v_res;
-
- // makevectors(from.angles);
- v_res = normalize(to - from.origin);
- v_res = vectoangles(v_res);
- v_res = v_res - from.angles;
-
- if (v_res_x < 0) v_res_x += 360;
- if (v_res_x > 180) v_res_x -= 360;
+ if (v_res_x < 0) v_res_x += 360;
+ if (v_res_x > 180) v_res_x -= 360;
- if (v_res_y < 0) v_res_y += 360;
- if (v_res_y > 180) v_res_y -= 360;
+ if (v_res_y < 0) v_res_y += 360;
+ if (v_res_y > 180) v_res_y -= 360;
return v_res;
}
-vector angleofs3(vector from,vector from_a, entity to)
+vector angleofs3(vector from, vector from_a, entity to)
{
vector v_res;
-
- // makevectors(from.angles);
+
v_res = normalize(to.origin - from);
v_res = vectoangles(v_res);
v_res = v_res - from_a;
- if (v_res_x < 0) v_res_x += 360;
- if (v_res_x > 180) v_res_x -= 360;
+ if (v_res_x < 0) v_res_x += 360;
+ if (v_res_x > 180) v_res_x -= 360;
- if (v_res_y < 0) v_res_y += 360;
- if (v_res_y > 180) v_res_y -= 360;
+ if (v_res_y < 0) v_res_y += 360;
+ if (v_res_y > 180) v_res_y -= 360;
return v_res;
}
-float turret_tag_setup()
-{
- if(!self.tur_head)
- {
- dprint("Call to turret_tag_setup with self.tur_head missing!\n");
- self.tur_shotorg = '0 0 0';
- return 0;
- }
-
- //if not(self.turrcaps_flags & TFL_TURRCAPS_HEADATTACHED)
- // 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;
-}
-
+/*
+* Update self.tur_shotorg by getting up2date bone info
+* NOTICE this func overwrites the global v_forward, v_right and v_up vectors.
+*/
float turret_tag_fire_update()
{
if(!self.tur_head)
{
- dprint("Call to turret_tag_fire_update with self.tur_head missing!\n");
+ error("Call to turret_tag_fire_update with self.tur_head missing!\n");
self.tur_shotorg = '0 0 0';
- return 0;
+ return FALSE;
}
- self.tur_shotorg = gettaginfo(self.tur_head,gettagindex(self.tur_head,"tag_fire"));
+ 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;
+ return TRUE;
}
-void FireImoBeam (vector start,vector end,vector smin,vector smax,
- float bforce,float f_dmg,float f_velfactor, float deathtype)
+/*
+* Railgun-like beam, but has thickness and suppots slowing of target
+*/
+void FireImoBeam (vector start, vector end, vector smin, vector smax,
+ float bforce, float f_dmg, float f_velfactor, float deathtype)
{
local vector hitloc, force, endpoint, dir;
trace_endpos = endpoint;
}
+// Plug this into wherever precache is done.
+void g_turrets_common_precash()
+{
+ precache_model ("models/turrets/c512.md3");
+ precache_model ("models/marker.md3");
+}
+
void turrets_precache_debug_models()
{
precache_model ("models/turrets/c512.md3");
//precache_model ("models/turrets/plasma.md3");
//precache_model ("models/turrets/tesla_head.md3");
//precache_model ("models/turrets/tesla_base.md3");
- //turrets_precache_debug_models();
+ #ifdef TURRET_DEBUG
+ turrets_precache_debug_models();
+ #endif
+}
+
+
+#ifdef TURRET_DEBUG
+void SUB_Remove();
+void marker_think()
+{
+ if(self.cnt)
+ if(self.cnt < time)
+ {
+ self.think = SUB_Remove;
+ self.nextthink = time;
+ return;
+ }
+
+ self.frame += 1;
+ if(self.frame > 29)
+ self.frame = 0;
+
+ self.nextthink = time;
+}
+
+void mark_error(vector where,float lifetime)
+{
+ entity err;
+
+ err = spawn();
+ err.classname = "error_marker";
+ setmodel(err,"models/marker.md3");
+ setorigin(err,where);
+ err.movetype = MOVETYPE_NONE;
+ err.think = marker_think;
+ err.nextthink = time;
+ err.skin = 0;
+ if(lifetime)
+ err.cnt = lifetime + time;
+}
+
+void mark_info(vector where,float lifetime)
+{
+ entity err;
+
+ err = spawn();
+ err.classname = "info_marker";
+ setmodel(err,"models/marker.md3");
+ setorigin(err,where);
+ err.movetype = MOVETYPE_NONE;
+ err.think = marker_think;
+ err.nextthink = time;
+ err.skin = 1;
+ if(lifetime)
+ err.cnt = lifetime + time;
+}
+
+entity mark_misc(vector where,float lifetime)
+{
+ entity err;
+
+ err = spawn();
+ err.classname = "mark_misc";
+ setmodel(err,"models/marker.md3");
+ setorigin(err,where);
+ err.movetype = MOVETYPE_NONE;
+ err.think = marker_think;
+ err.nextthink = time;
+ err.skin = 3;
+ if(lifetime)
+ err.cnt = lifetime + time;
+ return err;
+}
+
+/*
+* Paint a v_color colord circle on target onwho
+* that fades away over f_time
+*/
+void paint_target(entity onwho, float f_size, vector v_color, float f_time)
+{
+ entity e;
+
+ e = spawn();
+ setmodel(e, "models/turrets/c512.md3"); // precision set above
+ e.scale = (f_size/512);
+ //setsize(e, '0 0 0', '0 0 0');
+ //setattachment(e,onwho,"");
+ setorigin(e,onwho.origin + '0 0 1');
+ e.alpha = 0.15;
+ e.movetype = MOVETYPE_FLY;
+
+ e.velocity = (v_color * 32); // + '0 0 1' * 64;
+
+ e.colormod = v_color;
+ SUB_SetFade(e,time,f_time);
+}
+
+void paint_target2(entity onwho, float f_size, vector v_color, float f_time)
+{
+ entity e;
+
+ e = spawn();
+ setmodel(e, "models/turrets/c512.md3"); // precision set above
+ e.scale = (f_size/512);
+ setsize(e, '0 0 0', '0 0 0');
+
+ setorigin(e,onwho.origin + '0 0 1');
+ e.alpha = 0.15;
+ e.movetype = MOVETYPE_FLY;
+
+ e.velocity = (v_color * 32); // + '0 0 1' * 64;
+ e.avelocity_x = -128;
+
+ e.colormod = v_color;
+ SUB_SetFade(e,time,f_time);
+}
+
+void paint_target3(vector where, float f_size, vector v_color, float f_time)
+{
+ entity e;
+ e = spawn();
+ setmodel(e, "models/turrets/c512.md3"); // precision set above
+ e.scale = (f_size/512);
+ setsize(e, '0 0 0', '0 0 0');
+ setorigin(e,where+ '0 0 1');
+ e.movetype = MOVETYPE_NONE;
+ e.velocity = '0 0 0';
+ e.colormod = v_color;
+ SUB_SetFade(e,time,f_time);
}
+#endif
/*
* Generic bias aware score system.
*/
-float turret_stdproc_targetscore_generic(entity e_turret,entity e_target)
+float turret_stdproc_targetscore_generic(entity e_turret, entity e_target)
{
//vector v_tmp;
float d_dist; // Defendmode Distance
float ikr; // ideal kill range
- if(!e_target) return 0;
-
- //if (e_target == e_turret.enemy) s_score = 1;
+ /*
+ if(!e_target)
+ return 0;
+ */
if (e_turret.tur_defend)
{
if ((e_turret.target_select_playerbias > 0) && (e_target.flags & FL_CLIENT))
p_score = 1;
- d_score = max(d_score,0);
- a_score = max(a_score,0);
- m_score = max(m_score,0);
- p_score = max(p_score,0);
+ d_score = max(d_score, 0);
+ a_score = max(a_score, 0);
+ m_score = max(m_score, 0);
+ p_score = max(p_score, 0);
score = (d_score * e_turret.target_select_rangebias) +
(a_score * e_turret.target_select_anglebias) +
proj.bot_dodgerating = self.shot_dmg;
proj.think = turret_ewheel_projectile_explode;
proj.nextthink = time + 9;
- proj.solid = SOLID_BBOX;
+ //proj.solid = SOLID_TRIGGER;
proj.movetype = MOVETYPE_FLYMISSILE;
proj.velocity = normalize(self.tur_shotdir_updated + randomvec() * self.shot_spread) * self.shot_speed;
proj.touch = turret_ewheel_projectile_explode;
proj.enemy = self.enemy;
proj.flags = FL_PROJECTILE | FL_NOTARGET;
+ PROJECTILE_MAKETRIGGER(proj);
CSQCProjectile(proj, TRUE, PROJECTILE_LASER, TRUE);
}
self.target_select_flags = TFL_TARGETSELECT_PLAYERS | TFL_TARGETSELECT_RANGELIMTS | TFL_TARGETSELECT_TEAMCHECK | TFL_TARGETSELECT_LOS;
+ self.target_select_flags = 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_validate_flags = TFL_TARGETSELECT_RANGELIMTS | TFL_TARGETSELECT_TEAMCHECK;// | TFL_TARGETSELECT_LOS;
self.damage_flags |= TFL_DMG_DEATH_NOGIBS;
self.iscreature = TRUE;
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 (!turret_tag_setup())
+ if (!turret_tag_fire_update())
dprint("Warning: Turret ",self.classname, " faild to initialize md3 tags\n");
//setorigin(self,self.origin + '0 0 128');
self.damage_flags |= TFL_DMG_HEADSHAKE;
self.target_select_flags |= TFL_TARGETSELECT_NOTURRETS | TFL_TARGETSELECT_MISSILESONLY;
- if (!turret_tag_setup())
+ if (!turret_tag_fire_update())
dprint("Warning: Turret ",self.classname, " faild to initialize md3 tags\n");
// Our fire routine
return;
}
- if (!turret_tag_setup())
+ if (!turret_tag_fire_update())
dprint("Warning: Turret ",self.classname, " faild to initialize md3 tags\n");
self.turret_firefunc = turret_hellion_attack;
self.target_validate_flags = TFL_TARGETSELECT_PLAYERS | TFL_TARGETSELECT_TEAMCHECK;
- if (!turret_tag_setup())
+ if (!turret_tag_fire_update())
dprint("Warning: Turret ",self.classname, " faild to initialize md3 tags\n");
// Our fire routine
self.ammo_flags = TFL_AMMO_BULLETS | TFL_AMMO_RECHARGE | TFL_AMMO_RECIVE;
self.turrcaps_flags = TFL_TURRCAPS_PLAYERKILL;
- self.aim_flags = TFL_AIM_LEAD;
-
- if(cvar("g_antilag_bullets"))
- self.turrcaps_flags |= TFL_TURRCAPS_HITSCAN;
- else
- self.aim_flags |= TFL_AIM_SHOTTIMECOMPENSATE;
+ self.aim_flags = TFL_AIM_LEAD | TFL_AIM_SHOTTIMECOMPENSATE;
+
+ if not (cvar("g_antilag_bullets"))
+ self.turrcaps_flags |= TFL_TURRCAPS_HITSCAN;
if (turret_stdproc_init("machinegun_std",0,"models/turrets/base.md3","models/turrets/machinegun.md3") == 0)
{
self.damage_flags |= TFL_DMG_HEADSHAKE;
- if (!turret_tag_setup())
+ if (!turret_tag_fire_update())
dprint("Warning: Turret ",self.classname, " faild to initialize md3 tags\n");
// Our fire routine
self.shoot_flags |= TFL_SHOOT_VOLLYALWAYS;
self.volly_counter = self.shot_volly;
- if (!turret_tag_setup())
+ if (!turret_tag_fire_update())
dprint("Warning: Turret ",self.classname, " faild to initialize md3 tags\n");
// Our fire routine
self.turrcaps_flags = TFL_TURRCAPS_SNIPER|TFL_TURRCAPS_HITSCAN|TFL_TURRCAPS_PLAYERKILL;
self.ammo_flags = TFL_AMMO_ENERGY | TFL_AMMO_RECHARGE | TFL_AMMO_RECIVE;
- self.aim_flags = TFL_AIM_ZEASE | TFL_AIM_LEAD;
+ self.aim_flags = TFL_AIM_LEAD;
if (turret_stdproc_init("phaser_std",0,"models/turrets/base.md3","models/turrets/phaser.md3") == 0)
{
return;
}
- if (!turret_tag_setup())
+ if (!turret_tag_fire_update())
dprint("Warning: Turret ",self.classname, " faild to initialize md3 tags\n");
self.turret_firecheckfunc = turret_phaser_firecheck;
self.damage_flags |= TFL_DMG_HEADSHAKE;
self.firecheck_flags |= TFL_FIRECHECK_AFF;
- if (!turret_tag_setup())
+ if (!turret_tag_fire_update())
dprint("Warning: Turret ",self.classname, " faild to initialize md3 tags\n");
// Our fireing routine
self.damage_flags |= TFL_DMG_HEADSHAKE;
self.firecheck_flags |= TFL_FIRECHECK_AFF;
- if (!turret_tag_setup())
+ if (!turret_tag_fire_update())
dprint("Warning: Turret ",self.classname, " faild to initialize md3 tags\n");
// Our fireing routine
self.target_validate_flags = TFL_TARGETSELECT_PLAYERS | TFL_TARGETSELECT_MISSILES |
TFL_TARGETSELECT_RANGELIMTS | TFL_TARGETSELECT_TEAMCHECK;
- if (!turret_tag_setup())
+ if (!turret_tag_fire_update())
dprint("Warning: Turret ",self.classname, " faild to initialize md3 tags\n");
self.turret_firefunc = turret_tesla_fire;
return;
}
- if (!turret_tag_setup())
+ if (!turret_tag_fire_update())
dprint("Warning: Turret ",self.classname, " faild to initialize md3 tags\n");
self.damage_flags |= TFL_DMG_DEATH_NOGIBS;
ftmp2 = ftmp * -1;
ftmp = bound(ftmp2, shortangle_f(player.v_angle_y - racer.angles_y, racer.angles_y), ftmp);
- ftmp2 = safeangle(racer.angles_y + ftmp);
+ ftmp2 = anglemods(racer.angles_y + ftmp);
// Roll
ftmp = bound(-45, shortangle_f(player.v_angle_z + ((racer.angles_y - ftmp2) * racer_turnroll), racer.angles_z), 45);
- ftmp = safeangle(racer.angles_z + ftmp);
+ ftmp = anglemods(racer.angles_z + ftmp);
racer.angles_z = bound(-85, ftmp, 85);
// Turn
ftmp2 = ftmp * -1;
ftmp = bound(ftmp2,shortangle_f(player.v_angle_x - racer.angles_x,racer.angles_x),ftmp);
- racer.angles_x = safeangle(racer.angles_x + ftmp);
+ racer.angles_x = anglemods(racer.angles_x + ftmp);
racer.angles_x *= -1;
df = racer.velocity * -0.5;
//vhic.angles_z = ftmp;
// Turn
- vhic.angles_y = safeangle(vhic.angles_y + ftmp);
+ vhic.angles_y = anglemods(vhic.angles_y + ftmp);
// Pitch Body
ftmp = raptor_pitchspeed * sys_frametime;
ftmp = bound(-ftmp, shortangle_f(player.v_angle_x - vhic.angles_x,vhic.angles_x), ftmp);
- vhic.angles_x = bound(-60,safeangle(vhic.angles_x + ftmp),60);
+ vhic.angles_x = bound(-60,anglemods(vhic.angles_x + ftmp),60);
vhic.angles_x *= -1;
if(raptor_movestyle == 1)
}
else
{
- spider.angles_y = safeangle(spider.angles_y + ftmp);
+ spider.angles_y = anglemods(spider.angles_y + ftmp);
spider.tur_head.angles_y -= ftmp;
if(player.movement_x != 0)
set g_turrets_unit_flac_std_shot_speed 9000
set g_turrets_unit_flac_std_shot_spread 0.02
set g_turrets_unit_flac_std_shot_force 25
+set g_turrets_unit_flac_std_shot_volly 0
+set g_turrets_unit_flac_std_shot_volly_refire 0
set g_turrets_unit_flac_std_target_range 4000
set g_turrets_unit_flac_std_target_range_min 500
set g_turrets_unit_flac_std_ammo_recharge 100
set g_turrets_unit_flac_std_aim_firetolerance_dist 150
-set g_turrets_unit_flac_std_aim_speed 360
+set g_turrets_unit_flac_std_aim_speed 200
set g_turrets_unit_flac_std_aim_maxrot 360
set g_turrets_unit_flac_std_aim_maxpitch 35
set g_turrets_unit_flac_std_track_type 3
-set g_turrets_unit_flac_std_track_accel_pitch 0.25
-set g_turrets_unit_flac_std_track_accel_rot 0.8
-set g_turrets_unit_flac_std_track_blendrate 0.6
+set g_turrets_unit_flac_std_track_accel_pitch 0.5
+set g_turrets_unit_flac_std_track_accel_rot 0.7
+set g_turrets_unit_flac_std_track_blendrate 0.2
set g_turrets_unit_hellion_std_track_type 3
set g_turrets_unit_hellion_std_track_accel_pitch 0.25
-set g_turrets_unit_hellion_std_track_accel_rot 0.5
-set g_turrets_unit_hellion_std_track_blendrate 0.75
+set g_turrets_unit_hellion_std_track_accel_rot 0.6
+set g_turrets_unit_hellion_std_track_blendrate 0.25
set g_turrets_unit_hk_std_track_type 3
set g_turrets_unit_hk_std_track_accel_pitch 0.25
-set g_turrets_unit_hk_std_track_accel_rot 0.5
-set g_turrets_unit_hk_std_track_blendrate 0.25
+set g_turrets_unit_hk_std_track_accel_rot 0.6
+set g_turrets_unit_hk_std_track_blendrate 0.2
set g_turrets_unit_machinegun_std_ammo_recharge 75
set g_turrets_unit_machinegun_std_aim_firetolerance_dist 25
-set g_turrets_unit_machinegun_std_aim_speed 720
+set g_turrets_unit_machinegun_std_aim_speed 120
set g_turrets_unit_machinegun_std_aim_maxrot 360
set g_turrets_unit_machinegun_std_aim_maxpitch 25
set g_turrets_unit_machinegun_std_track_type 3
-set g_turrets_unit_machinegun_std_track_accel_pitch 0.5
-set g_turrets_unit_machinegun_std_track_accel_rot 0.75
-set g_turrets_unit_machinegun_std_track_blendrate 0.5
+set g_turrets_unit_machinegun_std_track_accel_pitch 0.4
+set g_turrets_unit_machinegun_std_track_accel_rot 0.9
+set g_turrets_unit_machinegun_std_track_blendrate 0.2
set g_turrets_unit_mlrs_std_ammo_recharge 70
set g_turrets_unit_mlrs_std_aim_firetolerance_dist 120
-set g_turrets_unit_mlrs_std_aim_speed 270
+set g_turrets_unit_mlrs_std_aim_speed 100
set g_turrets_unit_mlrs_std_aim_maxrot 360
set g_turrets_unit_mlrs_std_aim_maxpitch 20
set g_turrets_unit_mlrs_std_track_type 3
set g_turrets_unit_mlrs_std_track_accel_pitch 0.5
-set g_turrets_unit_mlrs_std_track_accel_rot 0.8
+set g_turrets_unit_mlrs_std_track_accel_rot 0.7
set g_turrets_unit_mlrs_std_track_blendrate 0.2
set g_turrets_unit_phaser_std_aim_firetolerance_dist 100
-set g_turrets_unit_phaser_std_aim_speed 540
+set g_turrets_unit_phaser_std_aim_speed 300
set g_turrets_unit_phaser_std_aim_maxrot 360
set g_turrets_unit_phaser_std_aim_maxpitch 30
set g_turrets_unit_phaser_std_track_type 3
set g_turrets_unit_phaser_std_track_accel_pitch 0.5
set g_turrets_unit_phaser_std_track_accel_rot 0.65
-set g_turrets_unit_phaser_std_track_blendrate 0.5
+set g_turrets_unit_phaser_std_track_blendrate 0.2
// If predicted emeypos is this or closer to predicted impact, fire is ok
set g_turrets_unit_plasma_std_aim_firetolerance_dist 120
// Aim how fast. for track_type 1 this is dgr/sec, for 2 & 3 its the maximum angle speed added each second
-set g_turrets_unit_plasma_std_aim_speed 270
+set g_turrets_unit_plasma_std_aim_speed 200
// Max rottation of head
set g_turrets_unit_plasma_std_aim_maxrot 360
// Max pitch of head
set g_turrets_unit_plasma_std_track_type 3
// Following controls how _track_type = 3 works.
set g_turrets_unit_plasma_std_track_accel_pitch 0.5
-set g_turrets_unit_plasma_std_track_accel_rot 0.8
+set g_turrets_unit_plasma_std_track_accel_rot 0.7
set g_turrets_unit_plasma_std_track_blendrate 0.2
set g_turrets_unit_plasma_dual_aim_firetolerance_dist 200
-set g_turrets_unit_plasma_dual_aim_speed 270
+set g_turrets_unit_plasma_dual_aim_speed 100
set g_turrets_unit_plasma_dual_aim_maxrot 360
set g_turrets_unit_plasma_dual_aim_maxpitch 30
set g_turrets_unit_plasma_dual_track_type 3
set g_turrets_unit_plasma_dual_track_accel_pitch 0.5
-set g_turrets_unit_plasma_dual_track_accel_rot 0.75
-set g_turrets_unit_plasma_dual_track_blendrate 0.75
+set g_turrets_unit_plasma_dual_track_accel_rot 0.7
+set g_turrets_unit_plasma_dual_track_blendrate 0.2