// Comment out below to skip turrets #define TTURRETS_ENABLED #ifdef TTURRETS_ENABLED #ifdef SVQC //#message "with tZork turrets" float turret_count; vector real_origin(entity ent); /// Map time control over pain inflicted .float turret_scale_damage; /// Map time control targetting range .float turret_scale_range; /// Map time control refire .float turret_scale_refire; /// Map time control ammo held and recharged .float turret_scale_ammo; /// Map time control aim speed .float turret_scale_aim; /// Map time control health .float turret_scale_health; /// Map time control respawn time .float turret_scale_respawn; /// Used for cvar reloading .string cvar_basename; //.float spawnflags const float TSF_SUSPENDED = 1; /// Spawn a pillar model under the turret to make it look ok on uneven ground surfaces const float TSF_TERRAINBASE = 2; /// Disable builtin ammo regeneration const float TSF_NO_AMMO_REGEN = 4; /// Dont break path to chase enemys. will still fire at them if possible. const float TSF_NO_PATHBREAK = 8; /// Dont respawn const float TSL_NO_RESPAWN = 16; /// Let this turret roam when idle. const float TSL_ROAM = 32; /// target selection flags .float target_select_flags; /// target validatoin flags .float target_validate_flags; /// Dont select a target on its own. const float TFL_TARGETSELECT_NO = 2; /// Need line of sight const float TFL_TARGETSELECT_LOS = 4; /// Players are valid targets const float TFL_TARGETSELECT_PLAYERS = 8; /// Missiles are valid targets const float TFL_TARGETSELECT_MISSILES = 16; /// Responds to turret_trigger_target events const float TFL_TARGETSELECT_TRIGGERTARGET = 32; /// Angular limitations of turret head limits target selection const float TFL_TARGETSELECT_ANGLELIMITS = 64; /// Range limits apply in targetselection const float TFL_TARGETSELECT_RANGELIMTS = 128; /// DOnt select targets with a .team matching its own const float TFL_TARGETSELECT_TEAMCHECK = 256; /// Cant select targets on its own. needs to be triggerd or slaved. const float TFL_TARGETSELECT_NOBUILTIN = 512; /// TFL_TARGETSELECT_TEAMCHECK is inverted (selects only mebers of own .team) const float TFL_TARGETSELECT_OWNTEAM = 1024; /// Turrets aren't valid targets const float TFL_TARGETSELECT_NOTURRETS = 2048; /// Use feild of view const float TFL_TARGETSELECT_FOV = 4096; const float TFL_TARGETSELECT_MISSILESONLY = 8192; /// aim flags .float aim_flags; /// Dont aim. const float TFL_AIM_NO = 1; /// Go for ground, not direct hit, but only if target is on ground. const float TFL_AIM_GROUNDGROUND = 2; /// Try to predict target movement (does not account for gravity) const float TFL_AIM_LEAD = 4; /// Compensate for shot traveltime when lead const float TFL_AIM_SHOTTIMECOMPENSATE = 8; /// Try to do real prediction of targets z pos at impact. const float TFL_AIM_ZPREDICT = 16; /// Simply aim at target's current location const float TFL_AIM_SIMPLE = 32; /// track (turn and pitch head) flags .float track_flags; /// Dont move head const float TFL_TRACK_NO = 2; /// Pitch the head const float TFL_TRACK_PITCH = 4; /// Rotate the head const float TFL_TRACK_ROT = 8; /// How tracking is preformed .float track_type; /// Hard angle increments. Ugly for fast turning, best accuracy. const float TFL_TRACKTYPE_STEPMOTOR = 1; /// Smoth absolute movement. Looks ok, fair accuracy. const float TFL_TRACKTYPE_FLUIDPRECISE = 2; /// Simulated inertia. "Wobbly mode" Looks kool, can mean really bad accuracy depending on how the fields below are set const float TFL_TRACKTYPE_FLUIDINERTIA = 3; /// TFL_TRACKTYPE_FLUIDINERTIA: pitch multiplier .float track_accel_pitch; /// TFL_TRACKTYPE_FLUIDINERTIA: rotation multiplier .float track_accel_rot; /// TFL_TRACKTYPE_FLUIDINERTIA: Blendrate with old rotation (inertia simulation) 1 = only old, 0 = only new .float track_blendrate; /// How prefire check is preformed .float firecheck_flags; /// Dont kill the dead const float TFL_FIRECHECK_DEAD = 4; /// Range limits apply const float TFL_FIRECHECK_DISTANCES = 8; /// Line Of Sight needs to be clear const float TFL_FIRECHECK_LOS = 16; /// Consider distance inpactpoint<->aimspot const float TFL_FIRECHECK_AIMDIST = 32; /// Consider enemy origin<->impactpoint const float TFL_FIRECHECK_REALDIST = 64; /// Consider angular diff head<->aimspot const float TFL_FIRECHECK_ANGLEDIST = 128; /// (re)consider target.team<->self.team const float TFL_FIRECHECK_TEAMCECK = 256; /// Try to avoid friendly fire const float TFL_FIRECHECK_AFF = 512; /// Own .ammo needs to be >= then own .shot_dmg const float TFL_FIRECHECK_OWM_AMMO = 1024; /// Others ammo need to be < others .ammo_max const float TFL_FIRECHECK_OTHER_AMMO = 2048; /// Check own .attack_finished_single vs time const float TFL_FIRECHECK_REFIRE = 4096; /// Move the acctual target to aimspot before tracing impact (and back after) //#define TFL_FIRECHECK_VERIFIED 8192 /// Dont do any chekcs const float TFL_FIRECHECK_NO = 16384; /// How shooting is done .float shoot_flags; /// Dont shoot const float TFL_SHOOT_NO = 64; /// Fire in vollys (partial implementation through .shot_volly) const float TFL_SHOOT_VOLLY = 2; /// Always do a full volly, even if target is lost or dead. (not implemented) const float TFL_SHOOT_VOLLYALWAYS = 4; /// Loop though all valid tarters, and hit them. const float TFL_SHOOT_HITALLVALID = 8; /// Fiering makes unit loose target (after volly is done, if in volly mode) const float TFL_SHOOT_CLEARTARGET = 16; ///Custom shooting; const float TFL_SHOOT_CUSTOM = 32; /// Information aboute the units capabilities .float turrcaps_flags; /// No kown capabilities const float TFL_TURRCAPS_NONE = 0; /// Capable of sniping const float TFL_TURRCAPS_SNIPER = 2; /// Capable of splasdamage const float TFL_TURRCAPS_RADIUSDMG = 4; /// Has one or more cannons with zero shot traveltime const float TFL_TURRCAPS_HITSCAN = 8; /// More then one (type of) gun const float TFL_TURRCAPS_MULTIGUN = 16; /// Carries at least one guided weapon const float TFL_TURRCAPS_GUIDED = 32; /// At least one gun fiers slow projectiles const float TFL_TURRCAPS_SLOWPROJ = 64; /// At least one gun fiers medium speed projectiles const float TFL_TURRCAPS_MEDPROJ = 128; /// At least one gun fiers fast projectiles const float TFL_TURRCAPS_FASTPROJ = 256; /// At least one gun capable of damaging players const float TFL_TURRCAPS_PLAYERKILL = 512; /// At least one gun that can shoot town missiles const float TFL_TURRCAPS_MISSILEKILL = 1024; /// Has support capabilities. powerplants and sutch. const float TFL_TURRCAPS_SUPPORT = 2048; /// Proveides at least one type of ammmo const float TFL_TURRCAPS_AMMOSOURCE = 4096; /// Can recive targets from external sources const float TFL_TURRCAPS_RECIVETARGETS = 8192; /// Capable of self-transport const float TFL_TURRCAPS_MOVE = 16384; /// Will roam arround even if not chasing anyting const float TFL_TURRCAPS_ROAM = 32768; const float TFL_TURRCAPS_ISTURRET = 65536; /// Ammo types needed and/or provided //.float ammo_flags; #define ammo_flags currentammo /// Has and needs no ammo const float TFL_AMMO_NONE = 64; /// Uses power const float TFL_AMMO_ENERGY = 2; /// Uses bullets const float TFL_AMMO_BULLETS = 4; /// Uses explosives const float TFL_AMMO_ROCKETS = 8; /// Regenerates ammo on its own const float TFL_AMMO_RECHARGE = 16; /// Can recive ammo from others const float TFL_AMMO_RECIVE = 32; /// How incomming damage is handeld .float damage_flags; /// Cant be hurt const float TFL_DMG_NO = 256; /// Can be damaged const float TFL_DMG_YES = 2; /// Can be damaged by teammates const float TFL_DMG_TAKEFROMTEAM = 4; /// Traget attackers const float TFL_DMG_RETALIATE = 8; /// Target attackers, even is on own team const float TFL_DMG_RETALIATEONTEAM = 16; /// Loses target when damaged const float TFL_DMG_TARGETLOSS = 32; /// Reciving damage trows off aim (pointless atm, aim gets recalculated to fast). not implemented. const float TFL_DMG_AIMSHAKE = 64; /// Reciving damage slaps the head arround const float TFL_DMG_HEADSHAKE = 128; /// Die and stay dead. const float TFL_DMG_DEATH_NORESPAWN = 256; // Spawnflags /// Spawn in teambased modes const float TFL_SPAWN_TEAM = 2; /// Spawn in FFA modes const float TFL_SPAWN_FFA = 4; /* * Fields used by turrets */ /// Turrets internal ai speed .float ticrate; /// Where to point the when no target .vector idle_aim; /// Top part of turret .entity tur_head; /// Start/respawn health .float tur_health; /// Defend this entity (or ratehr this entitys position) .entity tur_defend; /// and shoot from here. (can be non constant, think MLRS) .vector tur_shotorg; /// Aim at this spot .vector tur_aimpos; /// Predicted time the round will impact .float tur_impacttime; // Predicted place the round will impact //.vector tur_impactpoint; // unused /// What entity the aimtrace hit, if any. .entity tur_impactent; /// Distance to enemy .float tur_dist_enemy; /// Distance to aimspot .float tur_dist_aimpos; /// Distance impact<->aim .float tur_dist_impact_to_aimpos; /// Decresment counter form .shot_volly to 0. .float volly_counter; /* * Projectile/missile. its up to the individual turret implementation to ** deal the damage, blow upp the missile or whatever. */ /// Track then refireing is possible //.float attack_finished; = attack_finished_single /// Shoot this often .float shot_refire; /// Shots travel this fast, when appliable .float shot_speed; /// Inaccuracy .float shot_spread; /// Estimated (core) damage of projectiles. also reduce on ammo with this amount when fiering .float shot_dmg; /// If radius dmg, this is how big that radius is. .float shot_radius; /// Max force exserted by round impact .float shot_force; /// < 1 = shoot # times at target (if possible) .float shot_volly; /// Refire after a compleated volly. .float shot_volly_refire; /// Consider targets within this range .float target_range; /// Dont consider targets closer then .float target_range_min; /// Targets closer to this are prefered .float target_range_optimal; /* * The standard targetselection tries to select a target based on * range, angle offset, target type, "is old target" * Thise biases will allow score scaling to (dis)favor diffrent targets */ /// (dis)Favor best range this mutch .float target_select_rangebias; /// (dis)Favor targeting my old enemy this mutch .float target_select_samebias; /// (dis)Favor targeting the enemy closest to my guns current angle this mutch .float target_select_anglebias; /// (dis)Favor Missiles? (-1 to diable targeting compleatly) .float target_select_missilebias; /// (dis)Favot living players (-1 to diable targeting compleatly) .float target_select_playerbias; /// Field of view //.float target_select_fov; /// Last timestamp this turret aquierd a valid target .float target_select_time; /// Throttle re-validation of current target .float target_validate_time; /* * Aim refers to real aiming, not gun pos (thats done by track) */ /// Maximum offset between impact and aim spot to fire .float aim_firetolerance_dist; /// 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 .float aim_maxpitch; /// I cant rotate more then this .float aim_maxrot; // Ammo/power. keeping dmg and ammo on a one to one ratio is preferable (for rating) /// Staring & current ammo .float ammo; /// Regenerate this mutch ammo (per second) .float ammo_recharge; /// Max amount of ammo i can hold .float ammo_max; // Uncomment below to enable various debug output. //#define TURRET_DEBUG //#define TURRET_DEBUG_TARGETVALIDATE //#define TURRET_DEBUG_TARGETSELECT #ifdef TURRET_DEBUG .float tur_dbg_dmg_t_h; // Total dmg that hit something (can be more then tur_dbg_dmg_t_f since it should count radius dmg. .float tur_dbg_dmg_t_f; // Total damage spent .float tur_dbg_start; // When did i go online? .float tur_dbg_tmr1; // timer for random use .float tur_dbg_tmr2; // timer for random use .float tur_dbg_tmr3; // timer for random use .vector tur_dbg_rvec; // Random vector, mainly for coloruing stuff' #endif // System main's /// Main AI loop void turret_think(); /// Prefire checks and sutch void turret_fire(); // Callbacks /// implements the actual fiering .void() turret_firefunc; /// prefire checks go here. return 1 to go bang, 0 not to. .float() turret_firecheckfunc; /// Execure AFTER main AI loop .void() turret_postthink; /// Add a target .float(entity e_target,entity e_sender) turret_addtarget; .void() turret_diehook; .void() turret_respawnhook; /* * Target selection, preferably but not nessesarely * return a normalized result. */ /// Function to use for target evaluation. usualy turret_stdproc_targetscore_generic .float(entity _turret, entity _target) turret_score_target; /* * Target selection */ /// Generic, fairly smart, bias-aware target selection. float turret_stdproc_targetscore_generic(entity _turret, entity _target); /// Experimental supportunits targetselector float turret_stdproc_targetscore_support(entity _turret,entity _target); /* * Aim functions */ /// Generic aimer guided by self.aim_flags vector turret_stdproc_aim_generic(); /* * Turret turning & pitch */ /// Tries to line up the turret head with the aimpos void turret_stdproc_track(); /// Generic damage handeling. blows up the turret when health <= 0 void turret_stdproc_damage (entity inflictor, entity attacker, float damage, float deathtype, vector hitloc, vector vforce); /// Spawns a explotion, does some damage & trows bits arround. void turret_stdproc_die(); /// reassembles the turret. void turret_stdproc_respawn(); /// Evaluate target validity float turret_validate_target(entity e_turret,entity e_target,float validate_flags); /// Turret Head Angle Diff Vector. updated by a sucsessfull call to turret_validate_target vector tvt_thadv; /// Turret Angle Diff Vector. updated by a sucsessfull call to turret_validate_target vector tvt_tadv; /// Turret Head Angle Diff Float. updated by a sucsessfull call to turret_validate_target float tvt_thadf; /// Turret Angle Diff Float. updated by a sucsessfull call to turret_validate_target float tvt_tadf; /// Distance. updated by a sucsessfull call to turret_validate_target float tvt_dist; /// updates aim org, shot org, shot dir and enemy org for selected turret void turret_do_updates(entity e_turret); .vector tur_shotdir_updated; void turrets_precash(); #endif // SVQC // common .int turret_type; const int TID_COMMON = 1; const int TID_EWHEEL = 2; const int TID_FLAC = 3; const int TID_FUSION = 4; const int TID_HELLION = 5; const int TID_HK = 6; const int TID_MACHINEGUN = 7; const int TID_MLRS = 8; const int TID_PHASER = 9; const int TID_PLASMA = 10; const int TID_PLASMA_DUAL = 11; const int TID_TESLA = 12; const int TID_WALKER = 13; const int TID_LAST = 13; const int TNSF_UPDATE = 2; const int TNSF_STATUS = 4; const int TNSF_SETUP = 8; const int TNSF_ANG = 16; const int TNSF_AVEL = 32; const int TNSF_MOVE = 64; .float anim_start_time; const int TNSF_ANIM = 128; const int TNSF_FULL_UPDATE = 16777215; #endif // TTURRETS_ENABLED