d_score = min(ikr, tvt_dist) / max(ikr, tvt_dist);
}
- a_score = 1 - tvt_thadf / _turret.aim_maxrotate;
+ a_score = 1 - tvt_thadf / _turret.aim_maxrot;
if ((_turret.target_select_missilebias > 0) && (_target.flags & FL_PROJECTILE))
m_score = 1;
// Main functions
-#define cvar_base "g_turrets_unit_"
.float clientframe;
void turrets_setframe(entity this, float _frame, float client_only)
{
void load_unit_settings(entity ent, bool is_reload)
{
- string unitname = ent.netname;
- string sbase;
-
if (ent == NULL)
return;
if(!ent.turret_scale_health) ent.turret_scale_health = 1;
if(!ent.turret_scale_respawn) ent.turret_scale_respawn = 1;
- sbase = strcat(cvar_base,unitname);
if (is_reload)
{
ent.enemy = NULL;
ent.tur_head.angles = '0 0 0';
}
- SetResourceExplicit(ent, RES_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_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"));
- ent.target_select_anglebias = cvar(strcat(sbase,"_target_select_anglebias"));
- ent.target_select_missilebias = cvar(strcat(sbase,"_target_select_missilebias"));
- 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(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(strcat(sbase,"_aim_firetolerance_dist"));
- ent.aim_speed = cvar(strcat(sbase,"_aim_speed")) * ent.turret_scale_aim;
- ent.aim_maxrotate = cvar(strcat(sbase,"_aim_maxrot"));
- ent.aim_maxpitch = cvar(strcat(sbase,"_aim_maxpitch"));
-
- ent.track_type = cvar(strcat(sbase,"_track_type"));
- ent.track_accel_pitch = cvar(strcat(sbase,"_track_accel_pitch"));
- ent.track_accel_rotate = cvar(strcat(sbase,"_track_accel_rot"));
- ent.track_blendrate = cvar(strcat(sbase,"_track_blendrate"));
+ string unitname = ent.netname;
+ #define X(class, prefix, fld, type) ent.fld = cvar(strcat("g_turrets_unit_", prefix, "_", #fld));
+ TR_PROPS_COMMON(X, , unitname)
+ #undef X
+
+ ent.ammo_max *= ent.turret_scale_ammo;
+ ent.ammo_recharge *= ent.turret_scale_ammo;
+ ent.aim_speed *= ent.turret_scale_aim;
+ ent.health *= ent.turret_scale_health;
+ ent.respawntime *= ent.turret_scale_respawn;
+ ent.shot_dmg *= ent.turret_scale_damage;
+ ent.shot_refire *= ent.turret_scale_refire;
+ ent.shot_radius *= ent.turret_scale_damage;
+ ent.shot_force *= ent.turret_scale_damage;
+ ent.shot_volly_refire *= ent.turret_scale_refire;
+ ent.target_range *= ent.turret_scale_range;
+ ent.target_range_min *= ent.turret_scale_range;
+ ent.target_range_optimal *= ent.turret_scale_range;
if(is_reload) {
Turret tur = get_turretinfo(ent.m_id);
if (this.track_flags & TFL_TRACK_ROTATE)
{
this.tur_head.angles_y += bound(-f_tmp, move_angle_y, f_tmp);
- if(this.tur_head.angles_y > this.aim_maxrotate)
- this.tur_head.angles_y = this.aim_maxrotate;
+ if(this.tur_head.angles_y > this.aim_maxrot)
+ this.tur_head.angles_y = this.aim_maxrot;
- if(this.tur_head.angles_y < -this.aim_maxrotate)
- this.tur_head.angles_y = this.aim_maxrotate;
+ if(this.tur_head.angles_y < -this.aim_maxrot)
+ this.tur_head.angles_y = this.aim_maxrot;
}
// CSQC
case TFL_TRACKTYPE_FLUIDINERTIA:
f_tmp = this.aim_speed * this.ticrate; // dgr/sec -> dgr/tic
move_angle_x = bound(-this.aim_speed, move_angle_x * this.track_accel_pitch * f_tmp, this.aim_speed);
- move_angle_y = bound(-this.aim_speed, move_angle_y * this.track_accel_rotate * f_tmp, this.aim_speed);
+ move_angle_y = bound(-this.aim_speed, move_angle_y * this.track_accel_rot * f_tmp, this.aim_speed);
move_angle = (this.tur_head.avelocity * this.track_blendrate) + (move_angle * (1 - this.track_blendrate));
break;
{
this.tur_head.avelocity_y = move_angle_y;
- if((this.tur_head.angles_y + this.tur_head.avelocity_y * this.ticrate) > this.aim_maxrotate)
+ if((this.tur_head.angles_y + this.tur_head.avelocity_y * this.ticrate) > this.aim_maxrot)
{
this.tur_head.avelocity_y = 0;
- this.tur_head.angles_y = this.aim_maxrotate;
+ this.tur_head.angles_y = this.aim_maxrot;
this.SendFlags |= TNSF_ANG;
}
- if((this.tur_head.angles_y + this.tur_head.avelocity_y * this.ticrate) < -this.aim_maxrotate)
+ if((this.tur_head.angles_y + this.tur_head.avelocity_y * this.ticrate) < -this.aim_maxrot)
{
this.tur_head.avelocity_y = 0;
- this.tur_head.angles_y = -this.aim_maxrotate;
+ this.tur_head.angles_y = -this.aim_maxrot;
this.SendFlags |= TNSF_ANG;
}
if (fabs(tvt_tadv_x) > e_turret.aim_maxpitch)
return -17;
- if (fabs(tvt_tadv_y) > e_turret.aim_maxrotate)
+ if (fabs(tvt_tadv_y) > e_turret.aim_maxrot)
return -18;
}
tur.target_range = bound(0, (TRY(tur.target_range) : tur.shot_speed * 0.5 ), max_shot_distance);
tur.target_range_min = bound(0, (TRY(tur.target_range_min) : tur.shot_radius * 2 ), max_shot_distance);
tur.target_range_optimal = bound(0, (TRY(tur.target_range_optimal) : tur.target_range * 0.5 ), max_shot_distance);
- tur.aim_maxrotate = bound(0, (TRY(tur.aim_maxrotate) : 90 ), 360);
+ tur.aim_maxrot = bound(0, (TRY(tur.aim_maxrot) : 90 ), 360);
tur.aim_maxpitch = bound(0, (TRY(tur.aim_maxpitch) : 20 ), 90);
tur.aim_speed = bound(0.1, (TRY(tur.aim_speed) : 36 ), 1000);
tur.aim_firetolerance_dist = bound(0.1, (TRY(tur.aim_firetolerance_dist) : 5 + (tur.shot_radius * 2) ), max_shot_distance);
this.aim_speed = bound(0.1, ((!this.aim_speed) ? 180 : this.aim_speed), 1000);
if(!this.track_accel_pitch) { this.track_accel_pitch = 0.5; }
- if(!this.track_accel_rotate) { this.track_accel_rotate = 0.5; }
+ if(!this.track_accel_rot) { this.track_accel_rot = 0.5; }
if(!this.track_blendrate) { this.track_blendrate = 0.35; }
}
entity turret_select_target(entity this);
// turret fields
+
+#define X(class, prefix, fld, type) .type fld;
+TR_PROPS_COMMON(X, , )
+#undef X
+/*
+.float shot_volly; // smaller than 1 = shoot # times at target
+.float shot_volly_refire; // refire after completed volly
+*/
+
.float ticrate; // interal ai think rate
.entity tur_head; // top part of the turret
.entity tur_defend; // defend this entity
.float tur_dist_impact_to_aimpos; // distance impact<->aim
.float volly_counter; // decrement counter from .shot_volly to 0
-.float shot_refire; // attack refire
-.float shot_speed; // projectile speed
-.float shot_spread; // inaccuracy
-.float shot_dmg; // core damage of projectile
-.float shot_radius; // projectile damage radius
-.float shot_force; // projectile damage force
-.float shot_volly; // smaller than 1 = shoot # times at target
-.float shot_volly_refire; // refire after completed volly
-
-.float target_range;
-.float target_range_min;
-.float target_range_optimal;
-
-.float target_select_rangebias;
-.float target_select_samebias;
-.float target_select_anglebias;
-.float target_select_missilebias;
-.float target_select_playerbias;
.float target_select_time; // last time turret had a valid target
.float target_validate_time; // throttle re-validation of current target
-.float aim_firetolerance_dist;
-.float aim_speed;
-.float aim_maxpitch;
-.float aim_maxrotate;
.float ammo; // current ammo
-.float ammo_recharge; // recharge rate
-.float ammo_max; // maximum ammo
-
.vector idle_aim;
/// Map time control over pain inflicted
.float turret_scale_respawn;
// tracking type
-.float track_type;
const float TFL_TRACKTYPE_STEPMOTOR = 1; // hard angle increments, ugly for fast turning with best accuracy
const float TFL_TRACKTYPE_FLUIDPRECISE = 2; // smooth absolute movement, looks OK with fair accuracy
const float TFL_TRACKTYPE_FLUIDINERTIA = 3; // simulated inertia ("wobbly" mode), worst accuracy, depends on below flags
-.float track_accel_pitch;
-.float track_accel_rotate;
-.float track_blendrate;
void turret_respawn(entity this);