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