1 // Comment out below to skip turrets
2 #define TTURRETS_ENABLED
4 #ifdef TTURRETS_ENABLED
6 #message "with tZork turrets"
10 vector real_origin(entity ent);
12 /// Map time control over pain inflicted
13 .float turret_scale_damage;
14 /// Map time control targetting range
15 .float turret_scale_range;
16 /// Map time control refire
17 .float turret_scale_refire;
18 /// Map time control ammo held and recharged
19 .float turret_scale_ammo;
20 /// Map time control aim speed
21 .float turret_scale_aim;
22 /// Map time control health
23 .float turret_scale_health;
24 /// Map time control respawn time
25 .float turret_scale_respawn;
27 /// Used for cvar reloading
28 .string cvar_basename;
31 /// Spawn a pillar model under the turret to make it look ok on uneven ground surfaces
32 #define TSF_TERRAINBASE 2
33 /// Disable builtin ammo regeneration
34 #define TSF_NO_AMMO_REGEN 4
35 /// Dont break path to chase enemys. will still fire at them if possible.
36 #define TSF_NO_PATHBREAK 8
38 #define TSL_NO_RESPAWN 16
40 /// target selection flags
41 .float target_select_flags;
42 /// target validatoin flags
43 .float target_validate_flags;
44 /// Dont select a target on its own.
45 #define TFL_TARGETSELECT_NO 2
46 /// Need line of sight
47 #define TFL_TARGETSELECT_LOS 4
48 /// Players are valid targets
49 #define TFL_TARGETSELECT_PLAYERS 8
50 /// Missiles are valid targets
51 #define TFL_TARGETSELECT_MISSILES 16
52 /// Responds to turret_trigger_target events
53 #define TFL_TARGETSELECT_TRIGGERTARGET 32
54 /// Angular limitations of turret head limits target selection
55 #define TFL_TARGETSELECT_ANGLELIMITS 64
56 /// Range limits apply in targetselection
57 #define TFL_TARGETSELECT_RANGELIMTS 128
58 /// DOnt select targets with a .team matching its own
59 #define TFL_TARGETSELECT_TEAMCHECK 256
60 /// Cant select targets on its own. needs to be triggerd or slaved.
61 #define TFL_TARGETSELECT_NOBUILTIN 512
62 /// TFL_TARGETSELECT_TEAMCHECK is inverted (selects only mebers of own .team)
63 #define TFL_TARGETSELECT_OWNTEAM 1024
64 /// Turrets aren't valid targets
65 #define TFL_TARGETSELECT_NOTURRETS 2048
67 #define TFL_TARGETSELECT_FOV 4096
69 #define TFL_TARGETSELECT_MISSILESONLY 8192
75 /// Go for ground, not direct hit
76 #define TFL_AIM_GROUND 2
77 /// Go for ground, not direct hit, but only if target is on ground.
78 #define TFL_AIM_GROUND2 4
79 /// Use balistic aim. FIXME: not implemented
80 #define TFL_AIM_BALISTIC 8
81 /// Try to predict target movement (does not account for gravity)
82 #define TFL_AIM_LEAD 16
83 /// Compensate for shot traveltime when lead
84 #define TFL_AIM_SHOTTIMECOMPENSATE 32
85 /// Aim slightly in front of target
86 #define TFL_AIM_INFRONT 64
87 /// Aim slightly behind target
88 #define TFL_AIM_BEHIND 128
89 /// blend real and predicted z positions. (fake bounce prediction)
90 #define TFL_AIM_ZEASE 256
91 /// Try to do real prediction of targets z pos at impact.
92 #define TFL_AIM_ZPREDICT 512
93 /// Simply aim at target's current location
94 #define TFL_AIM_SIMPLE 1024
96 /// track (turn and pitch head) flags
99 #define TFL_TRACK_NO 2
101 #define TFL_TRACK_PITCH 4
103 #define TFL_TRACK_ROT 8
105 /// How tracking is preformed
107 /// Hard angle increments. Ugly for fast turning, best accuracy.
108 #define TFL_TRACKTYPE_STEPMOTOR 1
109 /// Smoth absolute movement. Looks ok, fair accuracy.
110 #define TFL_TRACKTYPE_FLUIDPRECISE 2
111 /// Simulated inertia. "Wobbly mode" Looks kool, can mean really bad accuracy depending on how the feilds below are set
112 #define TFL_TRACKTYPE_FLUIDINERTIA 3
113 /// TFL_TRACKTYPE_FLUIDINERTIA: pitch multiplier
114 .float track_accel_pitch;
115 /// TFL_TRACKTYPE_FLUIDINERTIA: rotation multiplier
116 .float track_accel_rot;
117 /// TFL_TRACKTYPE_FLUIDINERTIA: Blendrate with old rotation (inertia simulation) 1 = only old, 0 = only new
118 .float track_blendrate;
120 /// How prefire check is preformed
121 .float firecheck_flags;
122 /// Dont kill the world
123 #define TFL_FIRECHECK_WORLD 2
124 /// Dont kill the dead
125 #define TFL_FIRECHECK_DEAD 4
126 /// Range limits apply
127 #define TFL_FIRECHECK_DISTANCES 8
128 /// Line Of Sight needs to be clear
129 #define TFL_FIRECHECK_LOS 16
130 /// Consider distance inpactpoint<->aimspot
131 #define TFL_FIRECHECK_AIMDIST 32
132 /// Consider enemy origin<->impactpoint
133 #define TFL_FIRECHECK_REALDIST 64
134 /// Consider angular diff head<->aimspot
135 #define TFL_FIRECHECK_ANGLEDIST 128
136 /// (re)consider target.team<->self.team
137 #define TFL_FIRECHECK_TEAMCECK 256
138 /// Try to avoid friendly fire
139 #define TFL_FIRECHECK_AFF 512
140 /// Own .ammo needs to be >= then own .shot_dmg
141 #define TFL_FIRECHECK_OWM_AMMO 1024
142 /// Others ammo need to be < others .ammo_max
143 #define TFL_FIRECHECK_OTHER_AMMO 2048
144 /// Check own .attack_finished_single vs time
145 #define TFL_FIRECHECK_REFIRE 4096
146 /// Move the acctual target to aimspot before tracing impact (and back after)
147 #define TFL_FIRECHECK_VERIFIED 8192
148 /// Dont do any chekcs
149 #define TFL_FIRECHECK_NO 16384
151 /// How shooting is done
154 #define TFL_SHOOT_NO 64
155 /// Fire in vollys (partial implementation through .shot_volly)
156 #define TFL_SHOOT_VOLLY 2
157 /// Always do a full volly, even if target is lost or dead. (not implemented)
158 #define TFL_SHOOT_VOLLYALWAYS 4
159 /// Loop though all valid tarters, and hit them.
160 #define TFL_SHOOT_HITALLVALID 8
161 /// Fiering makes unit loose target (after volly is done, if in volly mode)
162 #define TFL_SHOOT_CLEARTARGET 16
164 #define TFL_SHOOT_CUSTOM 32
166 /// Information aboute the units capabilities
167 .float turrcaps_flags;
168 /// No kown capabilities
169 #define TFL_TURRCAPS_NONE 0
170 /// Capable of sniping
171 #define TFL_TURRCAPS_SNIPER 2
172 /// Capable of splasdamage
173 #define TFL_TURRCAPS_RADIUSDMG 4
174 /// Has one or more cannons with zero shot traveltime
175 #define TFL_TURRCAPS_HITSCAN 8
176 /// More then one (type of) gun
177 #define TFL_TURRCAPS_MULTIGUN 16
178 /// Carries at least one guided weapon
179 #define TFL_TURRCAPS_GUIDED 32
180 /// At least one gun fiers slow projectiles
181 #define TFL_TURRCAPS_SLOWPROJ 64
182 /// At least one gun fiers medium speed projectiles
183 #define TFL_TURRCAPS_MEDPROJ 128
184 /// At least one gun fiers fast projectiles
185 #define TFL_TURRCAPS_FASTPROJ 256
186 /// At least one gun capable of damaging players
187 #define TFL_TURRCAPS_PLAYERKILL 512
188 /// At least one gun that can shoot town missiles
189 #define TFL_TURRCAPS_MISSILEKILL 1024
190 /// Has support capabilities. powerplants and sutch.
191 #define TFL_TURRCAPS_SUPPORT 2048
192 /// Proveides at least one type of ammmo
193 #define TFL_TURRCAPS_AMMOSOURCE 4096
194 /// Can recive targets from external sources
195 #define TFL_TURRCAPS_RECIVETARGETS 8192
196 /// Capable of self-transport
197 #define TFL_TURRCAPS_MOVE 16384
198 /// Will roam arround even if not chasing anyting
199 #define TFL_TURRCAPS_ROAM 32768
200 #define TFL_TURRCAPS_ISTURRET 65536
202 /// Ammo types needed and/or provided
204 /// Has and needs no ammo
205 #define TFL_AMMO_NONE 64
207 #define TFL_AMMO_ENERGY 2
209 #define TFL_AMMO_BULLETS 4
211 #define TFL_AMMO_ROCKETS 8
212 /// Regenerates ammo on its own
213 #define TFL_AMMO_RECHARGE 16
214 /// Can recive ammo from others
215 #define TFL_AMMO_RECIVE 32
217 /// How incomming damage is handeld
220 #define TFL_DMG_NO 256
222 #define TFL_DMG_YES 2
223 /// Can be damaged by teammates
224 #define TFL_DMG_TAKEFROMTEAM 4
226 #define TFL_DMG_RETALIATE 8
227 /// Target attackers, even is on own team
228 #define TFL_DMG_RETALIATEONTEAM 16
229 /// Loses target when damaged
230 #define TFL_DMG_TARGETLOSS 32
231 /// Reciving damage trows off aim (pointless atm, aim gets recalculated to fast). not implemented.
232 #define TFL_DMG_AIMSHAKE 64
233 /// Reciving damage slaps the head arround
234 #define TFL_DMG_HEADSHAKE 128
235 /// Die and stay dead.
236 #define TFL_DMG_DEATH_NORESPAWN 256
237 /// Supress std turret gibs on death
238 #define TFL_DMG_DEATH_NOGIBS 512
241 /// Spawn in teambased modes
242 #define TFL_SPAWN_TEAM 2
243 /// Spawn in FFA modes
244 #define TFL_SPAWN_FFA 4
248 * Fields used by turrets
250 /// Turrets internal ai speed
253 /// Where to point the when no target
256 /// Top part of turret
259 /// Start/respawn health
262 /// Defend this entity (or ratehr this entitys position)
268 // Aim from this point,
269 //.vector tur_aimorg;
271 /// and shoot from here. (can be non constant, think MLRS)
277 /// Predicted time the round will impact
278 .float tur_impacttime;
280 // Predicted place the round will impact
281 //.vector tur_impactpoint; // unused
283 /// What entity the aimtrace hit, if any.
284 .entity tur_impactent;
286 /// Distance to enemy
287 .float tur_dist_enemy;
289 /// Distance to aimspot
290 .float tur_dist_aimpos;
292 /// Distance impact<->aim
293 .float tur_dist_impact_to_aimpos;
295 /// Decresment counter form .shot_volly to 0.
296 .float volly_counter;
299 * Projectile/missile. its up to the individual turret implementation to
300 ** deal the damage, blow upp the missile or whatever.
302 /// Track then refireing is possible
303 //.float attack_finished; = attack_finished_single
306 /// Shots travel this fast, when appliable
310 /// Estimated (core) damage of projectiles. also reduce on ammo with this amount when fiering
312 /// If radius dmg, this is how big that radius is.
314 /// Max force exserted by round impact
316 /// < 1 = shoot # times at target (if possible)
318 /// Refire after a compleated volly.
319 .float shot_volly_refire;
321 /// Consider targets within this range
323 /// Dont consider targets closer then
324 .float target_range_min;
325 // Engage fire routine on targets within
326 //.float target_range_fire; // no practical use aymore, work with target_range insted.
327 /// Targets closer to this are prefered
328 .float target_range_optimal;
331 * The standard targetselection tries to select a target based on
332 * range, angle offset, target type, "is old target"
333 * Thise biases will allow score scaling to (dis)favor diffrent targets
335 /// (dis)Favor best range this mutch
336 .float target_select_rangebias;
337 /// (dis)Favor targeting my old enemy this mutch
338 .float target_select_samebias;
339 /// (dis)Favor targeting the enemy closest to my guns current angle this mutch
340 .float target_select_anglebias;
341 /// (dis)Favor Missiles? (-1 to diable targeting compleatly)
342 .float target_select_missilebias;
343 /// (dis)Favot living players (-1 to diable targeting compleatly)
344 .float target_select_playerbias;
346 //.float target_select_fov;
347 /// Last thimestamp this surret aquierd a valid target
348 .float target_select_time;
351 * Aim refers to real aiming, not gun pos (thats done by track)
353 /// Maximum offset between impact and aim spot to fire
354 .float aim_firetolerance_dist;
355 // Maximum angular offset between head and aimspot to fire
356 //.float aim_firetolerance_angle;
357 /// How fast can i rotate/pitch (per second in stepmotor mode, base force in smooth modes)
359 /// cant aim higher/lower then this
361 /// I cant rotate more then this
364 // Ammo/power. keeping dmg and ammo on a one to one ratio is preferable (for rating)
365 /// Staring & current ammo
367 /// Regenerate this mutch ammo (per second)
368 .float ammo_recharge;
369 /// Max amount of ammo i can hold
373 // Uncomment below to enable various debug output.
374 //#define TURRET_DEBUG
375 //#define TURRET_DEBUG_TARGETVALIDATE
376 //#define TURRET_DEBUG_TARGETSELECT
379 .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.
380 .float tur_dbg_dmg_t_f; // Total damage spent
381 .float tur_dbg_start; // When did i go online?
382 .float tur_dbg_tmr1; // timer for random use
383 .float tur_dbg_tmr2; // timer for random use
384 .float tur_dbg_tmr3; // timer for random use
385 .vector tur_dbg_rvec; // Random vector, mainly for coloruing stuff'
391 /// Prefire checks and sutch
395 /// implements the actual fiering
396 .void() turret_firefunc;
397 /// prefire checks go here. return 1 to go bang, 0 not to.
398 .float() turret_firecheckfunc;
399 // Execure BEFORE main ai loop. return 0 to cancel any following proccessing.
400 //.float() turret_prethink;
401 /// Execure AFTER main AI loop
402 .void() turret_postthink;
405 .float(entity e_target,entity e_sender) turret_addtarget;
407 //.float call_diehook;
408 //.float call_respwnhook;
409 .void() turret_diehook;
410 .void() turret_respawnhook;
416 #define TEH_RESPAWN 16
419 #define TEH_SELECT 128
420 .float(float event_id) turret_eventhook;
424 * Some turrets need other aimsystems then other.
425 * This should return the place to aim at, not acctualy turn or
428 * use turret_stdproc_aim* or Make your own.
429 * Make sure you update tur_enemy_dist and tur_enemy_adist
430 * with the apropriate info, if you do.
434 // function used to aim, usualy turret_stdproc_aim_generic
435 //.vector() turret_aim;
438 * This is where the acctual turret turning should take place
439 * Use turret_stdproc_track or make your own.
442 // Function used to turn and pitch the .tur_head usualy turret_stdproc_track
443 //.void() turret_track;
446 * Target selection, preferably but not nessesarely
447 * return a normalized result.
449 /// Function to use for target evaluation. usualy turret_stdproc_targetscore_generic
450 .float(entity e_turret, entity e_target) turret_score_target;
453 * Damage, death and respawn.
455 //void turret_gibs_precash();
456 // generalized so save mem (on fields)
457 // Function to handle incomming damage. usualy turret_stdproc_damage
458 //.void(entity inflictor, entity attacker, float damage, float deathtype, vector hitloc, vector vforce) turret_damagefunc;
459 // Function to handle the event of death. usualy turret_stdproc_die
460 //.void() turret_diefunc;
461 // Function that handles rebirth. usualy turret_stdproc_respawn
462 //.void() turret_spawnfunc;
465 * Stuff to plug into requierd but unused callbacks.
468 //float turret_stdproc_true();
470 //float turret_stdproc_false();
471 /// Always return nothing at all
472 //void turret_stdproc_nothing();
477 // noting uses the following atm.
478 // "closeer is beter" selection
479 //float turret_stdproc_targetscore_close(entity e_turret, entity e_target);
480 // "further is beter" selection
481 //float turret_stdproc_targetscore_far(entity e_turret, entity e_target);
482 // only target_range_optimal
483 //float turret_stdproc_targetscore_optimal(entity e_turret, entity e_target);
485 //float turret_stdproc_targetscore_defend(entity e_turret, entity e_target);
486 /// Generic fairly smart bias-aware target selection.
487 float turret_stdproc_targetscore_generic(entity e_turret, entity e_target);
488 /// Experimental supportunits targetselector
489 float turret_stdproc_targetscore_support(entity e_turret,entity e_target);
494 /// Generic aimer guided by self.aim_flags
495 vector turret_stdproc_aim_generic()
496 // Straight line, current location
497 //vector turret_stdproc_aim_simple()
500 * Turret turning & pitch
502 /// Tries to line up the turret head with the aimpos
503 void turret_stdproc_track();
505 /// Generic damage handeling. blows up the turret when health <= 0
506 void turret_stdproc_damage (entity inflictor, entity attacker, float damage, float deathtype, vector hitloc, vector vforce);
507 /// Spawns a explotion, does some damage & trows bits arround.
508 void turret_stdproc_die();
509 /// reassembles the turret.
510 void turret_stdproc_respawn();
512 /// Evaluate target validity
513 float turret_validate_target(entity e_turret,entity e_target,float validate_flags);
514 /// Turret Head Angle Diff Vector. updated by a sucsessfull call to turret_validate_target
516 /// Turret Angle Diff Vector. updated by a sucsessfull call to turret_validate_target
518 /// Turret Head Angle Diff Float. updated by a sucsessfull call to turret_validate_target
520 /// Turret Angle Diff Float. updated by a sucsessfull call to turret_validate_target
522 /// Distance. updated by a sucsessfull call to turret_validate_target
525 /// updates aim org, shot org, shot dir and enemy org for selected turret
526 void turret_do_updates(entity e_turret);
527 //.vector tur_aimorg_updated; // creates to much aim issues. using tur_shotorg_updated insted.
528 //.vector tur_shotorg_updated; // DP8815 fixes gettaginfo, no longer needed.
529 .vector tur_shotdir_updated;
531 void turrets_precash();
535 #endif // TTURRETS_ENABLED