r4856 - in trunk/data/qcsrc/server: . tturrets/include tturrets/system tturrets/units
DONOTREPLY at icculus.org
DONOTREPLY at icculus.org
Fri Oct 24 03:54:21 EDT 2008
Author: tzork
Date: 2008-10-24 03:54:17 -0400 (Fri, 24 Oct 2008)
New Revision: 4856
Added:
trunk/data/qcsrc/server/tturrets/include/turrets.qh
trunk/data/qcsrc/server/tturrets/include/turrets_early.qh
trunk/data/qcsrc/server/tturrets/system/system_aimprocs.qc
trunk/data/qcsrc/server/tturrets/system/system_damage.qc
trunk/data/qcsrc/server/tturrets/system/system_main.qc
trunk/data/qcsrc/server/tturrets/system/system_misc.qc
trunk/data/qcsrc/server/tturrets/system/system_scoreprocs.qc
trunk/data/qcsrc/server/tturrets/units/unit_checkpoint.qc
trunk/data/qcsrc/server/tturrets/units/unit_common.qc
trunk/data/qcsrc/server/tturrets/units/unit_flac.qc
trunk/data/qcsrc/server/tturrets/units/unit_fusionreactor.qc
trunk/data/qcsrc/server/tturrets/units/unit_hellion.qc
trunk/data/qcsrc/server/tturrets/units/unit_hk.qc
trunk/data/qcsrc/server/tturrets/units/unit_machinegun.qc
trunk/data/qcsrc/server/tturrets/units/unit_mlrs.qc
trunk/data/qcsrc/server/tturrets/units/unit_phaser.qc
trunk/data/qcsrc/server/tturrets/units/unit_plasma.qc
trunk/data/qcsrc/server/tturrets/units/unit_targettrigger.qc
trunk/data/qcsrc/server/tturrets/units/unit_tessla.qc
trunk/data/qcsrc/server/tturrets/units/unit_walker.qc
Removed:
trunk/data/qcsrc/server/tturrets/include/turret_tturrets.qh
trunk/data/qcsrc/server/tturrets/include/turret_tturrets_early.qh
trunk/data/qcsrc/server/tturrets/system/turret_system_aimprocs.qc
trunk/data/qcsrc/server/tturrets/system/turret_system_damage.qc
trunk/data/qcsrc/server/tturrets/system/turret_system_main.qc
trunk/data/qcsrc/server/tturrets/system/turret_system_misc.qc
trunk/data/qcsrc/server/tturrets/system/turret_system_scoreprocs.qc
trunk/data/qcsrc/server/tturrets/units/turret_unit_common.qc
trunk/data/qcsrc/server/tturrets/units/turret_unit_flac.qc
trunk/data/qcsrc/server/tturrets/units/turret_unit_fusionreactor.qc
trunk/data/qcsrc/server/tturrets/units/turret_unit_hellion.qc
trunk/data/qcsrc/server/tturrets/units/turret_unit_hk.qc
trunk/data/qcsrc/server/tturrets/units/turret_unit_machinegun.qc
trunk/data/qcsrc/server/tturrets/units/turret_unit_mlrs.qc
trunk/data/qcsrc/server/tturrets/units/turret_unit_phaser.qc
trunk/data/qcsrc/server/tturrets/units/turret_unit_plasma.qc
trunk/data/qcsrc/server/tturrets/units/turret_unit_targettrigger.qc
trunk/data/qcsrc/server/tturrets/units/turret_unit_tessla.qc
trunk/data/qcsrc/server/tturrets/units/turret_unit_walker.qc
Modified:
trunk/data/qcsrc/server/progs.src
Log:
renamed src files. to much turrets/turret_something/tturret... ;)
Modified: trunk/data/qcsrc/server/progs.src
===================================================================
--- trunk/data/qcsrc/server/progs.src 2008-10-24 07:48:04 UTC (rev 4855)
+++ trunk/data/qcsrc/server/progs.src 2008-10-24 07:54:17 UTC (rev 4856)
@@ -10,7 +10,7 @@
../common/util.qh
//// tZork Turrets ////
-tturrets/include/turret_tturrets_early.qh
+tturrets/include/turrets_early.qh
campaign.qh
../common/campaign_common.qh
@@ -136,7 +136,7 @@
//// tZork Turrets ////
-tturrets/include/turret_tturrets.qh
+tturrets/include/turrets.qh
scores.qc
Deleted: trunk/data/qcsrc/server/tturrets/include/turret_tturrets.qh
===================================================================
--- trunk/data/qcsrc/server/tturrets/include/turret_tturrets.qh 2008-10-24 07:48:04 UTC (rev 4855)
+++ trunk/data/qcsrc/server/tturrets/include/turret_tturrets.qh 2008-10-24 07:54:17 UTC (rev 4856)
@@ -1,31 +0,0 @@
-#ifdef TTURRETS_ENABLED
-
-// Include section.
-#include "../system/turret_system_misc.qc" /// Assorted junk & jewls
-#include "../system/turret_system_main.qc" /// And routines
-#include "../system/turret_system_aimprocs.qc" /// Aiming realted stuff
-#include "../system/turret_system_scoreprocs.qc" /// Target calssification
-#include "../system/turret_system_damage.qc" /// Outch, they are hurting me! what should i do?
-
-#include "../units/turret_unit_common.qc" /// Some "make life easyer" funcs.
-
-// Non combat units
-#include "../units/turret_unit_fusionreactor.qc" /// Supply unites that need it with power
-// #include "../units/turret_unit_targetcomputer.qc" /// Optimized target selection for multiple units
-#include "../units/turret_unit_targettrigger.qc" /// Hit me!
-
-// Combat units
-#include "../units/turret_unit_plasma.qc" /// Basic energy cannon
-#include "../units/turret_unit_mlrs.qc" /// Basic multibay RL
-#include "../units/turret_unit_hellion.qc" /// Seeking missiles MLRS
-#include "../units/turret_unit_flac.qc" /// anti missile turret
-#include "../units/turret_unit_phaser.qc" /// ZzzapT
-//#include "../units/turret_unit_gauss.qc" /// Railgun
-#include "../units/turret_unit_hk.qc" /// Hunter killers
-#include "../units/turret_unit_machinegun.qc" /// whacka
-//#include "../units/turret_unit_minigun.qc" /// whacka whacka
-#include "../units/turret_unit_tessla.qc" /// Chain lightning capabale turret
-#include "../units/turret_unit_walker.qc"
-//#include "../units/turret_unit_howitzer.qc"
-
-#endif // TTURRETS_ENABLED
Deleted: trunk/data/qcsrc/server/tturrets/include/turret_tturrets_early.qh
===================================================================
--- trunk/data/qcsrc/server/tturrets/include/turret_tturrets_early.qh 2008-10-24 07:48:04 UTC (rev 4855)
+++ trunk/data/qcsrc/server/tturrets/include/turret_tturrets_early.qh 2008-10-24 07:54:17 UTC (rev 4856)
@@ -1,472 +0,0 @@
-// Comment out below to skip turrets
-#define TTURRETS_ENABLED
-
-#ifdef TTURRETS_ENABLED
-
-#message "with tZork turrets rc2"
-
-vector real_origin(entity ent);
-
-/// target selection flags
-.float target_select_flags;
-.float target_validate_flags;
-/// Dont select a target on its own.
-#define TFL_TARGETSELECT_NO 1024
-/// Need line of sight
-#define TFL_TARGETSELECT_LOS 2
-/// Players are valid targets
-#define TFL_TARGETSELECT_PLAYERS 4
-/// Missiles are valid targets
-#define TFL_TARGETSELECT_MISSILES 8
-/// Responds to turret_trigger_target events
-#define TFL_TARGETSELECT_TRIGGERTARGET 16
-/// Angular limitations of turret head limits target selection
-#define TFL_TARGETSELECT_ANGLELIMITS 32
-/// Range limits apply in targetselection
-#define TFL_TARGETSELECT_RANGELIMTS 64
-/// DOnt select targets with a .team matching its own
-#define TFL_TARGETSELECT_TEAMCHECK 4096
-/// Cant select targets on its own. needs to be triggerd or slaved.
-#define TFL_TARGETSELECT_NOBUILTIN 256
-/// TFL_TARGETSELECT_TEAMCHECK is inverted (selects only mebers of own .team)
-#define TFL_TARGETSELECT_OWNTEAM 2048
-/// Turrets aren't valid targets
-#define TFL_TARGETSELECT_NOTURRETS 128
-
-/// aim flags
-.float aim_flags;
-/// Dont aim.
-#define TFL_AIM_NO 1
-/// Go for ground, not direct hit
-#define TFL_AIM_GROUND 2
-/// Go for ground, not direct hit if target is on ground too
-#define TFL_AIM_GROUND2 4
-/// Use balistic aim (not implemented)
-#define TFL_AIM_BALISTIC 8
-/// Try to predict target movement (does not account for gravity)
-#define TFL_AIM_LEAD 16
-/// Compensate for shot traveltime when lead
-#define TFL_AIM_SHOTTIMECOMPENSATE 32
-/// Aim slightly in front of target
-#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
-/// Try to do real prediction of targets z pos at impact.
-//#define TFL_AIM_ZPREDICT 256
-/// Just poitn at target's current location
-#define TFL_AIM_SIMPLE 512
-
-/// track (turn and pitch head) flags
-.float track_flags;
-/// Dont move head
-#define TFL_TRACK_NO 2
-/// Pitch the head
-#define TFL_TRACK_PITCH 4
-/// Rotate the head
-#define TFL_TRACK_ROT 8
-
-/// How tracking is preformed
-.float track_type;
-/// Hard angle increments. Ugly for fast turning, best accuracy.
-#define TFL_TRACKTYPE_STEPMOTOR 1
-/// Smoth absolute movement. Looks ok, fair accuracy.
-#define TFL_TRACKTYPE_FLUIDPRECISE 2
-/// Simulated inertia. "Wobbly mode" Looks kool, can mean terrible accuracy depending on how the feilds below are set
-#define 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 do any chekcs
-#define TFL_FIRECHECK_NO 8192
-/// Dont kill the world
-#define TFL_FIRECHECK_WORLD 2
-/// Dont kill the dead
-#define TFL_FIRECHECK_DEAD 4
-/// Range limits apply
-#define TFL_FIRECHECK_DISTANCES 8
-/// Line Of Sight needs to be clear
-#define TFL_FIRECHECK_LOS 16
-/// Consider distance inpactpoint<->aimspot
-#define TFL_FIRECHECK_AIMDIST 32
-/// Consider enemy origin<->impactpoint
-#define TFL_FIRECHECK_REALDIST 64
-/// Consider angular diff head<->aimspot
-#define TFL_FIRECHECK_ANGLEDIST 128
-/// (re)consider target.team<->self.team
-#define TFL_FIRECHECK_TEAMCECK 256
-/// Try to avoid friendly fire
-#define TFL_FIRECHECK_AFF 512
-/// Own .ammo needs to be >= then own .shot_dmg
-#define TFL_FIRECHECK_OWM_AMMO 1024
-/// Others ammo need to be < others .ammo_max
-#define TFL_FIRECHECK_OTHER_AMMO 2048
-/// Check own .attack_finished_single vs time
-#define TFL_FIRECHECK_REFIRE 4096
-
-/// How shooting is done
-.float shoot_flags;
-/// Dont shoot
-#define TFL_SHOOT_NO 64
-/// Fire in vollys (partial implementation through .shot_volly)
-#define TFL_SHOOT_VOLLY 2
-/// Always do a full volly, even if target is lost or dead. (not implemented)
-#define TFL_SHOOT_VOLLYALWAYS 4
-/// Loop though all valid tarters, and hit them.
-#define TFL_SHOOT_HITALLVALID 8
-/// Fiering makes unit loose target (after volly is done, if in volly mode)
-#define TFL_SHOOT_CLEARTARGET 16
-///Custom shooting;
-#define TFL_SHOOT_CUSTOM 32
-
-/// Information aboute the units capabilities
-.float turrcaps_flags;
-/// No kown capabilities
-#define TFL_TURRCAPS_NONE 0
-/// Capable of sniping
-#define TFL_TURRCAPS_SNIPER 2
-/// Capable of splasdamage
-#define TFL_TURRCAPS_RADIUSDMG 4
-/// Has one or more cannons with zero shot traveltime
-#define TFL_TURRCAPS_HITSCAN 8
-/// More then one (type of) gun
-#define TFL_TURRCAPS_MULTIGUN 16
-/// Carries at least one guided weapon
-#define TFL_TURRCAPS_GUIDED 32
-/// At least one gun fiers slow projectiles
-#define TFL_TURRCAPS_SLOWPROJ 64
-/// At least one gun fiers medium speed projectiles
-#define TFL_TURRCAPS_MEDPROJ 128
-/// At least one gun fiers fast projectiles
-#define TFL_TURRCAPS_FASTPROJ 256
-/// At least one gun capable of damaging players
-#define TFL_TURRCAPS_PLAYERKILL 512
-/// At least one gun that can shoot town missiles
-#define TFL_TURRCAPS_MISSILEKILL 1024
-/// Has support capabilities. powerplants and sutch.
-#define TFL_TURRCAPS_SUPPORT 2048
-/// Proveides at least one type of ammmo
-#define TFL_TURRCAPS_AMMOSOURCE 4096
-/// Can recive targets from external sources
-#define TFL_TURRCAPS_RECIVETARGETS 8192
-/// Capable of self-transport
-#define TFL_TURRCAPS_MOVE 16384
-/// Will roam arround even if not chasing anyting
-#define TFL_TURRCAPS_ROAM 32768
-#define TFL_TURRCAPS_LINKED 65536
-
-/// Ammo types needed and/or provided
-.float ammo_flags;
-/// Has and needs no ammo
-#define TFL_AMMO_NONE 64
-/// Uses power
-#define TFL_AMMO_ENERGY 2
-/// Uses bullets
-#define TFL_AMMO_BULLETS 4
-/// Uses explosives
-#define TFL_AMMO_ROCKETS 8
-/// Regenerates ammo on its own
-#define TFL_AMMO_RECHARGE 16
-/// Can recive ammo from others
-#define TFL_AMMO_RECIVE 32
-
-/// How incomming damage is handeld
-.float damage_flags;
-/// Cant be hurt
-#define TFL_DMG_NO 256
-/// Can be damaged
-#define TFL_DMG_YES 2
-/// Can be damaged by teammates
-#define TFL_DMG_TAKEFROMTEAM 4
-/// Traget attackers
-#define TFL_DMG_RETALIATE 8
-/// Target attackers, even is on own team
-#define TFL_DMG_RETALIATEONTEAM 16
-/// Loses target when damaged
-#define TFL_DMG_TARGETLOSS 32
-/// Reciving damage trows off aim
-#define TFL_DMG_AIMSHAKE 64
-/// Reciving damage slaps the head arround
-#define TFL_DMG_HEADSHAKE 128
-/// Die and stay dead.
-#define TFL_DMG_DEATH_NORESPAWN 256
-
-// Spawnflags
-/// Spawn in teambased modes
-#define TFL_SPAWN_TEAM 2
-/// Spawn in FFA modes
-#define TFL_SPAWN_FFA 4
-/// Respawn after death
-#define TFL_SPAWN_RESPAWN 8
-
-/*
-* Fields commnly used by turrets
-*/
-/// Turrets internal ai speed
-.float ticrate;
-/// Where to point the head 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;
-/// on/off toggle.
-.float tur_active;
-/// Aim from this point,
-.vector tur_aimorg;
-/// and shoot from here. (could 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;
-/// What entity the aimtrace hit, if any.
-.entity tur_impactent;
-/// Distance to enemy
-.float tur_dist_enemy;
-/// Distance impact<->aim
-.float tur_dist_toaimpos;
-/// 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 or borken volly.
-.float shot_volly_refire;
-
-/// Consider targets within this range
-.float target_range;
-/// Dont consider targets closer then
-.float target_range_min;
-/// Engage fire routine on targets within
-.float target_range_fire;
-/// 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;
-
-/*
-* 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;
-/// 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
-.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 BEFORE main ai loop. return 0 to cancel any following proccessing.
-//.float() turret_prethink;
-/// Execure AFTER main AI loop UNLESS turret_prethink returnd 0
-.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;
-
-/*
-#define TEH_THINK 2
-#define TEH_DAMAGE 4
-#define TEH_DIE 8
-#define TEH_RESPAWN 16
-#define TEH_TRACK 32
-#define TEH_AIM 64
-#define TEH_SELECT 128
-.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
-* return a normalized result.
-*/
-/// 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
-*/
-/// "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.
-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()
-
-/*
-* 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_aimorg_updated;
-.vector tur_shotorg_updated;
-.vector tur_shotdir_updated;
-
-void turrets_precash();
-#endif // TTURRETS_ENABLED
Copied: trunk/data/qcsrc/server/tturrets/include/turrets.qh (from rev 4854, trunk/data/qcsrc/server/tturrets/include/turret_tturrets.qh)
===================================================================
--- trunk/data/qcsrc/server/tturrets/include/turrets.qh (rev 0)
+++ trunk/data/qcsrc/server/tturrets/include/turrets.qh 2008-10-24 07:54:17 UTC (rev 4856)
@@ -0,0 +1,28 @@
+#ifdef TTURRETS_ENABLED
+
+// Include section.
+#include "../system/system_misc.qc" /// Assorted junk & jewls
+#include "../system/system_main.qc" /// And routines
+#include "../system/system_aimprocs.qc" /// Aiming realted stuff
+#include "../system/system_scoreprocs.qc" /// Target calssification
+#include "../system/system_damage.qc" /// Outch, they are hurting me! what should i do?
+
+#include "../units/unit_common.qc" /// Some "make life easyer" funcs.
+
+// Non combat units
+#include "../units/unit_fusionreactor.qc" /// Supply unites that need it with power
+#include "../units/unit_targettrigger.qc" /// Hit me!
+
+// Combat units
+#include "../units/unit_plasma.qc" /// Basic energy cannon
+#include "../units/unit_mlrs.qc" /// Basic multibay RL
+#include "../units/unit_hellion.qc" /// Seeking missiles MLRS
+#include "../units/unit_flac.qc" /// anti missile turret
+#include "../units/unit_phaser.qc" /// ZzzapT
+#include "../units/unit_hk.qc" /// Hunter killers
+#include "../units/unit_machinegun.qc" /// whacka
+#include "../units/unit_tessla.qc" /// Chain lightning capabale turret
+#include "../units/unit_walker.qc"
+
+
+#endif // TTURRETS_ENABLED
Property changes on: trunk/data/qcsrc/server/tturrets/include/turrets.qh
___________________________________________________________________
Name: svn:mergeinfo
+
Copied: trunk/data/qcsrc/server/tturrets/include/turrets_early.qh (from rev 4854, trunk/data/qcsrc/server/tturrets/include/turret_tturrets_early.qh)
===================================================================
--- trunk/data/qcsrc/server/tturrets/include/turrets_early.qh (rev 0)
+++ trunk/data/qcsrc/server/tturrets/include/turrets_early.qh 2008-10-24 07:54:17 UTC (rev 4856)
@@ -0,0 +1,472 @@
+// Comment out below to skip turrets
+#define TTURRETS_ENABLED
+
+#ifdef TTURRETS_ENABLED
+
+#message "with tZork turrets rc2"
+
+vector real_origin(entity ent);
+
+/// target selection flags
+.float target_select_flags;
+.float target_validate_flags;
+/// Dont select a target on its own.
+#define TFL_TARGETSELECT_NO 1024
+/// Need line of sight
+#define TFL_TARGETSELECT_LOS 2
+/// Players are valid targets
+#define TFL_TARGETSELECT_PLAYERS 4
+/// Missiles are valid targets
+#define TFL_TARGETSELECT_MISSILES 8
+/// Responds to turret_trigger_target events
+#define TFL_TARGETSELECT_TRIGGERTARGET 16
+/// Angular limitations of turret head limits target selection
+#define TFL_TARGETSELECT_ANGLELIMITS 32
+/// Range limits apply in targetselection
+#define TFL_TARGETSELECT_RANGELIMTS 64
+/// DOnt select targets with a .team matching its own
+#define TFL_TARGETSELECT_TEAMCHECK 4096
+/// Cant select targets on its own. needs to be triggerd or slaved.
+#define TFL_TARGETSELECT_NOBUILTIN 256
+/// TFL_TARGETSELECT_TEAMCHECK is inverted (selects only mebers of own .team)
+#define TFL_TARGETSELECT_OWNTEAM 2048
+/// Turrets aren't valid targets
+#define TFL_TARGETSELECT_NOTURRETS 128
+
+/// aim flags
+.float aim_flags;
+/// Dont aim.
+#define TFL_AIM_NO 1
+/// Go for ground, not direct hit
+#define TFL_AIM_GROUND 2
+/// Go for ground, not direct hit if target is on ground too
+#define TFL_AIM_GROUND2 4
+/// Use balistic aim (not implemented)
+#define TFL_AIM_BALISTIC 8
+/// Try to predict target movement (does not account for gravity)
+#define TFL_AIM_LEAD 16
+/// Compensate for shot traveltime when lead
+#define TFL_AIM_SHOTTIMECOMPENSATE 32
+/// Aim slightly in front of target
+#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
+/// Try to do real prediction of targets z pos at impact.
+//#define TFL_AIM_ZPREDICT 256
+/// Just poitn at target's current location
+#define TFL_AIM_SIMPLE 512
+
+/// track (turn and pitch head) flags
+.float track_flags;
+/// Dont move head
+#define TFL_TRACK_NO 2
+/// Pitch the head
+#define TFL_TRACK_PITCH 4
+/// Rotate the head
+#define TFL_TRACK_ROT 8
+
+/// How tracking is preformed
+.float track_type;
+/// Hard angle increments. Ugly for fast turning, best accuracy.
+#define TFL_TRACKTYPE_STEPMOTOR 1
+/// Smoth absolute movement. Looks ok, fair accuracy.
+#define TFL_TRACKTYPE_FLUIDPRECISE 2
+/// Simulated inertia. "Wobbly mode" Looks kool, can mean terrible accuracy depending on how the feilds below are set
+#define 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 do any chekcs
+#define TFL_FIRECHECK_NO 8192
+/// Dont kill the world
+#define TFL_FIRECHECK_WORLD 2
+/// Dont kill the dead
+#define TFL_FIRECHECK_DEAD 4
+/// Range limits apply
+#define TFL_FIRECHECK_DISTANCES 8
+/// Line Of Sight needs to be clear
+#define TFL_FIRECHECK_LOS 16
+/// Consider distance inpactpoint<->aimspot
+#define TFL_FIRECHECK_AIMDIST 32
+/// Consider enemy origin<->impactpoint
+#define TFL_FIRECHECK_REALDIST 64
+/// Consider angular diff head<->aimspot
+#define TFL_FIRECHECK_ANGLEDIST 128
+/// (re)consider target.team<->self.team
+#define TFL_FIRECHECK_TEAMCECK 256
+/// Try to avoid friendly fire
+#define TFL_FIRECHECK_AFF 512
+/// Own .ammo needs to be >= then own .shot_dmg
+#define TFL_FIRECHECK_OWM_AMMO 1024
+/// Others ammo need to be < others .ammo_max
+#define TFL_FIRECHECK_OTHER_AMMO 2048
+/// Check own .attack_finished_single vs time
+#define TFL_FIRECHECK_REFIRE 4096
+
+/// How shooting is done
+.float shoot_flags;
+/// Dont shoot
+#define TFL_SHOOT_NO 64
+/// Fire in vollys (partial implementation through .shot_volly)
+#define TFL_SHOOT_VOLLY 2
+/// Always do a full volly, even if target is lost or dead. (not implemented)
+#define TFL_SHOOT_VOLLYALWAYS 4
+/// Loop though all valid tarters, and hit them.
+#define TFL_SHOOT_HITALLVALID 8
+/// Fiering makes unit loose target (after volly is done, if in volly mode)
+#define TFL_SHOOT_CLEARTARGET 16
+///Custom shooting;
+#define TFL_SHOOT_CUSTOM 32
+
+/// Information aboute the units capabilities
+.float turrcaps_flags;
+/// No kown capabilities
+#define TFL_TURRCAPS_NONE 0
+/// Capable of sniping
+#define TFL_TURRCAPS_SNIPER 2
+/// Capable of splasdamage
+#define TFL_TURRCAPS_RADIUSDMG 4
+/// Has one or more cannons with zero shot traveltime
+#define TFL_TURRCAPS_HITSCAN 8
+/// More then one (type of) gun
+#define TFL_TURRCAPS_MULTIGUN 16
+/// Carries at least one guided weapon
+#define TFL_TURRCAPS_GUIDED 32
+/// At least one gun fiers slow projectiles
+#define TFL_TURRCAPS_SLOWPROJ 64
+/// At least one gun fiers medium speed projectiles
+#define TFL_TURRCAPS_MEDPROJ 128
+/// At least one gun fiers fast projectiles
+#define TFL_TURRCAPS_FASTPROJ 256
+/// At least one gun capable of damaging players
+#define TFL_TURRCAPS_PLAYERKILL 512
+/// At least one gun that can shoot town missiles
+#define TFL_TURRCAPS_MISSILEKILL 1024
+/// Has support capabilities. powerplants and sutch.
+#define TFL_TURRCAPS_SUPPORT 2048
+/// Proveides at least one type of ammmo
+#define TFL_TURRCAPS_AMMOSOURCE 4096
+/// Can recive targets from external sources
+#define TFL_TURRCAPS_RECIVETARGETS 8192
+/// Capable of self-transport
+#define TFL_TURRCAPS_MOVE 16384
+/// Will roam arround even if not chasing anyting
+#define TFL_TURRCAPS_ROAM 32768
+#define TFL_TURRCAPS_LINKED 65536
+
+/// Ammo types needed and/or provided
+.float ammo_flags;
+/// Has and needs no ammo
+#define TFL_AMMO_NONE 64
+/// Uses power
+#define TFL_AMMO_ENERGY 2
+/// Uses bullets
+#define TFL_AMMO_BULLETS 4
+/// Uses explosives
+#define TFL_AMMO_ROCKETS 8
+/// Regenerates ammo on its own
+#define TFL_AMMO_RECHARGE 16
+/// Can recive ammo from others
+#define TFL_AMMO_RECIVE 32
+
+/// How incomming damage is handeld
+.float damage_flags;
+/// Cant be hurt
+#define TFL_DMG_NO 256
+/// Can be damaged
+#define TFL_DMG_YES 2
+/// Can be damaged by teammates
+#define TFL_DMG_TAKEFROMTEAM 4
+/// Traget attackers
+#define TFL_DMG_RETALIATE 8
+/// Target attackers, even is on own team
+#define TFL_DMG_RETALIATEONTEAM 16
+/// Loses target when damaged
+#define TFL_DMG_TARGETLOSS 32
+/// Reciving damage trows off aim
+#define TFL_DMG_AIMSHAKE 64
+/// Reciving damage slaps the head arround
+#define TFL_DMG_HEADSHAKE 128
+/// Die and stay dead.
+#define TFL_DMG_DEATH_NORESPAWN 256
+
+// Spawnflags
+/// Spawn in teambased modes
+#define TFL_SPAWN_TEAM 2
+/// Spawn in FFA modes
+#define TFL_SPAWN_FFA 4
+/// Respawn after death
+#define TFL_SPAWN_RESPAWN 8
+
+/*
+* Fields commnly used by turrets
+*/
+/// Turrets internal ai speed
+.float ticrate;
+/// Where to point the head 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;
+/// on/off toggle.
+.float tur_active;
+/// Aim from this point,
+.vector tur_aimorg;
+/// and shoot from here. (could 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;
+/// What entity the aimtrace hit, if any.
+.entity tur_impactent;
+/// Distance to enemy
+.float tur_dist_enemy;
+/// Distance impact<->aim
+.float tur_dist_toaimpos;
+/// 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 or borken volly.
+.float shot_volly_refire;
+
+/// Consider targets within this range
+.float target_range;
+/// Dont consider targets closer then
+.float target_range_min;
+/// Engage fire routine on targets within
+.float target_range_fire;
+/// 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;
+
+/*
+* 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;
+/// 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
+.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 BEFORE main ai loop. return 0 to cancel any following proccessing.
+//.float() turret_prethink;
+/// Execure AFTER main AI loop UNLESS turret_prethink returnd 0
+.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;
+
+/*
+#define TEH_THINK 2
+#define TEH_DAMAGE 4
+#define TEH_DIE 8
+#define TEH_RESPAWN 16
+#define TEH_TRACK 32
+#define TEH_AIM 64
+#define TEH_SELECT 128
+.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
+* return a normalized result.
+*/
+/// 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
+*/
+/// "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.
+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()
+
+/*
+* 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_aimorg_updated;
+.vector tur_shotorg_updated;
+.vector tur_shotdir_updated;
+
+void turrets_precash();
+#endif // TTURRETS_ENABLED
Property changes on: trunk/data/qcsrc/server/tturrets/include/turrets_early.qh
___________________________________________________________________
Name: svn:mergeinfo
+
Copied: trunk/data/qcsrc/server/tturrets/system/system_aimprocs.qc (from rev 4854, trunk/data/qcsrc/server/tturrets/system/turret_system_aimprocs.qc)
===================================================================
--- trunk/data/qcsrc/server/tturrets/system/system_aimprocs.qc (rev 0)
+++ trunk/data/qcsrc/server/tturrets/system/system_aimprocs.qc 2008-10-24 07:54:17 UTC (rev 4856)
@@ -0,0 +1,140 @@
+/*
+* Straight line, Dead-on (no prediction)
+* Usefull for "stupid turrets" or ones
+* that launch guided weapons and just need to apeer to
+* somewhat face (and/or track) the target.
+
+supports:
+TFL_AIM_NO
+*/
+/*
+vector turret_stdproc_aim_simple()
+{
+ float s_bu; // Solidity backup (for ground shooters)
+ vector aim_pos;
+
+ if (self.aim_flags & TFL_AIM_NO) return self.idle_aim;
+
+ aim_pos = self.enemy.origin;
+
+ // Target ground?
+ if (self.aim_flags & TFL_AIM_GROUND)
+ {
+ s_bu = self.enemy.solid;
+ self.enemy.solid = SOLID_NOT;
+ traceline(self.enemy.origin + '0 0 128',self.enemy.origin + '0 0 -99999',1,self.enemy);
+ self.enemy.solid = s_bu;
+ aim_pos = trace_endpos;
+ }
+
+ // This is where its at.
+ return aim_pos;
+}
+*/
+
+/*
+* Generic aim
+
+supports:
+TFL_AIM_NO
+TFL_AIM_GROUND
+TFL_AIM_LEAD
+TFL_AIM_SHOTTIMECOMPENSATE
+TFL_AIM_INFRONT
+TFL_AIM_BEHIND
+TFL_AIM_ZEASE
+
+not supported:
+TFL_AIM_BALISTIC
+*/
+
+
+vector turret_stdproc_aim_generic()
+{
+ vector pre_pos;
+ // entity mover;
+
+ if (self.aim_flags == TFL_AIM_NO)
+ return self.idle_aim;
+
+ // Baseline
+ pre_pos = real_origin(self.enemy);
+
+ if(self.aim_flags & TFL_AIM_SIMPLE)
+ return pre_pos;
+
+ // Lead?
+ //pre_pos = pre_pos + bot_shotlead(self.enemy.origin, self.enemy.velocity, self.shot_speed, 0.01); //self.enemy.velocity; * (self.tur_dist_enemy / self.shot_speed);
+ if (self.aim_flags & TFL_AIM_LEAD)
+ if (self.aim_flags & TFL_AIM_SHOTTIMECOMPENSATE) // Need to conpensate for shot traveltime
+ {
+ pre_pos = pre_pos + self.enemy.velocity * (self.tur_dist_enemy / self.shot_speed);
+
+ // FIXME slow projectiles misspredict (well all do, bit the slow ons miss :P)
+ }
+ else if (self.turrcaps_flags & TFL_TURRCAPS_HITSCAN) // Hitscan gun, conpensate for frametime and posibly refire offset.
+ pre_pos = pre_pos + self.enemy.velocity * (frametime + min(max(self.attack_finished_single - time,0),self.ticrate*2));
+ else // No lead
+ pre_pos += self.enemy.velocity;
+
+
+ // Smooth out predict-Z?
+ /*
+ if (self.aim_flags & TFL_AIM_ZEASE)
+ {
+ vector v;
+ v = real_origin(self.enemy);
+ pre_pos_z = (pre_pos_z + v_z) * 0.5;
+ }
+ */
+
+ /*
+ if (self.aim_flags & TFL_AIM_INFRONT) // Aim a bit in front of the target
+ pre_pos -= normalize(self.tur_aimorg_updated - pre_pos) * 32;
+
+ if (self.aim_flags & TFL_AIM_BEHIND) // Aim a bit behind the target
+ pre_pos += normalize(self.tur_aimorg_updated - pre_pos) * 32;
+
+ */
+ // This turret should hit the ground neer a target rather the do a direct hit
+
+ if ( (self.aim_flags & TFL_AIM_GROUND) ||
+ ((self.aim_flags & TFL_AIM_GROUND2) && (self.enemy.flags & FL_ONGROUND)) )
+ {
+ traceline(pre_pos + '0 0 8',pre_pos - '0 0 10000',1,self.enemy);
+ pre_pos = trace_endpos;
+ }
+
+
+
+
+
+
+
+ return pre_pos;
+}
+
+
+/*
+* Aim where it is
+supports:
+TFL_AIM_NO
+*/
+/*
+vector turret_stdproc_aim_rail()
+{
+ vector pre_pos;
+
+ if (self.aim_flags & TFL_AIM_NO)
+ return self.idle_aim;
+
+ pre_pos = real_origin(self.enemy);
+
+ self.tur_dist_toaimpos = vlen(self.enemy.origin - self.tur_aimorg_updated);
+
+ self.tur_impacttime = time;
+
+ return pre_pos;
+
+}
+*/
Property changes on: trunk/data/qcsrc/server/tturrets/system/system_aimprocs.qc
___________________________________________________________________
Name: svn:mergeinfo
+
Copied: trunk/data/qcsrc/server/tturrets/system/system_damage.qc (from rev 4854, trunk/data/qcsrc/server/tturrets/system/turret_system_damage.qc)
===================================================================
--- trunk/data/qcsrc/server/tturrets/system/system_damage.qc (rev 0)
+++ trunk/data/qcsrc/server/tturrets/system/system_damage.qc 2008-10-24 07:54:17 UTC (rev 4856)
@@ -0,0 +1,319 @@
+/*
+* Trow a turret gib
+*/
+void turret_gib_damage (entity inflictor, entity attacker, float damage, float deathtype, vector hitloc, vector vforce)
+{
+ self.velocity += vforce;
+}
+
+void turret_trowgib(
+ vector v_from, vector v_to, vector v_colormod,
+ string smodel,
+ float f_lifetime, float f_fadetime, float b_burn)
+{
+ local entity gib;
+ local entity burn;
+
+ gib = spawn();
+
+ gib.classname = "turret_gib";
+ 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;
+ gib.health = -1;
+ gib.effects = EF_LOWPRECISION;
+ gib.flags = FL_NOTARGET;
+ gib.colormod = v_colormod;
+ gib.velocity = v_to;
+
+ if (b_burn)
+ {
+ burn = spawn();
+ 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);
+ }
+}
+
+void turret_gib_boom()
+{
+ entity gib;
+ float i;
+ string s;
+
+ for (i = 1; i < 5; i = i +1)
+ {
+ gib = spawn();
+ gib.classname = "turret_gib";
+
+ s = strcat("models/turrets/head-gib",ftos(i));
+ s = strcat(s,".md3");
+ // bprint("s:",s,"\n");
+ 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;
+ gib.takedamage = DAMAGE_YES;
+ gib.event_damage = turret_gib_damage;
+ gib.health = -1;
+ gib.effects = EF_LOWPRECISION;
+ gib.flags = FL_NOTARGET;
+ gib.velocity = self.velocity + (randomvec() * 700);
+ gib.avelocity = randomvec() * 64;
+ }
+
+ WriteByte (MSG_BROADCAST, SVC_TEMPENTITY);
+ WriteByte (MSG_BROADCAST, 78);
+ WriteCoord (MSG_BROADCAST, self.origin_x);
+ WriteCoord (MSG_BROADCAST, self.origin_y);
+ WriteCoord (MSG_BROADCAST, self.origin_z);
+
+ remove(self);
+}
+
+void turret_trowgib2(
+ vector v_from, vector v_to, vector v_colormod,
+ entity e_mimic, float boomtime)
+{
+ entity gib;
+
+ gib = spawn();
+
+ gib.classname = "turret_gib";
+ setmodel(gib,e_mimic.model);
+ setorigin(gib,v_from);
+
+ gib.solid = SOLID_BBOX;
+
+ gib.movetype = MOVETYPE_BOUNCE;
+ gib.gravity = 0.75;
+ gib.damageforcescale = 2;
+ gib.takedamage = DAMAGE_YES;
+ gib.event_damage = turret_gib_damage;
+ gib.health = -1;
+ gib.effects = EF_LOWPRECISION;
+ gib.flags = FL_NOTARGET;
+ gib.colormod = v_colormod;
+ gib.velocity = v_to;
+ gib.avelocity = randomvec() * 32;
+ gib.think = turret_gib_boom;
+ gib.nextthink = boomtime;
+ gib.effects = EF_FLAME;
+
+
+}
+/*
+* Spawn a boom, trow fake bits arround
+* and hide the real ones.
+*/
+void turret_stdproc_die()
+{
+ vector org2;
+ vector t_dir;
+
+ // self.tur_active = 0;
+
+ self.deadflag = DEAD_DEAD;
+ self.tur_head.deadflag = self.deadflag;
+
+ sound (self, CHAN_PLAYER, "weapons/rocket_impact.wav", 1, ATTN_NORM);
+ org2 = self.origin + '0 0 40';
+
+// Explotion grafix
+ WriteByte (MSG_BROADCAST, SVC_TEMPENTITY);
+ WriteByte (MSG_BROADCAST, 78);
+ WriteCoord (MSG_BROADCAST, org2_x);
+ WriteCoord (MSG_BROADCAST, org2_y);
+ WriteCoord (MSG_BROADCAST, org2_z);
+
+// Unsolidify and hide real parts
+ self.solid = SOLID_NOT;
+ self.tur_head.solid = self.solid;
+
+ self.alpha = -1;
+ self.tur_head.alpha = -1;
+
+ self.takedamage = DAMAGE_NO;
+ self.tur_head.takedamage = self.takedamage;
+
+ self.effects = 0;
+ self.tur_head.effects = self.effects;
+
+ self.health = 0;
+
+
+// Trow fake parts arround
+
+ // base
+ 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);
+ 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);
+ }
+ else
+ {
+ 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));
+
+
+// Go boom
+ RadiusDamage (self,self, min(self.ammo,50),min(self.ammo,50) * 0.25,250,world,min(self.ammo,50)*5,0,world);
+
+ if(self.damage_flags & TFL_DMG_DEATH_NORESPAWN)
+ {
+ if (self.turret_diehook)
+ self.turret_diehook();
+
+ remove(self.tur_head);
+ remove(self);
+ }
+ else
+ {
+ // Setup respawn
+ self.nextthink = time + self.respawntime;
+ //self.think = self.turret_spawnfunc;
+ self.think = turret_stdproc_respawn;
+ if (self.turret_diehook)
+ self.turret_diehook();
+ }
+
+}
+
+void turret_stdproc_respawn()
+{
+ // self.tur_active = 1;
+
+ // Make sure all parts belong to the same team since
+ // this function doubles as "teamchange" function.
+ self.tur_head.team = self.team;
+ if (self.team == COLOR_TEAM1)
+ self.colormod = '1.4 0.8 0.8';
+ else if (self.team == COLOR_TEAM2)
+ self.colormod = '0.8 0.8 1.4';
+ else
+ self.colormod = '0 0 0'; // reset
+
+ self.deadflag = DEAD_NO;
+ self.tur_head.deadflag = self.deadflag;
+ self.effects = self.tur_head.effects = 0;
+
+ self.solid = SOLID_BBOX;
+ self.tur_head.solid = self.solid;
+
+ self.alpha = 1;
+ self.tur_head.alpha = self.alpha;
+
+ self.takedamage = DAMAGE_YES;
+ self.tur_head.takedamage = self.takedamage;
+
+ self.avelocity = '0 0 0';
+ self.tur_head.avelocity = self.avelocity;
+ self.tur_head.angles = self.idle_aim;
+
+ self.health = self.tur_health;
+
+ self.enemy = world;
+ self.volly_counter = self.shot_volly;
+ self.ammo = self.ammo_max;
+
+ self.nextthink = time + self.ticrate;
+ self.think = turret_think;
+
+ if (self.turret_respawnhook)
+ self.turret_respawnhook();
+
+}
+
+/*
+* Standard damage proc.
+*/
+void turret_stdproc_damage (entity inflictor, entity attacker, float damage, float deathtype, vector hitloc, vector vforce)
+{
+ entity baseent,oldself;
+ // entity player;
+
+ if (self.health <= 0) return;
+
+ // Damage func is shared on all parts as standard, we need to know what the master entity of this turret is.
+ // if ((self.classname == "turret_head")||(self.classname == "turret_gun")||(self.classname == "turret_badge"))
+ if (self.owner)
+ baseent = self.owner;
+ else
+ baseent = self;
+
+ if (teamplay != 0)
+ {
+ if (self.team == attacker.team)
+ {
+ sprint(attacker, "\{1}Turret tells you: I'm on your team!\n");
+ return;
+ }
+ else
+ {
+ /*
+ // This will get enoying fast...
+ FOR_EACH_PLAYER(player)
+ if(player.team == self.team)
+ sprint(player, "The enemy is attacking your base!");
+
+ */
+ }
+
+ }
+
+ baseent.health = baseent.health - damage;
+
+ // thorw head slightly off aim when hit?
+ if ((self.classname == "turret_head") || (self.classname == "turret_gun"))
+ if (self.damage_flags & TFL_DMG_HEADSHAKE)
+ {
+ // makevectors(baseent.tur_head.v_angle);
+ baseent.tur_head.angles = baseent.tur_head.angles + randomvec() * damage;
+ }
+
+ if (self.turrcaps_flags & TFL_TURRCAPS_MOVE)
+ {
+ self.velocity = self.velocity + vforce;
+ }
+
+
+ // Start burning when we have 10% or less health left
+ if (self.health < (self.tur_health * 0.1))
+ self.effects = EF_FLAME;
+
+ if (self.health <= 0)
+ {
+ oldself = self;
+ self = baseent;
+ turret_stdproc_die();
+ self = oldself;
+
+ //baseent.turret_diefunc();
+ }
+}
+
+
Property changes on: trunk/data/qcsrc/server/tturrets/system/system_damage.qc
___________________________________________________________________
Name: svn:mergeinfo
+
Copied: trunk/data/qcsrc/server/tturrets/system/system_main.qc (from rev 4854, trunk/data/qcsrc/server/tturrets/system/turret_system_main.qc)
===================================================================
--- trunk/data/qcsrc/server/tturrets/system/system_main.qc (rev 0)
+++ trunk/data/qcsrc/server/tturrets/system/system_main.qc 2008-10-24 07:54:17 UTC (rev 4856)
@@ -0,0 +1,1104 @@
+#define cvar_base "g_turrets_unit_"
+
+//.float tur_lastscore;
+.string cvar_basename;
+
+string cvar_gets(string s_base,string s_add)
+{
+ return strcat(s_base,s_add);
+}
+
+.float turret_scale_damage;
+.float turret_scale_range;
+.float turret_scale_refire;
+.float turret_scale_ammo;
+.float turret_scale_aim;
+.float turret_scale_health;
+.float turret_scale_respawn;
+
+void load_unit_settings(entity ent,string unitname,float is_reload)
+{
+
+ string sbase;
+
+ if (ent == world)
+ return;
+
+ if (!ent.turret_scale_damage) ent.turret_scale_damage = 1;
+ if (!ent.turret_scale_range) ent.turret_scale_range = 1;
+ if (!ent.turret_scale_refire) ent.turret_scale_refire = 1;
+ if (!ent.turret_scale_ammo) ent.turret_scale_ammo = 1;
+ if (!ent.turret_scale_aim) ent.turret_scale_aim = 1;
+ 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 = world;
+ ent.tur_head.avelocity = '0 0 0';
+ ent.tur_head.angles = ent.angles;
+ }
+ ent.health = cvar(cvar_gets(sbase,"_health")) * ent.turret_scale_health;
+ ent.respawntime = cvar(cvar_gets(sbase,"_respawntime")) * ent.turret_scale_respawn;
+
+ ent.shot_dmg = cvar(cvar_gets(sbase,"_shot_dmg")) * ent.turret_scale_damage;
+ ent.shot_refire = cvar(cvar_gets(sbase,"_shot_refire")) * ent.turret_scale_refire;
+ ent.shot_radius = cvar(cvar_gets(sbase,"_shot_radius")) * ent.turret_scale_damage;
+ ent.shot_speed = cvar(cvar_gets(sbase,"_shot_speed"));
+ ent.shot_spread = cvar(cvar_gets(sbase,"_shot_spread"));
+ ent.shot_force = cvar(cvar_gets(sbase,"_shot_force")) * ent.turret_scale_damage;
+ ent.shot_volly = cvar(cvar_gets(sbase,"_shot_volly"));
+ ent.shot_volly_refire = cvar(cvar_gets(sbase,"_shot_volly_refire")) * ent.turret_scale_refire;
+
+ ent.target_range = cvar(cvar_gets(sbase,"_target_range")) * ent.turret_scale_range;
+ ent.target_range_min = cvar(cvar_gets(sbase,"_target_range_min")) * ent.turret_scale_range;
+ ent.target_range_fire = cvar(cvar_gets(sbase,"_target_range_fire")) * ent.turret_scale_range;
+ ent.target_range_optimal = cvar(cvar_gets(sbase,"_target_range_optimal")) * ent.turret_scale_range;
+
+ ent.target_select_rangebias = cvar(cvar_gets(sbase,"_target_select_rangebias"));
+ ent.target_select_samebias = cvar(cvar_gets(sbase,"_target_select_samebias"));
+ ent.target_select_anglebias = cvar(cvar_gets(sbase,"_target_select_anglebias"));
+ ent.target_select_playerbias = cvar(cvar_gets(sbase,"_target_select_playerbias"));
+
+ ent.ammo_max = cvar(cvar_gets(sbase,"_ammo_max")) * ent.turret_scale_ammo;
+ //ent.ammo = cvar(cvar_gets(sbase,"_ammo"));
+ ent.ammo_recharge = cvar(cvar_gets(sbase,"_ammo_recharge")) * ent.turret_scale_ammo;
+
+ ent.aim_firetolerance_dist = cvar(cvar_gets(sbase,"_aim_firetolerance_dist"));
+// ent.aim_firetolerance_angle = cvar(cvar_gets(sbase,"_aim_firetolerance_angle"));
+ ent.aim_speed = cvar(cvar_gets(sbase,"_aim_speed")) * ent.turret_scale_aim;
+ ent.aim_maxrot = cvar(cvar_gets(sbase,"_aim_maxrot"));
+ ent.aim_maxpitch = cvar(cvar_gets(sbase,"_aim_maxpitch"));
+
+ ent.track_type = cvar(cvar_gets(sbase,"_track_type"));
+ ent.track_accel_pitch = cvar(cvar_gets(sbase,"_track_accel_pitch"));
+ ent.track_accel_rot = cvar(cvar_gets(sbase,"_track_accel_rot"));
+ ent.track_blendrate = cvar(cvar_gets(sbase,"_track_blendrate"));
+}
+
+float turret_stdproc_true()
+{
+ return 1;
+}
+
+float turret_stdproc_false()
+{
+ return 0;
+}
+
+void turret_stdproc_nothing()
+{
+ return;
+}
+
+/**
+** updates enemy distances, preicted impact point/time
+** & aim<->predict impact distance.
+** Also translates shoot & aimorgs by current rotation.
+**/
+void turret_do_updates(entity e_turret)
+{
+ if (self.turrcaps_flags & TFL_TURRCAPS_LINKED)
+ {
+ e_turret.tur_head.angles_x = e_turret.tur_head.angles_x * -1;
+ e_turret.angles_x = e_turret.angles_x * -1;
+ makevectors(e_turret.tur_head.angles + e_turret.angles);
+ e_turret.tur_head.angles_x = e_turret.tur_head.angles_x * -1;
+ e_turret.angles_x = e_turret.angles_x * -1;
+ }
+ else
+ {
+ e_turret.tur_head.angles_x = e_turret.tur_head.angles_x * -1;
+ makevectors(e_turret.tur_head.angles);
+ e_turret.tur_head.angles_x = e_turret.tur_head.angles_x * -1;
+ }
+ // v_right = (v_right * -1);
+ e_turret.tur_shotorg_updated = e_turret.origin + v_forward * e_turret.tur_shotorg_x + v_right * e_turret.tur_shotorg_y + v_up * e_turret.tur_shotorg_z;
+
+ e_turret.tur_shotdir_updated = normalize((e_turret.tur_shotorg_updated + v_forward) - e_turret.tur_shotorg_updated);
+ e_turret.tur_aimorg_updated = e_turret.origin + v_forward * e_turret.tur_aimorg_x + v_right * e_turret.tur_aimorg_y + v_up * e_turret.tur_aimorg_z;
+
+
+ e_turret.tur_dist_enemy = vlen(e_turret.tur_aimorg_updated - real_origin(e_turret.enemy));
+
+ traceline(e_turret.tur_aimorg_updated,e_turret.tur_aimorg_updated+(e_turret.tur_shotdir_updated * e_turret.tur_dist_enemy),MOVE_NORMAL,e_turret);
+
+ e_turret.tur_impactpoint = trace_endpos;
+ e_turret.tur_impactent = trace_ent;
+ //e_turret.tur_impacttime = e_turret.tur_dist_enemy / e_turret.shot_speed;
+ e_turret.tur_impacttime = e_turret.tur_dist_enemy / e_turret.shot_speed;
+ e_turret.tur_dist_toaimpos = vlen(trace_endpos - e_turret.tur_aimpos);
+}
+
+/**
+** Handles head rotation according to
+** the units .track_type and .track_flags
+**/
+void turret_stdproc_track()
+{
+ vector wish_angle; // This is where we'd need to be
+
+ vector real_angle; // This is where we can go
+ float f_tmp;
+
+
+ if (self.track_flags == TFL_TRACK_NO)
+ return;
+
+ if(!self.tur_active)
+ {
+ wish_angle = self.idle_aim - ('1 0 0' * self.aim_maxpitch);
+ }
+ else if (self.enemy == world)
+ {
+ if (self.turrcaps_flags & TFL_TURRCAPS_LINKED)
+ wish_angle = self.idle_aim + self.angles;
+ else
+ if(cvar("g_turrets_aimidle_delay") > (time - self.lip))
+ wish_angle = self.idle_aim;
+ else
+ wish_angle = self.tur_head.angles;
+
+ }
+ else
+ {
+ // Find the direction
+ if (self.turrcaps_flags & TFL_TURRCAPS_LINKED)
+ wish_angle = normalize(self.tur_aimpos - self.origin);
+ else
+ wish_angle = normalize(self.tur_aimpos - self.tur_head.origin);
+
+ wish_angle = vectoangles(wish_angle); // And make a angle
+ }
+
+ // Find the diffrence between where we currently aim and where we want to aim
+ if (self.turrcaps_flags & TFL_TURRCAPS_LINKED)
+ real_angle = wish_angle - (self.angles + self.tur_head.angles);
+ else
+ {
+ //if(vlen(wish_angle - self.tur_head.angles) > vlen(self.tur_head.angles - wish_angle))
+ real_angle = wish_angle - self.tur_head.angles;
+ //else
+ // real_angle = self.tur_head.angles - wish_angle;
+ }
+
+ /*
+ if(real_angle_y > 180)
+ bprint("^3");
+ if(real_angle_y < -180)
+ bprint("^1");
+ string s;
+ s = vtos(real_angle);
+ bprint("RA1: ",s);
+ */
+
+
+ if (real_angle_x < 0) real_angle_x += 360;
+ if (real_angle_x > 180) real_angle_x -= 360;
+
+ if (real_angle_y < 0) real_angle_y += 360;
+ if (real_angle_y >= 180) real_angle_y -= 360;
+
+ //s = vtos(real_angle);
+ //bprint(" RA2: ",s,"\n");
+
+ // Limit pitch
+
+ if (self.track_flags & TFL_TRACK_PITCH)
+ real_angle_x = bound(self.aim_maxpitch * -1,real_angle_x,self.aim_maxpitch);
+
+ // Limit rot
+ if (self.track_flags & TFL_TRACK_ROT)
+ real_angle_y = bound(self.aim_maxrot * -1,real_angle_y,self.aim_maxrot);
+
+
+ if (self.track_type == TFL_TRACKTYPE_STEPMOTOR)
+ {
+ f_tmp = self.aim_speed * self.ticrate; // dgr/sec -> dgr/tic
+
+ // Limit turning speed
+ real_angle_x = bound((-1 * f_tmp),real_angle_x, f_tmp);
+ real_angle_y = bound((-1 * f_tmp),real_angle_y, f_tmp);
+
+ // Limit pich and rot.
+ if (self.track_flags & TFL_TRACK_PITCH)
+ self.tur_head.angles_x = bound((-1 * self.aim_maxpitch),self.tur_head.angles_x + real_angle_x,self.aim_maxpitch);
+
+ if (self.track_flags & TFL_TRACK_ROT)
+ self.tur_head.angles_y = bound((-1 * self.aim_maxrot),self.tur_head.angles_y + real_angle_y,self.aim_maxrot);
+
+ return;
+ }
+
+ if (self.track_type == TFL_TRACKTYPE_FLUIDPRECISE)
+ {
+ if (self.track_flags & TFL_TRACK_PITCH)
+ self.tur_head.avelocity_x = real_angle_x;
+
+ if (self.track_flags & TFL_TRACK_ROT)
+ self.tur_head.avelocity_y = real_angle_y;
+ }
+ else if (self.track_type == TFL_TRACKTYPE_FLUIDINERTIA)
+ {
+ f_tmp = self.aim_speed * self.ticrate;
+
+ real_angle_y = bound(self.aim_speed * -1,real_angle_y * self.track_accel_rot * f_tmp,self.aim_speed);
+ real_angle_x = bound(self.aim_speed * -1,real_angle_x * self.track_accel_pitch * f_tmp,self.aim_speed);
+ real_angle = (self.tur_head.avelocity * self.track_blendrate) + (real_angle * (1 - self.track_blendrate));
+
+ if (self.track_flags & TFL_TRACK_PITCH) self.tur_head.avelocity_x = real_angle_x;
+ if (self.track_flags & TFL_TRACK_ROT) self.tur_head.avelocity_y = real_angle_y;
+ self.tur_head.avelocity_z = real_angle_z;
+ }
+
+ // Limit pitch
+ /*
+ if (self.track_flags & TFL_TRACK_PITCH)
+ {
+ if (self.tur_head.angles_x > self.aim_maxpitch)
+ {
+ self.tur_head.angles_x = self.aim_maxpitch;
+ self.tur_head.avelocity_x = 0;
+ }
+ else if (self.tur_head.angles_x < (self.aim_maxpitch * -1))
+ {
+ self.tur_head.angles_x = (self.aim_maxpitch * -1);
+ self.tur_head.avelocity_x = 0;
+ }
+ }
+
+ // Limit rot
+ if (self.track_flags & TFL_TRACK_ROT)
+ {
+ if (self.tur_head.angles_y > self.aim_maxrot)
+ {
+ self.tur_head.angles_y = self.aim_maxrot;
+ self.tur_head.avelocity_y = 0;
+ }
+ else if (self.tur_head.angles_y < (self.aim_maxrot * -1))
+ {
+ self.tur_head.angles_y = (self.aim_maxrot * -1);
+ self.tur_head.avelocity_y = 0;
+ }
+ }
+ */
+
+
+}
+
+/*
+ + = implemented
+ - = not implemented
+
+ + TFL_FIRECHECK_NO
+ + TFL_FIRECHECK_WORLD
+ + TFL_FIRECHECK_DEAD
+ + TFL_FIRECHECK_DISTANCES
+ - TFL_FIRECHECK_LOS
+ + TFL_FIRECHECK_AIMDIST
+ + TFL_FIRECHECK_REALDIST
+ - TFL_FIRECHECK_ANGLEDIST
+ - TFL_FIRECHECK_TEAMCECK
+ + TFL_FIRECHECK_AFF
+ + TFL_FIRECHECK_OWM_AMMO
+ + TFL_FIRECHECK_OTHER_AMMO
+ + TFL_FIRECHECK_REFIRE
+*/
+
+/**
+** Preforms pre-fire checks based on the uints firecheck_flags
+**/
+float turret_stdproc_firecheck()
+{
+ // This one just dont care =)
+ if (self.firecheck_flags & TFL_FIRECHECK_NO) return 1;
+
+ // Ready?
+ if (self.firecheck_flags & TFL_FIRECHECK_REFIRE)
+ if (self.attack_finished_single >= time) return 0;
+
+ //
+ if (self.firecheck_flags & TFL_FIRECHECK_DEAD)
+ if (self.enemy.deadflag != DEAD_NO) return 0;
+
+ // Plz stop killing the world!
+ if (self.firecheck_flags & TFL_FIRECHECK_WORLD)
+ if (self.enemy == world) return 0;
+
+ // Own ammo?
+ if (self.firecheck_flags & TFL_FIRECHECK_OWM_AMMO)
+ if (self.ammo < self.shot_dmg) return 0;
+
+ // Other's ammo? (carefull using this...)
+ if (self.firecheck_flags & TFL_FIRECHECK_OTHER_AMMO)
+ if (self.enemy.ammo >= self.enemy.ammo_max) return 0;
+
+ if (self.firecheck_flags & TFL_FIRECHECK_DISTANCES)
+ {
+ // Not close enougth?
+ if (self.tur_dist_enemy > self.target_range_fire) return 0;
+
+ // To close?
+ if (self.tur_dist_enemy < self.target_range_min) return 0;
+ }
+
+ // Try to avoid FF?
+ if (self.firecheck_flags & TFL_FIRECHECK_AFF)
+ if (self.tur_impactent.team == self.team) return 0;
+
+ // aim<->predicted impact
+ if (self.firecheck_flags & TFL_FIRECHECK_AIMDIST)
+ if (self.tur_dist_toaimpos > self.aim_firetolerance_dist) return 0;
+
+ // Volly status
+ if (self.shot_volly > 1)
+ {
+ if (self.volly_counter == self.shot_volly)
+ if (self.ammo < (self.shot_dmg * self.shot_volly))
+ return 0;
+ }
+
+ //if(self.tur_enemy_adist >= self.aim_firetolerance) return 0;
+
+
+ return 1;
+}
+
+/*
+ + TFL_TARGETSELECT_NO
+ + TFL_TARGETSELECT_LOS
+ + TFL_TARGETSELECT_PLAYERS
+ + TFL_TARGETSELECT_MISSILES
+ - TFL_TARGETSELECT_TRIGGERTARGET
+ + TFL_TARGETSELECT_ANGLELIMITS
+ + TFL_TARGETSELECT_RANGELIMTS
+ + TFL_TARGETSELECT_TEAMCHECK
+ - TFL_TARGETSELECT_NOBUILTIN
+ + TFL_TARGETSELECT_OWNTEAM
+*/
+
+/**
+** Evaluate a entity for target valitity based on validate_flags
+**/
+float turret_validate_target(entity e_turret,entity e_target,float validate_flags)
+{
+ vector v_tmp;
+
+ //if(!validate_flags & TFL_TARGETSELECT_NOBUILTIN)
+ // return -0.5;
+
+ if (!e_target)// == world)
+ return -1;
+
+ if (e_target.classname == "grapplinghook")
+ return - 1.5;
+
+ if(g_onslaught)
+ if (substring(e_target.classname, 0, 10) == "onslaught_") // don't attack onslaught targets, that's the player's job!
+ return - 1.75;
+
+ if (validate_flags & TFL_TARGETSELECT_NO)
+ return -2;
+
+ // If only this was used more..
+ if (e_target.flags & FL_NOTARGET)
+ return -3;
+
+ // Cant touch this
+ if ((e_target.takedamage == DAMAGE_NO) || (e_target.health < 0))
+ return -4;
+
+ // player
+ if (e_target.flags & FL_CLIENT)
+ {
+ if (!(validate_flags & TFL_TARGETSELECT_PLAYERS))
+ return -5;
+
+ if (e_target.deadflag != DEAD_NO)
+ return -6;
+ }
+
+ // enemy turrets
+ if (e_target.turret_firefunc || e_target.owner.tur_head == e_target)
+ {
+ if (validate_flags & TFL_TARGETSELECT_NOTURRETS)
+ return -5.5;
+ }
+
+ // Missile
+ if (e_target.flags & FL_PROJECTILE)
+ {
+ if (!(validate_flags & TFL_TARGETSELECT_MISSILES))
+ return -7;
+ }
+
+ // Team check
+ if (validate_flags & TFL_TARGETSELECT_TEAMCHECK)
+ {
+ if (validate_flags & TFL_TARGETSELECT_OWNTEAM)
+ {
+ if (e_target.team != e_turret.team)
+ return -8;
+
+ if (e_turret.team != e_target.owner.team)
+ return -8.5;
+ }
+ else
+ {
+ if (e_target.team == e_turret.team)
+ return -9;
+
+ if (e_turret.team == e_target.owner.team)
+ return -9.5;
+ }
+ }
+
+ // Line of sight?
+ if (validate_flags & TFL_TARGETSELECT_LOS)
+ {
+ v_tmp = real_origin(e_target) + ((e_target.mins + e_target.maxs) * 0.5);
+ //v_tmp = e_target.origin;
+ traceline(e_turret.origin,v_tmp,0,e_turret);
+
+ if (e_turret.aim_firetolerance_dist < vlen(v_tmp - trace_endpos))
+ return -10;
+ }
+
+ // Can we even aim this thing? (anglecheck)
+ tvt_thadv = angleofs(e_turret.tur_head,e_target);
+ tvt_tadv = angleofs(e_turret,e_target);
+ tvt_thadf = vlen(tvt_thadv);
+ tvt_tadf = vlen(tvt_tadv);
+
+ if (validate_flags & TFL_TARGETSELECT_ANGLELIMITS)
+ {
+ if (fabs(tvt_tadv_x) > e_turret.aim_maxpitch)
+ return -11;
+
+ if (fabs(tvt_tadv_y) > e_turret.aim_maxrot)
+ return -12;
+ }
+
+ // Range limits?
+ tvt_dist = vlen(e_turret.origin - real_origin(e_target));
+ if (validate_flags & TFL_TARGETSELECT_RANGELIMTS)
+ {
+ if (tvt_dist < e_turret.target_range_min)
+ return -13;
+
+ if (tvt_dist > e_turret.target_range)
+ return -14;
+ }
+
+#ifdef TURRET_DEBUG_TARGETSELECT
+ bprint("Target:",e_target.netname," is a valid target for ",e_turret.netname,"\n");
+#endif
+
+ return 1;
+}
+
+entity turret_select_target()
+{
+ entity e; // target looper entity
+ entity e_enemy; // currently best scoreing enemy
+
+ float score; // current target (e) score
+ float m_score; // current best target (e_enemy) score
+ float f;
+ // string s;
+ e = findradius(self.origin,self.target_range);
+
+ // Nothing to aim at.
+ if (!e) return world;
+
+ m_score = 0;
+
+ while (e)
+ {
+ f = turret_validate_target(self,e,self.target_select_flags);
+ //s = ftos(f);
+ //bprint(e.netname, " = ",s,"\n");
+ if (f > 0)
+ {
+
+ score = self.turret_score_target(self,e);
+
+ if ((score > m_score) && (score > 0))
+ {
+ e_enemy = e;
+ m_score = score;
+ }
+ }
+
+ e = e.chain;
+ }
+
+// self.tur_lastscore = m_score;
+
+ //if (self.enemy != e_enemy)
+ //self.volly_counter = 0;
+
+ return e_enemy;
+}
+
+void turret_think()
+{
+ entity e;
+
+ self.nextthink = (time + self.ticrate);
+
+ // ONS uses somewhat backwards linking.
+ if (teamplay)
+ {
+ if (g_onslaught)
+ {
+
+ }
+ else
+ {
+ if (self.target)
+ {
+ e = find(world,targetname,self.target);
+ if (e != world)
+ self.team = e.team;
+ }
+ }
+
+ if (self.team != self.tur_head.team)
+ turret_stdproc_respawn();
+ }
+
+
+ if (cvar("g_turrets_reloadcvars") == 1)
+ {
+ e = nextent(world);
+ while (e)
+ {
+ if (e.tur_head != world)
+ {
+
+ load_unit_settings(e,e.cvar_basename,1);
+ e.turret_postthink();
+ }
+
+ e = nextent(e);
+ }
+
+ cvar_set("g_turrets_reloadcvars","0");
+ }
+
+#ifdef TURRET_DEBUG
+ if (self.tur_dbg_tmr1 < time)
+ {
+ if (self.enemy) paint_target (self.enemy,128,self.tur_dbg_rvec,0.9);
+ paint_target(self,256,self.tur_dbg_rvec,0.9);
+ self.tur_dbg_tmr1 = time + 1;
+ }
+#endif
+
+ //Do custom prethink, and bail if it fails.
+ //if (!self.turret_prethink()) return;
+
+ // Handle ammo
+ if (self.ammo < self.ammo_max)
+ self.ammo = min(self.ammo + self.ammo_recharge,self.ammo_max);
+
+
+ // Inactive turrets needs to run the think loop too
+ // So they can handle animation and wake up if need be.
+ if(!self.tur_active)
+ {
+ turret_stdproc_track();
+ return;
+ }
+
+ //This is just wrong :|
+ if(self.deadflag != DEAD_NO)
+ {
+ dprint("Warning:dead turret running the think function!\n");
+ //self.enemy = world;
+ //turret_stdproc_track();
+ 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)
+ {
+
+ // Do a self.turret_fire for every valid target.
+ e = findradius(self.origin,self.target_range);
+
+ while (e)
+ {
+ if (turret_validate_target(self,e,self.target_validate_flags))
+ {
+ self.enemy = e;
+
+ turret_do_updates(self);
+
+ if ( self.turret_firecheckfunc() ) turret_fire();
+ }
+
+ e = e.chain;
+ }
+ self.enemy = world;
+
+ }
+ else
+ {
+ // Check if we have a vailid enemy, and try to find one if we dont.
+ if ((turret_validate_target(self,self.enemy,self.target_validate_flags) <= 0) || (self.cnt < time))
+ {
+ self.enemy = turret_select_target();
+ self.cnt = time + cvar("g_turrets_targetscan_mindelay");
+ }
+
+
+ // No target, just go to idle, do any custom stuff and bail.
+ if (self.enemy == world)
+ {
+ // Turn & pitch
+ if (!self.track_flags & TFL_TRACK_NO)
+ turret_stdproc_track();
+
+ // do any per-turret stuff
+ self.turret_postthink();
+
+ // And bail.
+ return;
+ }
+ else
+ self.lip = time; // Keep track of the last time we had a target.
+
+ turret_do_updates(self);
+
+ // Predict or whatnot
+ if not((self.aim_flags & TFL_AIM_NO))
+ self.tur_aimpos = turret_stdproc_aim_generic();
+
+ // Fire?
+ if (self.turret_firecheckfunc() != 0)
+ turret_fire();
+
+ turret_do_updates(self);
+
+ // Turn & pitch
+ if (!self.track_flags & TFL_TRACK_NO)
+ turret_stdproc_track();
+
+ turret_do_updates(self);
+
+ // Fire?
+ if (self.turret_firecheckfunc() != 0)
+ turret_fire();
+ }
+
+ // do any per-turret stuff
+ self.turret_postthink();
+}
+
+void turret_fire()
+{
+ if (cvar("g_turrets_nofire") != 0) return;
+ if ((!self.tur_active) || (self.deadflag != DEAD_NO)) return;
+
+ self.turret_firefunc();
+
+ self.attack_finished_single = time + self.shot_refire;
+ self.ammo = self.ammo - self.shot_dmg;
+ self.volly_counter = self.volly_counter - 1;
+
+
+ if (self.volly_counter <= 0)
+ {
+ self.volly_counter = self.shot_volly;
+ if (self.shoot_flags & TFL_SHOOT_CLEARTARGET) self.enemy = world;
+
+ if (self.shot_volly > 1)
+ self.attack_finished_single = time + self.shot_volly_refire;
+ }
+
+
+#ifdef TURRET_DEBUG
+ if (self.enemy) paint_target3(self.tur_aimpos ,64,self.tur_dbg_rvec,self.tur_impacttime+0.25);
+#endif
+}
+
+void turret_stdproc_fire()
+{
+ dprint("^1Bang, ^3your dead^7 ",self.enemy.netname,"! ^1(turret with no real firefunc)\n");
+}
+
+void turret_stdproc_use()
+{
+ // bprint("Used:",self.netname, " By ",other.netname,"\n");
+
+ // ONS Uses _use to communicate.
+ if (g_onslaught)
+ {
+ entity e;
+
+ if (self.targetname)
+ {
+ e = find(world,target,self.targetname);
+ if (e != world)
+ self.team = e.team;
+ }
+
+ if (self.team != self.tur_head.team)
+ turret_stdproc_respawn();
+
+ if(self.team == 0)
+ self.tur_active = 0;
+ else
+ self.tur_active = 1;
+
+ }
+ else
+ {
+ if (self.tur_active)
+ self.tur_active = 0;
+ else
+ self.tur_active = 1;
+ }
+
+}
+
+/*
+* Standard turret initialization. use this!
+* (unless you have a very good reason not to.)
+* Any special stuff like multiple cannon models should be done
+* after this is proc called.
+* if the return value is 0, the turret should be removed.
+*/
+float turret_stdproc_init (string cvar_base_name)
+{
+ entity e;
+
+ // Are turrets allowed atm?
+ if (cvar("g_turrets") == 0) return 0;
+
+ // Better more then once then never.
+ // turret_gibs_precash();
+
+ if (self.spawnflags & 2)
+ {
+ entity tb;
+ precache_model("models/turrets/terrainbase.md3");
+ tb = spawn();
+ setmodel(tb,"models/turrets/terrainbase.md3");
+ setorigin(tb,self.origin);
+ tb.solid = SOLID_BBOX;
+ makestatic(tb);
+ }
+
+ self.cvar_basename = cvar_base_name;
+ load_unit_settings(self,self.cvar_basename,0);
+
+ // Group all turrets into the same team if in non teamplaymode, so they dont try to kill eachother.
+ if (cvar("g_assult") != 0)
+ {
+ if (!self.team)
+ self.team = 14; // Assume turrets are on the defending side if not explicitly set otehrwize
+ }
+ else if (!teamplay)
+ self.team = MAX_SHOT_DISTANCE;
+ else if(g_onslaught && self.targetname)
+ {
+ e = find(world,target,self.targetname);
+ if(e != world)
+ self.team = e.team;
+ }
+ else if(!self.team)
+ self.team = MAX_SHOT_DISTANCE;
+
+
+ /*
+ * Try to guess some reasonaly defaults
+ * for missing params and do sanety checks
+ * thise checks could produce some "interesting" results
+ * if it hits a glitch in my logic :P so try to set as mutch
+ * as possible beforehand.
+ */
+ if (self.turrcaps_flags & TFL_TURRCAPS_SUPPORT)
+ {
+ // Support units generaly dont need to have a high speed ai-loop
+ if (!self.ticrate) self.ticrate = 0.25; // Speed of this turrets AI loop
+ }
+ else
+ {
+ if (!self.ticrate) self.ticrate = 0.1; // Speed of this turrets AI loop
+ }
+
+ self.ticrate = bound(0.01,self.ticrate,60); // keep it sane plz
+
+// General stuff
+ if (self.netname == "") self.netname = "turret";
+
+ if (!self.respawntime) self.respawntime = 60;
+ self.respawntime = max(-1,self.respawntime);
+
+ if (!self.health) self.health = 1000;
+ self.tur_health = max(1,self.health);
+
+ if (!self.turrcaps_flags) self.turrcaps_flags = TFL_TURRCAPS_RADIUSDMG | TFL_TURRCAPS_MEDPROJ | TFL_TURRCAPS_PLAYERKILL;
+
+ if (!self.damage_flags) self.damage_flags = TFL_DMG_YES | TFL_DMG_RETALIATE | TFL_DMG_AIMSHAKE;
+
+// Shot stuff.
+ if (!self.shot_refire) self.shot_refire = 1;
+ self.shot_refire = bound(0.01,self.shot_refire,9999);
+
+ if (!self.shot_dmg) self.shot_dmg = self.shot_refire * 50;
+ self.shot_dmg = max(1,self.shot_dmg);
+
+ if (!self.shot_radius) self.shot_radius = self.shot_dmg * 0.5;
+ self.shot_radius = max(1,self.shot_radius);
+
+ if (!self.shot_speed) self.shot_speed = 2500;
+ self.shot_speed = max(1,self.shot_speed);
+
+ if (!self.shot_spread) self.shot_spread = 0.0125;
+ self.shot_spread = bound(0.0001,self.shot_spread,500);
+
+ if (!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);
+
+ if (!self.shot_volly) self.shot_volly = 1;
+ self.shot_volly = bound(1,self.shot_volly,floor(self.ammo_max / self.shot_dmg));
+
+ if (!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);
+
+ if (!self.firecheck_flags)
+ self.firecheck_flags = TFL_FIRECHECK_WORLD | TFL_FIRECHECK_DEAD | TFL_FIRECHECK_DISTANCES |
+ TFL_FIRECHECK_LOS | TFL_FIRECHECK_AIMDIST | TFL_FIRECHECK_TEAMCECK |
+ TFL_FIRECHECK_OWM_AMMO | TFL_FIRECHECK_REFIRE | TFL_FIRECHECK_WORLD;
+
+// Range stuff.
+ if (!self.target_range) self.target_range = self.shot_speed * 0.5;
+ self.target_range = bound(0,self.target_range,MAX_SHOT_DISTANCE);
+
+ if (!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);
+
+ if (!self.target_range_optimal) self.target_range_optimal = self.target_range_fire * 0.5;
+ self.target_range_optimal = bound(0,self.target_range_optimal,MAX_SHOT_DISTANCE);
+
+
+// Aim stuff.
+ if (!self.aim_maxrot) self.aim_maxrot = 45;
+ self.aim_maxrot = bound(0,self.aim_maxrot,361);
+
+ if (!self.aim_maxpitch) self.aim_maxpitch = 20;
+ self.aim_maxpitch = bound(0,self.aim_maxpitch,90);
+
+ if (!self.aim_speed) self.aim_speed = 36;
+ self.aim_speed = bound(0.1,self.aim_speed, 1000);
+
+ if (!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);
+
+// if (!self.aim_firetolerance_angle) self.aim_firetolerance_angle = 10;
+// self.aim_firetolerance_angle = bound(0.1,self.aim_firetolerance_angle,360);
+
+ if (!self.aim_flags) self.aim_flags = TFL_AIM_LEAD | TFL_AIM_SHOTTIMECOMPENSATE | TFL_AIM_ZEASE;
+
+ // Sill the most tested (and aim-effective)
+ if (!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
+ if (!self.aim_speed) self.aim_speed = 180;
+ self.aim_speed = bound(0.1,self.aim_speed, 1000);
+
+ if (!self.track_accel_pitch) self.track_accel_pitch = 0.75;
+ if (!self.track_accel_rot) self.track_accel_rot = 0.75;
+ if (!self.track_blendrate) self.track_blendrate = 0.35;
+ }
+
+ if (!self.track_flags) self.track_flags = TFL_TRACK_PITCH | TFL_TRACK_ROT;
+
+
+// Target selection stuff.
+ if (!self.target_select_rangebias) self.target_select_rangebias = 1;
+ self.target_select_rangebias = bound(-10,self.target_select_rangebias,10);
+
+ if (!self.target_select_samebias) self.target_select_samebias = 1;
+ self.target_select_samebias = bound(-10,self.target_select_samebias,10);
+
+ if (!self.target_select_anglebias) self.target_select_anglebias = 1;
+ self.target_select_anglebias = bound(-10,self.target_select_anglebias,10);
+
+ if (!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);
+
+ if (!self.target_select_flags)
+ if (self.turrcaps_flags & TFL_TURRCAPS_MISSILEKILL)
+ self.target_select_flags = TFL_TARGETSELECT_LOS | TFL_TARGETSELECT_MISSILES |
+ TFL_TARGETSELECT_TEAMCHECK | TFL_TARGETSELECT_RANGELIMTS | TFL_TARGETSELECT_ANGLELIMITS;
+ else
+ self.target_select_flags = TFL_TARGETSELECT_LOS | TFL_TARGETSELECT_PLAYERS |
+ TFL_TARGETSELECT_TEAMCHECK | TFL_TARGETSELECT_RANGELIMTS | TFL_TARGETSELECT_ANGLELIMITS;
+
+ //if(!self.target_validate_flags)
+ self.target_validate_flags = self.target_select_flags;
+
+
+// Ammo stuff
+ if (!self.ammo_max) self.ammo_max = self.shot_dmg * 10;
+ self.ammo_max = max(self.shot_dmg,self.ammo_max);
+
+ if (!self.ammo) self.ammo = self.shot_dmg * 5;
+ self.ammo = bound(0,self.ammo,self.ammo_max);
+
+ if (!self.ammo_recharge) self.ammo_recharge = self.shot_dmg / 2;
+ 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;
+
+ if (!self.ammo_flags) self.ammo_flags = TFL_AMMO_ENERGY | TFL_AMMO_RECHARGE;
+
+// Offsets & origins
+ if (!self.tur_aimorg) self.tur_aimorg = '0 0 50';
+ if (!self.tur_shotorg) self.tur_shotorg = '50 0 50';
+
+// End of default & sanety checks, start building the turret.
+
+// Spawn extra bits
+ self.tur_head = spawn();
+
+ self.tur_head.netname = self.tur_head.classname = "turret_head";
+ self.tur_head.team = self.team;
+
+ // Defend mode?
+ if (self.target != "")
+ {
+ self.tur_defend = find(world, targetname, self.target);
+ if (self.tur_defend == world)
+ {
+ self.target = "";
+ dprint("Turret has invalid defendpoint!\n");
+ }
+ }
+
+// Claim ownership
+ self.tur_head.owner = self;
+
+// Put pices in place
+
+ if (!(self.turrcaps_flags & TFL_TURRCAPS_LINKED))
+ setorigin(self.tur_head,self.origin);
+
+ // In target defense mode, aim on the spot to defens when idle.
+ if (self.tur_defend)
+ self.idle_aim = self.tur_head.angles + angleofs(self.tur_head,self.tur_defend);
+ else
+ self.idle_aim = self.angles;
+
+ if (!(self.turrcaps_flags & TFL_TURRCAPS_LINKED))
+ self.tur_head.angles = self.idle_aim;
+
+ if (!self.health) self.health = 150;
+ self.tur_health = self.health;
+
+ //Solid bbox for preformance reasons
+ self.solid = SOLID_BBOX;
+ self.tur_head.solid = SOLID_BBOX;
+
+ self.takedamage = DAMAGE_AIM;
+ self.tur_head.takedamage = DAMAGE_AIM;
+
+ self.movetype = MOVETYPE_NOCLIP;
+ self.tur_head.movetype = MOVETYPE_NOCLIP;
+
+ // Team colouring?track
+ if (self.team == COLOR_TEAM1) self.colormod = '1.4 0.8 0.8';
+ if (self.team == COLOR_TEAM2) self.colormod = '0.8 0.8 1.4';
+
+ // Attach stdprocs. override when and what needed
+ if (self.turrcaps_flags & TFL_TURRCAPS_SUPPORT)
+ {
+ //self.turret_prethink = turret_stdproc_true;
+ self.turret_score_target = turret_stdproc_targetscore_support;
+ //self.turret_aim = turret_stdproc_aim_generic;
+ //self.turret_track = turret_stdproc_track;
+ self.turret_firecheckfunc = turret_stdproc_firecheck;
+ self.turret_firefunc = turret_stdproc_fire;
+ self.turret_postthink = turret_stdproc_nothing;
+
+ //self.turret_damagefunc = turret_stdproc_damage;
+ self.event_damage = turret_stdproc_damage;
+ self.tur_head.event_damage = turret_stdproc_damage;
+
+ //self.turret_diefunc = turret_stdproc_die;
+ //self.turret_spawnfunc = turret_stdproc_respawn;
+
+ }
+ else
+ {
+
+ //self.turret_prethink = turret_stdproc_true;
+ self.turret_score_target = turret_stdproc_targetscore_generic;
+
+ //if (self.aim_flags & TFL_AIM_SIMPLE)
+ // self.turret_aim = turret_stdproc_aim_simple;
+ //else
+ // self.turret_aim = turret_stdproc_aim_generic;
+
+ //self.turret_track = turret_stdproc_track;
+ self.turret_firecheckfunc = turret_stdproc_firecheck;
+ self.turret_firefunc = turret_stdproc_fire;
+ self.turret_postthink = turret_stdproc_nothing;
+
+ //self.turret_damagefunc = turret_stdproc_damage;
+ self.event_damage = turret_stdproc_damage;
+ self.tur_head.event_damage = turret_stdproc_damage;
+
+ //self.turret_diefunc = turret_stdproc_die;
+ //self.turret_spawnfunc = turret_stdproc_respawn;
+ self.turret_addtarget = turret_stdproc_false;
+ }
+
+ self.use = turret_stdproc_use;
+ self.bot_attack = TRUE;
+
+ // Initiate the main AI loop
+ self.think = turret_think;
+ self.nextthink = time + self.ticrate;
+
+ self.tur_head.team = self.team;
+ self.view_ofs = '0 0 0';
+
+#ifdef TURRET_DEBUG
+ self.tur_dbg_start = self.nextthink;
+ while (vlen(self.tur_dbg_rvec) < 2)
+ self.tur_dbg_rvec = randomvec() * 4;
+
+ self.tur_dbg_rvec_x = fabs(self.tur_dbg_rvec_x);
+ self.tur_dbg_rvec_y = fabs(self.tur_dbg_rvec_y);
+ self.tur_dbg_rvec_z = fabs(self.tur_dbg_rvec_z);
+#endif
+
+ // Its all good.
+ self.classname = "turret_main";
+
+ self.tur_active = 1;
+
+ if (g_onslaught)
+ self.use();
+
+ return 1;
+}
+
+
Property changes on: trunk/data/qcsrc/server/tturrets/system/system_main.qc
___________________________________________________________________
Name: svn:mergeinfo
+
Copied: trunk/data/qcsrc/server/tturrets/system/system_misc.qc (from rev 4854, trunk/data/qcsrc/server/tturrets/system/turret_system_misc.qc)
===================================================================
--- trunk/data/qcsrc/server/tturrets/system/system_misc.qc (rev 0)
+++ trunk/data/qcsrc/server/tturrets/system/system_misc.qc 2008-10-24 07:54:17 UTC (rev 4856)
@@ -0,0 +1,123 @@
+//--// Some support routines //--//
+
+// Get real origin
+vector real_origin(entity ent)
+{
+ entity e;
+ vector v;
+
+ 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 precashing is done.
+void g_turrets_common_precash()
+{
+ precache_model ("models/turrets/c512.md3");
+}
+
+/*
+* 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_y < 0) v_res_y += 360;
+ if (v_res_y > 180) v_res_y -= 360;
+
+ return v_res;
+}
+
Property changes on: trunk/data/qcsrc/server/tturrets/system/system_misc.qc
___________________________________________________________________
Name: svn:mergeinfo
+
Copied: trunk/data/qcsrc/server/tturrets/system/system_scoreprocs.qc (from rev 4854, trunk/data/qcsrc/server/tturrets/system/turret_system_scoreprocs.qc)
===================================================================
--- trunk/data/qcsrc/server/tturrets/system/system_scoreprocs.qc (rev 0)
+++ trunk/data/qcsrc/server/tturrets/system/system_scoreprocs.qc 2008-10-24 07:54:17 UTC (rev 4856)
@@ -0,0 +1,164 @@
+/*
+.float target_select_flags; /// target selection flags
+float TFL_TARGETSELECT_NO = 1; /// Dont select a target on its own.
+float TFL_TARGETSELECT_LOS = 2; /// Need line of sight
+float TFL_TARGETSELECT_PLAYERS = 4; /// Players are valid targets
+float TFL_TARGETSELECT_MISSILES = 8; /// Missiles are valid targets
+float TFL_TARGETSELECT_TRIGGERTARGET = 16; /// Responds to turret_trigger_target events
+float TFL_TARGETSELECT_ANGLELIMITS = 32; /// Angular limitations of turret head limits target selection
+float TFL_TARGETSELECT_RANGELIMTS = 64; /// Range limits apply in targetselection
+float TFL_TARGETSELECT_TEAMCHECK = 128; /// Consider team own <-> targets team
+float TFL_TARGETSELECT_NOBUILTIN = 256; /// Cant select targets on its own. needs to be triggerd or slaved.
+float TFL_TARGETSELECT_OWNTEAM = 512;
+*/
+
+float turret_stdproc_targetscore_support(entity e_turret,entity e_target)
+{
+ float score; // Total score
+ float s_score,d_score;
+
+ if (e_turret.enemy == e_target) s_score = 1;
+
+ d_score = min(e_turret.target_range_optimal,tvt_dist) / max(e_turret.target_range_optimal,tvt_dist);
+
+ score = (d_score * e_turret.target_select_rangebias) +
+ (s_score * e_turret.target_select_samebias);
+
+ return score;
+}
+
+/*
+* Generic bias aware score system.
+*/
+float turret_stdproc_targetscore_generic(entity e_turret,entity e_target)
+{
+ //vector v_tmp;
+ float d_dist; // Defendmode Distance
+
+ float score; // Total score
+ float d_score; // Distance score
+ //float da_score; // Distance from aimpoint score
+ float a_score; // Angular score
+ float s_score; // samescore (same target as last time)
+ float m_score; // missile score
+ float p_score; // player score
+
+ float ikr; // ideal kill range
+
+ if(!e_target) return 0;
+
+ if (e_target == e_turret.enemy) s_score = 1;
+
+ if (e_turret.tur_defend)
+ {
+ d_dist = vlen(real_origin(e_target) - e_turret.tur_defend.origin);
+ ikr = vlen(e_turret.origin - e_turret.tur_defend.origin);
+ d_score = 1 - d_dist / e_turret.target_range;
+ }
+ else
+ {
+ // Make a normlized value base on the targets distance from our optimal killzone
+ ikr = e_turret.target_range_optimal;
+ d_score = min(ikr,tvt_dist) / max(ikr,tvt_dist);
+ }
+
+ /*
+ // Determine the maximum time it could take this turrent to aim at someting.
+ max_aim_delay = (max(e_turret.aim_maxrot,e_turret.aim_maxpitch) / e_turret.aim_speed * 2);
+
+ // Find out how long it would take to aim at this taget.
+ aim_delay = (thadf+0.01) / e_turret.aim_speed;
+
+ // Turn this info into a normalized value.
+ aim_delay = (min(max_aim_delay,aim_delay) / max_aim_delay);
+ a_score = 1 - aim_delay;
+ */
+
+ //a_score = 1 - (tvt_thadf / max(e_turret.aim_maxrot,e_turret.aim_maxpitch));
+ a_score = 1 - tvt_thadf / e_turret.aim_maxrot;
+
+ if ((e_turret.target_select_missilebias > 0) && (e_target.flags & FL_PROJECTILE))
+ m_score = 1;
+
+ if ((e_turret.target_select_playerbias > 0) && (e_target.flags & FL_CLIENT))
+ p_score = 1;
+
+ d_score = max(d_score,0);
+ s_score = max(s_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) +
+ (s_score * e_turret.target_select_samebias) +
+ (a_score * e_turret.target_select_anglebias) +
+ (m_score * e_turret.target_select_missilebias) +
+ (p_score * e_turret.target_select_playerbias);
+
+ if(e_turret.target_range_fire < vlen(e_turret.tur_shotorg_updated - real_origin(e_target)))
+ score *= 0.1;
+
+#ifdef TURRET_DEBUG
+ string sd,sv,sa,sm,sp,ss;
+ string sdt,svt,sat,smt,spt;
+
+ sd = ftos(d_score);
+ d_score *= e_turret.target_select_rangebias;
+ sdt = ftos(d_score);
+
+ //sv = ftos(v_score);
+ //v_score *= e_turret.target_select_samebias;
+ //svt = ftos(v_score);
+
+ sa = ftos(a_score);
+ a_score *= e_turret.target_select_anglebias;
+ sat = ftos(a_score);
+
+ sm = ftos(m_score);
+ m_score *= e_turret.target_select_missilebias;
+ smt = ftos(m_score);
+
+ sp = ftos(p_score);
+ p_score *= e_turret.target_select_playerbias;
+ spt = ftos(p_score);
+
+
+ ss = ftos(score);
+ bprint("^3Target scores^7 \[ ",e_turret.netname, " \] ^3for^7 \[ ", e_target.netname," \]\n");
+ bprint("^5Range:\[ ",sd, " \]^2+bias:\[ ",sdt," \]\n");
+ //bprint("^5Volly:\[ ",sv, " \]^2+bias:\[ ",svt," \]\n");
+ bprint("^5Angle:\[ ",sa, " \]^2+bias:\[ ",sat," \]\n");
+ bprint("^5Missile:\[ ",sm," \]^2+bias:\[ ",smt," \]\n");
+ bprint("^5Player:\[ ",sp, " \]^2+bias:\[ ",spt," \]\n");
+ bprint("^3Total (w/bias):\[^1",ss,"\]\n");
+
+#endif
+
+ return score;
+}
+
+float turret_stdproc_targetscore_close(entity e_turret,entity e_target)
+{
+ return 1 - (tvt_dist / e_turret.target_range);
+}
+
+float turret_stdproc_targetscore_far (entity e_turret,entity e_target)
+{
+ return tvt_dist / e_turret.target_range;
+}
+
+float turret_stdproc_targetscore_optimal(entity e_turret,entity e_target)
+{
+ return min(e_turret.target_range_optimal,tvt_dist) / max(e_turret.target_range_optimal,tvt_dist);
+}
+
+float turret_stdproc_score_angular(entity e_turret,entity e_target)
+{
+ return 1 - (tvt_thadf / e_turret.aim_maxrot);
+}
+
+float turret_stdproc_targetscore_defend(entity e_turret,entity e_target)
+{
+ return 0;
+ //min(e_target.origin,e_turret.tur_defend.origin) / max(e_target.origin,e_turret.tur_defend.origin);
+}
Property changes on: trunk/data/qcsrc/server/tturrets/system/system_scoreprocs.qc
___________________________________________________________________
Name: svn:mergeinfo
+
Deleted: trunk/data/qcsrc/server/tturrets/system/turret_system_aimprocs.qc
===================================================================
--- trunk/data/qcsrc/server/tturrets/system/turret_system_aimprocs.qc 2008-10-24 07:48:04 UTC (rev 4855)
+++ trunk/data/qcsrc/server/tturrets/system/turret_system_aimprocs.qc 2008-10-24 07:54:17 UTC (rev 4856)
@@ -1,140 +0,0 @@
-/*
-* Straight line, Dead-on (no prediction)
-* Usefull for "stupid turrets" or ones
-* that launch guided weapons and just need to apeer to
-* somewhat face (and/or track) the target.
-
-supports:
-TFL_AIM_NO
-*/
-/*
-vector turret_stdproc_aim_simple()
-{
- float s_bu; // Solidity backup (for ground shooters)
- vector aim_pos;
-
- if (self.aim_flags & TFL_AIM_NO) return self.idle_aim;
-
- aim_pos = self.enemy.origin;
-
- // Target ground?
- if (self.aim_flags & TFL_AIM_GROUND)
- {
- s_bu = self.enemy.solid;
- self.enemy.solid = SOLID_NOT;
- traceline(self.enemy.origin + '0 0 128',self.enemy.origin + '0 0 -99999',1,self.enemy);
- self.enemy.solid = s_bu;
- aim_pos = trace_endpos;
- }
-
- // This is where its at.
- return aim_pos;
-}
-*/
-
-/*
-* Generic aim
-
-supports:
-TFL_AIM_NO
-TFL_AIM_GROUND
-TFL_AIM_LEAD
-TFL_AIM_SHOTTIMECOMPENSATE
-TFL_AIM_INFRONT
-TFL_AIM_BEHIND
-TFL_AIM_ZEASE
-
-not supported:
-TFL_AIM_BALISTIC
-*/
-
-
-vector turret_stdproc_aim_generic()
-{
- vector pre_pos;
- // entity mover;
-
- if (self.aim_flags == TFL_AIM_NO)
- return self.idle_aim;
-
- // Baseline
- pre_pos = real_origin(self.enemy);
-
- if(self.aim_flags & TFL_AIM_SIMPLE)
- return pre_pos;
-
- // Lead?
- //pre_pos = pre_pos + bot_shotlead(self.enemy.origin, self.enemy.velocity, self.shot_speed, 0.01); //self.enemy.velocity; * (self.tur_dist_enemy / self.shot_speed);
- if (self.aim_flags & TFL_AIM_LEAD)
- if (self.aim_flags & TFL_AIM_SHOTTIMECOMPENSATE) // Need to conpensate for shot traveltime
- {
- pre_pos = pre_pos + self.enemy.velocity * (self.tur_dist_enemy / self.shot_speed);
-
- // FIXME slow projectiles misspredict (well all do, bit the slow ons miss :P)
- }
- else if (self.turrcaps_flags & TFL_TURRCAPS_HITSCAN) // Hitscan gun, conpensate for frametime and posibly refire offset.
- pre_pos = pre_pos + self.enemy.velocity * (frametime + min(max(self.attack_finished_single - time,0),self.ticrate*2));
- else // No lead
- pre_pos += self.enemy.velocity;
-
-
- // Smooth out predict-Z?
- /*
- if (self.aim_flags & TFL_AIM_ZEASE)
- {
- vector v;
- v = real_origin(self.enemy);
- pre_pos_z = (pre_pos_z + v_z) * 0.5;
- }
- */
-
- /*
- if (self.aim_flags & TFL_AIM_INFRONT) // Aim a bit in front of the target
- pre_pos -= normalize(self.tur_aimorg_updated - pre_pos) * 32;
-
- if (self.aim_flags & TFL_AIM_BEHIND) // Aim a bit behind the target
- pre_pos += normalize(self.tur_aimorg_updated - pre_pos) * 32;
-
- */
- // This turret should hit the ground neer a target rather the do a direct hit
-
- if ( (self.aim_flags & TFL_AIM_GROUND) ||
- ((self.aim_flags & TFL_AIM_GROUND2) && (self.enemy.flags & FL_ONGROUND)) )
- {
- traceline(pre_pos + '0 0 8',pre_pos - '0 0 10000',1,self.enemy);
- pre_pos = trace_endpos;
- }
-
-
-
-
-
-
-
- return pre_pos;
-}
-
-
-/*
-* Aim where it is
-supports:
-TFL_AIM_NO
-*/
-/*
-vector turret_stdproc_aim_rail()
-{
- vector pre_pos;
-
- if (self.aim_flags & TFL_AIM_NO)
- return self.idle_aim;
-
- pre_pos = real_origin(self.enemy);
-
- self.tur_dist_toaimpos = vlen(self.enemy.origin - self.tur_aimorg_updated);
-
- self.tur_impacttime = time;
-
- return pre_pos;
-
-}
-*/
Deleted: trunk/data/qcsrc/server/tturrets/system/turret_system_damage.qc
===================================================================
--- trunk/data/qcsrc/server/tturrets/system/turret_system_damage.qc 2008-10-24 07:48:04 UTC (rev 4855)
+++ trunk/data/qcsrc/server/tturrets/system/turret_system_damage.qc 2008-10-24 07:54:17 UTC (rev 4856)
@@ -1,319 +0,0 @@
-/*
-* Trow a turret gib
-*/
-void turret_gib_damage (entity inflictor, entity attacker, float damage, float deathtype, vector hitloc, vector vforce)
-{
- self.velocity += vforce;
-}
-
-void turret_trowgib(
- vector v_from, vector v_to, vector v_colormod,
- string smodel,
- float f_lifetime, float f_fadetime, float b_burn)
-{
- local entity gib;
- local entity burn;
-
- gib = spawn();
-
- gib.classname = "turret_gib";
- 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;
- gib.health = -1;
- gib.effects = EF_LOWPRECISION;
- gib.flags = FL_NOTARGET;
- gib.colormod = v_colormod;
- gib.velocity = v_to;
-
- if (b_burn)
- {
- burn = spawn();
- 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);
- }
-}
-
-void turret_gib_boom()
-{
- entity gib;
- float i;
- string s;
-
- for (i = 1; i < 5; i = i +1)
- {
- gib = spawn();
- gib.classname = "turret_gib";
-
- s = strcat("models/turrets/head-gib",ftos(i));
- s = strcat(s,".md3");
- // bprint("s:",s,"\n");
- 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;
- gib.takedamage = DAMAGE_YES;
- gib.event_damage = turret_gib_damage;
- gib.health = -1;
- gib.effects = EF_LOWPRECISION;
- gib.flags = FL_NOTARGET;
- gib.velocity = self.velocity + (randomvec() * 700);
- gib.avelocity = randomvec() * 64;
- }
-
- WriteByte (MSG_BROADCAST, SVC_TEMPENTITY);
- WriteByte (MSG_BROADCAST, 78);
- WriteCoord (MSG_BROADCAST, self.origin_x);
- WriteCoord (MSG_BROADCAST, self.origin_y);
- WriteCoord (MSG_BROADCAST, self.origin_z);
-
- remove(self);
-}
-
-void turret_trowgib2(
- vector v_from, vector v_to, vector v_colormod,
- entity e_mimic, float boomtime)
-{
- entity gib;
-
- gib = spawn();
-
- gib.classname = "turret_gib";
- setmodel(gib,e_mimic.model);
- setorigin(gib,v_from);
-
- gib.solid = SOLID_BBOX;
-
- gib.movetype = MOVETYPE_BOUNCE;
- gib.gravity = 0.75;
- gib.damageforcescale = 2;
- gib.takedamage = DAMAGE_YES;
- gib.event_damage = turret_gib_damage;
- gib.health = -1;
- gib.effects = EF_LOWPRECISION;
- gib.flags = FL_NOTARGET;
- gib.colormod = v_colormod;
- gib.velocity = v_to;
- gib.avelocity = randomvec() * 32;
- gib.think = turret_gib_boom;
- gib.nextthink = boomtime;
- gib.effects = EF_FLAME;
-
-
-}
-/*
-* Spawn a boom, trow fake bits arround
-* and hide the real ones.
-*/
-void turret_stdproc_die()
-{
- vector org2;
- vector t_dir;
-
- // self.tur_active = 0;
-
- self.deadflag = DEAD_DEAD;
- self.tur_head.deadflag = self.deadflag;
-
- sound (self, CHAN_PLAYER, "weapons/rocket_impact.wav", 1, ATTN_NORM);
- org2 = self.origin + '0 0 40';
-
-// Explotion grafix
- WriteByte (MSG_BROADCAST, SVC_TEMPENTITY);
- WriteByte (MSG_BROADCAST, 78);
- WriteCoord (MSG_BROADCAST, org2_x);
- WriteCoord (MSG_BROADCAST, org2_y);
- WriteCoord (MSG_BROADCAST, org2_z);
-
-// Unsolidify and hide real parts
- self.solid = SOLID_NOT;
- self.tur_head.solid = self.solid;
-
- self.alpha = -1;
- self.tur_head.alpha = -1;
-
- self.takedamage = DAMAGE_NO;
- self.tur_head.takedamage = self.takedamage;
-
- self.effects = 0;
- self.tur_head.effects = self.effects;
-
- self.health = 0;
-
-
-// Trow fake parts arround
-
- // base
- 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);
- 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);
- }
- else
- {
- 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));
-
-
-// Go boom
- RadiusDamage (self,self, min(self.ammo,50),min(self.ammo,50) * 0.25,250,world,min(self.ammo,50)*5,0,world);
-
- if(self.damage_flags & TFL_DMG_DEATH_NORESPAWN)
- {
- if (self.turret_diehook)
- self.turret_diehook();
-
- remove(self.tur_head);
- remove(self);
- }
- else
- {
- // Setup respawn
- self.nextthink = time + self.respawntime;
- //self.think = self.turret_spawnfunc;
- self.think = turret_stdproc_respawn;
- if (self.turret_diehook)
- self.turret_diehook();
- }
-
-}
-
-void turret_stdproc_respawn()
-{
- // self.tur_active = 1;
-
- // Make sure all parts belong to the same team since
- // this function doubles as "teamchange" function.
- self.tur_head.team = self.team;
- if (self.team == COLOR_TEAM1)
- self.colormod = '1.4 0.8 0.8';
- else if (self.team == COLOR_TEAM2)
- self.colormod = '0.8 0.8 1.4';
- else
- self.colormod = '0 0 0'; // reset
-
- self.deadflag = DEAD_NO;
- self.tur_head.deadflag = self.deadflag;
- self.effects = self.tur_head.effects = 0;
-
- self.solid = SOLID_BBOX;
- self.tur_head.solid = self.solid;
-
- self.alpha = 1;
- self.tur_head.alpha = self.alpha;
-
- self.takedamage = DAMAGE_YES;
- self.tur_head.takedamage = self.takedamage;
-
- self.avelocity = '0 0 0';
- self.tur_head.avelocity = self.avelocity;
- self.tur_head.angles = self.idle_aim;
-
- self.health = self.tur_health;
-
- self.enemy = world;
- self.volly_counter = self.shot_volly;
- self.ammo = self.ammo_max;
-
- self.nextthink = time + self.ticrate;
- self.think = turret_think;
-
- if (self.turret_respawnhook)
- self.turret_respawnhook();
-
-}
-
-/*
-* Standard damage proc.
-*/
-void turret_stdproc_damage (entity inflictor, entity attacker, float damage, float deathtype, vector hitloc, vector vforce)
-{
- entity baseent,oldself;
- // entity player;
-
- if (self.health <= 0) return;
-
- // Damage func is shared on all parts as standard, we need to know what the master entity of this turret is.
- // if ((self.classname == "turret_head")||(self.classname == "turret_gun")||(self.classname == "turret_badge"))
- if (self.owner)
- baseent = self.owner;
- else
- baseent = self;
-
- if (teamplay != 0)
- {
- if (self.team == attacker.team)
- {
- sprint(attacker, "\{1}Turret tells you: I'm on your team!\n");
- return;
- }
- else
- {
- /*
- // This will get enoying fast...
- FOR_EACH_PLAYER(player)
- if(player.team == self.team)
- sprint(player, "The enemy is attacking your base!");
-
- */
- }
-
- }
-
- baseent.health = baseent.health - damage;
-
- // thorw head slightly off aim when hit?
- if ((self.classname == "turret_head") || (self.classname == "turret_gun"))
- if (self.damage_flags & TFL_DMG_HEADSHAKE)
- {
- // makevectors(baseent.tur_head.v_angle);
- baseent.tur_head.angles = baseent.tur_head.angles + randomvec() * damage;
- }
-
- if (self.turrcaps_flags & TFL_TURRCAPS_MOVE)
- {
- self.velocity = self.velocity + vforce;
- }
-
-
- // Start burning when we have 10% or less health left
- if (self.health < (self.tur_health * 0.1))
- self.effects = EF_FLAME;
-
- if (self.health <= 0)
- {
- oldself = self;
- self = baseent;
- turret_stdproc_die();
- self = oldself;
-
- //baseent.turret_diefunc();
- }
-}
-
-
Deleted: trunk/data/qcsrc/server/tturrets/system/turret_system_main.qc
===================================================================
--- trunk/data/qcsrc/server/tturrets/system/turret_system_main.qc 2008-10-24 07:48:04 UTC (rev 4855)
+++ trunk/data/qcsrc/server/tturrets/system/turret_system_main.qc 2008-10-24 07:54:17 UTC (rev 4856)
@@ -1,1104 +0,0 @@
-#define cvar_base "g_turrets_unit_"
-
-//.float tur_lastscore;
-.string cvar_basename;
-
-string cvar_gets(string s_base,string s_add)
-{
- return strcat(s_base,s_add);
-}
-
-.float turret_scale_damage;
-.float turret_scale_range;
-.float turret_scale_refire;
-.float turret_scale_ammo;
-.float turret_scale_aim;
-.float turret_scale_health;
-.float turret_scale_respawn;
-
-void load_unit_settings(entity ent,string unitname,float is_reload)
-{
-
- string sbase;
-
- if (ent == world)
- return;
-
- if (!ent.turret_scale_damage) ent.turret_scale_damage = 1;
- if (!ent.turret_scale_range) ent.turret_scale_range = 1;
- if (!ent.turret_scale_refire) ent.turret_scale_refire = 1;
- if (!ent.turret_scale_ammo) ent.turret_scale_ammo = 1;
- if (!ent.turret_scale_aim) ent.turret_scale_aim = 1;
- 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 = world;
- ent.tur_head.avelocity = '0 0 0';
- ent.tur_head.angles = ent.angles;
- }
- ent.health = cvar(cvar_gets(sbase,"_health")) * ent.turret_scale_health;
- ent.respawntime = cvar(cvar_gets(sbase,"_respawntime")) * ent.turret_scale_respawn;
-
- ent.shot_dmg = cvar(cvar_gets(sbase,"_shot_dmg")) * ent.turret_scale_damage;
- ent.shot_refire = cvar(cvar_gets(sbase,"_shot_refire")) * ent.turret_scale_refire;
- ent.shot_radius = cvar(cvar_gets(sbase,"_shot_radius")) * ent.turret_scale_damage;
- ent.shot_speed = cvar(cvar_gets(sbase,"_shot_speed"));
- ent.shot_spread = cvar(cvar_gets(sbase,"_shot_spread"));
- ent.shot_force = cvar(cvar_gets(sbase,"_shot_force")) * ent.turret_scale_damage;
- ent.shot_volly = cvar(cvar_gets(sbase,"_shot_volly"));
- ent.shot_volly_refire = cvar(cvar_gets(sbase,"_shot_volly_refire")) * ent.turret_scale_refire;
-
- ent.target_range = cvar(cvar_gets(sbase,"_target_range")) * ent.turret_scale_range;
- ent.target_range_min = cvar(cvar_gets(sbase,"_target_range_min")) * ent.turret_scale_range;
- ent.target_range_fire = cvar(cvar_gets(sbase,"_target_range_fire")) * ent.turret_scale_range;
- ent.target_range_optimal = cvar(cvar_gets(sbase,"_target_range_optimal")) * ent.turret_scale_range;
-
- ent.target_select_rangebias = cvar(cvar_gets(sbase,"_target_select_rangebias"));
- ent.target_select_samebias = cvar(cvar_gets(sbase,"_target_select_samebias"));
- ent.target_select_anglebias = cvar(cvar_gets(sbase,"_target_select_anglebias"));
- ent.target_select_playerbias = cvar(cvar_gets(sbase,"_target_select_playerbias"));
-
- ent.ammo_max = cvar(cvar_gets(sbase,"_ammo_max")) * ent.turret_scale_ammo;
- //ent.ammo = cvar(cvar_gets(sbase,"_ammo"));
- ent.ammo_recharge = cvar(cvar_gets(sbase,"_ammo_recharge")) * ent.turret_scale_ammo;
-
- ent.aim_firetolerance_dist = cvar(cvar_gets(sbase,"_aim_firetolerance_dist"));
-// ent.aim_firetolerance_angle = cvar(cvar_gets(sbase,"_aim_firetolerance_angle"));
- ent.aim_speed = cvar(cvar_gets(sbase,"_aim_speed")) * ent.turret_scale_aim;
- ent.aim_maxrot = cvar(cvar_gets(sbase,"_aim_maxrot"));
- ent.aim_maxpitch = cvar(cvar_gets(sbase,"_aim_maxpitch"));
-
- ent.track_type = cvar(cvar_gets(sbase,"_track_type"));
- ent.track_accel_pitch = cvar(cvar_gets(sbase,"_track_accel_pitch"));
- ent.track_accel_rot = cvar(cvar_gets(sbase,"_track_accel_rot"));
- ent.track_blendrate = cvar(cvar_gets(sbase,"_track_blendrate"));
-}
-
-float turret_stdproc_true()
-{
- return 1;
-}
-
-float turret_stdproc_false()
-{
- return 0;
-}
-
-void turret_stdproc_nothing()
-{
- return;
-}
-
-/**
-** updates enemy distances, preicted impact point/time
-** & aim<->predict impact distance.
-** Also translates shoot & aimorgs by current rotation.
-**/
-void turret_do_updates(entity e_turret)
-{
- if (self.turrcaps_flags & TFL_TURRCAPS_LINKED)
- {
- e_turret.tur_head.angles_x = e_turret.tur_head.angles_x * -1;
- e_turret.angles_x = e_turret.angles_x * -1;
- makevectors(e_turret.tur_head.angles + e_turret.angles);
- e_turret.tur_head.angles_x = e_turret.tur_head.angles_x * -1;
- e_turret.angles_x = e_turret.angles_x * -1;
- }
- else
- {
- e_turret.tur_head.angles_x = e_turret.tur_head.angles_x * -1;
- makevectors(e_turret.tur_head.angles);
- e_turret.tur_head.angles_x = e_turret.tur_head.angles_x * -1;
- }
- // v_right = (v_right * -1);
- e_turret.tur_shotorg_updated = e_turret.origin + v_forward * e_turret.tur_shotorg_x + v_right * e_turret.tur_shotorg_y + v_up * e_turret.tur_shotorg_z;
-
- e_turret.tur_shotdir_updated = normalize((e_turret.tur_shotorg_updated + v_forward) - e_turret.tur_shotorg_updated);
- e_turret.tur_aimorg_updated = e_turret.origin + v_forward * e_turret.tur_aimorg_x + v_right * e_turret.tur_aimorg_y + v_up * e_turret.tur_aimorg_z;
-
-
- e_turret.tur_dist_enemy = vlen(e_turret.tur_aimorg_updated - real_origin(e_turret.enemy));
-
- traceline(e_turret.tur_aimorg_updated,e_turret.tur_aimorg_updated+(e_turret.tur_shotdir_updated * e_turret.tur_dist_enemy),MOVE_NORMAL,e_turret);
-
- e_turret.tur_impactpoint = trace_endpos;
- e_turret.tur_impactent = trace_ent;
- //e_turret.tur_impacttime = e_turret.tur_dist_enemy / e_turret.shot_speed;
- e_turret.tur_impacttime = e_turret.tur_dist_enemy / e_turret.shot_speed;
- e_turret.tur_dist_toaimpos = vlen(trace_endpos - e_turret.tur_aimpos);
-}
-
-/**
-** Handles head rotation according to
-** the units .track_type and .track_flags
-**/
-void turret_stdproc_track()
-{
- vector wish_angle; // This is where we'd need to be
-
- vector real_angle; // This is where we can go
- float f_tmp;
-
-
- if (self.track_flags == TFL_TRACK_NO)
- return;
-
- if(!self.tur_active)
- {
- wish_angle = self.idle_aim - ('1 0 0' * self.aim_maxpitch);
- }
- else if (self.enemy == world)
- {
- if (self.turrcaps_flags & TFL_TURRCAPS_LINKED)
- wish_angle = self.idle_aim + self.angles;
- else
- if(cvar("g_turrets_aimidle_delay") > (time - self.lip))
- wish_angle = self.idle_aim;
- else
- wish_angle = self.tur_head.angles;
-
- }
- else
- {
- // Find the direction
- if (self.turrcaps_flags & TFL_TURRCAPS_LINKED)
- wish_angle = normalize(self.tur_aimpos - self.origin);
- else
- wish_angle = normalize(self.tur_aimpos - self.tur_head.origin);
-
- wish_angle = vectoangles(wish_angle); // And make a angle
- }
-
- // Find the diffrence between where we currently aim and where we want to aim
- if (self.turrcaps_flags & TFL_TURRCAPS_LINKED)
- real_angle = wish_angle - (self.angles + self.tur_head.angles);
- else
- {
- //if(vlen(wish_angle - self.tur_head.angles) > vlen(self.tur_head.angles - wish_angle))
- real_angle = wish_angle - self.tur_head.angles;
- //else
- // real_angle = self.tur_head.angles - wish_angle;
- }
-
- /*
- if(real_angle_y > 180)
- bprint("^3");
- if(real_angle_y < -180)
- bprint("^1");
- string s;
- s = vtos(real_angle);
- bprint("RA1: ",s);
- */
-
-
- if (real_angle_x < 0) real_angle_x += 360;
- if (real_angle_x > 180) real_angle_x -= 360;
-
- if (real_angle_y < 0) real_angle_y += 360;
- if (real_angle_y >= 180) real_angle_y -= 360;
-
- //s = vtos(real_angle);
- //bprint(" RA2: ",s,"\n");
-
- // Limit pitch
-
- if (self.track_flags & TFL_TRACK_PITCH)
- real_angle_x = bound(self.aim_maxpitch * -1,real_angle_x,self.aim_maxpitch);
-
- // Limit rot
- if (self.track_flags & TFL_TRACK_ROT)
- real_angle_y = bound(self.aim_maxrot * -1,real_angle_y,self.aim_maxrot);
-
-
- if (self.track_type == TFL_TRACKTYPE_STEPMOTOR)
- {
- f_tmp = self.aim_speed * self.ticrate; // dgr/sec -> dgr/tic
-
- // Limit turning speed
- real_angle_x = bound((-1 * f_tmp),real_angle_x, f_tmp);
- real_angle_y = bound((-1 * f_tmp),real_angle_y, f_tmp);
-
- // Limit pich and rot.
- if (self.track_flags & TFL_TRACK_PITCH)
- self.tur_head.angles_x = bound((-1 * self.aim_maxpitch),self.tur_head.angles_x + real_angle_x,self.aim_maxpitch);
-
- if (self.track_flags & TFL_TRACK_ROT)
- self.tur_head.angles_y = bound((-1 * self.aim_maxrot),self.tur_head.angles_y + real_angle_y,self.aim_maxrot);
-
- return;
- }
-
- if (self.track_type == TFL_TRACKTYPE_FLUIDPRECISE)
- {
- if (self.track_flags & TFL_TRACK_PITCH)
- self.tur_head.avelocity_x = real_angle_x;
-
- if (self.track_flags & TFL_TRACK_ROT)
- self.tur_head.avelocity_y = real_angle_y;
- }
- else if (self.track_type == TFL_TRACKTYPE_FLUIDINERTIA)
- {
- f_tmp = self.aim_speed * self.ticrate;
-
- real_angle_y = bound(self.aim_speed * -1,real_angle_y * self.track_accel_rot * f_tmp,self.aim_speed);
- real_angle_x = bound(self.aim_speed * -1,real_angle_x * self.track_accel_pitch * f_tmp,self.aim_speed);
- real_angle = (self.tur_head.avelocity * self.track_blendrate) + (real_angle * (1 - self.track_blendrate));
-
- if (self.track_flags & TFL_TRACK_PITCH) self.tur_head.avelocity_x = real_angle_x;
- if (self.track_flags & TFL_TRACK_ROT) self.tur_head.avelocity_y = real_angle_y;
- self.tur_head.avelocity_z = real_angle_z;
- }
-
- // Limit pitch
- /*
- if (self.track_flags & TFL_TRACK_PITCH)
- {
- if (self.tur_head.angles_x > self.aim_maxpitch)
- {
- self.tur_head.angles_x = self.aim_maxpitch;
- self.tur_head.avelocity_x = 0;
- }
- else if (self.tur_head.angles_x < (self.aim_maxpitch * -1))
- {
- self.tur_head.angles_x = (self.aim_maxpitch * -1);
- self.tur_head.avelocity_x = 0;
- }
- }
-
- // Limit rot
- if (self.track_flags & TFL_TRACK_ROT)
- {
- if (self.tur_head.angles_y > self.aim_maxrot)
- {
- self.tur_head.angles_y = self.aim_maxrot;
- self.tur_head.avelocity_y = 0;
- }
- else if (self.tur_head.angles_y < (self.aim_maxrot * -1))
- {
- self.tur_head.angles_y = (self.aim_maxrot * -1);
- self.tur_head.avelocity_y = 0;
- }
- }
- */
-
-
-}
-
-/*
- + = implemented
- - = not implemented
-
- + TFL_FIRECHECK_NO
- + TFL_FIRECHECK_WORLD
- + TFL_FIRECHECK_DEAD
- + TFL_FIRECHECK_DISTANCES
- - TFL_FIRECHECK_LOS
- + TFL_FIRECHECK_AIMDIST
- + TFL_FIRECHECK_REALDIST
- - TFL_FIRECHECK_ANGLEDIST
- - TFL_FIRECHECK_TEAMCECK
- + TFL_FIRECHECK_AFF
- + TFL_FIRECHECK_OWM_AMMO
- + TFL_FIRECHECK_OTHER_AMMO
- + TFL_FIRECHECK_REFIRE
-*/
-
-/**
-** Preforms pre-fire checks based on the uints firecheck_flags
-**/
-float turret_stdproc_firecheck()
-{
- // This one just dont care =)
- if (self.firecheck_flags & TFL_FIRECHECK_NO) return 1;
-
- // Ready?
- if (self.firecheck_flags & TFL_FIRECHECK_REFIRE)
- if (self.attack_finished_single >= time) return 0;
-
- //
- if (self.firecheck_flags & TFL_FIRECHECK_DEAD)
- if (self.enemy.deadflag != DEAD_NO) return 0;
-
- // Plz stop killing the world!
- if (self.firecheck_flags & TFL_FIRECHECK_WORLD)
- if (self.enemy == world) return 0;
-
- // Own ammo?
- if (self.firecheck_flags & TFL_FIRECHECK_OWM_AMMO)
- if (self.ammo < self.shot_dmg) return 0;
-
- // Other's ammo? (carefull using this...)
- if (self.firecheck_flags & TFL_FIRECHECK_OTHER_AMMO)
- if (self.enemy.ammo >= self.enemy.ammo_max) return 0;
-
- if (self.firecheck_flags & TFL_FIRECHECK_DISTANCES)
- {
- // Not close enougth?
- if (self.tur_dist_enemy > self.target_range_fire) return 0;
-
- // To close?
- if (self.tur_dist_enemy < self.target_range_min) return 0;
- }
-
- // Try to avoid FF?
- if (self.firecheck_flags & TFL_FIRECHECK_AFF)
- if (self.tur_impactent.team == self.team) return 0;
-
- // aim<->predicted impact
- if (self.firecheck_flags & TFL_FIRECHECK_AIMDIST)
- if (self.tur_dist_toaimpos > self.aim_firetolerance_dist) return 0;
-
- // Volly status
- if (self.shot_volly > 1)
- {
- if (self.volly_counter == self.shot_volly)
- if (self.ammo < (self.shot_dmg * self.shot_volly))
- return 0;
- }
-
- //if(self.tur_enemy_adist >= self.aim_firetolerance) return 0;
-
-
- return 1;
-}
-
-/*
- + TFL_TARGETSELECT_NO
- + TFL_TARGETSELECT_LOS
- + TFL_TARGETSELECT_PLAYERS
- + TFL_TARGETSELECT_MISSILES
- - TFL_TARGETSELECT_TRIGGERTARGET
- + TFL_TARGETSELECT_ANGLELIMITS
- + TFL_TARGETSELECT_RANGELIMTS
- + TFL_TARGETSELECT_TEAMCHECK
- - TFL_TARGETSELECT_NOBUILTIN
- + TFL_TARGETSELECT_OWNTEAM
-*/
-
-/**
-** Evaluate a entity for target valitity based on validate_flags
-**/
-float turret_validate_target(entity e_turret,entity e_target,float validate_flags)
-{
- vector v_tmp;
-
- //if(!validate_flags & TFL_TARGETSELECT_NOBUILTIN)
- // return -0.5;
-
- if (!e_target)// == world)
- return -1;
-
- if (e_target.classname == "grapplinghook")
- return - 1.5;
-
- if(g_onslaught)
- if (substring(e_target.classname, 0, 10) == "onslaught_") // don't attack onslaught targets, that's the player's job!
- return - 1.75;
-
- if (validate_flags & TFL_TARGETSELECT_NO)
- return -2;
-
- // If only this was used more..
- if (e_target.flags & FL_NOTARGET)
- return -3;
-
- // Cant touch this
- if ((e_target.takedamage == DAMAGE_NO) || (e_target.health < 0))
- return -4;
-
- // player
- if (e_target.flags & FL_CLIENT)
- {
- if (!(validate_flags & TFL_TARGETSELECT_PLAYERS))
- return -5;
-
- if (e_target.deadflag != DEAD_NO)
- return -6;
- }
-
- // enemy turrets
- if (e_target.turret_firefunc || e_target.owner.tur_head == e_target)
- {
- if (validate_flags & TFL_TARGETSELECT_NOTURRETS)
- return -5.5;
- }
-
- // Missile
- if (e_target.flags & FL_PROJECTILE)
- {
- if (!(validate_flags & TFL_TARGETSELECT_MISSILES))
- return -7;
- }
-
- // Team check
- if (validate_flags & TFL_TARGETSELECT_TEAMCHECK)
- {
- if (validate_flags & TFL_TARGETSELECT_OWNTEAM)
- {
- if (e_target.team != e_turret.team)
- return -8;
-
- if (e_turret.team != e_target.owner.team)
- return -8.5;
- }
- else
- {
- if (e_target.team == e_turret.team)
- return -9;
-
- if (e_turret.team == e_target.owner.team)
- return -9.5;
- }
- }
-
- // Line of sight?
- if (validate_flags & TFL_TARGETSELECT_LOS)
- {
- v_tmp = real_origin(e_target) + ((e_target.mins + e_target.maxs) * 0.5);
- //v_tmp = e_target.origin;
- traceline(e_turret.origin,v_tmp,0,e_turret);
-
- if (e_turret.aim_firetolerance_dist < vlen(v_tmp - trace_endpos))
- return -10;
- }
-
- // Can we even aim this thing? (anglecheck)
- tvt_thadv = angleofs(e_turret.tur_head,e_target);
- tvt_tadv = angleofs(e_turret,e_target);
- tvt_thadf = vlen(tvt_thadv);
- tvt_tadf = vlen(tvt_tadv);
-
- if (validate_flags & TFL_TARGETSELECT_ANGLELIMITS)
- {
- if (fabs(tvt_tadv_x) > e_turret.aim_maxpitch)
- return -11;
-
- if (fabs(tvt_tadv_y) > e_turret.aim_maxrot)
- return -12;
- }
-
- // Range limits?
- tvt_dist = vlen(e_turret.origin - real_origin(e_target));
- if (validate_flags & TFL_TARGETSELECT_RANGELIMTS)
- {
- if (tvt_dist < e_turret.target_range_min)
- return -13;
-
- if (tvt_dist > e_turret.target_range)
- return -14;
- }
-
-#ifdef TURRET_DEBUG_TARGETSELECT
- bprint("Target:",e_target.netname," is a valid target for ",e_turret.netname,"\n");
-#endif
-
- return 1;
-}
-
-entity turret_select_target()
-{
- entity e; // target looper entity
- entity e_enemy; // currently best scoreing enemy
-
- float score; // current target (e) score
- float m_score; // current best target (e_enemy) score
- float f;
- // string s;
- e = findradius(self.origin,self.target_range);
-
- // Nothing to aim at.
- if (!e) return world;
-
- m_score = 0;
-
- while (e)
- {
- f = turret_validate_target(self,e,self.target_select_flags);
- //s = ftos(f);
- //bprint(e.netname, " = ",s,"\n");
- if (f > 0)
- {
-
- score = self.turret_score_target(self,e);
-
- if ((score > m_score) && (score > 0))
- {
- e_enemy = e;
- m_score = score;
- }
- }
-
- e = e.chain;
- }
-
-// self.tur_lastscore = m_score;
-
- //if (self.enemy != e_enemy)
- //self.volly_counter = 0;
-
- return e_enemy;
-}
-
-void turret_think()
-{
- entity e;
-
- self.nextthink = (time + self.ticrate);
-
- // ONS uses somewhat backwards linking.
- if (teamplay)
- {
- if (g_onslaught)
- {
-
- }
- else
- {
- if (self.target)
- {
- e = find(world,targetname,self.target);
- if (e != world)
- self.team = e.team;
- }
- }
-
- if (self.team != self.tur_head.team)
- turret_stdproc_respawn();
- }
-
-
- if (cvar("g_turrets_reloadcvars") == 1)
- {
- e = nextent(world);
- while (e)
- {
- if (e.tur_head != world)
- {
-
- load_unit_settings(e,e.cvar_basename,1);
- e.turret_postthink();
- }
-
- e = nextent(e);
- }
-
- cvar_set("g_turrets_reloadcvars","0");
- }
-
-#ifdef TURRET_DEBUG
- if (self.tur_dbg_tmr1 < time)
- {
- if (self.enemy) paint_target (self.enemy,128,self.tur_dbg_rvec,0.9);
- paint_target(self,256,self.tur_dbg_rvec,0.9);
- self.tur_dbg_tmr1 = time + 1;
- }
-#endif
-
- //Do custom prethink, and bail if it fails.
- //if (!self.turret_prethink()) return;
-
- // Handle ammo
- if (self.ammo < self.ammo_max)
- self.ammo = min(self.ammo + self.ammo_recharge,self.ammo_max);
-
-
- // Inactive turrets needs to run the think loop too
- // So they can handle animation and wake up if need be.
- if(!self.tur_active)
- {
- turret_stdproc_track();
- return;
- }
-
- //This is just wrong :|
- if(self.deadflag != DEAD_NO)
- {
- dprint("Warning:dead turret running the think function!\n");
- //self.enemy = world;
- //turret_stdproc_track();
- 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)
- {
-
- // Do a self.turret_fire for every valid target.
- e = findradius(self.origin,self.target_range);
-
- while (e)
- {
- if (turret_validate_target(self,e,self.target_validate_flags))
- {
- self.enemy = e;
-
- turret_do_updates(self);
-
- if ( self.turret_firecheckfunc() ) turret_fire();
- }
-
- e = e.chain;
- }
- self.enemy = world;
-
- }
- else
- {
- // Check if we have a vailid enemy, and try to find one if we dont.
- if ((turret_validate_target(self,self.enemy,self.target_validate_flags) <= 0) || (self.cnt < time))
- {
- self.enemy = turret_select_target();
- self.cnt = time + cvar("g_turrets_targetscan_mindelay");
- }
-
-
- // No target, just go to idle, do any custom stuff and bail.
- if (self.enemy == world)
- {
- // Turn & pitch
- if (!self.track_flags & TFL_TRACK_NO)
- turret_stdproc_track();
-
- // do any per-turret stuff
- self.turret_postthink();
-
- // And bail.
- return;
- }
- else
- self.lip = time; // Keep track of the last time we had a target.
-
- turret_do_updates(self);
-
- // Predict or whatnot
- if not((self.aim_flags & TFL_AIM_NO))
- self.tur_aimpos = turret_stdproc_aim_generic();
-
- // Fire?
- if (self.turret_firecheckfunc() != 0)
- turret_fire();
-
- turret_do_updates(self);
-
- // Turn & pitch
- if (!self.track_flags & TFL_TRACK_NO)
- turret_stdproc_track();
-
- turret_do_updates(self);
-
- // Fire?
- if (self.turret_firecheckfunc() != 0)
- turret_fire();
- }
-
- // do any per-turret stuff
- self.turret_postthink();
-}
-
-void turret_fire()
-{
- if (cvar("g_turrets_nofire") != 0) return;
- if ((!self.tur_active) || (self.deadflag != DEAD_NO)) return;
-
- self.turret_firefunc();
-
- self.attack_finished_single = time + self.shot_refire;
- self.ammo = self.ammo - self.shot_dmg;
- self.volly_counter = self.volly_counter - 1;
-
-
- if (self.volly_counter <= 0)
- {
- self.volly_counter = self.shot_volly;
- if (self.shoot_flags & TFL_SHOOT_CLEARTARGET) self.enemy = world;
-
- if (self.shot_volly > 1)
- self.attack_finished_single = time + self.shot_volly_refire;
- }
-
-
-#ifdef TURRET_DEBUG
- if (self.enemy) paint_target3(self.tur_aimpos ,64,self.tur_dbg_rvec,self.tur_impacttime+0.25);
-#endif
-}
-
-void turret_stdproc_fire()
-{
- dprint("^1Bang, ^3your dead^7 ",self.enemy.netname,"! ^1(turret with no real firefunc)\n");
-}
-
-void turret_stdproc_use()
-{
- // bprint("Used:",self.netname, " By ",other.netname,"\n");
-
- // ONS Uses _use to communicate.
- if (g_onslaught)
- {
- entity e;
-
- if (self.targetname)
- {
- e = find(world,target,self.targetname);
- if (e != world)
- self.team = e.team;
- }
-
- if (self.team != self.tur_head.team)
- turret_stdproc_respawn();
-
- if(self.team == 0)
- self.tur_active = 0;
- else
- self.tur_active = 1;
-
- }
- else
- {
- if (self.tur_active)
- self.tur_active = 0;
- else
- self.tur_active = 1;
- }
-
-}
-
-/*
-* Standard turret initialization. use this!
-* (unless you have a very good reason not to.)
-* Any special stuff like multiple cannon models should be done
-* after this is proc called.
-* if the return value is 0, the turret should be removed.
-*/
-float turret_stdproc_init (string cvar_base_name)
-{
- entity e;
-
- // Are turrets allowed atm?
- if (cvar("g_turrets") == 0) return 0;
-
- // Better more then once then never.
- // turret_gibs_precash();
-
- if (self.spawnflags & 2)
- {
- entity tb;
- precache_model("models/turrets/terrainbase.md3");
- tb = spawn();
- setmodel(tb,"models/turrets/terrainbase.md3");
- setorigin(tb,self.origin);
- tb.solid = SOLID_BBOX;
- makestatic(tb);
- }
-
- self.cvar_basename = cvar_base_name;
- load_unit_settings(self,self.cvar_basename,0);
-
- // Group all turrets into the same team if in non teamplaymode, so they dont try to kill eachother.
- if (cvar("g_assult") != 0)
- {
- if (!self.team)
- self.team = 14; // Assume turrets are on the defending side if not explicitly set otehrwize
- }
- else if (!teamplay)
- self.team = MAX_SHOT_DISTANCE;
- else if(g_onslaught && self.targetname)
- {
- e = find(world,target,self.targetname);
- if(e != world)
- self.team = e.team;
- }
- else if(!self.team)
- self.team = MAX_SHOT_DISTANCE;
-
-
- /*
- * Try to guess some reasonaly defaults
- * for missing params and do sanety checks
- * thise checks could produce some "interesting" results
- * if it hits a glitch in my logic :P so try to set as mutch
- * as possible beforehand.
- */
- if (self.turrcaps_flags & TFL_TURRCAPS_SUPPORT)
- {
- // Support units generaly dont need to have a high speed ai-loop
- if (!self.ticrate) self.ticrate = 0.25; // Speed of this turrets AI loop
- }
- else
- {
- if (!self.ticrate) self.ticrate = 0.1; // Speed of this turrets AI loop
- }
-
- self.ticrate = bound(0.01,self.ticrate,60); // keep it sane plz
-
-// General stuff
- if (self.netname == "") self.netname = "turret";
-
- if (!self.respawntime) self.respawntime = 60;
- self.respawntime = max(-1,self.respawntime);
-
- if (!self.health) self.health = 1000;
- self.tur_health = max(1,self.health);
-
- if (!self.turrcaps_flags) self.turrcaps_flags = TFL_TURRCAPS_RADIUSDMG | TFL_TURRCAPS_MEDPROJ | TFL_TURRCAPS_PLAYERKILL;
-
- if (!self.damage_flags) self.damage_flags = TFL_DMG_YES | TFL_DMG_RETALIATE | TFL_DMG_AIMSHAKE;
-
-// Shot stuff.
- if (!self.shot_refire) self.shot_refire = 1;
- self.shot_refire = bound(0.01,self.shot_refire,9999);
-
- if (!self.shot_dmg) self.shot_dmg = self.shot_refire * 50;
- self.shot_dmg = max(1,self.shot_dmg);
-
- if (!self.shot_radius) self.shot_radius = self.shot_dmg * 0.5;
- self.shot_radius = max(1,self.shot_radius);
-
- if (!self.shot_speed) self.shot_speed = 2500;
- self.shot_speed = max(1,self.shot_speed);
-
- if (!self.shot_spread) self.shot_spread = 0.0125;
- self.shot_spread = bound(0.0001,self.shot_spread,500);
-
- if (!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);
-
- if (!self.shot_volly) self.shot_volly = 1;
- self.shot_volly = bound(1,self.shot_volly,floor(self.ammo_max / self.shot_dmg));
-
- if (!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);
-
- if (!self.firecheck_flags)
- self.firecheck_flags = TFL_FIRECHECK_WORLD | TFL_FIRECHECK_DEAD | TFL_FIRECHECK_DISTANCES |
- TFL_FIRECHECK_LOS | TFL_FIRECHECK_AIMDIST | TFL_FIRECHECK_TEAMCECK |
- TFL_FIRECHECK_OWM_AMMO | TFL_FIRECHECK_REFIRE | TFL_FIRECHECK_WORLD;
-
-// Range stuff.
- if (!self.target_range) self.target_range = self.shot_speed * 0.5;
- self.target_range = bound(0,self.target_range,MAX_SHOT_DISTANCE);
-
- if (!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);
-
- if (!self.target_range_optimal) self.target_range_optimal = self.target_range_fire * 0.5;
- self.target_range_optimal = bound(0,self.target_range_optimal,MAX_SHOT_DISTANCE);
-
-
-// Aim stuff.
- if (!self.aim_maxrot) self.aim_maxrot = 45;
- self.aim_maxrot = bound(0,self.aim_maxrot,361);
-
- if (!self.aim_maxpitch) self.aim_maxpitch = 20;
- self.aim_maxpitch = bound(0,self.aim_maxpitch,90);
-
- if (!self.aim_speed) self.aim_speed = 36;
- self.aim_speed = bound(0.1,self.aim_speed, 1000);
-
- if (!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);
-
-// if (!self.aim_firetolerance_angle) self.aim_firetolerance_angle = 10;
-// self.aim_firetolerance_angle = bound(0.1,self.aim_firetolerance_angle,360);
-
- if (!self.aim_flags) self.aim_flags = TFL_AIM_LEAD | TFL_AIM_SHOTTIMECOMPENSATE | TFL_AIM_ZEASE;
-
- // Sill the most tested (and aim-effective)
- if (!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
- if (!self.aim_speed) self.aim_speed = 180;
- self.aim_speed = bound(0.1,self.aim_speed, 1000);
-
- if (!self.track_accel_pitch) self.track_accel_pitch = 0.75;
- if (!self.track_accel_rot) self.track_accel_rot = 0.75;
- if (!self.track_blendrate) self.track_blendrate = 0.35;
- }
-
- if (!self.track_flags) self.track_flags = TFL_TRACK_PITCH | TFL_TRACK_ROT;
-
-
-// Target selection stuff.
- if (!self.target_select_rangebias) self.target_select_rangebias = 1;
- self.target_select_rangebias = bound(-10,self.target_select_rangebias,10);
-
- if (!self.target_select_samebias) self.target_select_samebias = 1;
- self.target_select_samebias = bound(-10,self.target_select_samebias,10);
-
- if (!self.target_select_anglebias) self.target_select_anglebias = 1;
- self.target_select_anglebias = bound(-10,self.target_select_anglebias,10);
-
- if (!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);
-
- if (!self.target_select_flags)
- if (self.turrcaps_flags & TFL_TURRCAPS_MISSILEKILL)
- self.target_select_flags = TFL_TARGETSELECT_LOS | TFL_TARGETSELECT_MISSILES |
- TFL_TARGETSELECT_TEAMCHECK | TFL_TARGETSELECT_RANGELIMTS | TFL_TARGETSELECT_ANGLELIMITS;
- else
- self.target_select_flags = TFL_TARGETSELECT_LOS | TFL_TARGETSELECT_PLAYERS |
- TFL_TARGETSELECT_TEAMCHECK | TFL_TARGETSELECT_RANGELIMTS | TFL_TARGETSELECT_ANGLELIMITS;
-
- //if(!self.target_validate_flags)
- self.target_validate_flags = self.target_select_flags;
-
-
-// Ammo stuff
- if (!self.ammo_max) self.ammo_max = self.shot_dmg * 10;
- self.ammo_max = max(self.shot_dmg,self.ammo_max);
-
- if (!self.ammo) self.ammo = self.shot_dmg * 5;
- self.ammo = bound(0,self.ammo,self.ammo_max);
-
- if (!self.ammo_recharge) self.ammo_recharge = self.shot_dmg / 2;
- 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;
-
- if (!self.ammo_flags) self.ammo_flags = TFL_AMMO_ENERGY | TFL_AMMO_RECHARGE;
-
-// Offsets & origins
- if (!self.tur_aimorg) self.tur_aimorg = '0 0 50';
- if (!self.tur_shotorg) self.tur_shotorg = '50 0 50';
-
-// End of default & sanety checks, start building the turret.
-
-// Spawn extra bits
- self.tur_head = spawn();
-
- self.tur_head.netname = self.tur_head.classname = "turret_head";
- self.tur_head.team = self.team;
-
- // Defend mode?
- if (self.target != "")
- {
- self.tur_defend = find(world, targetname, self.target);
- if (self.tur_defend == world)
- {
- self.target = "";
- dprint("Turret has invalid defendpoint!\n");
- }
- }
-
-// Claim ownership
- self.tur_head.owner = self;
-
-// Put pices in place
-
- if (!(self.turrcaps_flags & TFL_TURRCAPS_LINKED))
- setorigin(self.tur_head,self.origin);
-
- // In target defense mode, aim on the spot to defens when idle.
- if (self.tur_defend)
- self.idle_aim = self.tur_head.angles + angleofs(self.tur_head,self.tur_defend);
- else
- self.idle_aim = self.angles;
-
- if (!(self.turrcaps_flags & TFL_TURRCAPS_LINKED))
- self.tur_head.angles = self.idle_aim;
-
- if (!self.health) self.health = 150;
- self.tur_health = self.health;
-
- //Solid bbox for preformance reasons
- self.solid = SOLID_BBOX;
- self.tur_head.solid = SOLID_BBOX;
-
- self.takedamage = DAMAGE_AIM;
- self.tur_head.takedamage = DAMAGE_AIM;
-
- self.movetype = MOVETYPE_NOCLIP;
- self.tur_head.movetype = MOVETYPE_NOCLIP;
-
- // Team colouring?track
- if (self.team == COLOR_TEAM1) self.colormod = '1.4 0.8 0.8';
- if (self.team == COLOR_TEAM2) self.colormod = '0.8 0.8 1.4';
-
- // Attach stdprocs. override when and what needed
- if (self.turrcaps_flags & TFL_TURRCAPS_SUPPORT)
- {
- //self.turret_prethink = turret_stdproc_true;
- self.turret_score_target = turret_stdproc_targetscore_support;
- //self.turret_aim = turret_stdproc_aim_generic;
- //self.turret_track = turret_stdproc_track;
- self.turret_firecheckfunc = turret_stdproc_firecheck;
- self.turret_firefunc = turret_stdproc_fire;
- self.turret_postthink = turret_stdproc_nothing;
-
- //self.turret_damagefunc = turret_stdproc_damage;
- self.event_damage = turret_stdproc_damage;
- self.tur_head.event_damage = turret_stdproc_damage;
-
- //self.turret_diefunc = turret_stdproc_die;
- //self.turret_spawnfunc = turret_stdproc_respawn;
-
- }
- else
- {
-
- //self.turret_prethink = turret_stdproc_true;
- self.turret_score_target = turret_stdproc_targetscore_generic;
-
- //if (self.aim_flags & TFL_AIM_SIMPLE)
- // self.turret_aim = turret_stdproc_aim_simple;
- //else
- // self.turret_aim = turret_stdproc_aim_generic;
-
- //self.turret_track = turret_stdproc_track;
- self.turret_firecheckfunc = turret_stdproc_firecheck;
- self.turret_firefunc = turret_stdproc_fire;
- self.turret_postthink = turret_stdproc_nothing;
-
- //self.turret_damagefunc = turret_stdproc_damage;
- self.event_damage = turret_stdproc_damage;
- self.tur_head.event_damage = turret_stdproc_damage;
-
- //self.turret_diefunc = turret_stdproc_die;
- //self.turret_spawnfunc = turret_stdproc_respawn;
- self.turret_addtarget = turret_stdproc_false;
- }
-
- self.use = turret_stdproc_use;
- self.bot_attack = TRUE;
-
- // Initiate the main AI loop
- self.think = turret_think;
- self.nextthink = time + self.ticrate;
-
- self.tur_head.team = self.team;
- self.view_ofs = '0 0 0';
-
-#ifdef TURRET_DEBUG
- self.tur_dbg_start = self.nextthink;
- while (vlen(self.tur_dbg_rvec) < 2)
- self.tur_dbg_rvec = randomvec() * 4;
-
- self.tur_dbg_rvec_x = fabs(self.tur_dbg_rvec_x);
- self.tur_dbg_rvec_y = fabs(self.tur_dbg_rvec_y);
- self.tur_dbg_rvec_z = fabs(self.tur_dbg_rvec_z);
-#endif
-
- // Its all good.
- self.classname = "turret_main";
-
- self.tur_active = 1;
-
- if (g_onslaught)
- self.use();
-
- return 1;
-}
-
-
Deleted: trunk/data/qcsrc/server/tturrets/system/turret_system_misc.qc
===================================================================
--- trunk/data/qcsrc/server/tturrets/system/turret_system_misc.qc 2008-10-24 07:48:04 UTC (rev 4855)
+++ trunk/data/qcsrc/server/tturrets/system/turret_system_misc.qc 2008-10-24 07:54:17 UTC (rev 4856)
@@ -1,123 +0,0 @@
-//--// Some support routines //--//
-
-// Get real origin
-vector real_origin(entity ent)
-{
- entity e;
- vector v;
-
- 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 precashing is done.
-void g_turrets_common_precash()
-{
- precache_model ("models/turrets/c512.md3");
-}
-
-/*
-* 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_y < 0) v_res_y += 360;
- if (v_res_y > 180) v_res_y -= 360;
-
- return v_res;
-}
-
Deleted: trunk/data/qcsrc/server/tturrets/system/turret_system_scoreprocs.qc
===================================================================
--- trunk/data/qcsrc/server/tturrets/system/turret_system_scoreprocs.qc 2008-10-24 07:48:04 UTC (rev 4855)
+++ trunk/data/qcsrc/server/tturrets/system/turret_system_scoreprocs.qc 2008-10-24 07:54:17 UTC (rev 4856)
@@ -1,164 +0,0 @@
-/*
-.float target_select_flags; /// target selection flags
-float TFL_TARGETSELECT_NO = 1; /// Dont select a target on its own.
-float TFL_TARGETSELECT_LOS = 2; /// Need line of sight
-float TFL_TARGETSELECT_PLAYERS = 4; /// Players are valid targets
-float TFL_TARGETSELECT_MISSILES = 8; /// Missiles are valid targets
-float TFL_TARGETSELECT_TRIGGERTARGET = 16; /// Responds to turret_trigger_target events
-float TFL_TARGETSELECT_ANGLELIMITS = 32; /// Angular limitations of turret head limits target selection
-float TFL_TARGETSELECT_RANGELIMTS = 64; /// Range limits apply in targetselection
-float TFL_TARGETSELECT_TEAMCHECK = 128; /// Consider team own <-> targets team
-float TFL_TARGETSELECT_NOBUILTIN = 256; /// Cant select targets on its own. needs to be triggerd or slaved.
-float TFL_TARGETSELECT_OWNTEAM = 512;
-*/
-
-float turret_stdproc_targetscore_support(entity e_turret,entity e_target)
-{
- float score; // Total score
- float s_score,d_score;
-
- if (e_turret.enemy == e_target) s_score = 1;
-
- d_score = min(e_turret.target_range_optimal,tvt_dist) / max(e_turret.target_range_optimal,tvt_dist);
-
- score = (d_score * e_turret.target_select_rangebias) +
- (s_score * e_turret.target_select_samebias);
-
- return score;
-}
-
-/*
-* Generic bias aware score system.
-*/
-float turret_stdproc_targetscore_generic(entity e_turret,entity e_target)
-{
- //vector v_tmp;
- float d_dist; // Defendmode Distance
-
- float score; // Total score
- float d_score; // Distance score
- //float da_score; // Distance from aimpoint score
- float a_score; // Angular score
- float s_score; // samescore (same target as last time)
- float m_score; // missile score
- float p_score; // player score
-
- float ikr; // ideal kill range
-
- if(!e_target) return 0;
-
- if (e_target == e_turret.enemy) s_score = 1;
-
- if (e_turret.tur_defend)
- {
- d_dist = vlen(real_origin(e_target) - e_turret.tur_defend.origin);
- ikr = vlen(e_turret.origin - e_turret.tur_defend.origin);
- d_score = 1 - d_dist / e_turret.target_range;
- }
- else
- {
- // Make a normlized value base on the targets distance from our optimal killzone
- ikr = e_turret.target_range_optimal;
- d_score = min(ikr,tvt_dist) / max(ikr,tvt_dist);
- }
-
- /*
- // Determine the maximum time it could take this turrent to aim at someting.
- max_aim_delay = (max(e_turret.aim_maxrot,e_turret.aim_maxpitch) / e_turret.aim_speed * 2);
-
- // Find out how long it would take to aim at this taget.
- aim_delay = (thadf+0.01) / e_turret.aim_speed;
-
- // Turn this info into a normalized value.
- aim_delay = (min(max_aim_delay,aim_delay) / max_aim_delay);
- a_score = 1 - aim_delay;
- */
-
- //a_score = 1 - (tvt_thadf / max(e_turret.aim_maxrot,e_turret.aim_maxpitch));
- a_score = 1 - tvt_thadf / e_turret.aim_maxrot;
-
- if ((e_turret.target_select_missilebias > 0) && (e_target.flags & FL_PROJECTILE))
- m_score = 1;
-
- if ((e_turret.target_select_playerbias > 0) && (e_target.flags & FL_CLIENT))
- p_score = 1;
-
- d_score = max(d_score,0);
- s_score = max(s_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) +
- (s_score * e_turret.target_select_samebias) +
- (a_score * e_turret.target_select_anglebias) +
- (m_score * e_turret.target_select_missilebias) +
- (p_score * e_turret.target_select_playerbias);
-
- if(e_turret.target_range_fire < vlen(e_turret.tur_shotorg_updated - real_origin(e_target)))
- score *= 0.1;
-
-#ifdef TURRET_DEBUG
- string sd,sv,sa,sm,sp,ss;
- string sdt,svt,sat,smt,spt;
-
- sd = ftos(d_score);
- d_score *= e_turret.target_select_rangebias;
- sdt = ftos(d_score);
-
- //sv = ftos(v_score);
- //v_score *= e_turret.target_select_samebias;
- //svt = ftos(v_score);
-
- sa = ftos(a_score);
- a_score *= e_turret.target_select_anglebias;
- sat = ftos(a_score);
-
- sm = ftos(m_score);
- m_score *= e_turret.target_select_missilebias;
- smt = ftos(m_score);
-
- sp = ftos(p_score);
- p_score *= e_turret.target_select_playerbias;
- spt = ftos(p_score);
-
-
- ss = ftos(score);
- bprint("^3Target scores^7 \[ ",e_turret.netname, " \] ^3for^7 \[ ", e_target.netname," \]\n");
- bprint("^5Range:\[ ",sd, " \]^2+bias:\[ ",sdt," \]\n");
- //bprint("^5Volly:\[ ",sv, " \]^2+bias:\[ ",svt," \]\n");
- bprint("^5Angle:\[ ",sa, " \]^2+bias:\[ ",sat," \]\n");
- bprint("^5Missile:\[ ",sm," \]^2+bias:\[ ",smt," \]\n");
- bprint("^5Player:\[ ",sp, " \]^2+bias:\[ ",spt," \]\n");
- bprint("^3Total (w/bias):\[^1",ss,"\]\n");
-
-#endif
-
- return score;
-}
-
-float turret_stdproc_targetscore_close(entity e_turret,entity e_target)
-{
- return 1 - (tvt_dist / e_turret.target_range);
-}
-
-float turret_stdproc_targetscore_far (entity e_turret,entity e_target)
-{
- return tvt_dist / e_turret.target_range;
-}
-
-float turret_stdproc_targetscore_optimal(entity e_turret,entity e_target)
-{
- return min(e_turret.target_range_optimal,tvt_dist) / max(e_turret.target_range_optimal,tvt_dist);
-}
-
-float turret_stdproc_score_angular(entity e_turret,entity e_target)
-{
- return 1 - (tvt_thadf / e_turret.aim_maxrot);
-}
-
-float turret_stdproc_targetscore_defend(entity e_turret,entity e_target)
-{
- return 0;
- //min(e_target.origin,e_turret.tur_defend.origin) / max(e_target.origin,e_turret.tur_defend.origin);
-}
Deleted: trunk/data/qcsrc/server/tturrets/units/turret_unit_common.qc
===================================================================
--- trunk/data/qcsrc/server/tturrets/units/turret_unit_common.qc 2008-10-24 07:48:04 UTC (rev 4855)
+++ trunk/data/qcsrc/server/tturrets/units/turret_unit_common.qc 2008-10-24 07:54:17 UTC (rev 4856)
@@ -1,150 +0,0 @@
-float turret_tag_setup(float linked)
-{
- vector v;
- float f;
-
- // Laters dooz
- if (linked)
- return 0;
-
- f = gettagindex(self,"tag_head");
- v = gettaginfo(self,f);
- v = v + self.origin;
- setorigin(self.tur_head,v);
-
- f = gettagindex(self.tur_head,"tag_fire");
- v = gettaginfo(self.tur_head,f) + (self.tur_head.origin - self.origin);
- v_y *= -1;
- self.tur_shotorg = v;
-
- f = gettagindex(self.tur_head,"tag_aim");
- v = gettaginfo(self.tur_head,f) + (self.tur_head.origin - self.origin);
- self.tur_aimorg = v;
-
- return 1;
-}
-
-float turret_tag_fire_update()
-{
- vector v;
- float f;
-
- f = gettagindex(self.tur_head,"tag_fire");
- v = gettaginfo(self.tur_head,f) + (self.tur_head.origin - self.origin);
- v_y *= -1;
- self.tur_shotorg = v;
-
- f = gettagindex(self.tur_head,"tag_aim");
- v = gettaginfo(self.tur_head,f) + (self.tur_head.origin - self.origin);
- self.tur_aimorg = v;
-
- return 1;
-}
-
-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;
- local entity ent;
-
- dir = normalize(end - start);
- force = dir * bforce;
-
- // go a little bit into the wall because we need to hit this wall later
- end = end + dir;
-
- // trace multiple times until we hit a wall, each obstacle will be made unsolid.
- // note down which entities were hit so we can damage them later
- while (1)
- {
- tracebox(start, smin, smax, end, FALSE, self);
-
- // if it is world we can't hurt it so stop now
- if (trace_ent == world || trace_fraction == 1)
- break;
-
- if (trace_ent.solid == SOLID_BSP)
- break;
-
- // make the entity non-solid so we can hit the next one
- trace_ent.railgunhit = TRUE;
- trace_ent.railgunhitloc = end;
- trace_ent.railgunhitsolidbackup = trace_ent.solid;
-
- // stop if this is a wall
-
-
- // make the entity non-solid
- trace_ent.solid = SOLID_NOT;
- }
-
- endpoint = trace_endpos;
-
- // find all the entities the railgun hit and restore their solid state
- ent = findfloat(world, railgunhit, TRUE);
- while (ent)
- {
- // restore their solid type
- ent.solid = ent.railgunhitsolidbackup;
- ent = findfloat(ent, railgunhit, TRUE);
- }
-
- // find all the entities the railgun hit and hurt them
- ent = findfloat(world, railgunhit, TRUE);
- while (ent)
- {
- // get the details we need to call the damage function
- hitloc = ent.railgunhitloc;
- ent.railgunhitloc = '0 0 0';
- ent.railgunhitsolidbackup = SOLID_NOT;
- ent.railgunhit = FALSE;
-
- // apply the damage
- if (ent.takedamage)
- {
- Damage (ent, self, self, f_dmg, deathtype, hitloc, force);
- ent.velocity = ent.velocity * f_velfactor;
- //ent.alpha = 0.25 + random() * 0.75;
- }
-
- // advance to the next entity
- ent = findfloat(ent, railgunhit, TRUE);
- }
- trace_endpos = endpoint;
-}
-
-void turrets_precash()
-{
- precache_model ("models/turrets/c512.md3");
-
- precache_sound ("turrets/phaser.ogg");
-
- precache_model ("models/turrets/base-gib1.md3");
- precache_model ("models/turrets/base-gib2.md3");
- precache_model ("models/turrets/base-gib3.md3");
- precache_model ("models/turrets/base-gib4.md3");
-
- precache_model ("models/turrets/head-gib1.md3");
- precache_model ("models/turrets/head-gib2.md3");
- precache_model ("models/turrets/head-gib3.md3");
- precache_model ("models/turrets/head-gib4.md3");
-
- precache_model ("models/turrets/base.md3");
- precache_model ("models/turrets/flac.md3");
- precache_model ("models/turrets/pd_proj.md3");
- precache_model ("models/turrets/reactor.md3");
- precache_model ("models/turrets/mlrs_rocket.md3");
- precache_model ("models/turrets/hellion.md3");
- precache_model ("models/turrets/hunter2.md3");
- precache_model ("models/turrets/hk.md3");
- precache_model ("models/turrets/machinegun.md3");
- precache_model ("models/turrets/rocket.md3");
- precache_model ("models/turrets/mlrs.md3");
- precache_model ("models/turrets/phaser.md3");
- precache_model ("models/turrets/phaser_beam.md3");
- precache_model ("models/turrets/plasmad.md3");
- precache_model ("models/turrets/plasma.md3");
- precache_model ("models/turrets/tesla_head.md3");
- precache_model ("models/turrets/tesla_base.md3");
-}
Deleted: trunk/data/qcsrc/server/tturrets/units/turret_unit_flac.qc
===================================================================
--- trunk/data/qcsrc/server/tturrets/units/turret_unit_flac.qc 2008-10-24 07:48:04 UTC (rev 4855)
+++ trunk/data/qcsrc/server/tturrets/units/turret_unit_flac.qc 2008-10-24 07:54:17 UTC (rev 4856)
@@ -1,106 +0,0 @@
-void spawnfunc_turret_flac();
-void turret_flac_dinit();
-void turret_flac_attack();
-void turret_flac_projectile_explode();
-
-void turret_flac_attack()
-{
- local entity proj;
-
- turret_tag_fire_update();
-
- sound (self, CHAN_WEAPON, "weapons/hagar_fire.wav", 1, ATTN_NORM);
- proj = spawn ();
- setorigin(proj, self.tur_shotorg_updated);
- setmodel(proj, "models/turrets/pd_proj.md3");
- setsize(proj, '0 0 0', '0 0 0');
- proj.classname = "turret_fire";
- proj.owner = self;
- proj.bot_dodge = TRUE;
- proj.bot_dodgerating = self.shot_dmg;
- proj.solid = SOLID_NOT;
- proj.movetype = MOVETYPE_FLYMISSILE;
- proj.flags = FL_PROJECTILE;
- proj.effects = EF_LOWPRECISION;
- proj.takedamage = DAMAGE_YES;
- proj.health = 10;
- proj.velocity = (self.tur_shotdir_updated + randomvec() * self.shot_spread) * self.shot_speed;
- proj.angles = vectoangles(proj.velocity);
- proj.touch = turret_flac_projectile_explode;
- proj.think = turret_flac_projectile_explode;
- proj.nextthink = time + (vlen(self.tur_aimpos - self.tur_shotorg_updated) / self.shot_speed) + (random() * self.shot_spread);
-
- self.tur_head.frame = self.tur_head.frame + 1;
- if (self.tur_head.frame >= 4) self.tur_head.frame = 0;
-
-}
-
-void turret_flac_projectile_explode()
-{
- float ftmp;
-
- te_explosion (self.origin);
-
- ftmp = crandom();
- if (ftmp<-0.7)
- sound (self, CHAN_PROJECTILE, "weapons/hagexp1.wav", 1, ATTN_NORM);
- else if (ftmp<0.4)
- sound (self, CHAN_PROJECTILE, "weapons/hagexp2.wav", 1, ATTN_NORM);
- else if (ftmp<1)
- sound (self, CHAN_PROJECTILE, "weapons/hagexp3.wav", 1, ATTN_NORM);
-
-
- self.event_damage = SUB_Null;
-
-
-#ifdef TURRET_DEBUG
-
- ftmp = RadiusDamage (self, self.owner, self.owner.shot_dmg, 0, self.owner.shot_radius, world, self.owner.shot_force, DEATH_TURRET, world);
- self.owner.tur_dbg_dmg_t_h = self.owner.tur_dbg_dmg_t_h + ftmp; //self.owner.shot_dmg;
- self.owner.tur_dbg_dmg_t_f = self.owner.tur_dbg_dmg_t_f + self.owner.shot_dmg;
-#else
- RadiusDamage (self, self.owner, self.owner.shot_dmg, 0, self.owner.shot_radius, world, self.owner.shot_force, DEATH_TURRET, world);
-#endif
-
- remove (self);
-}
-
-
-void turret_flac_dinit()
-{
- if (self.netname == "") self.netname = "FLAC Cannon";
-
-
- self.turrcaps_flags = TFL_TURRCAPS_RADIUSDMG | TFL_TURRCAPS_FASTPROJ | TFL_TURRCAPS_MISSILEKILL;
- self.ammo_flags = TFL_AMMO_ROCKETS | TFL_AMMO_RECHARGE;
- self.aim_flags = TFL_AIM_LEAD | TFL_AIM_SHOTTIMECOMPENSATE;
-
- if (turret_stdproc_init("flac_std") == 0)
- {
- remove(self);
- return;
- }
-
- setmodel(self,"models/turrets/base.md3");
- setmodel(self.tur_head,"models/turrets/flac.md3");
-
- if (!turret_tag_setup(0))
- dprint("Warning: Turret ",self.classname, " faild to initialize md3 tags\n");
-
- // Our fire routine
- self.turret_firefunc = turret_flac_attack;
-
-}
-/*QUAKED turret_flac (0 .5 .8) ?
-*/
-
-void spawnfunc_turret_flac()
-{
- //precache_model ("models/turrets/base.md3");
- //precache_model ("models/turrets/flac.md3");
- //precache_model("models/turrets/pd_proj.md3");
-
- self.think = turret_flac_dinit;
- self.nextthink = time + 0.5;
-}
-
Deleted: trunk/data/qcsrc/server/tturrets/units/turret_unit_fusionreactor.qc
===================================================================
--- trunk/data/qcsrc/server/tturrets/units/turret_unit_fusionreactor.qc 2008-10-24 07:48:04 UTC (rev 4855)
+++ trunk/data/qcsrc/server/tturrets/units/turret_unit_fusionreactor.qc 2008-10-24 07:54:17 UTC (rev 4856)
@@ -1,81 +0,0 @@
-void spawnfunc_turret_fusionreactor();
-void turret_fusionreactor_dinit();
-void turret_fusionreactor_fire();
-
-float turret_fusionreactor_firecheck()
-{
- if (self.enemy == world) return 0;
-
- if (!self.enemy.ammo_flags & TFL_AMMO_RECIVE) return 0;
- if (!self.enemy.ammo_flags & TFL_AMMO_ENERGY) return 0;
-
- if (self.ammo < self.shot_dmg) return 0;
- if (self.enemy.ammo >= self.enemy.ammo_max) return 0;
- if (self.tur_dist_enemy > self.target_range_fire) return 0;
- if (self.tur_dist_enemy < self.target_range_min) return 0;
-
- return 1;
-}
-
-
-void turret_fusionreactor_fire()
-{
- self.enemy.ammo = min(self.enemy.ammo + self.shot_dmg,self.enemy.ammo_max);
- //te_lightning1(world,self.origin,self.enemy.origin);
-}
-
-void turret_fusionreactor_postthink()
-{
-}
-
-
-void turret_fusionreactor_dinit()
-{
- if (self.netname == "") self.netname = "Fusionreactor";
-
- self.turrcaps_flags =TFL_TURRCAPS_SUPPORT | TFL_TURRCAPS_AMMOSOURCE;
-
- self.ammo_flags = TFL_AMMO_ENERGY | TFL_AMMO_RECHARGE;
-
- self.target_select_flags = TFL_TARGETSELECT_TEAMCHECK | TFL_TARGETSELECT_OWNTEAM | TFL_TARGETSELECT_RANGELIMTS;
-
- self.firecheck_flags = TFL_FIRECHECK_OWM_AMMO | TFL_FIRECHECK_OTHER_AMMO | TFL_FIRECHECK_DISTANCES | TFL_FIRECHECK_DEAD | TFL_FIRECHECK_WORLD;
-
- self.shoot_flags = TFL_SHOOT_HITALLVALID;
-
- self.aim_flags = TFL_AIM_NO;
-
- self.track_flags = TFL_TRACK_NO;
-
- if (turret_stdproc_init("fusreac_std") == 0)
- {
- remove(self);
- return;
- }
-
- setmodel(self,"models/turrets/base.md3");
- setmodel(self.tur_head,"models/turrets/reactor.md3");
-
- //if(!turret_tag_setup(0))
- // dprint("Warning: Turret ",self.classname, " faild to initialize md3 tags\n");
-
- self.tur_head.scale = 0.75;
- setorigin(self.tur_head,self.origin + '0 0 25');
- self.tur_head.avelocity = '0 50 0';
-
- self.turret_firecheckfunc = turret_fusionreactor_firecheck;
- self.turret_firefunc = turret_fusionreactor_fire;
-
- self.turret_postthink = turret_fusionreactor_postthink;
-}
-
-/*QUAKED turret_fusionreactor (0 .5 .8) ?
-*/
-void spawnfunc_turret_fusionreactor()
-{
- //precache_model ("models/turrets/reactor.md3");
- //precache_model ("models/turrets/base.md3");
-
- self.think = turret_fusionreactor_dinit;
- self.nextthink = time + 0.5;
-}
Deleted: trunk/data/qcsrc/server/tturrets/units/turret_unit_hellion.qc
===================================================================
--- trunk/data/qcsrc/server/tturrets/units/turret_unit_hellion.qc 2008-10-24 07:48:04 UTC (rev 4855)
+++ trunk/data/qcsrc/server/tturrets/units/turret_unit_hellion.qc 2008-10-24 07:54:17 UTC (rev 4856)
@@ -1,221 +0,0 @@
-.float shot_speed_max;
-.float shot_speed_gain;
-
-void spawnfunc_turret_hellion();
-void turret_hellion_dinit();
-void turret_hellion_attack();
-void turret_hellion_missile_explode();
-void turret_hellion_missile_think();
-void turret_hellion_missile_damage (entity inflictor, entity attacker, float damage, float deathtype, vector hitloc, vector vforce)
-
-void turret_hellion_postthink()
-{
- if (cvar("g_turrets_reloadcvars"))
- {
- if (!self.shot_speed_max) self.shot_speed_max = cvar("g_turrets_unit_hellion_std_shot_speed_max");
- if (!self.shot_speed_gain) self.shot_speed_gain = cvar("g_turrets_unit_hellion_std_shot_speed_gain");
- }
-
- if (self.tur_head.frame != 0)
- self.tur_head.frame = self.tur_head.frame + 1;
-
- if (self.tur_head.frame > 7)
- self.tur_head.frame = 0;
-}
-
-void turret_hellion_attack()
-{
- local entity missile;
-
- sound (self, CHAN_WEAPON, "weapons/hagar_fire.wav", 1, ATTN_NORM);
-
- missile = spawn ();
- setorigin(missile, self.tur_shotorg_updated);
- sound (missile, CHAN_PROJECTILE, "weapons/rocket_fly.wav", 0.4, ATTN_NORM);
- setmodel (missile, "models/turrets/mlrs_rocket.md3"); // precision set below
- setsize (missile, '-3 -3 -3', '3 3 3'); // give it some size so it can be shot
-
- missile.classname = "hellion_missile";
- missile.owner = self;
- missile.bot_dodge = TRUE;
- missile.bot_dodgerating = self.shot_dmg;
- missile.takedamage = DAMAGE_YES;
- missile.damageforcescale = 2;
- missile.health = 50;
- missile.enemy = self.enemy;
- missile.think = turret_hellion_missile_think;
- missile.nextthink = time + 0.2;
- missile.solid = SOLID_BBOX;
- missile.movetype = MOVETYPE_FLYMISSILE;
- missile.effects = EF_LOWPRECISION;
- missile.velocity = (self.tur_shotdir_updated + randomvec() * self.shot_spread) * self.shot_speed; // + ('0 0 1' * self.shot_speed * 0.15);
- missile.angles = vectoangles(missile.velocity);
- missile.touch = turret_hellion_missile_explode;
- missile.flags = FL_PROJECTILE;
- missile.solid = SOLID_BBOX;
- missile.tur_health = time + 9;
- missile.tur_aimpos = randomvec() * 128;
- te_explosion (missile.origin);
-
- // switch tubes
- self.tur_shotorg_y = self.tur_shotorg_y * -1;
-
- if (self.tur_head.frame == 0)
- self.tur_head.frame = self.tur_head.frame + 1;
-
-}
-
-void turret_hellion_missile_damage (entity inflictor, entity attacker, float damage, float deathtype, vector hitloc, vector vforce)
-{
- self.health = self.health - damage;
- self.velocity = self.velocity + vforce;
- if (self.health <= 0) turret_hellion_missile_explode();
-}
-
-void turret_hellion_missile_think()
-{
- vector olddir,newdir;
- vector pre_pos;
- float itime;
-
- self.nextthink = time + 0.1;
-
- // Enemy in range?
- if (vlen(self.origin - self.enemy.origin) < self.owner.shot_radius * 0.25)
- turret_hellion_missile_explode();
-
- olddir = normalize(self.velocity);
-
- if (self.tur_health < time) turret_hellion_missile_explode();
-
- // Enemy dead? just keep on the current heading then.
- if ((self.enemy == world) || (self.enemy.deadflag != DEAD_NO))
- {
-
- // Make sure we dont return to tracking a respawned player
- self.enemy = world;
-
- // Accelerate
- self.velocity = olddir * min(vlen(self.velocity) * self.owner.shot_speed_gain,self.owner.shot_speed_max);
-
- // Turn model
- self.angles = vectoangles(self.velocity);
-
- //if ( (vlen(self.origin - self.owner.origin)) > (self.owner.shot_radius * 10) )
- // turret_hellion_missile_explode();
-
- // return;
- }
-
- olddir = normalize(self.velocity);
-
- if (self.enemy)
- {
- // Predict enemy position
- itime = vlen(self.enemy.origin - self.origin) / vlen(self.velocity);
- pre_pos = self.enemy.origin + self.enemy.velocity * itime;
- }
- else
- {
- pre_pos = self.origin + olddir * 1024;
- }
-
- pre_pos = (pre_pos + self.enemy.origin) * 0.5;
-
- //pre_pos += randomvec() * 128; //self.tur_aimpos * (sin(32) * time) ;
-
-
- // Find out the direction to that place
- newdir = normalize(pre_pos - self.origin);
-
- // Turn
- newdir = normalize(olddir + newdir * 0.5);
-
- // Accelerate
- self.velocity = newdir * min(vlen(self.velocity) * self.owner.shot_speed_gain,self.owner.shot_speed_max);
-
- // Turn model
- self.angles = vectoangles(self.velocity);
-
- if (time+itime < time+0.1)
- {
- self.think = turret_hellion_missile_explode;
- self.nextthink = time + itime;
- }
-}
-
-void turret_hellion_missile_explode()
-{
- vector org2;
- float d;
-
- sound (self, CHAN_PROJECTILE, "weapons/rocket_impact.wav", 1, ATTN_NORM);
- org2 = findbetterlocation (self.origin, 16);
-
- // LordHavoc: TE_TEI_BIGEXPLOSION
- WriteByte (MSG_BROADCAST, SVC_TEMPENTITY);
- WriteByte (MSG_BROADCAST, 78);
- WriteCoord (MSG_BROADCAST, org2_x);
- WriteCoord (MSG_BROADCAST, org2_y);
- WriteCoord (MSG_BROADCAST, org2_z);
-
- self.event_damage = SUB_Null;
- d = RadiusDamage (self, self.owner, self.owner.shot_dmg, 0, self.owner.shot_radius, world, self.owner.shot_force, DEATH_TURRET, world);
-
-#ifdef TURRET_DEBUG
- self.owner.tur_dbg_dmg_t_h = self.owner.tur_dbg_dmg_t_h + d; //self.owner.shot_dmg;
- self.owner.tur_dbg_dmg_t_f = self.owner.tur_dbg_dmg_t_f + self.owner.shot_dmg;
-#endif
-
- // Target dead, get another is still targeting the same.
- if ((self.enemy.deadflag != DEAD_NO) && (self.enemy == self.owner.enemy))
- self.owner.enemy = world;
-
- remove (self);
-}
-
-void turret_hellion_dinit()
-{
- if (self.netname == "") self.netname = "Hellion Missile Turret";
-
- if (!self.shot_speed_max) self.shot_speed_max = cvar("g_turrets_unit_hellion_std_shot_speed_max");
- if (!self.shot_speed_gain) self.shot_speed_gain = cvar("g_turrets_unit_hellion_std_shot_speed_gain");
-
- self.turrcaps_flags = TFL_TURRCAPS_RADIUSDMG | TFL_TURRCAPS_FASTPROJ | TFL_TURRCAPS_PLAYERKILL | TFL_TURRCAPS_MISSILEKILL;
- self.aim_flags = TFL_AIM_SIMPLE;
- self.target_select_flags = TFL_TARGETSELECT_LOS | TFL_TARGETSELECT_PLAYERS | TFL_TARGETSELECT_TRIGGERTARGET | TFL_TARGETSELECT_RANGELIMTS | TFL_TARGETSELECT_TEAMCHECK ;
- self.firecheck_flags = TFL_FIRECHECK_WORLD | TFL_FIRECHECK_DEAD | TFL_FIRECHECK_DISTANCES | TFL_FIRECHECK_TEAMCECK | TFL_FIRECHECK_REFIRE | TFL_FIRECHECK_AFF | TFL_FIRECHECK_OWM_AMMO;
- self.ammo_flags = TFL_AMMO_ROCKETS | TFL_AMMO_RECHARGE;
-
- if (turret_stdproc_init("hellion_std") == 0)
- {
- remove(self);
- return;
- }
-
- setmodel(self,"models/turrets/base.md3");
- setmodel(self.tur_head,"models/turrets/hellion.md3");
-
- if (!turret_tag_setup(0))
- dprint("Warning: Turret ",self.classname, " faild to initialize md3 tags\n");
-
- // Our fire routine
- self.turret_firefunc = turret_hellion_attack;
-
- // Custom animations and sutch
- self.turret_postthink = turret_hellion_postthink;
-}
-
-/*QUAKED turret_hellion (0 .5 .8) ?
-*/
-void spawnfunc_turret_hellion()
-{
- //precache_model ( "models/turrets/mlrs_rocket.md3");
- //precache_model ("models/turrets/hellion.md3");
- //precache_model ("models/turrets/base.md3");
-
- self.think = turret_hellion_dinit;
- self.nextthink = time + 0.5;
-}
-
-
Deleted: trunk/data/qcsrc/server/tturrets/units/turret_unit_hk.qc
===================================================================
--- trunk/data/qcsrc/server/tturrets/units/turret_unit_hk.qc 2008-10-24 07:48:04 UTC (rev 4855)
+++ trunk/data/qcsrc/server/tturrets/units/turret_unit_hk.qc 2008-10-24 07:54:17 UTC (rev 4856)
@@ -1,470 +0,0 @@
-//#define TURRET_DEBUG_HK
-
-#ifdef TURRET_DEBUG_HK
-.float atime;
-#endif
-
-void spawnfunc_turret_hk();
-void turret_hk_dinit();
-void turret_hk_attack();
-void turret_hk_missile_explode();
-void turret_hk_missile_think();
-void turret_hk_missile_damage (entity inflictor, entity attacker, float damage, float deathtype, vector hitloc, vector force);
-float turret_hk_addtarget(entity e_target,entity e_sender);
-//void turret_hk_missile_touch();
-
-float hk_maxspeed;
-float hk_minspeed;
-float hk_accel;
-float hk_accel2;
-float hk_decel;
-
-float turret_hk_addtarget(entity e_target,entity e_sender)
-{
- if (e_target)
- {
- if (turret_validate_target(self,e_target,self.target_validate_flags) > 0)
- {
- self.enemy = e_target;
- return 1;
- }
- }
-
- return 0;
-}
-
-float hk_is_valid_target(entity e_target)
-{
- if (e_target == world)
- return 0;
-
- // If only this was used more..
- if (e_target.flags & FL_NOTARGET)
- return 0;
-
- // Cant touch this
- if ((e_target.takedamage == DAMAGE_NO) || (e_target.health < 0))
- return 0;
-
- // player
- if (e_target.flags & FL_CLIENT)
- {
- if (self.owner.target_select_playerbias < 0)
- return 0;
-
- if (e_target.deadflag != DEAD_NO)
- return 0;
- }
-
- // Missile
- if ((e_target.flags & FL_PROJECTILE) && (self.owner.target_select_missilebias < 0))
- return 0;
-
- // Team check
- if ((e_target.team == self.owner.team) || (self.owner.team == e_target.owner.team))
- return 0;
-
- return 1;
-}
-
-void turret_hk_missile_damage (entity inflictor, entity attacker, float damage, float deathtype, vector hitloc, vector force)
-{
- if (attacker.team == self.team)
- damage *= 0.5;
-
- self.velocity += force;
-
- self.health -= damage;
-
- if (self.health <= 0)
- turret_hk_missile_explode();
-}
-
-void turret_hk_attack()
-{
- local entity missile;
- //local entity flash2;
-
- sound (self, CHAN_WEAPON, "weapons/rocket_fire.wav", 1, ATTN_NORM);
-
- missile = spawn ();
- missile.solid = SOLID_BBOX;
- setmodel (missile, "models/turrets/hunter2.md3"); // precision set below
- setsize (missile, missile.mins,missile.maxs); // give it some size so it can be shot
- sound (missile, CHAN_PROJECTILE, "weapons/rocket_fly.wav", 0.4, ATTN_NORM);
- setorigin(missile, self.tur_shotorg_updated);
-
- missile.scale = 1;
- missile.classname = "hk_missile";
- missile.owner = self;
- missile.bot_dodge = TRUE;
- missile.bot_dodgerating = self.shot_dmg;
- missile.takedamage = DAMAGE_YES;
- missile.damageforcescale = 4;
- missile.health = 10;
- missile.think = turret_hk_missile_think;
- missile.event_damage = turret_hk_missile_damage;
- missile.nextthink = time + 0.25;
- missile.movetype = MOVETYPE_BOUNCEMISSILE;
- missile.effects = EF_LOWPRECISION;
- missile.velocity = self.tur_shotdir_updated * (self.shot_speed * 0.75);
- missile.angles = vectoangles(missile.velocity);
- missile.touch = turret_hk_missile_explode; //turret_hk_missile_touch;
- missile.flags = FL_PROJECTILE;
- missile.enemy = self.enemy;
- missile.team = self.team;
- missile.cnt = time + 30;
- missile.ticrate = max(cvar("sys_ticrate"),0.05);
-
- te_explosion (missile.origin);
-
- if (self.tur_head.frame == 0)
- self.tur_head.frame = self.tur_head.frame + 1;
-
-}
-
-/*
-void turret_hk_missile_touch()
-{
- if(other == self.enemy)
- turret_hk_missile_explode();
- else
- {
- if(self.cnt < time)
- {
- self.cnt = time + 0.25;
- self.health = self.health - 5;
- if(self.health <= 0)
- turret_hk_missile_explode();
-
- }
- }
-}
-*/
-
-void turret_hk_missile_think()
-{
- vector vu, vd, vf, vl, vr, ve; // Vector (direction)
- float fu, fd, ff, fl, fr, fe; // Fraction to solid
- vector olddir,wishdir,newdir; // Final direction
- float lt_for; // Length of Trace FORwrad
- float lt_seek; // Length of Trace SEEK (left, right, up down)
- float pt_seek; // Pitch of Trace SEEK (How mutch to angele left, right up, down trace towards v_forward)
- vector pre_pos;
- float myspeed;
- entity e;
- float ad,edist;
-
- self.nextthink = time + self.ticrate;
-
- //if (self.cnt < time)
- // turret_hk_missile_explode();
-
- if (self.enemy.deadflag != DEAD_NO)
- self.enemy = world;
-
- // Pick the closest valid target.
- if (!self.enemy)
- {
- e = findradius(self.origin, 5000);
- while (e)
- {
- if (hk_is_valid_target(e))
- {
- if (!self.enemy)
- self.enemy = e;
- else
- if (vlen(self.origin - e.origin) < vlen(self.origin - self.enemy.origin))
- self.enemy = e;
- }
- e = e.chain;
- }
- }
-
- self.angles = vectoangles(self.velocity);
- self.angles_x = self.angles_x * -1;
- makevectors(self.angles);
- self.angles_x = self.angles_x * -1;
-
- if (self.enemy)
- {
- edist = vlen(self.origin - self.enemy.origin);
- // Close enougth to do decent damage?
- if ( edist <= (self.owner.shot_radius * 0.25) )
- {
- turret_hk_missile_explode();
- return;
- }
-
- // Get data on enemy position
- pre_pos = self.enemy.origin +
- self.enemy.velocity *
- min((vlen(self.enemy.origin - self.origin) / vlen(self.velocity)),0.5);
-
- traceline(self.origin, pre_pos,TRUE,self.enemy);
- ve = normalize(pre_pos - self.origin);
- fe = trace_fraction;
-
- }
- else
- {
- fe = 0;
- }
-
- if ((fe != 1) || (self.enemy == world) || (edist > 1000))
- {
- myspeed = vlen(self.velocity);
-
- lt_for = myspeed * 3;
- lt_seek = myspeed * 2.95;
-
- // Trace forward
- traceline(self.origin, self.origin + v_forward * lt_for,FALSE,self);
- vf = trace_endpos;
- ff = trace_fraction;
-
- // Find angular offset
- ad = vlen(vectoangles(normalize(self.enemy.origin - self.origin)) - self.angles);
-
- // To close to something, Slow down!
- if ( ((ff < 0.7) || (ad > 4)) && (myspeed > hk_minspeed) )
- myspeed = max(myspeed * hk_decel,hk_minspeed);
-
- // Failry clear, accelerate.
- if ( (ff > 0.7) && (myspeed < hk_maxspeed) )
- myspeed = min(myspeed * hk_accel,hk_maxspeed);
-
- // Setup trace pitch
- pt_seek = 1 - ff;
- pt_seek = bound(0.15,pt_seek,0.8);
- if (ff < 0.5) pt_seek = 1;
-
- // Trace left
- traceline(self.origin, self.origin + (-1 * (v_right * pt_seek) + (v_forward * ff)) * lt_seek,FALSE,self);
- vl = trace_endpos;
- fl = trace_fraction;
-
- // Trace right
- traceline(self.origin, self.origin + ((v_right * pt_seek) + (v_forward * ff)) * lt_seek ,FALSE,self);
- vr = trace_endpos;
- fr = trace_fraction;
-
- // Trace up
- traceline(self.origin, self.origin + ((v_up * pt_seek) + (v_forward * ff)) * lt_seek ,FALSE,self);
- vu = trace_endpos;
- fu = trace_fraction;
-
- // Trace down
- traceline(self.origin, self.origin + (-1 * (v_up * pt_seek) + (v_forward * ff)) * lt_seek ,FALSE,self);
- vd = trace_endpos;
- fd = trace_fraction;
-
- vl = normalize(vl - self.origin);
- vr = normalize(vr - self.origin);
- vu = normalize(vu - self.origin);
- vd = normalize(vd - self.origin);
-
- // Panic tresh passed, find a single direction and turn as hard as we can
- if (pt_seek == 1)
- {
- wishdir = v_right;
- if (fl > fr) wishdir = -1 * v_right;
- if (fu > fl) wishdir = v_up;
- if (fd > fu) wishdir = -1 * v_up;
- }
- else
- {
- // Normalize our trace vectors to make a smooth path
- wishdir = normalize( (vl * fl) + (vr * fr) + (vu * fu) + (vd * fd) );
- }
-
- if (self.enemy)
- {
- if (fe < 0.1) fe = 0.1; // Make sure we always try to move sligtly towards our target
- wishdir = (wishdir * (1 - fe)) + (ve * fe);
- }
- }
- else
- {
- // Got a clear path to target, speed up fast (if not at full speed) and go straight for it.
- myspeed = vlen(self.velocity);
- if (myspeed < hk_maxspeed)
- myspeed = min(myspeed * hk_accel2,hk_maxspeed);
-
- wishdir = ve;
- //wishdir = normalize(self.enemy.origin - (self.enemy.origin + self.enemy.velocity));
- }
-
- if ((myspeed > hk_minspeed) && (self.cnt > time))
- myspeed = min(myspeed * hk_accel2,hk_maxspeed);
-
- // Ranoutagazfish?
- if (self.cnt < time)
- {
- self.cnt = time + 0.25;
- self.nextthink = 0;
- self.movetype = MOVETYPE_BOUNCE;
- sound (self, CHAN_VOICE, "", 0.4, ATTN_NORM);
- return;
- }
-
- // Calculate new heading
- olddir = normalize(self.velocity);
-
- newdir = normalize(olddir + wishdir * cvar("g_turrets_unit_hk_std_shot_speed_turnrate"));
-
- //fu = (1 / hk_maxspeed) * myspeed;
- //fd = fu - (0.75 - 0.25);
- //newdir = normalize(olddir + wishdir * fd);
-
- // Set heading & speed
- self.velocity = newdir * myspeed;
-
- // Align model with new heading
- self.angles = vectoangles(self.velocity);
-
-
-#ifdef TURRET_DEBUG_HK
- //if(self.atime < time) {
- if ((fe <= 0.99)||(edist > 1000))
- {
- te_lightning2(world,self.origin, self.origin + vr * lt_seek);
- te_lightning2(world,self.origin, self.origin + vl * lt_seek);
- te_lightning2(world,self.origin, self.origin + vu * lt_seek);
- te_lightning2(world,self.origin, self.origin + vd * lt_seek);
- te_lightning2(world,self.origin, vf);
- }
- else
- {
- te_lightning2(world,self.origin, self.enemy.origin);
- }
- bprint("Speed: ", ftos(rint(myspeed)), "\n");
- bprint("Trace to solid: ", ftos(rint(ff * 100)), "%\n");
- bprint("Trace to target:", ftos(rint(fe * 100)), "%\n");
- self.atime = time + 0.2;
- //}
-#endif
-}
-
-void turret_hk_missile_explode()
-{
- vector org2;
- float d;
-
- if ((other == self.owner)||(other == self.owner.tur_head))
- return;
-
- //vector org2;
- sound (self, CHAN_PROJECTILE, "weapons/rocket_impact.wav", 1, ATTN_NORM);
- org2 = findbetterlocation (self.origin, 16);
-
- // LordHavoc: TE_TEI_BIGEXPLOSION
- WriteByte (MSG_BROADCAST, SVC_TEMPENTITY);
- WriteByte (MSG_BROADCAST, 78);
- WriteCoord (MSG_BROADCAST, org2_x);
- WriteCoord (MSG_BROADCAST, org2_y);
- WriteCoord (MSG_BROADCAST, org2_z);
-
- self.event_damage = SUB_Null;
- d = RadiusDamage (self, self.owner, self.owner.shot_dmg, 0, self.owner.shot_radius, world, self.owner.shot_force, DEATH_TURRET, world);
-
-#ifdef TURRET_DEBUG
- self.owner.tur_dbg_dmg_t_h = self.owner.tur_dbg_dmg_t_h + d; //self.owner.shot_dmg;
- self.owner.tur_dbg_dmg_t_f = self.owner.tur_dbg_dmg_t_f + self.owner.shot_dmg;
-#endif
-
- // Target dead, get another is still targeting the same.
- if ((self.enemy.deadflag != DEAD_NO) && (self.enemy == self.owner.enemy))
- self.owner.enemy = world;
-
- remove (self);
-}
-
-void turret_hk_postthink()
-{
- if (cvar("g_turrets_reloadcvars"))
- {
- hk_maxspeed = cvar("g_turrets_unit_hk_std_shot_speed_max");
- hk_minspeed = cvar("g_turrets_unit_hk_std_shot_speed");
- hk_accel = cvar("g_turrets_unit_hk_std_shot_speed_accel");
- hk_accel2 = cvar("g_turrets_unit_hk_std_shot_speed_accel2");
- hk_decel = cvar("g_turrets_unit_hk_std_shot_speed_decel");
- }
-
- if (self.tur_head.frame != 0)
- self.tur_head.frame = self.tur_head.frame + 1;
-
- if (self.tur_head.frame > 5)
- self.tur_head.frame = 0;
-
-}
-
-void turret_hk_dinit()
-{
- if (self.netname == "") self.netname = "Hunter-killer turret";
-
- hk_maxspeed = cvar("g_turrets_unit_hk_std_shot_speed_max");
- hk_minspeed = cvar("g_turrets_unit_hk_std_shot_speed");
- hk_accel = cvar("g_turrets_unit_hk_std_shot_speed_accel");
- hk_accel2 = cvar("g_turrets_unit_hk_std_shot_speed_accel2");
- hk_decel = cvar("g_turrets_unit_hk_std_shot_speed_decel");
-
- self.turrcaps_flags = TFL_TURRCAPS_RADIUSDMG | TFL_TURRCAPS_MEDPROJ | TFL_TURRCAPS_PLAYERKILL | TFL_TURRCAPS_RECIVETARGETS;
-
- self.ammo_flags = TFL_AMMO_ROCKETS | TFL_AMMO_RECHARGE;
-
- self.aim_flags = TFL_AIM_SIMPLE;
-
- self.target_select_flags = TFL_TARGETSELECT_LOS | TFL_TARGETSELECT_PLAYERS | TFL_TARGETSELECT_TRIGGERTARGET | TFL_TARGETSELECT_RANGELIMTS | TFL_TARGETSELECT_TEAMCHECK;
-
- self.firecheck_flags = TFL_FIRECHECK_WORLD | TFL_FIRECHECK_DEAD | TFL_FIRECHECK_TEAMCECK | TFL_FIRECHECK_REFIRE | TFL_FIRECHECK_AFF;
-
- self.target_select_flags = TFL_TARGETSELECT_LOS | TFL_TARGETSELECT_PLAYERS | TFL_TARGETSELECT_TRIGGERTARGET | TFL_TARGETSELECT_RANGELIMTS | TFL_TARGETSELECT_TEAMCHECK;
-
- self.shoot_flags = TFL_SHOOT_CLEARTARGET;
-
- if (turret_stdproc_init("hk_std") == 0)
- {
- remove(self);
- return;
- }
-
- self.target_validate_flags = TFL_TARGETSELECT_PLAYERS | TFL_TARGETSELECT_TEAMCHECK;
-
- setmodel(self,"models/turrets/base.md3");
- setmodel(self.tur_head,"models/turrets/hk.md3");
-
- if (!turret_tag_setup(0))
- dprint("Warning: Turret ",self.classname, " faild to initialize md3 tags\n");
-
- // Our fire routine
- self.turret_firefunc = turret_hk_attack;
-
- // re-color badge & handle recoil effect
- self.turret_postthink = turret_hk_postthink;
-
- // What to do when reciveing foreign target data
- self.turret_addtarget = turret_hk_addtarget;
-}
-
-/*
-* Turret that fires Hunter-killer missiles.
-* Missiles seek their target and try to avoid obstacles. If target dies early, they
-* pick a new one on their own.
-*/
-
-/*QUAKED turret_hk (0 .5 .8) ?
-hunter-killer missiles.
-*/
-
-void spawnfunc_turret_hk()
-{
- //precache_model ( "models/turrets/hunter2.md3");
- //precache_model ("models/turrets/base.md3");
- //precache_model ("models/turrets/hk.md3");
-
- self.think = turret_hk_dinit;
- self.nextthink = time + 0.5;
-}
-
-
Deleted: trunk/data/qcsrc/server/tturrets/units/turret_unit_machinegun.qc
===================================================================
--- trunk/data/qcsrc/server/tturrets/units/turret_unit_machinegun.qc 2008-10-24 07:48:04 UTC (rev 4855)
+++ trunk/data/qcsrc/server/tturrets/units/turret_unit_machinegun.qc 2008-10-24 07:54:17 UTC (rev 4856)
@@ -1,71 +0,0 @@
-void spawnfunc_turret_machinegun();
-void turret_machinegun_std_init();
-void turret_machinegun_attack();
-
-//.float bulletcounter;
-void turret_machinegun_attack()
-{
-
- entity flash;
- sound (self, CHAN_WEAPON, "weapons/uzi_fire.wav", 1, ATTN_NORM);
- fireBullet (self.tur_shotorg_updated, self.tur_shotdir_updated,self.shot_spread, self.shot_dmg, self.shot_force, DEATH_TURRET, FALSE);
-
- te_smallflash(self.tur_shotorg_updated);
- trailparticles(self,particleeffectnum("EF_MGTURRETTRAIL"),self.tur_shotorg_updated,trace_endpos);
-
- // muzzle flash for 3rd person view
- flash = spawn();
- //setorigin(flash, '43 1 8');
- setmodel(flash, "models/uziflash.md3"); // precision set below
- setattachment(flash, self.tur_head, "tag_fire");
- flash.think = W_Uzi_Flash_Go;
- flash.nextthink = time + 0.02;
- flash.frame = 2;
- flash.angles_z = flash.v_angle_z + random() * 180;
- flash.alpha = 1;
- flash.effects = EF_ADDITIVE | EF_FULLBRIGHT | EF_LOWPRECISION;
-}
-
-
-void turret_machinegun_std_init()
-{
- if (self.netname == "") self.netname = "Machinegun Turret";
-
- self.ammo_flags = TFL_AMMO_BULLETS | TFL_AMMO_RECHARGE | TFL_AMMO_RECIVE;
- self.turrcaps_flags = TFL_TURRCAPS_HITSCAN | TFL_TURRCAPS_PLAYERKILL;
- self.aim_flags = TFL_AIM_LEAD | TFL_AIM_ZEASE;
-
- if (turret_stdproc_init("machinegun_std") == 0)
- {
- remove(self);
- return;
- }
-
- setmodel(self,"models/turrets/base.md3");
- setmodel(self.tur_head,"models/turrets/machinegun.md3");
-
- if (!turret_tag_setup(0))
- dprint("Warning: Turret ",self.classname, " faild to initialize md3 tags\n");
-
- // Our fire routine
- self.turret_firefunc = turret_machinegun_attack;
-
-}
-
-
-
-/*
-* machinegun turret. does what you'd expect
-*/
-
-/*QUAKED turret_machinegun (0 .5 .8) ?
-*/
-void spawnfunc_turret_machinegun()
-{
- //precache_model ("models/turrets/machinegun.md3");
- //precache_model ("models/turrets/base.md3");
-
- self.think = turret_machinegun_std_init;
- self.nextthink = time + 0.5;
-}
-
Deleted: trunk/data/qcsrc/server/tturrets/units/turret_unit_mlrs.qc
===================================================================
--- trunk/data/qcsrc/server/tturrets/units/turret_unit_mlrs.qc 2008-10-24 07:48:04 UTC (rev 4855)
+++ trunk/data/qcsrc/server/tturrets/units/turret_unit_mlrs.qc 2008-10-24 07:54:17 UTC (rev 4856)
@@ -1,121 +0,0 @@
-void spawnfunc_turret_mlrs();
-void turret_mlrs_dinit();
-void turret_mlrs_attack();
-void turret_mlrs_projectile_explode();
-
-void turret_mlrs_postthink()
-{
-
- // 0 = full, 6 = empty
-
- self.tur_head.frame = rint(6 - (self.ammo / self.shot_dmg));
-
- //if ((self.tur_head.frame >= 6) && (self.attack_finished_single <= time))
- // self.tur_head.frame = 0;
-}
-
-void turret_mlrs_attack()
-{
- entity missile;
-
- turret_tag_fire_update();
-
- sound (self, CHAN_WEAPON, "weapons/rocket_fire.wav", 1, ATTN_NORM);
-
- missile = spawn ();
- setmodel (missile, "models/turrets/rocket.md3"); // precision set below
- setsize (missile, '-3 -3 -3', '3 3 3'); // give it some size so it can be shot
- sound (missile, CHAN_PROJECTILE, "weapons/rocket_fly.wav", 0.4, ATTN_NORM);
- setorigin(missile, self.tur_shotorg_updated);
- missile.classname = "mlrs_missile";
- missile.owner = self;
- missile.bot_dodge = TRUE;
- missile.bot_dodgerating = self.shot_dmg;
- missile.takedamage = DAMAGE_YES;
- missile.damageforcescale = 4;
- missile.health = 30;
- missile.think = turret_mlrs_projectile_explode;
- missile.nextthink = time + max(self.tur_impacttime,(self.shot_radius * 2) / self.shot_speed);
- missile.solid = SOLID_BBOX;
- missile.movetype = MOVETYPE_FLYMISSILE;
- missile.effects = EF_LOWPRECISION;
- missile.velocity = (self.tur_shotdir_updated + randomvec() * self.shot_spread) * self.shot_speed;
- missile.angles = vectoangles(missile.velocity);
- missile.touch = turret_mlrs_projectile_explode;
- missile.flags = FL_PROJECTILE;
- missile.solid = SOLID_BBOX;
- missile.enemy = self.enemy;
-
- te_explosion (missile.origin);
-
- //self.tur_head.frame = 7 - self.volly_counter;
-}
-
-void turret_mlrs_projectile_explode()
-{
- vector org2;
-
- //vector org2;
- sound (self, CHAN_PROJECTILE, "weapons/rocket_impact.wav", 1, ATTN_NORM);
- org2 = findbetterlocation (self.origin, 16);
- pointparticles(particleeffectnum("rocket_explode"), org2, '0 0 0', 1);
-
- self.event_damage = SUB_Null;
-
-#ifdef TURRET_DEBUG
- float d;
-
- d = RadiusDamage (self, self.owner, self.owner.shot_dmg, 0, self.owner.shot_radius, world, self.owner.shot_force, DEATH_TURRET, world);
- self.owner.tur_dbg_dmg_t_h = self.owner.tur_dbg_dmg_t_h + d; //self.owner.shot_dmg;
- self.owner.tur_dbg_dmg_t_f = self.owner.tur_dbg_dmg_t_f + self.owner.shot_dmg;
-#else
- RadiusDamage (self, self.owner, self.owner.shot_dmg, 0, self.owner.shot_radius, world, self.owner.shot_force, DEATH_TURRET, world);
-#endif
-
- // Target dead, get another is still targeting the same.
- if ((self.enemy.deadflag != DEAD_NO) && (self.enemy == self.owner.enemy))
- self.owner.enemy = world;
-
- remove (self);
-}
-
-void turret_mlrs_dinit()
-{
- if (self.netname == "") self.netname = "MLRS turret";
-
- self.turrcaps_flags = TFL_TURRCAPS_RADIUSDMG | TFL_TURRCAPS_MEDPROJ | TFL_TURRCAPS_PLAYERKILL;
- self.ammo_flags = TFL_AMMO_ROCKETS | TFL_AMMO_RECHARGE;
- self.aim_flags = TFL_AIM_LEAD | TFL_AIM_ZEASE | TFL_AIM_SHOTTIMECOMPENSATE;
-
- if (turret_stdproc_init("mlrs_std") == 0)
- {
- remove(self);
- return;
- }
-
- setmodel(self,"models/turrets/base.md3");
- setmodel(self.tur_head,"models/turrets/mlrs.md3");
-
- if (!turret_tag_setup(0))
- dprint("Warning: Turret ",self.classname, " faild to initialize md3 tags\n");
-
- // Our fire routine
- self.turret_firefunc = turret_mlrs_attack;
- self.turret_postthink = turret_mlrs_postthink;
-
-}
-
-/*QUAKED turret_mlrs (0 .5 .8) ?
-*/
-
-void spawnfunc_turret_mlrs()
-{
- //precache_model ( "models/turrets/rocket.md3");
- //precache_model ("models/turrets/mlrs.md3");
- //precache_model ("models/turrets/base.md3");
-
- self.think = turret_mlrs_dinit;
- self.nextthink = time + 0.5;
-}
-
-
Deleted: trunk/data/qcsrc/server/tturrets/units/turret_unit_phaser.qc
===================================================================
--- trunk/data/qcsrc/server/tturrets/units/turret_unit_phaser.qc 2008-10-24 07:48:04 UTC (rev 4855)
+++ trunk/data/qcsrc/server/tturrets/units/turret_unit_phaser.qc 2008-10-24 07:54:17 UTC (rev 4856)
@@ -1,148 +0,0 @@
-void spawnfunc_turret_phaser();
-void turret_phaser_dinit();
-void turret_phaser_attack();
-
-.float fireflag;
-
-float turret_phaser_firecheck()
-{
- if (self.fireflag != 0) return 0;
- return turret_stdproc_firecheck();
-}
-
-void turret_phaser_postthink()
-{
- if (self.tur_head.frame == 0)
- return;
-
- if (self.fireflag == 1)
- {
- if (self.tur_head.frame == 10)
- self.tur_head.frame = 1;
- else
- self.tur_head.frame = self.tur_head.frame +1;
- }
- else if (self.fireflag == 2 )
- {
- self.tur_head.frame = self.tur_head.frame +1;
- if (self.tur_head.frame == 15)
- {
- self.tur_head.frame = 0;
- self.fireflag = 0;
- }
- }
-}
-
-void beam_think()
-{
- if ((time > self.cnt)||(self.owner.deadflag != DEAD_NO))
- {
- self.owner.attack_finished_single = time + self.owner.shot_refire;
- self.owner.fireflag = 2;
- self.owner.tur_head.frame = 10;
- sound (self, CHAN_PROJECTILE, "", 1, ATTN_NORM);
- remove(self);
- return;
- }
-
- turret_do_updates(self.owner);
-
- if (time - self.shot_spread > 0)
- {
- self.shot_spread = time + 2;
- sound (self, CHAN_VOICE, "turrets/phaser.ogg", 1, ATTN_NORM);
- }
-
-
- self.nextthink = time + self.ticrate;
-
- self.owner.attack_finished_single = time + frametime;
- entity oldself;
- oldself = self;
- self = self.owner;
- FireImoBeam ( self.tur_shotorg_updated,
- self.tur_shotorg_updated + self.tur_shotdir_updated * self.target_range_fire,
- '-1 -1 -1' * self.shot_radius,
- '1 1 1' * self.shot_radius,
- self.shot_force,
- oldself.shot_dmg,
- 0.75,
- DEATH_TURRET);
- self = oldself;
- self.scale = vlen(self.owner.tur_shotorg_updated - trace_endpos) / 256;
-
-}
-
-void turret_phaser_attack()
-{
- entity beam;
-
- beam = spawn();
- beam.ticrate = 0.1; //cvar("sys_ticrate");
- setmodel(beam,"models/turrets/phaser_beam.md3");
- beam.effects = EF_LOWPRECISION;
- beam.solid = SOLID_NOT;
- beam.think = beam_think;
- beam.cnt = time + self.shot_speed;
- beam.shot_spread = time + 2;
- beam.nextthink = time;
- beam.owner = self;
- beam.shot_dmg = self.shot_dmg / (self.shot_speed / beam.ticrate);
- beam.scale = self.target_range_fire / 256;
- beam.movetype = MOVETYPE_NONE;
- beam.enemy = self.enemy;
- beam.bot_dodge = TRUE;
- beam.bot_dodgerating = beam.shot_dmg;
- sound (beam, CHAN_PROJECTILE, "turrets/phaser.ogg", 1, ATTN_NORM);
- self.fireflag = 1;
-
- beam.attack_finished_single = self.attack_finished_single;
- self.attack_finished_single = time; // + cvar("sys_ticrate");
-
- setattachment(beam,self.tur_head,"tag_fire");
-
- soundat (self, trace_endpos, CHAN_PROJECTILE, "weapons/neximpact.wav", VOL_BASE, ATTN_NORM);
-
- if (self.tur_head.frame == 0)
- self.tur_head.frame = 1;
-}
-
-void turret_phaser_dinit()
-{
- if (self.netname == "") self.netname = "Phaser Cannon";
-
- 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;
-
- if (turret_stdproc_init("phaser_std") == 0)
- {
- remove(self);
- return;
- }
-
- setmodel(self,"models/turrets/base.md3");
- setmodel(self.tur_head,"models/turrets/phaser.md3");
-
- if (!turret_tag_setup(0))
- dprint("Warning: Turret ",self.classname, " faild to initialize md3 tags\n");
-
- self.turret_firecheckfunc = turret_phaser_firecheck;
- self.turret_firefunc = turret_phaser_attack;
- self.turret_postthink = turret_phaser_postthink;
-
-}
-
-/*QUAKED turret_phaser(0 .5 .8) ?
-*/
-void spawnfunc_turret_phaser()
-{
- //precache_sound ("turrets/phaser.ogg");
- //precache_model ("models/turrets/phaser.md3");
- //precache_model ("models/turrets/phaser_beam.md3");
- //precache_model ("models/turrets/base.md3");
-
- self.think = turret_phaser_dinit;
- self.nextthink = time + 0.5;
-}
-
Deleted: trunk/data/qcsrc/server/tturrets/units/turret_unit_plasma.qc
===================================================================
--- trunk/data/qcsrc/server/tturrets/units/turret_unit_plasma.qc 2008-10-24 07:48:04 UTC (rev 4855)
+++ trunk/data/qcsrc/server/tturrets/units/turret_unit_plasma.qc 2008-10-24 07:54:17 UTC (rev 4856)
@@ -1,218 +0,0 @@
-void spawnfunc_turret_plasma();
-void spawnfunc_turret_plasma_dual();
-
-void turret_plasma_std_init();
-void turret_plasma_dual_init();
-
-void turret_plasma_attack();
-void turret_plasma_projectile_explode();
-
-void turret_plasma_postthink()
-{
- if (self.tur_head.frame != 0)
- self.tur_head.frame = self.tur_head.frame + 1;
-
- if (self.tur_head.frame >= 5)
- self.tur_head.frame = 0;
-
-}
-
-void turret_plasma_dualpostthink()
-{
- if (self.tur_head.frame != 0)
- self.tur_head.frame = self.tur_head.frame + 1;
-
- if (self.tur_head.frame >= 6)
- self.tur_head.frame = 0;
-}
-
-void turret_plasma_attack()
-{
- entity proj;
-
- turret_tag_fire_update();
-
- sound (self, CHAN_WEAPON, "weapons/hagar_fire.wav", 1, ATTN_NORM);
- proj = spawn ();
- setorigin(proj, self.tur_shotorg_updated);
- setsize(proj, '-0.5 -0.5 -0.5', '0.5 0.5 0.5');
- setmodel(proj, "models/elaser.mdl"); // precision set above
- proj.classname = "plasmabomb";
- proj.owner = self;
- proj.bot_dodge = FALSE;
- //proj.bot_dodgerating = self.shot_dmg;
- proj.think = turret_plasma_projectile_explode;
- proj.nextthink = time + 9;
- proj.solid = SOLID_BBOX;
- proj.movetype = MOVETYPE_FLYMISSILE;
- proj.velocity = (self.tur_shotdir_updated + randomvec() * self.shot_spread) * self.shot_speed;
- proj.angles = vectoangles(proj.velocity);
- proj.touch = turret_plasma_projectile_explode;
- proj.flags = FL_PROJECTILE;
- proj.effects = EF_LOWPRECISION | EF_BRIGHTFIELD;
- proj.enemy = self.enemy;
- proj.flags = FL_PROJECTILE | FL_NOTARGET;
-
- if (self.tur_head.frame == 0)
- self.tur_head.frame = 1;
-
- // Snapback the head
- // self.tur_head.angles_x = self.tur_head.angles_x + min((self.shot_dmg * 0.05),self.aim_maxpitch);
-
-}
-
-void turret_plasma_dual_attack()
-{
- entity proj;
-
- if (self.tur_head.frame > 2)
- self.tur_head.frame = 1;
-
- turret_tag_fire_update();
-
- sound (self, CHAN_WEAPON, "weapons/hagar_fire.wav", 1, ATTN_NORM);
- proj = spawn ();
- setorigin(proj, self.tur_shotorg_updated);
- setsize(proj, '0 0 0', '0 0 0');
- setmodel(proj, "models/elaser.mdl"); // precision set above
- proj.classname = "plasmabomb";
- proj.owner = self;
- proj.bot_dodge = TRUE;
- proj.bot_dodgerating = self.shot_dmg;
- proj.think = turret_plasma_projectile_explode;
- proj.nextthink = time + 9;
- proj.solid = SOLID_BBOX;
- proj.movetype = MOVETYPE_FLYMISSILE;
- proj.velocity = (self.tur_shotdir_updated + randomvec() * self.shot_spread) * self.shot_speed;
- proj.angles = vectoangles(proj.velocity);
- proj.touch = turret_plasma_projectile_explode;
- proj.flags = FL_PROJECTILE;
- proj.effects = EF_LOWPRECISION | EF_BRIGHTFIELD;
- proj.enemy = self.enemy;
- proj.flags = FL_PROJECTILE | FL_NOTARGET;
-
- if (self.tur_head.frame == 0)
- self.tur_head.frame = 1;
-
- // Snapback the head
- // self.tur_head.angles_x = self.tur_head.angles_x + min((self.shot_dmg * 0.05),self.aim_maxpitch);
-
-}
-
-void turret_plasma_projectile_explode()
-{
- vector org2;
-
- org2 = findbetterlocation (self.origin, 8);
- WriteByte (MSG_BROADCAST, SVC_TEMPENTITY);
- WriteByte (MSG_BROADCAST, 79);
- WriteCoord (MSG_BROADCAST, org2_x);
- WriteCoord (MSG_BROADCAST, org2_y);
- WriteCoord (MSG_BROADCAST, org2_z);
- WriteCoord (MSG_BROADCAST, 0); // SeienAbunae: groan... Useless clutter
- WriteCoord (MSG_BROADCAST, 0);
- WriteCoord (MSG_BROADCAST, 0);
- WriteByte (MSG_BROADCAST, 155);
-
- self.event_damage = SUB_Null;
-
-
-#ifdef TURRET_DEBUG
- float d;
-
- d = RadiusDamage (self, self.owner, self.owner.shot_dmg, 0, self.owner.shot_radius, world, self.owner.shot_force, DEATH_TURRET, world);
- self.owner.tur_dbg_dmg_t_h = self.owner.tur_dbg_dmg_t_h + d; //self.owner.shot_dmg;
- self.owner.tur_dbg_dmg_t_f = self.owner.tur_dbg_dmg_t_f + self.owner.shot_dmg;
-#else
- RadiusDamage (self, self.owner, self.owner.shot_dmg, 0, self.owner.shot_radius, world, self.owner.shot_force, DEATH_TURRET, world);
-#endif
- sound (self, CHAN_PROJECTILE, "weapons/electro_impact.wav", 1, ATTN_NORM);
-
- remove (self);
-}
-
-void turret_plasma_std_init()
-{
- if (self.netname == "") self.netname = "Plasma Cannon";
-
- self.ammo_flags = TFL_AMMO_ENERGY | TFL_AMMO_RECHARGE | TFL_AMMO_RECIVE;
- self.aim_flags = TFL_AIM_LEAD | TFL_AIM_SHOTTIMECOMPENSATE | TFL_AIM_ZEASE | TFL_AIM_GROUND2;
-
- if (turret_stdproc_init("plasma_std") == 0)
- {
- remove(self);
- return;
- }
-
- setmodel(self,"models/turrets/base.md3");
- setmodel(self.tur_head,"models/turrets/plasma.md3");
-
-
- if (!turret_tag_setup(0))
- dprint("Warning: Turret ",self.classname, " faild to initialize md3 tags\n");
-
- // Our fire routine
- self.turret_firefunc = turret_plasma_dual_attack;
-
- // re-color badge & handle recoil effect
- self.turret_postthink = turret_plasma_dualpostthink;
-}
-
-
-void turret_plasma_dual_init()
-{
- if (self.netname == "") self.netname = "Dual Plasma Cannon";
-
- self.ammo_flags = TFL_AMMO_ENERGY | TFL_AMMO_RECHARGE | TFL_AMMO_RECIVE;
-
- if (turret_stdproc_init("plasma_dual") == 0)
- {
- remove(self);
- return;
- }
-
- setmodel(self,"models/turrets/base.md3");
- setmodel(self.tur_head,"models/turrets/plasmad.md3");
-
- if (!turret_tag_setup(0))
- dprint("Warning: Turret ",self.classname, " faild to initialize md3 tags\n");
-
- // select aim
- self.aim_flags = TFL_AIM_LEAD | TFL_AIM_SHOTTIMECOMPENSATE | TFL_AIM_ZEASE | TFL_AIM_GROUND2;
-
- // Our fire routine
- self.turret_firefunc = turret_plasma_attack;
-
- // re-color badge & handle recoil effect
- self.turret_postthink = turret_plasma_postthink;
-}
-
-
-/*
-* Basic moderate (std) or fast (dual) fireing, short-mid range energy cannon.
-* Not too mutch of a therat on its own, but can be rather dangerous in groups.
-* Regenerates ammo slowly, support with a fusionreactor(s) to do some real damage.
-*/
-
-/*QUAKED turret_plasma (0 .5 .8) ?
-*/
-void spawnfunc_turret_plasma()
-{
- //precache_model ("models/turrets/plasma.md3");
- //precache_model ("models/turrets/base.md3");
-
- self.think = turret_plasma_std_init;
- self.nextthink = time + 0.5;
-}
-
-/*QUAKED turret_plasma_dual (0 .5 .8) ?
-*/
-void spawnfunc_turret_plasma_dual()
-{
- //precache_model ("models/turrets/plasmad.md3");
- //precache_model ("models/turrets/base.md3");
-
- self.think = turret_plasma_dual_init;
- self.nextthink = time + 0.5;
-}
-
Deleted: trunk/data/qcsrc/server/tturrets/units/turret_unit_targettrigger.qc
===================================================================
--- trunk/data/qcsrc/server/tturrets/units/turret_unit_targettrigger.qc 2008-10-24 07:48:04 UTC (rev 4855)
+++ trunk/data/qcsrc/server/tturrets/units/turret_unit_targettrigger.qc 2008-10-24 07:54:17 UTC (rev 4856)
@@ -1,41 +0,0 @@
-void spawnfunc_turret_targettrigger();
-void turret_targettrigger_touch();
-
-void turret_targettrigger_touch()
-{
- entity e;
- if (self.cnt > time) return;
- entity oldself;
- oldself = self;
-
- e = find(world, targetname, self.target);
- while (e)
- {
- if (e.turrcaps_flags & TFL_TURRCAPS_RECIVETARGETS)
- {
- self = e;
- e.turret_addtarget(other,oldself);
- }
-
- e = find(e, targetname, oldself.target);
- }
-
- oldself.cnt = time + 0.5;
-
- self = oldself;
-}
-
-/*QUAKED turret_targettrigger (.5 .5 .5) ?
-*/
-void spawnfunc_turret_targettrigger()
-{
- if (!cvar("g_turrets"))
- {
- remove(self);
- return;
- }
-
- InitTrigger ();
-
- self.touch = turret_targettrigger_touch;
-}
Deleted: trunk/data/qcsrc/server/tturrets/units/turret_unit_tessla.qc
===================================================================
--- trunk/data/qcsrc/server/tturrets/units/turret_unit_tessla.qc 2008-10-24 07:48:04 UTC (rev 4855)
+++ trunk/data/qcsrc/server/tturrets/units/turret_unit_tessla.qc 2008-10-24 07:54:17 UTC (rev 4856)
@@ -1,147 +0,0 @@
-void spawnfunc_turret_tesla();
-void turret_tesla_dinit();
-void turret_tesla_fire();
-
-.float toasted;
-entity toast(entity from, float range, float damage)
-{
- entity e;
- entity etarget;
- float d,dd;
-
- dd = range + 1;
-
- e = findradius(from.origin,range);
- while (e)
- {
- if ((e.toasted != 1) && (e != from))
- if (turret_validate_target(self,e,self.target_validate_flags) > 0)
- {
-
- traceline(from.origin,e.origin,0,from);
- if (trace_fraction > 0.9)
- {
- d = vlen(e.origin - from.origin);
- if (d < dd)
- {
- dd = d;
- etarget = e;
- }
- }
- }
- e = e.chain;
- }
-
- if (etarget)
- {
- te_smallflash(etarget.origin);
- te_lightning1(world,from.origin,etarget.origin);
- Damage(etarget,self,self,damage,DEATH_TURRET,etarget.origin,'0 0 0');
- etarget.toasted = 1;
- }
-
- return etarget;
-}
-
-void turret_tesla_fire()
-{
- entity e,t;
- float d,r,i;
-
- if (cvar("g_turrets_nofire") != 0)
- return;
-
- if (self.attack_finished_single > time) return;
-
- d = self.shot_dmg;
- r = self.target_range;
- e = spawn();
- setorigin(e,self.origin + self.tur_shotorg);
-
-
- self.target_validate_flags = TFL_TARGETSELECT_PLAYERS | TFL_TARGETSELECT_MISSILES |
- TFL_TARGETSELECT_RANGELIMTS | TFL_TARGETSELECT_TEAMCHECK;
-
- t = toast(e,r,d);
- remove(e);
-
- if (t == world) return;
-
- self.target_validate_flags = TFL_TARGETSELECT_PLAYERS | TFL_TARGETSELECT_MISSILES |
- TFL_TARGETSELECT_TEAMCHECK;
-
- self.attack_finished_single = time + self.shot_refire;
- self.ammo = self.ammo - self.shot_dmg;
- for (i = 0;i < 10;i = i + 1)
- {
- d *= 0.5;
- r *= 0.75;
- t = toast(t,r,d);
- if (t == world) break;
- }
-
- e = findchainfloat(toasted, 1);
- while (e)
- {
- e.toasted = 0;
- e = e.chain;
- }
-}
-
-void turret_tesla_postthink()
-{
- turret_tesla_fire();
-
- self.tur_head.frame = self.tur_head.frame + 1;
-
- if (self.tur_head.frame >= 11)
- self.tur_head.frame = 0;
-
- if (self.tur_head.avelocity == '0 0 0')
- self.tur_head.avelocity = '0 35 0';
-}
-
-
-void turret_tesla_dinit()
-{
- if (self.netname == "") self.netname = "Tesla Coil";
-
- self.turrcaps_flags = TFL_TURRCAPS_HITSCAN | TFL_TURRCAPS_PLAYERKILL | TFL_TURRCAPS_MISSILEKILL;
- self.target_select_flags = TFL_TARGETSELECT_NO;
- self.firecheck_flags = TFL_FIRECHECK_REFIRE;
- self.shoot_flags = TFL_SHOOT_CUSTOM;
- self.ammo_flags = TFL_AMMO_ENERGY | TFL_AMMO_RECHARGE | TFL_AMMO_RECIVE;
- self.aim_flags = TFL_AIM_NO;
- self.track_flags = TFL_TRACK_NO;
-
- if (turret_stdproc_init("tesla_std") == 0)
- {
- remove(self);
- return;
- }
-
- setmodel(self,"models/turrets/tesla_base.md3");
- setmodel(self.tur_head,"models/turrets/tesla_head.md3");
-
- self.target_validate_flags = TFL_TARGETSELECT_PLAYERS | TFL_TARGETSELECT_MISSILES |
- TFL_TARGETSELECT_RANGELIMTS | TFL_TARGETSELECT_TEAMCHECK;
-
- if (!turret_tag_setup(0))
- dprint("Warning: Turret ",self.classname, " faild to initialize md3 tags\n");
-
- self.turret_firefunc = turret_stdproc_nothing;
- self.turret_postthink = turret_tesla_postthink;
-}
-
-/*QUAKED turret_tesla (0 .5 .8) ?
-*/
-void spawnfunc_turret_tesla()
-{
- //precache_model ("models/turrets/tesla_head.md3");
- //precache_model ("models/turrets/tesla_base.md3");
-
-
- self.think = turret_tesla_dinit;
- self.nextthink = time + 0.5;
-}
-
Deleted: trunk/data/qcsrc/server/tturrets/units/turret_unit_walker.qc
===================================================================
--- trunk/data/qcsrc/server/tturrets/units/turret_unit_walker.qc 2008-10-24 07:48:04 UTC (rev 4855)
+++ trunk/data/qcsrc/server/tturrets/units/turret_unit_walker.qc 2008-10-24 07:54:17 UTC (rev 4856)
@@ -1,863 +0,0 @@
-#define ANIM_NO 0
-#define ANIM_WALK 1
-#define ANIM_RUN 1.1
-#define ANIM_STRAFE_L 2
-#define ANIM_STRAFE_R 3
-#define ANIM_TURN 2
-#define ANIM_JUMP 4
-#define ANIM_LAND 5
-#define ANIM_PAIN 6
-#define ANIM_MEELE 7
-.float animflag;
-
-//.float e_time;
-//.vector v_home;
-//.vector movepoint;
-//.entity wkr_waypoint;
-.entity wkr_props;
-.entity wkr_spawn;
-
-//.entity next;
-//.entity prev;
-/*
-.entity goalcurrent, goalstack01, goalstack02, goalstack03;
-.entity goalstack04, goalstack05, goalstack06, goalstack07;
-.entity goalstack08, goalstack09, goalstack10, goalstack11;
-.entity goalstack12, goalstack13, goalstack14, goalstack15;
-.entity goalstack16, goalstack17, goalstack18, goalstack19;
-.entity goalstack20, goalstack21, goalstack22, goalstack23;
-.entity goalstack24, goalstack25, goalstack26, goalstack27;
-.entity goalstack28, goalstack29, goalstack30, goalstack31;
-*/
-
-void checkpoint_think()
-{
- if(self.goalcurrent != world)
- te_lightning1(self,self.origin,self.goalcurrent.origin);
-
-
- self.nextthink = time + 0.5;
-}
-
-void turret_checkpoint_dinit()
-{
- entity e;
-
-
- if(self.target != "")
- {
- e = find(world,targetname,self.target);
- if(!e)
- {
- bprint("turret_checkpoint without valid target! (",vtos(self.origin),")\n");
- remove(self);
- return;
- }
-
- // TODO:: ADD WORLD-INTERACTIVE PATH SUBDEVISION IF PATH NOT CLEAR
- self.goalcurrent = e;
- }
-
- /*
- if(self.goalcurrent == world)
- {
- bprint("turret_checkpoint without valid target (",vtos(self.origin),")\n");
- remove(self);
- return;
- }
- */
-
- //self.think = checkpoint_think;
- //self.nextthink = 1;
-
-}
-
-/**
-.wait
-**/
-void spawnfunc_walker_checkpoint()
-{
- if(!self.wait)
- self.wait = 5;
-
- self.think = turret_checkpoint_dinit;
- self.nextthink = time + 0.25;
-}
-
-
-
-float walker_firecheck()
-{
- if (!turret_stdproc_firecheck()) return 0;
- //if(self.tur_cannon.frame != 0) return 0;
-
- //if(self.walking == 1) self.walking = 2;
- //if(self.walking != 0)
- // return 0;
-
- return 1;
-}
-
-void walker_meele_dmg()
-{
- vector where;
- entity e;
-
- makevectors(self.angles);
- where = self.origin + v_forward * 128;
-
- e = findradius(where,80);
- while(e)
- {
- if(turret_validate_target(self,e,self.target_validate_flags))
- if(e != self)
- Damage(e,self,self,cvar("g_turrets_unit_walker_std_meele_dmg "),DEATH_TURRET,'0 0 0', v_forward * cvar("g_turrets_unit_walker_std_meele_force") );
-
- e = e.chain;
- }
-}
-
-void walker_animate()
-{
-
- if(self.tur_head.frame != 0)
- self.tur_head.frame = self.tur_head.frame +1;
-
- if(self.tur_head.frame > 12)
- self.tur_head.frame = 0;
-
-
- switch(self.animflag)
- {
- case ANIM_NO:
- //if(self.frame != 0)
- // self.frame = 0;
- break;
-
- case ANIM_WALK:
- self.frame = self.frame + 1;
- if(self.frame > 25)
- self.frame = 5;
- break;
-
- case ANIM_RUN:
- self.frame = self.frame + 2;
- if(self.frame > 25)
- self.frame = 5;
- break;
-
- case ANIM_STRAFE_L:
- if(self.frame < 35) self.frame = 35;
- self.frame = self.frame + 1;
- if(self.frame > 55) self.frame = 35;
- break;
-
- case ANIM_STRAFE_R:
- if(self.frame < 65) self.frame = 65;
- self.frame = self.frame + 1;
- if(self.frame > 85) self.frame = 65;
- break;
-
- case ANIM_JUMP:
- if(self.frame < 95) self.frame = 95;
- if(self.frame > 100)
- self.frame = self.frame + 1;
-
- break;
-
- case ANIM_LAND:
- if(self.frame < 100) self.frame = 100;
- self.frame = self.frame + 1;
- if(self.frame > 107)
- self.animflag = ANIM_NO;
- break;
-
- case ANIM_PAIN:
- if(self.frame < 90) self.frame = 90;
- self.frame = self.frame + 1;
- if(self.frame > 95)
- self.animflag = ANIM_NO;
- break;
-
- case ANIM_MEELE:
- if(self.frame < 123) self.frame = 123;
- self.frame = self.frame + 1;
-
- if(self.frame == 133)
- walker_meele_dmg();
-
- if(self.frame > 140)
- self.animflag = ANIM_NO;
-
- }
-}
-
-
-
-
-
-void walker_rocket_explode()
-{
- vector org2;
-
- sound (self, CHAN_PROJECTILE, "weapons/rocket_impact.wav", 1, ATTN_NORM);
- org2 = findbetterlocation (self.origin, 16);
-
- WriteByte (MSG_BROADCAST, SVC_TEMPENTITY);
- WriteByte (MSG_BROADCAST, 78);
- WriteCoord (MSG_BROADCAST, org2_x);
- WriteCoord (MSG_BROADCAST, org2_y);
- WriteCoord (MSG_BROADCAST, org2_z);
-
- self.event_damage = SUB_Null;
-
- RadiusDamage (self, self.owner, cvar("g_turrets_unit_walker_std_rocket_dmg"), 0, cvar("g_turrets_unit_walker_std_rocket_radius"), world, cvar("g_turrets_unit_walker_std_rocket_force"), DEATH_TURRET, world);
-
- remove (self);
-}
-
-void walker_rocket_damage (entity inflictor, entity attacker, float damage, float deathtype, vector hitloc, vector vforce)
-{
- self.health = self.health - damage;
- self.velocity = self.velocity + vforce;
- if (self.health <= 0) walker_rocket_explode();
-}
-
-
-/*
-g_turrets_unit_walker_std_rocket_refire
-g_turrets_unit_walker_std_rocket_dmg
-g_turrets_unit_walker_std_rocket_radius
-g_turrets_unit_walker_std_rocket_force
-g_turrets_unit_walker_std_rocket_tunrate
-g_turrets_unit_walker_std_rocket_speed
-g_turrets_unit_walker_std_rocket_speed_add
-*/
-
-void walker_rocket_loop();
-void walker_rocket_think()
-{
- vector olddir,newdir;
- float edist;
- float itime;
- float m_speed;
-
- self.nextthink = time + 0.1;
-
- olddir = normalize(self.velocity);
- edist = vlen(self.enemy.origin - self.origin);
-
- // Simulate crudely guidance
- if(self.cnt < time)
- {
- if(edist < 1000)
- self.tur_shotorg = randomvec() * min(edist,64);
- else
- self.tur_shotorg = randomvec() * min(edist,256);
- self.cnt = time + 0.5;
- }
- if(edist < 256)
- self.tur_shotorg = '0 0 0';
-
-
- if (self.tur_health < time)
- {
- self.think = walker_rocket_explode;
- self.nextthink = time;
- return;
- }
-
- if((random() < 0.01) && (self.shot_dmg != 1337))
- {
- walker_rocket_loop();
- return;
- }
-
- olddir = normalize(self.velocity);
-
- // Accelerate
- m_speed = vlen(self.velocity) + cvar("g_turrets_unit_walker_std_rocket_speed_add");
-
- // Enemy dead? just keep on the current heading then.
- if ((self.enemy == world) || (self.enemy.deadflag != DEAD_NO))
- {
-
- // Make sure we dont return to tracking a respawned player
- self.enemy = world;
-
- // Turn model
- self.angles = vectoangles(self.velocity);
- }
-
- if (self.enemy)
- {
- // Predict enemy position
- itime = max(edist / m_speed,1);
- newdir = normalize((self.enemy.origin + self.tur_shotorg) - self.origin);
- }
- else
- {
- //pre_pos = self.origin + olddir;
- newdir = olddir;
- }
-
- // Turn
- newdir = normalize(olddir + newdir * cvar("g_turrets_unit_walker_std_rocket_tunrate"));
-
- self.velocity = newdir * m_speed;
-
- // Turn model
- self.angles = vectoangles(self.velocity);
-
- if (time+itime < time+0.1)
- {
- self.think = turret_hellion_missile_explode;
- self.nextthink = time + itime;
- }
-}
-
-void walker_rocket_loop3()
-{
- self.nextthink = time + 0.1;
- if(vlen(self.origin - self.tur_shotorg) < 128 )
- {
- self.think = walker_rocket_think;
- return;
- }
-
- vector newdir;
- vector olddir;
- float m_speed;
-
- m_speed = vlen(self.velocity) + cvar("g_turrets_unit_walker_std_rocket_speed_add");
-
- olddir = normalize(self.velocity);
-
-
- newdir = normalize(self.tur_shotorg - self.origin);
-
- newdir = normalize(olddir + newdir * cvar("g_turrets_unit_walker_std_rocket_tunrate"));
-
-
- self.velocity = newdir * m_speed;
- self.angles = vectoangles(self.velocity);
-}
-
-void walker_rocket_loop2()
-{
- self.nextthink = time + 0;
-
- if(vlen(self.origin - self.tur_shotorg) < 128 )
- {
- self.tur_shotorg = self.origin - '0 0 200';
- self.think = walker_rocket_loop3;
- return;
- }
-
- vector newdir;
- vector olddir;
- float m_speed;
-
- m_speed = vlen(self.velocity) + cvar("g_turrets_unit_walker_std_rocket_speed_add");
-
- olddir = normalize(self.velocity);
-
- newdir = normalize(self.tur_shotorg - self.origin);
-
- newdir = normalize(olddir + newdir * cvar("g_turrets_unit_walker_std_rocket_tunrate"));
-
- self.velocity = newdir * m_speed;
-
- self.angles = vectoangles(self.velocity);
-
-}
-
-void walker_rocket_loop()
-{
-
- self.nextthink= time + 0;
-
- self.tur_shotorg = self.origin + '0 0 400';
-
- self.think = walker_rocket_loop2;
-
- self.shot_dmg = 1337;
-}
-
-
-
-void walker_fire_rocket(vector org)
-{
-
- entity rocket;
-
-
- //self.angles_x *= -1;
- makevectors(self.angles);
- //self.angles_x *= -1;
-
- rocket = spawn ();
- setorigin(rocket, org);
-
- sound (self, CHAN_WEAPON, "weapons/hagar_fire.wav", 1, ATTN_NORM);
- sound (rocket, CHAN_PROJECTILE, "weapons/rocket_fly.wav", 0.4, ATTN_NORM);
- setmodel (rocket, "models/turrets/rocket.md3"); // precision set below
- setsize (rocket, '-3 -3 -3', '3 3 3'); // give it some size so it can be shot
-
- rocket.classname = "walker_rocket";
- rocket.owner = self;
- rocket.bot_dodge = TRUE;
- rocket.bot_dodgerating = 50;
- rocket.takedamage = DAMAGE_YES;
-
- rocket.damageforcescale = 2;
- rocket.health = 10;
- rocket.tur_shotorg = randomvec() * 512;
- rocket.cnt = time + 1;
- rocket.enemy = self.enemy;
-
- if(random() < 0.01)
- rocket.think = walker_rocket_loop;
- else
- rocket.think = walker_rocket_think;
-
- rocket.nextthink = time + 0.2;
- rocket.solid = SOLID_BBOX;
- rocket.movetype = MOVETYPE_FLYMISSILE;
- rocket.effects = EF_LOWPRECISION;
- rocket.velocity = ((v_forward + v_up * 0.5) +(randomvec() * 0.15))* cvar("g_turrets_unit_walker_std_rocket_speed");
- rocket.angles = vectoangles(rocket.velocity);
- rocket.touch = walker_rocket_explode;
- rocket.flags = FL_PROJECTILE;
- rocket.solid = SOLID_BBOX;
- rocket.tur_health = time + 9;
-
- te_explosion (rocket.origin);
-
-}
-
-#define s_turn 10
-#define s_walk 100
-#define s_run 300
-#define s_accel1 8
-#define s_accel2 16
-#define s_decel 8
-
-void rv_think()
-{
- float f;
- vector org;
-
- self.cnt = self.cnt -1;
- if(self.cnt < 0)
- {
- remove(self);
- return;
- }
-
- if(self.cnt> 1)
- f = gettagindex(self.owner,"tag_rocket01");
- else
- f = gettagindex(self.owner,"tag_rocket02");
-
- org = self.owner.origin + gettaginfo(self.owner,f);
-
-
- self.nextthink = time + 0.2;
-
- self = self.owner;
- walker_fire_rocket(org);
-}
-
-void walker_postthink()
-{
- vector wish_angle;
- vector real_angle;
- float turn_limit;
-
-
-
- if(self.flags & FL_ONGROUND)
- {
- self.animflag = ANIM_NO;
- }
-
- if(self.enemy)
- {
- if(self.tur_head.attack_finished_single < time)
- {
- entity rv;
- rv = spawn();
- rv.think = rv_think;
- rv.nextthink = time;
- rv.cnt = 4;
- rv.owner = self;
-
- self.tur_head.attack_finished_single = time + cvar("g_turrets_unit_walker_std_rocket_refire");
- }
-
- }
-
- if(self.goalcurrent)
- {
- //if(self.enemy && (self.tur_dist_enemy < self.target_range_fire))
- // self.animflag = ANIM_TURN;
- //else
- //{
- if(vlen(self.origin - self.goalcurrent.origin) < 32)
- if(self.goalcurrent.goalcurrent == world)
- self.goalcurrent = world; // Path endpoint reached, go roaming.
- else
- self.goalcurrent = self.goalcurrent.goalcurrent;
-
- self.animflag = ANIM_WALK;
- //}
-
-
- }
- else // Roaming mode
- {
-
- if(self.enemy)
- {
- wish_angle = angleofs(self,self.enemy); //normalize(self.origin-self.enemy.origin);
-
- if(self.tur_dist_enemy < cvar("g_turrets_unit_walker_std_meele_range"))
- {
-
- if(fabs(wish_angle_y) < 15)
- self.animflag = ANIM_MEELE;
- }
- else
- {
- if(fabs(wish_angle_y) < 15)
- self.animflag = ANIM_RUN;
- else if(fabs(wish_angle_y) < 30)
- self.animflag = ANIM_WALK;
- else
- self.animflag = ANIM_TURN;
-
- /*
- if(self.tur_dist_enemy > self.target_range_fire)
- self.animflag = ANIM_RUN;
- else if(vlen(self.origin - self.enemy.origin) > self.target_range_min)
- self.animflag = ANIM_WALK;
- else
- self.animflag = ANIM_TURN;
- */
- }
-
- }
- else
- self.animflag = ANIM_NO;
- }
-
-
- float s_speed;
-
- s_speed = vlen(self.velocity);
-
- // Turn on the spot
- if (self.animflag == ANIM_TURN) {
- if(self.enemy)
- wish_angle = normalize(self.enemy.origin - self.origin);
- else
- wish_angle = normalize(self.goalcurrent.origin - self.origin); wish_angle = vectoangles(wish_angle); // And make a angle
-
- real_angle = wish_angle - self.angles;
-
- if (real_angle_x < 0) real_angle_x += 360;
- if (real_angle_x > 180) real_angle_x -= 360;
-
- if (real_angle_y < 0) real_angle_y += 360;
- if (real_angle_y > 180) real_angle_y -= 360;
-
- turn_limit = cvar("g_turrets_unit_walker_turn_turnrate");
- // Convert from dgr/sec to dgr/tic
- turn_limit = turn_limit / (1 / self.ticrate);
-
- //real_angle_x = bound((-1 * turn_limit),real_angle_x, turn_limit);
- real_angle_y = bound((-1 * turn_limit),real_angle_y, turn_limit);
-
- self.angles_y = self.angles_y + real_angle_y;
-
- if(self.enemy)
- v_forward = normalize(self.enemy.origin - self.origin);
- else
- v_forward = normalize(self.goalcurrent.origin - self.origin);
-
- if(s_speed > s_turn)
- self.velocity = (v_forward * max((s_speed - s_decel),s_turn));
- if(s_speed < s_turn)
- self.velocity = (v_forward * min((s_speed + s_accel1),s_turn));
- }
- else if (self.animflag == ANIM_WALK) // Gg walking
- {
- if(self.goalcurrent)
- wish_angle = normalize(self.goalcurrent.origin - self.origin);
- else
- if(self.enemy)
- wish_angle = normalize(self.enemy.origin - self.origin);
- else
- wish_angle = self.angles;
-
-
- wish_angle = vectoangles(wish_angle); // And make a angle
- real_angle = wish_angle - self.angles;
-
- if (real_angle_x < 0) real_angle_x += 360;
- if (real_angle_x > 180) real_angle_x -= 360;
-
- if (real_angle_y < 0) real_angle_y += 360;
- if (real_angle_y > 180) real_angle_y -= 360;
-
- turn_limit = cvar("g_turrets_unit_walker_walk_turnrate");
- // Convert from dgr/sec to dgr/tic
- turn_limit = turn_limit / (1 / self.ticrate);
-
- //real_angle_x = bound((-1 * turn_limit),real_angle_x, turn_limit);
- real_angle_y = bound((-1 * turn_limit),real_angle_y, turn_limit);
-
- self.angles_y = self.angles_y + real_angle_y;
-
-
- if(self.goalcurrent)
- v_forward = normalize(self.goalcurrent.origin - self.origin);
- else
- if(self.enemy)
- v_forward = normalize(self.enemy.origin - self.origin);
-
- //self.velocity = v_forward * s_walk;
-
- if(self.flags & FL_ONGROUND)
- {
- if(s_speed > s_walk)
- self.velocity = (v_forward * max((s_speed - s_decel),s_walk));
- if(s_speed <= s_walk)
- self.velocity = (v_forward * min((s_speed + s_accel1),s_walk));
- }
-
-
- }
- else if (self.animflag == ANIM_RUN) // Move fast, turn slow
- {
- if(self.goalcurrent)
- wish_angle = normalize(self.goalcurrent.origin - self.origin);
- else
- if(self.enemy)
- wish_angle = normalize(self.enemy.origin - self.origin);
- else
- wish_angle = self.angles;
-
- wish_angle = vectoangles(wish_angle); // And make a angle
- real_angle = wish_angle - self.angles;
-
- if (real_angle_x < 0) real_angle_x += 360;
- if (real_angle_x > 180) real_angle_x -= 360;
-
- if (real_angle_y < 0) real_angle_y += 360;
- if (real_angle_y > 180) real_angle_y -= 360;
-
- turn_limit = cvar("g_turrets_unit_walker_run_turnrate");
- // Convert from dgr/sec to dgr/tic
- turn_limit = turn_limit / (1 / self.ticrate);
-
- //real_angle_x = bound((-1 * turn_limit),real_angle_x, turn_limit);
- real_angle_y = bound((-1 * turn_limit),real_angle_y, turn_limit);
-
- self.angles_y = self.angles_y + real_angle_y;
-
-
- if(self.enemy)
- v_forward = normalize(self.enemy.origin - self.origin);
- else
- v_forward = normalize(self.goalcurrent.origin - self.origin);
-
- if(self.flags & FL_ONGROUND)
- {
- if(s_speed > s_run)
- self.velocity = (v_forward * max((s_speed - s_decel),s_run));
- if(s_speed <= s_run)
- self.velocity = (v_forward * min((s_speed + s_accel2),s_run));
- }
- } else {
-
- if(self.flags & FL_ONGROUND)
- {
- makevectors(self.angles);
- if(s_speed > 0)
- self.velocity = min(s_speed - s_decel,0) * v_forward;
- }
- }
-
-
-
- walker_animate();
-
-
-}
-
-void walker_attack()
-{
- entity flash;
-
- //turret_do_updates(self);
-
- self.tur_head.frame = self.tur_head.frame + 1;
-
- sound (self, CHAN_WEAPON, "weapons/uzi_fire.wav", 1, ATTN_NORM);
-
-
- fireBullet (self.tur_shotorg_updated, self.tur_shotdir_updated,self.shot_spread, self.shot_dmg, self.shot_force, DEATH_TURRET, FALSE);
-
- te_smallflash(self.tur_shotorg_updated);
-
- if(!(self.uzi_bulletcounter & 3))
- {
-
- trailparticles(self,particleeffectnum("EF_MGTURRETTRAIL"),self.tur_shotorg_updated,trace_endpos);
- // te_lightning1(self,self.tur_shotorg_updated,trace_endpos);
- flash = spawn();
- setmodel(flash, "models/uziflash.md3"); // precision set below
- setattachment(flash, self.tur_head, "tag_fire");
- flash.scale = 3;
- flash.think = W_Uzi_Flash_Go;
- flash.nextthink = time + 0.02;
- flash.frame = 2;
- flash.angles_z = flash.v_angle_z + random() * 180;
- flash.alpha = 1;
- flash.effects = EF_ADDITIVE | EF_FULLBRIGHT | EF_LOWPRECISION;
- }
-
- self.uzi_bulletcounter = self.uzi_bulletcounter + 1;
-}
-
-void walker_respawnhook()
-{
- vector vtmp;
- self.origin = self.wkr_spawn.origin;
- self.wkr_props.solid = SOLID_BBOX;
- self.wkr_props.alpha = 1;
-
- self.angles = self.wkr_spawn.angles;
- vtmp = self.origin;
- vtmp_z +=self.wkr_spawn.origin_z + self.wkr_spawn.maxs_z;
- setorigin(self,vtmp);
-
-}
-void walker_diehook()
-{
- self.wkr_props.solid = SOLID_NOT;
- self.wkr_props.alpha = -1;
-}
-
-//.string target_start;
-void turret_walker_dinit()
-{
- entity e;
-
- if (self.netname == "") self.netname = "Walker Turret";
-
- if(self.target != "")
- {
- e = find(world,targetname,self.target);
- if(!e)
- {
- bprint("Warning! initital waypoint for Walker does NOT exsist!\n");
- self.target = "";
-
- //remove(self);
- //return;
- }
-
- if(e.classname != "walker_checkpoint")
- dprint("Warning: not a walker path\n");
- else
- self.goalcurrent = e;
- }
-
-
-
-
- self.wkr_props = spawn();
- self.wkr_spawn = spawn();
-
- self.ammo_flags = TFL_AMMO_BULLETS | TFL_AMMO_RECHARGE | TFL_AMMO_RECIVE;
- self.turrcaps_flags = TFL_TURRCAPS_HITSCAN | TFL_TURRCAPS_PLAYERKILL | TFL_TURRCAPS_MOVE | TFL_TURRCAPS_ROAM | TFL_TURRCAPS_LINKED;
- self.aim_flags = TFL_AIM_LEAD | TFL_AIM_ZEASE;
-
- self.turret_respawnhook = walker_respawnhook;
- self.turret_diehook = walker_diehook;
-
- self.ticrate = 0.05;
- if (turret_stdproc_init("walker_std") == 0)
- {
- remove(self);
- return;
- }
- // self.scale = 1.5;
- //setsize(self,'38 38 55','-38 -38 1');
-
- self.target_select_flags = TFL_TARGETSELECT_PLAYERS | 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.flags = FL_CLIENT;
- self.iscreature = TRUE;
- self.movetype = MOVETYPE_WALK;
- self.solid = SOLID_SLIDEBOX;
- self.takedamage = DAMAGE_AIM;
-
- setmodel(self.wkr_props,"models/turrets/walker_props.md3");
- setmodel(self.wkr_spawn,"models/turrets/walker_spawn.md3");
- setorigin(self.wkr_spawn,self.origin);
-
- self.wkr_spawn.angles = self.angles;
- self.wkr_spawn.solid = SOLID_NOT;
-
- traceline(self.wkr_spawn.origin + '0 0 10', self.wkr_spawn.origin - '0 0 10000', MOVE_NOMONSTERS, self);
- setorigin(self.wkr_spawn,trace_endpos + '0 0 4');
-
- setmodel(self,"models/turrets/walker_body.md3");
- setmodel(self.tur_head,"models/turrets/walker_head_minigun.md3");
-
- setattachment(self.tur_head,self,"tag_head");
- setattachment(self.wkr_props,self,"tag_head");
-
- vector v;
- float f;
- f = gettagindex(self.tur_head,"tag_fire");
- v = gettaginfo(self.tur_head,f);
- v_y = v_y * -1;
-
-
- //setsize(self,self.maxs,self.mins);
-
-
- self.tur_shotorg = v;
- self.tur_aimorg = v;
-
- self.idle_aim = '0 0 0';
-
-// self.v_home = self.origin;
-
- self.turret_firecheckfunc = walker_firecheck;
-
- // Our fire routine
- self.turret_firefunc = walker_attack;
-
- self.turret_postthink = walker_postthink;
-
-}
-
-
-void spawnfunc_turret_walker()
-{
- precache_model ("models/turrets/walker_head_minigun.md3");
- precache_model ("models/turrets/walker_body.md3");
- precache_model ("models/turrets/walker_props.md3");
- precache_model ("models/turrets/walker_spawn.md3");
- precache_model ( "models/turrets/rocket.md3");
-
- self.think = turret_walker_dinit;
- self.nextthink = time + 0.5;
-}
Added: trunk/data/qcsrc/server/tturrets/units/unit_checkpoint.qc
===================================================================
--- trunk/data/qcsrc/server/tturrets/units/unit_checkpoint.qc (rev 0)
+++ trunk/data/qcsrc/server/tturrets/units/unit_checkpoint.qc 2008-10-24 07:54:17 UTC (rev 4856)
@@ -0,0 +1,41 @@
+void checkpoint_think()
+{
+ if(self.goalcurrent != world)
+ te_lightning1(self,self.origin,self.goalcurrent.origin);
+
+
+ self.nextthink = time + 0.5;
+}
+
+void turret_checkpoint_dinit()
+{
+ entity e;
+
+
+ if(self.target != "")
+ {
+ e = find(world,targetname,self.target);
+ if(!e)
+ {
+ bprint("turret_checkpoint without valid target! (",vtos(self.origin),")\n");
+ remove(self);
+ return;
+ }
+
+ // TODO:: ADD WORLD-INTERACTIVE PATH SUBDEVISION IF PATH NOT CLEAR
+ self.goalcurrent = e;
+ }
+
+}
+
+/**
+.wait
+**/
+void spawnfunc_turret_checkpoint()
+{
+ if(!self.wait)
+ self.wait = 5;
+
+ self.think = turret_checkpoint_dinit;
+ self.nextthink = time + 0.25;
+}
Copied: trunk/data/qcsrc/server/tturrets/units/unit_common.qc (from rev 4853, trunk/data/qcsrc/server/tturrets/units/turret_unit_common.qc)
===================================================================
--- trunk/data/qcsrc/server/tturrets/units/unit_common.qc (rev 0)
+++ trunk/data/qcsrc/server/tturrets/units/unit_common.qc 2008-10-24 07:54:17 UTC (rev 4856)
@@ -0,0 +1,150 @@
+float turret_tag_setup(float linked)
+{
+ vector v;
+ float f;
+
+ // Laters dooz
+ if (linked)
+ return 0;
+
+ f = gettagindex(self,"tag_head");
+ v = gettaginfo(self,f);
+ v = v + self.origin;
+ setorigin(self.tur_head,v);
+
+ f = gettagindex(self.tur_head,"tag_fire");
+ v = gettaginfo(self.tur_head,f) + (self.tur_head.origin - self.origin);
+ v_y *= -1;
+ self.tur_shotorg = v;
+
+ f = gettagindex(self.tur_head,"tag_aim");
+ v = gettaginfo(self.tur_head,f) + (self.tur_head.origin - self.origin);
+ self.tur_aimorg = v;
+
+ return 1;
+}
+
+float turret_tag_fire_update()
+{
+ vector v;
+ float f;
+
+ f = gettagindex(self.tur_head,"tag_fire");
+ v = gettaginfo(self.tur_head,f) + (self.tur_head.origin - self.origin);
+ v_y *= -1;
+ self.tur_shotorg = v;
+
+ f = gettagindex(self.tur_head,"tag_aim");
+ v = gettaginfo(self.tur_head,f) + (self.tur_head.origin - self.origin);
+ self.tur_aimorg = v;
+
+ return 1;
+}
+
+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;
+ local entity ent;
+
+ dir = normalize(end - start);
+ force = dir * bforce;
+
+ // go a little bit into the wall because we need to hit this wall later
+ end = end + dir;
+
+ // trace multiple times until we hit a wall, each obstacle will be made unsolid.
+ // note down which entities were hit so we can damage them later
+ while (1)
+ {
+ tracebox(start, smin, smax, end, FALSE, self);
+
+ // if it is world we can't hurt it so stop now
+ if (trace_ent == world || trace_fraction == 1)
+ break;
+
+ if (trace_ent.solid == SOLID_BSP)
+ break;
+
+ // make the entity non-solid so we can hit the next one
+ trace_ent.railgunhit = TRUE;
+ trace_ent.railgunhitloc = end;
+ trace_ent.railgunhitsolidbackup = trace_ent.solid;
+
+ // stop if this is a wall
+
+
+ // make the entity non-solid
+ trace_ent.solid = SOLID_NOT;
+ }
+
+ endpoint = trace_endpos;
+
+ // find all the entities the railgun hit and restore their solid state
+ ent = findfloat(world, railgunhit, TRUE);
+ while (ent)
+ {
+ // restore their solid type
+ ent.solid = ent.railgunhitsolidbackup;
+ ent = findfloat(ent, railgunhit, TRUE);
+ }
+
+ // find all the entities the railgun hit and hurt them
+ ent = findfloat(world, railgunhit, TRUE);
+ while (ent)
+ {
+ // get the details we need to call the damage function
+ hitloc = ent.railgunhitloc;
+ ent.railgunhitloc = '0 0 0';
+ ent.railgunhitsolidbackup = SOLID_NOT;
+ ent.railgunhit = FALSE;
+
+ // apply the damage
+ if (ent.takedamage)
+ {
+ Damage (ent, self, self, f_dmg, deathtype, hitloc, force);
+ ent.velocity = ent.velocity * f_velfactor;
+ //ent.alpha = 0.25 + random() * 0.75;
+ }
+
+ // advance to the next entity
+ ent = findfloat(ent, railgunhit, TRUE);
+ }
+ trace_endpos = endpoint;
+}
+
+void turrets_precash()
+{
+ precache_model ("models/turrets/c512.md3");
+
+ precache_sound ("turrets/phaser.ogg");
+
+ precache_model ("models/turrets/base-gib1.md3");
+ precache_model ("models/turrets/base-gib2.md3");
+ precache_model ("models/turrets/base-gib3.md3");
+ precache_model ("models/turrets/base-gib4.md3");
+
+ precache_model ("models/turrets/head-gib1.md3");
+ precache_model ("models/turrets/head-gib2.md3");
+ precache_model ("models/turrets/head-gib3.md3");
+ precache_model ("models/turrets/head-gib4.md3");
+
+ precache_model ("models/turrets/base.md3");
+ precache_model ("models/turrets/flac.md3");
+ precache_model ("models/turrets/pd_proj.md3");
+ precache_model ("models/turrets/reactor.md3");
+ precache_model ("models/turrets/mlrs_rocket.md3");
+ precache_model ("models/turrets/hellion.md3");
+ precache_model ("models/turrets/hunter2.md3");
+ precache_model ("models/turrets/hk.md3");
+ precache_model ("models/turrets/machinegun.md3");
+ precache_model ("models/turrets/rocket.md3");
+ precache_model ("models/turrets/mlrs.md3");
+ precache_model ("models/turrets/phaser.md3");
+ precache_model ("models/turrets/phaser_beam.md3");
+ precache_model ("models/turrets/plasmad.md3");
+ precache_model ("models/turrets/plasma.md3");
+ precache_model ("models/turrets/tesla_head.md3");
+ precache_model ("models/turrets/tesla_base.md3");
+}
Property changes on: trunk/data/qcsrc/server/tturrets/units/unit_common.qc
___________________________________________________________________
Name: svn:mergeinfo
+
Copied: trunk/data/qcsrc/server/tturrets/units/unit_flac.qc (from rev 4853, trunk/data/qcsrc/server/tturrets/units/turret_unit_flac.qc)
===================================================================
--- trunk/data/qcsrc/server/tturrets/units/unit_flac.qc (rev 0)
+++ trunk/data/qcsrc/server/tturrets/units/unit_flac.qc 2008-10-24 07:54:17 UTC (rev 4856)
@@ -0,0 +1,106 @@
+void spawnfunc_turret_flac();
+void turret_flac_dinit();
+void turret_flac_attack();
+void turret_flac_projectile_explode();
+
+void turret_flac_attack()
+{
+ local entity proj;
+
+ turret_tag_fire_update();
+
+ sound (self, CHAN_WEAPON, "weapons/hagar_fire.wav", 1, ATTN_NORM);
+ proj = spawn ();
+ setorigin(proj, self.tur_shotorg_updated);
+ setmodel(proj, "models/turrets/pd_proj.md3");
+ setsize(proj, '0 0 0', '0 0 0');
+ proj.classname = "turret_fire";
+ proj.owner = self;
+ proj.bot_dodge = TRUE;
+ proj.bot_dodgerating = self.shot_dmg;
+ proj.solid = SOLID_NOT;
+ proj.movetype = MOVETYPE_FLYMISSILE;
+ proj.flags = FL_PROJECTILE;
+ proj.effects = EF_LOWPRECISION;
+ proj.takedamage = DAMAGE_YES;
+ proj.health = 10;
+ proj.velocity = (self.tur_shotdir_updated + randomvec() * self.shot_spread) * self.shot_speed;
+ proj.angles = vectoangles(proj.velocity);
+ proj.touch = turret_flac_projectile_explode;
+ proj.think = turret_flac_projectile_explode;
+ proj.nextthink = time + (vlen(self.tur_aimpos - self.tur_shotorg_updated) / self.shot_speed) + (random() * self.shot_spread);
+
+ self.tur_head.frame = self.tur_head.frame + 1;
+ if (self.tur_head.frame >= 4) self.tur_head.frame = 0;
+
+}
+
+void turret_flac_projectile_explode()
+{
+ float ftmp;
+
+ te_explosion (self.origin);
+
+ ftmp = crandom();
+ if (ftmp<-0.7)
+ sound (self, CHAN_PROJECTILE, "weapons/hagexp1.wav", 1, ATTN_NORM);
+ else if (ftmp<0.4)
+ sound (self, CHAN_PROJECTILE, "weapons/hagexp2.wav", 1, ATTN_NORM);
+ else if (ftmp<1)
+ sound (self, CHAN_PROJECTILE, "weapons/hagexp3.wav", 1, ATTN_NORM);
+
+
+ self.event_damage = SUB_Null;
+
+
+#ifdef TURRET_DEBUG
+
+ ftmp = RadiusDamage (self, self.owner, self.owner.shot_dmg, 0, self.owner.shot_radius, world, self.owner.shot_force, DEATH_TURRET, world);
+ self.owner.tur_dbg_dmg_t_h = self.owner.tur_dbg_dmg_t_h + ftmp; //self.owner.shot_dmg;
+ self.owner.tur_dbg_dmg_t_f = self.owner.tur_dbg_dmg_t_f + self.owner.shot_dmg;
+#else
+ RadiusDamage (self, self.owner, self.owner.shot_dmg, 0, self.owner.shot_radius, world, self.owner.shot_force, DEATH_TURRET, world);
+#endif
+
+ remove (self);
+}
+
+
+void turret_flac_dinit()
+{
+ if (self.netname == "") self.netname = "FLAC Cannon";
+
+
+ self.turrcaps_flags = TFL_TURRCAPS_RADIUSDMG | TFL_TURRCAPS_FASTPROJ | TFL_TURRCAPS_MISSILEKILL;
+ self.ammo_flags = TFL_AMMO_ROCKETS | TFL_AMMO_RECHARGE;
+ self.aim_flags = TFL_AIM_LEAD | TFL_AIM_SHOTTIMECOMPENSATE;
+
+ if (turret_stdproc_init("flac_std") == 0)
+ {
+ remove(self);
+ return;
+ }
+
+ setmodel(self,"models/turrets/base.md3");
+ setmodel(self.tur_head,"models/turrets/flac.md3");
+
+ if (!turret_tag_setup(0))
+ dprint("Warning: Turret ",self.classname, " faild to initialize md3 tags\n");
+
+ // Our fire routine
+ self.turret_firefunc = turret_flac_attack;
+
+}
+/*QUAKED turret_flac (0 .5 .8) ?
+*/
+
+void spawnfunc_turret_flac()
+{
+ //precache_model ("models/turrets/base.md3");
+ //precache_model ("models/turrets/flac.md3");
+ //precache_model("models/turrets/pd_proj.md3");
+
+ self.think = turret_flac_dinit;
+ self.nextthink = time + 0.5;
+}
+
Property changes on: trunk/data/qcsrc/server/tturrets/units/unit_flac.qc
___________________________________________________________________
Name: svn:mergeinfo
+
Copied: trunk/data/qcsrc/server/tturrets/units/unit_fusionreactor.qc (from rev 4853, trunk/data/qcsrc/server/tturrets/units/turret_unit_fusionreactor.qc)
===================================================================
--- trunk/data/qcsrc/server/tturrets/units/unit_fusionreactor.qc (rev 0)
+++ trunk/data/qcsrc/server/tturrets/units/unit_fusionreactor.qc 2008-10-24 07:54:17 UTC (rev 4856)
@@ -0,0 +1,81 @@
+void spawnfunc_turret_fusionreactor();
+void turret_fusionreactor_dinit();
+void turret_fusionreactor_fire();
+
+float turret_fusionreactor_firecheck()
+{
+ if (self.enemy == world) return 0;
+
+ if (!self.enemy.ammo_flags & TFL_AMMO_RECIVE) return 0;
+ if (!self.enemy.ammo_flags & TFL_AMMO_ENERGY) return 0;
+
+ if (self.ammo < self.shot_dmg) return 0;
+ if (self.enemy.ammo >= self.enemy.ammo_max) return 0;
+ if (self.tur_dist_enemy > self.target_range_fire) return 0;
+ if (self.tur_dist_enemy < self.target_range_min) return 0;
+
+ return 1;
+}
+
+
+void turret_fusionreactor_fire()
+{
+ self.enemy.ammo = min(self.enemy.ammo + self.shot_dmg,self.enemy.ammo_max);
+ //te_lightning1(world,self.origin,self.enemy.origin);
+}
+
+void turret_fusionreactor_postthink()
+{
+}
+
+
+void turret_fusionreactor_dinit()
+{
+ if (self.netname == "") self.netname = "Fusionreactor";
+
+ self.turrcaps_flags =TFL_TURRCAPS_SUPPORT | TFL_TURRCAPS_AMMOSOURCE;
+
+ self.ammo_flags = TFL_AMMO_ENERGY | TFL_AMMO_RECHARGE;
+
+ self.target_select_flags = TFL_TARGETSELECT_TEAMCHECK | TFL_TARGETSELECT_OWNTEAM | TFL_TARGETSELECT_RANGELIMTS;
+
+ self.firecheck_flags = TFL_FIRECHECK_OWM_AMMO | TFL_FIRECHECK_OTHER_AMMO | TFL_FIRECHECK_DISTANCES | TFL_FIRECHECK_DEAD | TFL_FIRECHECK_WORLD;
+
+ self.shoot_flags = TFL_SHOOT_HITALLVALID;
+
+ self.aim_flags = TFL_AIM_NO;
+
+ self.track_flags = TFL_TRACK_NO;
+
+ if (turret_stdproc_init("fusreac_std") == 0)
+ {
+ remove(self);
+ return;
+ }
+
+ setmodel(self,"models/turrets/base.md3");
+ setmodel(self.tur_head,"models/turrets/reactor.md3");
+
+ //if(!turret_tag_setup(0))
+ // dprint("Warning: Turret ",self.classname, " faild to initialize md3 tags\n");
+
+ self.tur_head.scale = 0.75;
+ setorigin(self.tur_head,self.origin + '0 0 25');
+ self.tur_head.avelocity = '0 50 0';
+
+ self.turret_firecheckfunc = turret_fusionreactor_firecheck;
+ self.turret_firefunc = turret_fusionreactor_fire;
+
+ self.turret_postthink = turret_fusionreactor_postthink;
+}
+
+/*QUAKED turret_fusionreactor (0 .5 .8) ?
+*/
+void spawnfunc_turret_fusionreactor()
+{
+ //precache_model ("models/turrets/reactor.md3");
+ //precache_model ("models/turrets/base.md3");
+
+ self.think = turret_fusionreactor_dinit;
+ self.nextthink = time + 0.5;
+}
Property changes on: trunk/data/qcsrc/server/tturrets/units/unit_fusionreactor.qc
___________________________________________________________________
Name: svn:mergeinfo
+
Copied: trunk/data/qcsrc/server/tturrets/units/unit_hellion.qc (from rev 4853, trunk/data/qcsrc/server/tturrets/units/turret_unit_hellion.qc)
===================================================================
--- trunk/data/qcsrc/server/tturrets/units/unit_hellion.qc (rev 0)
+++ trunk/data/qcsrc/server/tturrets/units/unit_hellion.qc 2008-10-24 07:54:17 UTC (rev 4856)
@@ -0,0 +1,221 @@
+.float shot_speed_max;
+.float shot_speed_gain;
+
+void spawnfunc_turret_hellion();
+void turret_hellion_dinit();
+void turret_hellion_attack();
+void turret_hellion_missile_explode();
+void turret_hellion_missile_think();
+void turret_hellion_missile_damage (entity inflictor, entity attacker, float damage, float deathtype, vector hitloc, vector vforce)
+
+void turret_hellion_postthink()
+{
+ if (cvar("g_turrets_reloadcvars"))
+ {
+ if (!self.shot_speed_max) self.shot_speed_max = cvar("g_turrets_unit_hellion_std_shot_speed_max");
+ if (!self.shot_speed_gain) self.shot_speed_gain = cvar("g_turrets_unit_hellion_std_shot_speed_gain");
+ }
+
+ if (self.tur_head.frame != 0)
+ self.tur_head.frame = self.tur_head.frame + 1;
+
+ if (self.tur_head.frame > 7)
+ self.tur_head.frame = 0;
+}
+
+void turret_hellion_attack()
+{
+ local entity missile;
+
+ sound (self, CHAN_WEAPON, "weapons/hagar_fire.wav", 1, ATTN_NORM);
+
+ missile = spawn ();
+ setorigin(missile, self.tur_shotorg_updated);
+ sound (missile, CHAN_PROJECTILE, "weapons/rocket_fly.wav", 0.4, ATTN_NORM);
+ setmodel (missile, "models/turrets/mlrs_rocket.md3"); // precision set below
+ setsize (missile, '-3 -3 -3', '3 3 3'); // give it some size so it can be shot
+
+ missile.classname = "hellion_missile";
+ missile.owner = self;
+ missile.bot_dodge = TRUE;
+ missile.bot_dodgerating = self.shot_dmg;
+ missile.takedamage = DAMAGE_YES;
+ missile.damageforcescale = 2;
+ missile.health = 50;
+ missile.enemy = self.enemy;
+ missile.think = turret_hellion_missile_think;
+ missile.nextthink = time + 0.2;
+ missile.solid = SOLID_BBOX;
+ missile.movetype = MOVETYPE_FLYMISSILE;
+ missile.effects = EF_LOWPRECISION;
+ missile.velocity = (self.tur_shotdir_updated + randomvec() * self.shot_spread) * self.shot_speed; // + ('0 0 1' * self.shot_speed * 0.15);
+ missile.angles = vectoangles(missile.velocity);
+ missile.touch = turret_hellion_missile_explode;
+ missile.flags = FL_PROJECTILE;
+ missile.solid = SOLID_BBOX;
+ missile.tur_health = time + 9;
+ missile.tur_aimpos = randomvec() * 128;
+ te_explosion (missile.origin);
+
+ // switch tubes
+ self.tur_shotorg_y = self.tur_shotorg_y * -1;
+
+ if (self.tur_head.frame == 0)
+ self.tur_head.frame = self.tur_head.frame + 1;
+
+}
+
+void turret_hellion_missile_damage (entity inflictor, entity attacker, float damage, float deathtype, vector hitloc, vector vforce)
+{
+ self.health = self.health - damage;
+ self.velocity = self.velocity + vforce;
+ if (self.health <= 0) turret_hellion_missile_explode();
+}
+
+void turret_hellion_missile_think()
+{
+ vector olddir,newdir;
+ vector pre_pos;
+ float itime;
+
+ self.nextthink = time + 0.1;
+
+ // Enemy in range?
+ if (vlen(self.origin - self.enemy.origin) < self.owner.shot_radius * 0.25)
+ turret_hellion_missile_explode();
+
+ olddir = normalize(self.velocity);
+
+ if (self.tur_health < time) turret_hellion_missile_explode();
+
+ // Enemy dead? just keep on the current heading then.
+ if ((self.enemy == world) || (self.enemy.deadflag != DEAD_NO))
+ {
+
+ // Make sure we dont return to tracking a respawned player
+ self.enemy = world;
+
+ // Accelerate
+ self.velocity = olddir * min(vlen(self.velocity) * self.owner.shot_speed_gain,self.owner.shot_speed_max);
+
+ // Turn model
+ self.angles = vectoangles(self.velocity);
+
+ //if ( (vlen(self.origin - self.owner.origin)) > (self.owner.shot_radius * 10) )
+ // turret_hellion_missile_explode();
+
+ // return;
+ }
+
+ olddir = normalize(self.velocity);
+
+ if (self.enemy)
+ {
+ // Predict enemy position
+ itime = vlen(self.enemy.origin - self.origin) / vlen(self.velocity);
+ pre_pos = self.enemy.origin + self.enemy.velocity * itime;
+ }
+ else
+ {
+ pre_pos = self.origin + olddir * 1024;
+ }
+
+ pre_pos = (pre_pos + self.enemy.origin) * 0.5;
+
+ //pre_pos += randomvec() * 128; //self.tur_aimpos * (sin(32) * time) ;
+
+
+ // Find out the direction to that place
+ newdir = normalize(pre_pos - self.origin);
+
+ // Turn
+ newdir = normalize(olddir + newdir * 0.5);
+
+ // Accelerate
+ self.velocity = newdir * min(vlen(self.velocity) * self.owner.shot_speed_gain,self.owner.shot_speed_max);
+
+ // Turn model
+ self.angles = vectoangles(self.velocity);
+
+ if (time+itime < time+0.1)
+ {
+ self.think = turret_hellion_missile_explode;
+ self.nextthink = time + itime;
+ }
+}
+
+void turret_hellion_missile_explode()
+{
+ vector org2;
+ float d;
+
+ sound (self, CHAN_PROJECTILE, "weapons/rocket_impact.wav", 1, ATTN_NORM);
+ org2 = findbetterlocation (self.origin, 16);
+
+ // LordHavoc: TE_TEI_BIGEXPLOSION
+ WriteByte (MSG_BROADCAST, SVC_TEMPENTITY);
+ WriteByte (MSG_BROADCAST, 78);
+ WriteCoord (MSG_BROADCAST, org2_x);
+ WriteCoord (MSG_BROADCAST, org2_y);
+ WriteCoord (MSG_BROADCAST, org2_z);
+
+ self.event_damage = SUB_Null;
+ d = RadiusDamage (self, self.owner, self.owner.shot_dmg, 0, self.owner.shot_radius, world, self.owner.shot_force, DEATH_TURRET, world);
+
+#ifdef TURRET_DEBUG
+ self.owner.tur_dbg_dmg_t_h = self.owner.tur_dbg_dmg_t_h + d; //self.owner.shot_dmg;
+ self.owner.tur_dbg_dmg_t_f = self.owner.tur_dbg_dmg_t_f + self.owner.shot_dmg;
+#endif
+
+ // Target dead, get another is still targeting the same.
+ if ((self.enemy.deadflag != DEAD_NO) && (self.enemy == self.owner.enemy))
+ self.owner.enemy = world;
+
+ remove (self);
+}
+
+void turret_hellion_dinit()
+{
+ if (self.netname == "") self.netname = "Hellion Missile Turret";
+
+ if (!self.shot_speed_max) self.shot_speed_max = cvar("g_turrets_unit_hellion_std_shot_speed_max");
+ if (!self.shot_speed_gain) self.shot_speed_gain = cvar("g_turrets_unit_hellion_std_shot_speed_gain");
+
+ self.turrcaps_flags = TFL_TURRCAPS_RADIUSDMG | TFL_TURRCAPS_FASTPROJ | TFL_TURRCAPS_PLAYERKILL | TFL_TURRCAPS_MISSILEKILL;
+ self.aim_flags = TFL_AIM_SIMPLE;
+ self.target_select_flags = TFL_TARGETSELECT_LOS | TFL_TARGETSELECT_PLAYERS | TFL_TARGETSELECT_TRIGGERTARGET | TFL_TARGETSELECT_RANGELIMTS | TFL_TARGETSELECT_TEAMCHECK ;
+ self.firecheck_flags = TFL_FIRECHECK_WORLD | TFL_FIRECHECK_DEAD | TFL_FIRECHECK_DISTANCES | TFL_FIRECHECK_TEAMCECK | TFL_FIRECHECK_REFIRE | TFL_FIRECHECK_AFF | TFL_FIRECHECK_OWM_AMMO;
+ self.ammo_flags = TFL_AMMO_ROCKETS | TFL_AMMO_RECHARGE;
+
+ if (turret_stdproc_init("hellion_std") == 0)
+ {
+ remove(self);
+ return;
+ }
+
+ setmodel(self,"models/turrets/base.md3");
+ setmodel(self.tur_head,"models/turrets/hellion.md3");
+
+ if (!turret_tag_setup(0))
+ dprint("Warning: Turret ",self.classname, " faild to initialize md3 tags\n");
+
+ // Our fire routine
+ self.turret_firefunc = turret_hellion_attack;
+
+ // Custom animations and sutch
+ self.turret_postthink = turret_hellion_postthink;
+}
+
+/*QUAKED turret_hellion (0 .5 .8) ?
+*/
+void spawnfunc_turret_hellion()
+{
+ //precache_model ( "models/turrets/mlrs_rocket.md3");
+ //precache_model ("models/turrets/hellion.md3");
+ //precache_model ("models/turrets/base.md3");
+
+ self.think = turret_hellion_dinit;
+ self.nextthink = time + 0.5;
+}
+
+
Property changes on: trunk/data/qcsrc/server/tturrets/units/unit_hellion.qc
___________________________________________________________________
Name: svn:mergeinfo
+
Copied: trunk/data/qcsrc/server/tturrets/units/unit_hk.qc (from rev 4853, trunk/data/qcsrc/server/tturrets/units/turret_unit_hk.qc)
===================================================================
--- trunk/data/qcsrc/server/tturrets/units/unit_hk.qc (rev 0)
+++ trunk/data/qcsrc/server/tturrets/units/unit_hk.qc 2008-10-24 07:54:17 UTC (rev 4856)
@@ -0,0 +1,470 @@
+//#define TURRET_DEBUG_HK
+
+#ifdef TURRET_DEBUG_HK
+.float atime;
+#endif
+
+void spawnfunc_turret_hk();
+void turret_hk_dinit();
+void turret_hk_attack();
+void turret_hk_missile_explode();
+void turret_hk_missile_think();
+void turret_hk_missile_damage (entity inflictor, entity attacker, float damage, float deathtype, vector hitloc, vector force);
+float turret_hk_addtarget(entity e_target,entity e_sender);
+//void turret_hk_missile_touch();
+
+float hk_maxspeed;
+float hk_minspeed;
+float hk_accel;
+float hk_accel2;
+float hk_decel;
+
+float turret_hk_addtarget(entity e_target,entity e_sender)
+{
+ if (e_target)
+ {
+ if (turret_validate_target(self,e_target,self.target_validate_flags) > 0)
+ {
+ self.enemy = e_target;
+ return 1;
+ }
+ }
+
+ return 0;
+}
+
+float hk_is_valid_target(entity e_target)
+{
+ if (e_target == world)
+ return 0;
+
+ // If only this was used more..
+ if (e_target.flags & FL_NOTARGET)
+ return 0;
+
+ // Cant touch this
+ if ((e_target.takedamage == DAMAGE_NO) || (e_target.health < 0))
+ return 0;
+
+ // player
+ if (e_target.flags & FL_CLIENT)
+ {
+ if (self.owner.target_select_playerbias < 0)
+ return 0;
+
+ if (e_target.deadflag != DEAD_NO)
+ return 0;
+ }
+
+ // Missile
+ if ((e_target.flags & FL_PROJECTILE) && (self.owner.target_select_missilebias < 0))
+ return 0;
+
+ // Team check
+ if ((e_target.team == self.owner.team) || (self.owner.team == e_target.owner.team))
+ return 0;
+
+ return 1;
+}
+
+void turret_hk_missile_damage (entity inflictor, entity attacker, float damage, float deathtype, vector hitloc, vector force)
+{
+ if (attacker.team == self.team)
+ damage *= 0.5;
+
+ self.velocity += force;
+
+ self.health -= damage;
+
+ if (self.health <= 0)
+ turret_hk_missile_explode();
+}
+
+void turret_hk_attack()
+{
+ local entity missile;
+ //local entity flash2;
+
+ sound (self, CHAN_WEAPON, "weapons/rocket_fire.wav", 1, ATTN_NORM);
+
+ missile = spawn ();
+ missile.solid = SOLID_BBOX;
+ setmodel (missile, "models/turrets/hunter2.md3"); // precision set below
+ setsize (missile, missile.mins,missile.maxs); // give it some size so it can be shot
+ sound (missile, CHAN_PROJECTILE, "weapons/rocket_fly.wav", 0.4, ATTN_NORM);
+ setorigin(missile, self.tur_shotorg_updated);
+
+ missile.scale = 1;
+ missile.classname = "hk_missile";
+ missile.owner = self;
+ missile.bot_dodge = TRUE;
+ missile.bot_dodgerating = self.shot_dmg;
+ missile.takedamage = DAMAGE_YES;
+ missile.damageforcescale = 4;
+ missile.health = 10;
+ missile.think = turret_hk_missile_think;
+ missile.event_damage = turret_hk_missile_damage;
+ missile.nextthink = time + 0.25;
+ missile.movetype = MOVETYPE_BOUNCEMISSILE;
+ missile.effects = EF_LOWPRECISION;
+ missile.velocity = self.tur_shotdir_updated * (self.shot_speed * 0.75);
+ missile.angles = vectoangles(missile.velocity);
+ missile.touch = turret_hk_missile_explode; //turret_hk_missile_touch;
+ missile.flags = FL_PROJECTILE;
+ missile.enemy = self.enemy;
+ missile.team = self.team;
+ missile.cnt = time + 30;
+ missile.ticrate = max(cvar("sys_ticrate"),0.05);
+
+ te_explosion (missile.origin);
+
+ if (self.tur_head.frame == 0)
+ self.tur_head.frame = self.tur_head.frame + 1;
+
+}
+
+/*
+void turret_hk_missile_touch()
+{
+ if(other == self.enemy)
+ turret_hk_missile_explode();
+ else
+ {
+ if(self.cnt < time)
+ {
+ self.cnt = time + 0.25;
+ self.health = self.health - 5;
+ if(self.health <= 0)
+ turret_hk_missile_explode();
+
+ }
+ }
+}
+*/
+
+void turret_hk_missile_think()
+{
+ vector vu, vd, vf, vl, vr, ve; // Vector (direction)
+ float fu, fd, ff, fl, fr, fe; // Fraction to solid
+ vector olddir,wishdir,newdir; // Final direction
+ float lt_for; // Length of Trace FORwrad
+ float lt_seek; // Length of Trace SEEK (left, right, up down)
+ float pt_seek; // Pitch of Trace SEEK (How mutch to angele left, right up, down trace towards v_forward)
+ vector pre_pos;
+ float myspeed;
+ entity e;
+ float ad,edist;
+
+ self.nextthink = time + self.ticrate;
+
+ //if (self.cnt < time)
+ // turret_hk_missile_explode();
+
+ if (self.enemy.deadflag != DEAD_NO)
+ self.enemy = world;
+
+ // Pick the closest valid target.
+ if (!self.enemy)
+ {
+ e = findradius(self.origin, 5000);
+ while (e)
+ {
+ if (hk_is_valid_target(e))
+ {
+ if (!self.enemy)
+ self.enemy = e;
+ else
+ if (vlen(self.origin - e.origin) < vlen(self.origin - self.enemy.origin))
+ self.enemy = e;
+ }
+ e = e.chain;
+ }
+ }
+
+ self.angles = vectoangles(self.velocity);
+ self.angles_x = self.angles_x * -1;
+ makevectors(self.angles);
+ self.angles_x = self.angles_x * -1;
+
+ if (self.enemy)
+ {
+ edist = vlen(self.origin - self.enemy.origin);
+ // Close enougth to do decent damage?
+ if ( edist <= (self.owner.shot_radius * 0.25) )
+ {
+ turret_hk_missile_explode();
+ return;
+ }
+
+ // Get data on enemy position
+ pre_pos = self.enemy.origin +
+ self.enemy.velocity *
+ min((vlen(self.enemy.origin - self.origin) / vlen(self.velocity)),0.5);
+
+ traceline(self.origin, pre_pos,TRUE,self.enemy);
+ ve = normalize(pre_pos - self.origin);
+ fe = trace_fraction;
+
+ }
+ else
+ {
+ fe = 0;
+ }
+
+ if ((fe != 1) || (self.enemy == world) || (edist > 1000))
+ {
+ myspeed = vlen(self.velocity);
+
+ lt_for = myspeed * 3;
+ lt_seek = myspeed * 2.95;
+
+ // Trace forward
+ traceline(self.origin, self.origin + v_forward * lt_for,FALSE,self);
+ vf = trace_endpos;
+ ff = trace_fraction;
+
+ // Find angular offset
+ ad = vlen(vectoangles(normalize(self.enemy.origin - self.origin)) - self.angles);
+
+ // To close to something, Slow down!
+ if ( ((ff < 0.7) || (ad > 4)) && (myspeed > hk_minspeed) )
+ myspeed = max(myspeed * hk_decel,hk_minspeed);
+
+ // Failry clear, accelerate.
+ if ( (ff > 0.7) && (myspeed < hk_maxspeed) )
+ myspeed = min(myspeed * hk_accel,hk_maxspeed);
+
+ // Setup trace pitch
+ pt_seek = 1 - ff;
+ pt_seek = bound(0.15,pt_seek,0.8);
+ if (ff < 0.5) pt_seek = 1;
+
+ // Trace left
+ traceline(self.origin, self.origin + (-1 * (v_right * pt_seek) + (v_forward * ff)) * lt_seek,FALSE,self);
+ vl = trace_endpos;
+ fl = trace_fraction;
+
+ // Trace right
+ traceline(self.origin, self.origin + ((v_right * pt_seek) + (v_forward * ff)) * lt_seek ,FALSE,self);
+ vr = trace_endpos;
+ fr = trace_fraction;
+
+ // Trace up
+ traceline(self.origin, self.origin + ((v_up * pt_seek) + (v_forward * ff)) * lt_seek ,FALSE,self);
+ vu = trace_endpos;
+ fu = trace_fraction;
+
+ // Trace down
+ traceline(self.origin, self.origin + (-1 * (v_up * pt_seek) + (v_forward * ff)) * lt_seek ,FALSE,self);
+ vd = trace_endpos;
+ fd = trace_fraction;
+
+ vl = normalize(vl - self.origin);
+ vr = normalize(vr - self.origin);
+ vu = normalize(vu - self.origin);
+ vd = normalize(vd - self.origin);
+
+ // Panic tresh passed, find a single direction and turn as hard as we can
+ if (pt_seek == 1)
+ {
+ wishdir = v_right;
+ if (fl > fr) wishdir = -1 * v_right;
+ if (fu > fl) wishdir = v_up;
+ if (fd > fu) wishdir = -1 * v_up;
+ }
+ else
+ {
+ // Normalize our trace vectors to make a smooth path
+ wishdir = normalize( (vl * fl) + (vr * fr) + (vu * fu) + (vd * fd) );
+ }
+
+ if (self.enemy)
+ {
+ if (fe < 0.1) fe = 0.1; // Make sure we always try to move sligtly towards our target
+ wishdir = (wishdir * (1 - fe)) + (ve * fe);
+ }
+ }
+ else
+ {
+ // Got a clear path to target, speed up fast (if not at full speed) and go straight for it.
+ myspeed = vlen(self.velocity);
+ if (myspeed < hk_maxspeed)
+ myspeed = min(myspeed * hk_accel2,hk_maxspeed);
+
+ wishdir = ve;
+ //wishdir = normalize(self.enemy.origin - (self.enemy.origin + self.enemy.velocity));
+ }
+
+ if ((myspeed > hk_minspeed) && (self.cnt > time))
+ myspeed = min(myspeed * hk_accel2,hk_maxspeed);
+
+ // Ranoutagazfish?
+ if (self.cnt < time)
+ {
+ self.cnt = time + 0.25;
+ self.nextthink = 0;
+ self.movetype = MOVETYPE_BOUNCE;
+ sound (self, CHAN_VOICE, "", 0.4, ATTN_NORM);
+ return;
+ }
+
+ // Calculate new heading
+ olddir = normalize(self.velocity);
+
+ newdir = normalize(olddir + wishdir * cvar("g_turrets_unit_hk_std_shot_speed_turnrate"));
+
+ //fu = (1 / hk_maxspeed) * myspeed;
+ //fd = fu - (0.75 - 0.25);
+ //newdir = normalize(olddir + wishdir * fd);
+
+ // Set heading & speed
+ self.velocity = newdir * myspeed;
+
+ // Align model with new heading
+ self.angles = vectoangles(self.velocity);
+
+
+#ifdef TURRET_DEBUG_HK
+ //if(self.atime < time) {
+ if ((fe <= 0.99)||(edist > 1000))
+ {
+ te_lightning2(world,self.origin, self.origin + vr * lt_seek);
+ te_lightning2(world,self.origin, self.origin + vl * lt_seek);
+ te_lightning2(world,self.origin, self.origin + vu * lt_seek);
+ te_lightning2(world,self.origin, self.origin + vd * lt_seek);
+ te_lightning2(world,self.origin, vf);
+ }
+ else
+ {
+ te_lightning2(world,self.origin, self.enemy.origin);
+ }
+ bprint("Speed: ", ftos(rint(myspeed)), "\n");
+ bprint("Trace to solid: ", ftos(rint(ff * 100)), "%\n");
+ bprint("Trace to target:", ftos(rint(fe * 100)), "%\n");
+ self.atime = time + 0.2;
+ //}
+#endif
+}
+
+void turret_hk_missile_explode()
+{
+ vector org2;
+ float d;
+
+ if ((other == self.owner)||(other == self.owner.tur_head))
+ return;
+
+ //vector org2;
+ sound (self, CHAN_PROJECTILE, "weapons/rocket_impact.wav", 1, ATTN_NORM);
+ org2 = findbetterlocation (self.origin, 16);
+
+ // LordHavoc: TE_TEI_BIGEXPLOSION
+ WriteByte (MSG_BROADCAST, SVC_TEMPENTITY);
+ WriteByte (MSG_BROADCAST, 78);
+ WriteCoord (MSG_BROADCAST, org2_x);
+ WriteCoord (MSG_BROADCAST, org2_y);
+ WriteCoord (MSG_BROADCAST, org2_z);
+
+ self.event_damage = SUB_Null;
+ d = RadiusDamage (self, self.owner, self.owner.shot_dmg, 0, self.owner.shot_radius, world, self.owner.shot_force, DEATH_TURRET, world);
+
+#ifdef TURRET_DEBUG
+ self.owner.tur_dbg_dmg_t_h = self.owner.tur_dbg_dmg_t_h + d; //self.owner.shot_dmg;
+ self.owner.tur_dbg_dmg_t_f = self.owner.tur_dbg_dmg_t_f + self.owner.shot_dmg;
+#endif
+
+ // Target dead, get another is still targeting the same.
+ if ((self.enemy.deadflag != DEAD_NO) && (self.enemy == self.owner.enemy))
+ self.owner.enemy = world;
+
+ remove (self);
+}
+
+void turret_hk_postthink()
+{
+ if (cvar("g_turrets_reloadcvars"))
+ {
+ hk_maxspeed = cvar("g_turrets_unit_hk_std_shot_speed_max");
+ hk_minspeed = cvar("g_turrets_unit_hk_std_shot_speed");
+ hk_accel = cvar("g_turrets_unit_hk_std_shot_speed_accel");
+ hk_accel2 = cvar("g_turrets_unit_hk_std_shot_speed_accel2");
+ hk_decel = cvar("g_turrets_unit_hk_std_shot_speed_decel");
+ }
+
+ if (self.tur_head.frame != 0)
+ self.tur_head.frame = self.tur_head.frame + 1;
+
+ if (self.tur_head.frame > 5)
+ self.tur_head.frame = 0;
+
+}
+
+void turret_hk_dinit()
+{
+ if (self.netname == "") self.netname = "Hunter-killer turret";
+
+ hk_maxspeed = cvar("g_turrets_unit_hk_std_shot_speed_max");
+ hk_minspeed = cvar("g_turrets_unit_hk_std_shot_speed");
+ hk_accel = cvar("g_turrets_unit_hk_std_shot_speed_accel");
+ hk_accel2 = cvar("g_turrets_unit_hk_std_shot_speed_accel2");
+ hk_decel = cvar("g_turrets_unit_hk_std_shot_speed_decel");
+
+ self.turrcaps_flags = TFL_TURRCAPS_RADIUSDMG | TFL_TURRCAPS_MEDPROJ | TFL_TURRCAPS_PLAYERKILL | TFL_TURRCAPS_RECIVETARGETS;
+
+ self.ammo_flags = TFL_AMMO_ROCKETS | TFL_AMMO_RECHARGE;
+
+ self.aim_flags = TFL_AIM_SIMPLE;
+
+ self.target_select_flags = TFL_TARGETSELECT_LOS | TFL_TARGETSELECT_PLAYERS | TFL_TARGETSELECT_TRIGGERTARGET | TFL_TARGETSELECT_RANGELIMTS | TFL_TARGETSELECT_TEAMCHECK;
+
+ self.firecheck_flags = TFL_FIRECHECK_WORLD | TFL_FIRECHECK_DEAD | TFL_FIRECHECK_TEAMCECK | TFL_FIRECHECK_REFIRE | TFL_FIRECHECK_AFF;
+
+ self.target_select_flags = TFL_TARGETSELECT_LOS | TFL_TARGETSELECT_PLAYERS | TFL_TARGETSELECT_TRIGGERTARGET | TFL_TARGETSELECT_RANGELIMTS | TFL_TARGETSELECT_TEAMCHECK;
+
+ self.shoot_flags = TFL_SHOOT_CLEARTARGET;
+
+ if (turret_stdproc_init("hk_std") == 0)
+ {
+ remove(self);
+ return;
+ }
+
+ self.target_validate_flags = TFL_TARGETSELECT_PLAYERS | TFL_TARGETSELECT_TEAMCHECK;
+
+ setmodel(self,"models/turrets/base.md3");
+ setmodel(self.tur_head,"models/turrets/hk.md3");
+
+ if (!turret_tag_setup(0))
+ dprint("Warning: Turret ",self.classname, " faild to initialize md3 tags\n");
+
+ // Our fire routine
+ self.turret_firefunc = turret_hk_attack;
+
+ // re-color badge & handle recoil effect
+ self.turret_postthink = turret_hk_postthink;
+
+ // What to do when reciveing foreign target data
+ self.turret_addtarget = turret_hk_addtarget;
+}
+
+/*
+* Turret that fires Hunter-killer missiles.
+* Missiles seek their target and try to avoid obstacles. If target dies early, they
+* pick a new one on their own.
+*/
+
+/*QUAKED turret_hk (0 .5 .8) ?
+hunter-killer missiles.
+*/
+
+void spawnfunc_turret_hk()
+{
+ //precache_model ( "models/turrets/hunter2.md3");
+ //precache_model ("models/turrets/base.md3");
+ //precache_model ("models/turrets/hk.md3");
+
+ self.think = turret_hk_dinit;
+ self.nextthink = time + 0.5;
+}
+
+
Property changes on: trunk/data/qcsrc/server/tturrets/units/unit_hk.qc
___________________________________________________________________
Name: svn:mergeinfo
+
Copied: trunk/data/qcsrc/server/tturrets/units/unit_machinegun.qc (from rev 4853, trunk/data/qcsrc/server/tturrets/units/turret_unit_machinegun.qc)
===================================================================
--- trunk/data/qcsrc/server/tturrets/units/unit_machinegun.qc (rev 0)
+++ trunk/data/qcsrc/server/tturrets/units/unit_machinegun.qc 2008-10-24 07:54:17 UTC (rev 4856)
@@ -0,0 +1,71 @@
+void spawnfunc_turret_machinegun();
+void turret_machinegun_std_init();
+void turret_machinegun_attack();
+
+//.float bulletcounter;
+void turret_machinegun_attack()
+{
+
+ entity flash;
+ sound (self, CHAN_WEAPON, "weapons/uzi_fire.wav", 1, ATTN_NORM);
+ fireBullet (self.tur_shotorg_updated, self.tur_shotdir_updated,self.shot_spread, self.shot_dmg, self.shot_force, DEATH_TURRET, FALSE);
+
+ te_smallflash(self.tur_shotorg_updated);
+ trailparticles(self,particleeffectnum("EF_MGTURRETTRAIL"),self.tur_shotorg_updated,trace_endpos);
+
+ // muzzle flash for 3rd person view
+ flash = spawn();
+ //setorigin(flash, '43 1 8');
+ setmodel(flash, "models/uziflash.md3"); // precision set below
+ setattachment(flash, self.tur_head, "tag_fire");
+ flash.think = W_Uzi_Flash_Go;
+ flash.nextthink = time + 0.02;
+ flash.frame = 2;
+ flash.angles_z = flash.v_angle_z + random() * 180;
+ flash.alpha = 1;
+ flash.effects = EF_ADDITIVE | EF_FULLBRIGHT | EF_LOWPRECISION;
+}
+
+
+void turret_machinegun_std_init()
+{
+ if (self.netname == "") self.netname = "Machinegun Turret";
+
+ self.ammo_flags = TFL_AMMO_BULLETS | TFL_AMMO_RECHARGE | TFL_AMMO_RECIVE;
+ self.turrcaps_flags = TFL_TURRCAPS_HITSCAN | TFL_TURRCAPS_PLAYERKILL;
+ self.aim_flags = TFL_AIM_LEAD | TFL_AIM_ZEASE;
+
+ if (turret_stdproc_init("machinegun_std") == 0)
+ {
+ remove(self);
+ return;
+ }
+
+ setmodel(self,"models/turrets/base.md3");
+ setmodel(self.tur_head,"models/turrets/machinegun.md3");
+
+ if (!turret_tag_setup(0))
+ dprint("Warning: Turret ",self.classname, " faild to initialize md3 tags\n");
+
+ // Our fire routine
+ self.turret_firefunc = turret_machinegun_attack;
+
+}
+
+
+
+/*
+* machinegun turret. does what you'd expect
+*/
+
+/*QUAKED turret_machinegun (0 .5 .8) ?
+*/
+void spawnfunc_turret_machinegun()
+{
+ //precache_model ("models/turrets/machinegun.md3");
+ //precache_model ("models/turrets/base.md3");
+
+ self.think = turret_machinegun_std_init;
+ self.nextthink = time + 0.5;
+}
+
Property changes on: trunk/data/qcsrc/server/tturrets/units/unit_machinegun.qc
___________________________________________________________________
Name: svn:mergeinfo
+
Copied: trunk/data/qcsrc/server/tturrets/units/unit_mlrs.qc (from rev 4853, trunk/data/qcsrc/server/tturrets/units/turret_unit_mlrs.qc)
===================================================================
--- trunk/data/qcsrc/server/tturrets/units/unit_mlrs.qc (rev 0)
+++ trunk/data/qcsrc/server/tturrets/units/unit_mlrs.qc 2008-10-24 07:54:17 UTC (rev 4856)
@@ -0,0 +1,121 @@
+void spawnfunc_turret_mlrs();
+void turret_mlrs_dinit();
+void turret_mlrs_attack();
+void turret_mlrs_projectile_explode();
+
+void turret_mlrs_postthink()
+{
+
+ // 0 = full, 6 = empty
+
+ self.tur_head.frame = rint(6 - (self.ammo / self.shot_dmg));
+
+ //if ((self.tur_head.frame >= 6) && (self.attack_finished_single <= time))
+ // self.tur_head.frame = 0;
+}
+
+void turret_mlrs_attack()
+{
+ entity missile;
+
+ turret_tag_fire_update();
+
+ sound (self, CHAN_WEAPON, "weapons/rocket_fire.wav", 1, ATTN_NORM);
+
+ missile = spawn ();
+ setmodel (missile, "models/turrets/rocket.md3"); // precision set below
+ setsize (missile, '-3 -3 -3', '3 3 3'); // give it some size so it can be shot
+ sound (missile, CHAN_PROJECTILE, "weapons/rocket_fly.wav", 0.4, ATTN_NORM);
+ setorigin(missile, self.tur_shotorg_updated);
+ missile.classname = "mlrs_missile";
+ missile.owner = self;
+ missile.bot_dodge = TRUE;
+ missile.bot_dodgerating = self.shot_dmg;
+ missile.takedamage = DAMAGE_YES;
+ missile.damageforcescale = 4;
+ missile.health = 30;
+ missile.think = turret_mlrs_projectile_explode;
+ missile.nextthink = time + max(self.tur_impacttime,(self.shot_radius * 2) / self.shot_speed);
+ missile.solid = SOLID_BBOX;
+ missile.movetype = MOVETYPE_FLYMISSILE;
+ missile.effects = EF_LOWPRECISION;
+ missile.velocity = (self.tur_shotdir_updated + randomvec() * self.shot_spread) * self.shot_speed;
+ missile.angles = vectoangles(missile.velocity);
+ missile.touch = turret_mlrs_projectile_explode;
+ missile.flags = FL_PROJECTILE;
+ missile.solid = SOLID_BBOX;
+ missile.enemy = self.enemy;
+
+ te_explosion (missile.origin);
+
+ //self.tur_head.frame = 7 - self.volly_counter;
+}
+
+void turret_mlrs_projectile_explode()
+{
+ vector org2;
+
+ //vector org2;
+ sound (self, CHAN_PROJECTILE, "weapons/rocket_impact.wav", 1, ATTN_NORM);
+ org2 = findbetterlocation (self.origin, 16);
+ pointparticles(particleeffectnum("rocket_explode"), org2, '0 0 0', 1);
+
+ self.event_damage = SUB_Null;
+
+#ifdef TURRET_DEBUG
+ float d;
+
+ d = RadiusDamage (self, self.owner, self.owner.shot_dmg, 0, self.owner.shot_radius, world, self.owner.shot_force, DEATH_TURRET, world);
+ self.owner.tur_dbg_dmg_t_h = self.owner.tur_dbg_dmg_t_h + d; //self.owner.shot_dmg;
+ self.owner.tur_dbg_dmg_t_f = self.owner.tur_dbg_dmg_t_f + self.owner.shot_dmg;
+#else
+ RadiusDamage (self, self.owner, self.owner.shot_dmg, 0, self.owner.shot_radius, world, self.owner.shot_force, DEATH_TURRET, world);
+#endif
+
+ // Target dead, get another is still targeting the same.
+ if ((self.enemy.deadflag != DEAD_NO) && (self.enemy == self.owner.enemy))
+ self.owner.enemy = world;
+
+ remove (self);
+}
+
+void turret_mlrs_dinit()
+{
+ if (self.netname == "") self.netname = "MLRS turret";
+
+ self.turrcaps_flags = TFL_TURRCAPS_RADIUSDMG | TFL_TURRCAPS_MEDPROJ | TFL_TURRCAPS_PLAYERKILL;
+ self.ammo_flags = TFL_AMMO_ROCKETS | TFL_AMMO_RECHARGE;
+ self.aim_flags = TFL_AIM_LEAD | TFL_AIM_ZEASE | TFL_AIM_SHOTTIMECOMPENSATE;
+
+ if (turret_stdproc_init("mlrs_std") == 0)
+ {
+ remove(self);
+ return;
+ }
+
+ setmodel(self,"models/turrets/base.md3");
+ setmodel(self.tur_head,"models/turrets/mlrs.md3");
+
+ if (!turret_tag_setup(0))
+ dprint("Warning: Turret ",self.classname, " faild to initialize md3 tags\n");
+
+ // Our fire routine
+ self.turret_firefunc = turret_mlrs_attack;
+ self.turret_postthink = turret_mlrs_postthink;
+
+}
+
+/*QUAKED turret_mlrs (0 .5 .8) ?
+*/
+
+void spawnfunc_turret_mlrs()
+{
+ //precache_model ( "models/turrets/rocket.md3");
+ //precache_model ("models/turrets/mlrs.md3");
+ //precache_model ("models/turrets/base.md3");
+
+ self.think = turret_mlrs_dinit;
+ self.nextthink = time + 0.5;
+}
+
+
Property changes on: trunk/data/qcsrc/server/tturrets/units/unit_mlrs.qc
___________________________________________________________________
Name: svn:mergeinfo
+
Copied: trunk/data/qcsrc/server/tturrets/units/unit_phaser.qc (from rev 4853, trunk/data/qcsrc/server/tturrets/units/turret_unit_phaser.qc)
===================================================================
--- trunk/data/qcsrc/server/tturrets/units/unit_phaser.qc (rev 0)
+++ trunk/data/qcsrc/server/tturrets/units/unit_phaser.qc 2008-10-24 07:54:17 UTC (rev 4856)
@@ -0,0 +1,148 @@
+void spawnfunc_turret_phaser();
+void turret_phaser_dinit();
+void turret_phaser_attack();
+
+.float fireflag;
+
+float turret_phaser_firecheck()
+{
+ if (self.fireflag != 0) return 0;
+ return turret_stdproc_firecheck();
+}
+
+void turret_phaser_postthink()
+{
+ if (self.tur_head.frame == 0)
+ return;
+
+ if (self.fireflag == 1)
+ {
+ if (self.tur_head.frame == 10)
+ self.tur_head.frame = 1;
+ else
+ self.tur_head.frame = self.tur_head.frame +1;
+ }
+ else if (self.fireflag == 2 )
+ {
+ self.tur_head.frame = self.tur_head.frame +1;
+ if (self.tur_head.frame == 15)
+ {
+ self.tur_head.frame = 0;
+ self.fireflag = 0;
+ }
+ }
+}
+
+void beam_think()
+{
+ if ((time > self.cnt)||(self.owner.deadflag != DEAD_NO))
+ {
+ self.owner.attack_finished_single = time + self.owner.shot_refire;
+ self.owner.fireflag = 2;
+ self.owner.tur_head.frame = 10;
+ sound (self, CHAN_PROJECTILE, "", 1, ATTN_NORM);
+ remove(self);
+ return;
+ }
+
+ turret_do_updates(self.owner);
+
+ if (time - self.shot_spread > 0)
+ {
+ self.shot_spread = time + 2;
+ sound (self, CHAN_VOICE, "turrets/phaser.ogg", 1, ATTN_NORM);
+ }
+
+
+ self.nextthink = time + self.ticrate;
+
+ self.owner.attack_finished_single = time + frametime;
+ entity oldself;
+ oldself = self;
+ self = self.owner;
+ FireImoBeam ( self.tur_shotorg_updated,
+ self.tur_shotorg_updated + self.tur_shotdir_updated * self.target_range_fire,
+ '-1 -1 -1' * self.shot_radius,
+ '1 1 1' * self.shot_radius,
+ self.shot_force,
+ oldself.shot_dmg,
+ 0.75,
+ DEATH_TURRET);
+ self = oldself;
+ self.scale = vlen(self.owner.tur_shotorg_updated - trace_endpos) / 256;
+
+}
+
+void turret_phaser_attack()
+{
+ entity beam;
+
+ beam = spawn();
+ beam.ticrate = 0.1; //cvar("sys_ticrate");
+ setmodel(beam,"models/turrets/phaser_beam.md3");
+ beam.effects = EF_LOWPRECISION;
+ beam.solid = SOLID_NOT;
+ beam.think = beam_think;
+ beam.cnt = time + self.shot_speed;
+ beam.shot_spread = time + 2;
+ beam.nextthink = time;
+ beam.owner = self;
+ beam.shot_dmg = self.shot_dmg / (self.shot_speed / beam.ticrate);
+ beam.scale = self.target_range_fire / 256;
+ beam.movetype = MOVETYPE_NONE;
+ beam.enemy = self.enemy;
+ beam.bot_dodge = TRUE;
+ beam.bot_dodgerating = beam.shot_dmg;
+ sound (beam, CHAN_PROJECTILE, "turrets/phaser.ogg", 1, ATTN_NORM);
+ self.fireflag = 1;
+
+ beam.attack_finished_single = self.attack_finished_single;
+ self.attack_finished_single = time; // + cvar("sys_ticrate");
+
+ setattachment(beam,self.tur_head,"tag_fire");
+
+ soundat (self, trace_endpos, CHAN_PROJECTILE, "weapons/neximpact.wav", VOL_BASE, ATTN_NORM);
+
+ if (self.tur_head.frame == 0)
+ self.tur_head.frame = 1;
+}
+
+void turret_phaser_dinit()
+{
+ if (self.netname == "") self.netname = "Phaser Cannon";
+
+ 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;
+
+ if (turret_stdproc_init("phaser_std") == 0)
+ {
+ remove(self);
+ return;
+ }
+
+ setmodel(self,"models/turrets/base.md3");
+ setmodel(self.tur_head,"models/turrets/phaser.md3");
+
+ if (!turret_tag_setup(0))
+ dprint("Warning: Turret ",self.classname, " faild to initialize md3 tags\n");
+
+ self.turret_firecheckfunc = turret_phaser_firecheck;
+ self.turret_firefunc = turret_phaser_attack;
+ self.turret_postthink = turret_phaser_postthink;
+
+}
+
+/*QUAKED turret_phaser(0 .5 .8) ?
+*/
+void spawnfunc_turret_phaser()
+{
+ //precache_sound ("turrets/phaser.ogg");
+ //precache_model ("models/turrets/phaser.md3");
+ //precache_model ("models/turrets/phaser_beam.md3");
+ //precache_model ("models/turrets/base.md3");
+
+ self.think = turret_phaser_dinit;
+ self.nextthink = time + 0.5;
+}
+
Property changes on: trunk/data/qcsrc/server/tturrets/units/unit_phaser.qc
___________________________________________________________________
Name: svn:mergeinfo
+
Copied: trunk/data/qcsrc/server/tturrets/units/unit_plasma.qc (from rev 4853, trunk/data/qcsrc/server/tturrets/units/turret_unit_plasma.qc)
===================================================================
--- trunk/data/qcsrc/server/tturrets/units/unit_plasma.qc (rev 0)
+++ trunk/data/qcsrc/server/tturrets/units/unit_plasma.qc 2008-10-24 07:54:17 UTC (rev 4856)
@@ -0,0 +1,218 @@
+void spawnfunc_turret_plasma();
+void spawnfunc_turret_plasma_dual();
+
+void turret_plasma_std_init();
+void turret_plasma_dual_init();
+
+void turret_plasma_attack();
+void turret_plasma_projectile_explode();
+
+void turret_plasma_postthink()
+{
+ if (self.tur_head.frame != 0)
+ self.tur_head.frame = self.tur_head.frame + 1;
+
+ if (self.tur_head.frame >= 5)
+ self.tur_head.frame = 0;
+
+}
+
+void turret_plasma_dualpostthink()
+{
+ if (self.tur_head.frame != 0)
+ self.tur_head.frame = self.tur_head.frame + 1;
+
+ if (self.tur_head.frame >= 6)
+ self.tur_head.frame = 0;
+}
+
+void turret_plasma_attack()
+{
+ entity proj;
+
+ turret_tag_fire_update();
+
+ sound (self, CHAN_WEAPON, "weapons/hagar_fire.wav", 1, ATTN_NORM);
+ proj = spawn ();
+ setorigin(proj, self.tur_shotorg_updated);
+ setsize(proj, '-0.5 -0.5 -0.5', '0.5 0.5 0.5');
+ setmodel(proj, "models/elaser.mdl"); // precision set above
+ proj.classname = "plasmabomb";
+ proj.owner = self;
+ proj.bot_dodge = FALSE;
+ //proj.bot_dodgerating = self.shot_dmg;
+ proj.think = turret_plasma_projectile_explode;
+ proj.nextthink = time + 9;
+ proj.solid = SOLID_BBOX;
+ proj.movetype = MOVETYPE_FLYMISSILE;
+ proj.velocity = (self.tur_shotdir_updated + randomvec() * self.shot_spread) * self.shot_speed;
+ proj.angles = vectoangles(proj.velocity);
+ proj.touch = turret_plasma_projectile_explode;
+ proj.flags = FL_PROJECTILE;
+ proj.effects = EF_LOWPRECISION | EF_BRIGHTFIELD;
+ proj.enemy = self.enemy;
+ proj.flags = FL_PROJECTILE | FL_NOTARGET;
+
+ if (self.tur_head.frame == 0)
+ self.tur_head.frame = 1;
+
+ // Snapback the head
+ // self.tur_head.angles_x = self.tur_head.angles_x + min((self.shot_dmg * 0.05),self.aim_maxpitch);
+
+}
+
+void turret_plasma_dual_attack()
+{
+ entity proj;
+
+ if (self.tur_head.frame > 2)
+ self.tur_head.frame = 1;
+
+ turret_tag_fire_update();
+
+ sound (self, CHAN_WEAPON, "weapons/hagar_fire.wav", 1, ATTN_NORM);
+ proj = spawn ();
+ setorigin(proj, self.tur_shotorg_updated);
+ setsize(proj, '0 0 0', '0 0 0');
+ setmodel(proj, "models/elaser.mdl"); // precision set above
+ proj.classname = "plasmabomb";
+ proj.owner = self;
+ proj.bot_dodge = TRUE;
+ proj.bot_dodgerating = self.shot_dmg;
+ proj.think = turret_plasma_projectile_explode;
+ proj.nextthink = time + 9;
+ proj.solid = SOLID_BBOX;
+ proj.movetype = MOVETYPE_FLYMISSILE;
+ proj.velocity = (self.tur_shotdir_updated + randomvec() * self.shot_spread) * self.shot_speed;
+ proj.angles = vectoangles(proj.velocity);
+ proj.touch = turret_plasma_projectile_explode;
+ proj.flags = FL_PROJECTILE;
+ proj.effects = EF_LOWPRECISION | EF_BRIGHTFIELD;
+ proj.enemy = self.enemy;
+ proj.flags = FL_PROJECTILE | FL_NOTARGET;
+
+ if (self.tur_head.frame == 0)
+ self.tur_head.frame = 1;
+
+ // Snapback the head
+ // self.tur_head.angles_x = self.tur_head.angles_x + min((self.shot_dmg * 0.05),self.aim_maxpitch);
+
+}
+
+void turret_plasma_projectile_explode()
+{
+ vector org2;
+
+ org2 = findbetterlocation (self.origin, 8);
+ WriteByte (MSG_BROADCAST, SVC_TEMPENTITY);
+ WriteByte (MSG_BROADCAST, 79);
+ WriteCoord (MSG_BROADCAST, org2_x);
+ WriteCoord (MSG_BROADCAST, org2_y);
+ WriteCoord (MSG_BROADCAST, org2_z);
+ WriteCoord (MSG_BROADCAST, 0); // SeienAbunae: groan... Useless clutter
+ WriteCoord (MSG_BROADCAST, 0);
+ WriteCoord (MSG_BROADCAST, 0);
+ WriteByte (MSG_BROADCAST, 155);
+
+ self.event_damage = SUB_Null;
+
+
+#ifdef TURRET_DEBUG
+ float d;
+
+ d = RadiusDamage (self, self.owner, self.owner.shot_dmg, 0, self.owner.shot_radius, world, self.owner.shot_force, DEATH_TURRET, world);
+ self.owner.tur_dbg_dmg_t_h = self.owner.tur_dbg_dmg_t_h + d; //self.owner.shot_dmg;
+ self.owner.tur_dbg_dmg_t_f = self.owner.tur_dbg_dmg_t_f + self.owner.shot_dmg;
+#else
+ RadiusDamage (self, self.owner, self.owner.shot_dmg, 0, self.owner.shot_radius, world, self.owner.shot_force, DEATH_TURRET, world);
+#endif
+ sound (self, CHAN_PROJECTILE, "weapons/electro_impact.wav", 1, ATTN_NORM);
+
+ remove (self);
+}
+
+void turret_plasma_std_init()
+{
+ if (self.netname == "") self.netname = "Plasma Cannon";
+
+ self.ammo_flags = TFL_AMMO_ENERGY | TFL_AMMO_RECHARGE | TFL_AMMO_RECIVE;
+ self.aim_flags = TFL_AIM_LEAD | TFL_AIM_SHOTTIMECOMPENSATE | TFL_AIM_ZEASE | TFL_AIM_GROUND2;
+
+ if (turret_stdproc_init("plasma_std") == 0)
+ {
+ remove(self);
+ return;
+ }
+
+ setmodel(self,"models/turrets/base.md3");
+ setmodel(self.tur_head,"models/turrets/plasma.md3");
+
+
+ if (!turret_tag_setup(0))
+ dprint("Warning: Turret ",self.classname, " faild to initialize md3 tags\n");
+
+ // Our fire routine
+ self.turret_firefunc = turret_plasma_dual_attack;
+
+ // re-color badge & handle recoil effect
+ self.turret_postthink = turret_plasma_dualpostthink;
+}
+
+
+void turret_plasma_dual_init()
+{
+ if (self.netname == "") self.netname = "Dual Plasma Cannon";
+
+ self.ammo_flags = TFL_AMMO_ENERGY | TFL_AMMO_RECHARGE | TFL_AMMO_RECIVE;
+
+ if (turret_stdproc_init("plasma_dual") == 0)
+ {
+ remove(self);
+ return;
+ }
+
+ setmodel(self,"models/turrets/base.md3");
+ setmodel(self.tur_head,"models/turrets/plasmad.md3");
+
+ if (!turret_tag_setup(0))
+ dprint("Warning: Turret ",self.classname, " faild to initialize md3 tags\n");
+
+ // select aim
+ self.aim_flags = TFL_AIM_LEAD | TFL_AIM_SHOTTIMECOMPENSATE | TFL_AIM_ZEASE | TFL_AIM_GROUND2;
+
+ // Our fire routine
+ self.turret_firefunc = turret_plasma_attack;
+
+ // re-color badge & handle recoil effect
+ self.turret_postthink = turret_plasma_postthink;
+}
+
+
+/*
+* Basic moderate (std) or fast (dual) fireing, short-mid range energy cannon.
+* Not too mutch of a therat on its own, but can be rather dangerous in groups.
+* Regenerates ammo slowly, support with a fusionreactor(s) to do some real damage.
+*/
+
+/*QUAKED turret_plasma (0 .5 .8) ?
+*/
+void spawnfunc_turret_plasma()
+{
+ //precache_model ("models/turrets/plasma.md3");
+ //precache_model ("models/turrets/base.md3");
+
+ self.think = turret_plasma_std_init;
+ self.nextthink = time + 0.5;
+}
+
+/*QUAKED turret_plasma_dual (0 .5 .8) ?
+*/
+void spawnfunc_turret_plasma_dual()
+{
+ //precache_model ("models/turrets/plasmad.md3");
+ //precache_model ("models/turrets/base.md3");
+
+ self.think = turret_plasma_dual_init;
+ self.nextthink = time + 0.5;
+}
+
Property changes on: trunk/data/qcsrc/server/tturrets/units/unit_plasma.qc
___________________________________________________________________
Name: svn:mergeinfo
+
Copied: trunk/data/qcsrc/server/tturrets/units/unit_targettrigger.qc (from rev 4853, trunk/data/qcsrc/server/tturrets/units/turret_unit_targettrigger.qc)
===================================================================
--- trunk/data/qcsrc/server/tturrets/units/unit_targettrigger.qc (rev 0)
+++ trunk/data/qcsrc/server/tturrets/units/unit_targettrigger.qc 2008-10-24 07:54:17 UTC (rev 4856)
@@ -0,0 +1,41 @@
+void spawnfunc_turret_targettrigger();
+void turret_targettrigger_touch();
+
+void turret_targettrigger_touch()
+{
+ entity e;
+ if (self.cnt > time) return;
+ entity oldself;
+ oldself = self;
+
+ e = find(world, targetname, self.target);
+ while (e)
+ {
+ if (e.turrcaps_flags & TFL_TURRCAPS_RECIVETARGETS)
+ {
+ self = e;
+ e.turret_addtarget(other,oldself);
+ }
+
+ e = find(e, targetname, oldself.target);
+ }
+
+ oldself.cnt = time + 0.5;
+
+ self = oldself;
+}
+
+/*QUAKED turret_targettrigger (.5 .5 .5) ?
+*/
+void spawnfunc_turret_targettrigger()
+{
+ if (!cvar("g_turrets"))
+ {
+ remove(self);
+ return;
+ }
+
+ InitTrigger ();
+
+ self.touch = turret_targettrigger_touch;
+}
Property changes on: trunk/data/qcsrc/server/tturrets/units/unit_targettrigger.qc
___________________________________________________________________
Name: svn:mergeinfo
+
Copied: trunk/data/qcsrc/server/tturrets/units/unit_tessla.qc (from rev 4853, trunk/data/qcsrc/server/tturrets/units/turret_unit_tessla.qc)
===================================================================
--- trunk/data/qcsrc/server/tturrets/units/unit_tessla.qc (rev 0)
+++ trunk/data/qcsrc/server/tturrets/units/unit_tessla.qc 2008-10-24 07:54:17 UTC (rev 4856)
@@ -0,0 +1,147 @@
+void spawnfunc_turret_tesla();
+void turret_tesla_dinit();
+void turret_tesla_fire();
+
+.float toasted;
+entity toast(entity from, float range, float damage)
+{
+ entity e;
+ entity etarget;
+ float d,dd;
+
+ dd = range + 1;
+
+ e = findradius(from.origin,range);
+ while (e)
+ {
+ if ((e.toasted != 1) && (e != from))
+ if (turret_validate_target(self,e,self.target_validate_flags) > 0)
+ {
+
+ traceline(from.origin,e.origin,0,from);
+ if (trace_fraction > 0.9)
+ {
+ d = vlen(e.origin - from.origin);
+ if (d < dd)
+ {
+ dd = d;
+ etarget = e;
+ }
+ }
+ }
+ e = e.chain;
+ }
+
+ if (etarget)
+ {
+ te_smallflash(etarget.origin);
+ te_lightning1(world,from.origin,etarget.origin);
+ Damage(etarget,self,self,damage,DEATH_TURRET,etarget.origin,'0 0 0');
+ etarget.toasted = 1;
+ }
+
+ return etarget;
+}
+
+void turret_tesla_fire()
+{
+ entity e,t;
+ float d,r,i;
+
+ if (cvar("g_turrets_nofire") != 0)
+ return;
+
+ if (self.attack_finished_single > time) return;
+
+ d = self.shot_dmg;
+ r = self.target_range;
+ e = spawn();
+ setorigin(e,self.origin + self.tur_shotorg);
+
+
+ self.target_validate_flags = TFL_TARGETSELECT_PLAYERS | TFL_TARGETSELECT_MISSILES |
+ TFL_TARGETSELECT_RANGELIMTS | TFL_TARGETSELECT_TEAMCHECK;
+
+ t = toast(e,r,d);
+ remove(e);
+
+ if (t == world) return;
+
+ self.target_validate_flags = TFL_TARGETSELECT_PLAYERS | TFL_TARGETSELECT_MISSILES |
+ TFL_TARGETSELECT_TEAMCHECK;
+
+ self.attack_finished_single = time + self.shot_refire;
+ self.ammo = self.ammo - self.shot_dmg;
+ for (i = 0;i < 10;i = i + 1)
+ {
+ d *= 0.5;
+ r *= 0.75;
+ t = toast(t,r,d);
+ if (t == world) break;
+ }
+
+ e = findchainfloat(toasted, 1);
+ while (e)
+ {
+ e.toasted = 0;
+ e = e.chain;
+ }
+}
+
+void turret_tesla_postthink()
+{
+ turret_tesla_fire();
+
+ self.tur_head.frame = self.tur_head.frame + 1;
+
+ if (self.tur_head.frame >= 11)
+ self.tur_head.frame = 0;
+
+ if (self.tur_head.avelocity == '0 0 0')
+ self.tur_head.avelocity = '0 35 0';
+}
+
+
+void turret_tesla_dinit()
+{
+ if (self.netname == "") self.netname = "Tesla Coil";
+
+ self.turrcaps_flags = TFL_TURRCAPS_HITSCAN | TFL_TURRCAPS_PLAYERKILL | TFL_TURRCAPS_MISSILEKILL;
+ self.target_select_flags = TFL_TARGETSELECT_NO;
+ self.firecheck_flags = TFL_FIRECHECK_REFIRE;
+ self.shoot_flags = TFL_SHOOT_CUSTOM;
+ self.ammo_flags = TFL_AMMO_ENERGY | TFL_AMMO_RECHARGE | TFL_AMMO_RECIVE;
+ self.aim_flags = TFL_AIM_NO;
+ self.track_flags = TFL_TRACK_NO;
+
+ if (turret_stdproc_init("tesla_std") == 0)
+ {
+ remove(self);
+ return;
+ }
+
+ setmodel(self,"models/turrets/tesla_base.md3");
+ setmodel(self.tur_head,"models/turrets/tesla_head.md3");
+
+ self.target_validate_flags = TFL_TARGETSELECT_PLAYERS | TFL_TARGETSELECT_MISSILES |
+ TFL_TARGETSELECT_RANGELIMTS | TFL_TARGETSELECT_TEAMCHECK;
+
+ if (!turret_tag_setup(0))
+ dprint("Warning: Turret ",self.classname, " faild to initialize md3 tags\n");
+
+ self.turret_firefunc = turret_stdproc_nothing;
+ self.turret_postthink = turret_tesla_postthink;
+}
+
+/*QUAKED turret_tesla (0 .5 .8) ?
+*/
+void spawnfunc_turret_tesla()
+{
+ //precache_model ("models/turrets/tesla_head.md3");
+ //precache_model ("models/turrets/tesla_base.md3");
+
+
+ self.think = turret_tesla_dinit;
+ self.nextthink = time + 0.5;
+}
+
Property changes on: trunk/data/qcsrc/server/tturrets/units/unit_tessla.qc
___________________________________________________________________
Name: svn:mergeinfo
+
Copied: trunk/data/qcsrc/server/tturrets/units/unit_walker.qc (from rev 4850, trunk/data/qcsrc/server/tturrets/units/turret_unit_walker.qc)
===================================================================
--- trunk/data/qcsrc/server/tturrets/units/unit_walker.qc (rev 0)
+++ trunk/data/qcsrc/server/tturrets/units/unit_walker.qc 2008-10-24 07:54:17 UTC (rev 4856)
@@ -0,0 +1,798 @@
+#define ANIM_NO 0
+#define ANIM_WALK 1
+#define ANIM_RUN 1.1
+#define ANIM_STRAFE_L 2
+#define ANIM_STRAFE_R 3
+#define ANIM_TURN 2
+#define ANIM_JUMP 4
+#define ANIM_LAND 5
+#define ANIM_PAIN 6
+#define ANIM_MEELE 7
+.float animflag;
+
+.entity wkr_props;
+.entity wkr_spawn;
+
+#define WALKER_MIN '-70 -70 5'
+#define WALKER_MAX '70 70 70'
+
+/*
+.entity goalcurrent, goalstack01, goalstack02, goalstack03;
+.entity goalstack04, goalstack05, goalstack06, goalstack07;
+.entity goalstack08, goalstack09, goalstack10, goalstack11;
+.entity goalstack12, goalstack13, goalstack14, goalstack15;
+.entity goalstack16, goalstack17, goalstack18, goalstack19;
+.entity goalstack20, goalstack21, goalstack22, goalstack23;
+.entity goalstack24, goalstack25, goalstack26, goalstack27;
+.entity goalstack28, goalstack29, goalstack30, goalstack31;
+*/
+
+float walker_firecheck()
+{
+ if (!turret_stdproc_firecheck()) return 0;
+ //if(self.tur_cannon.frame != 0) return 0;
+
+ //if(self.walking == 1) self.walking = 2;
+ //if(self.walking != 0)
+ // return 0;
+
+ return 1;
+}
+
+void walker_meele_dmg()
+{
+ vector where;
+ entity e;
+
+ makevectors(self.angles);
+ where = self.origin + v_forward * 128;
+
+ e = findradius(where,80);
+ while(e)
+ {
+ if(turret_validate_target(self,e,self.target_validate_flags))
+ if(e != self)
+ Damage(e,self,self,cvar("g_turrets_unit_walker_std_meele_dmg "),DEATH_TURRET,'0 0 0', v_forward * cvar("g_turrets_unit_walker_std_meele_force") );
+
+ e = e.chain;
+ }
+}
+
+void walker_animate()
+{
+
+ if(self.tur_head.frame != 0)
+ self.tur_head.frame = self.tur_head.frame +1;
+
+ if(self.tur_head.frame > 12)
+ self.tur_head.frame = 0;
+
+
+ switch(self.animflag)
+ {
+ case ANIM_NO:
+ //if(self.frame != 0)
+ // self.frame = 0;
+ break;
+
+ case ANIM_WALK:
+ self.frame = self.frame + 1;
+ if(self.frame > 25)
+ self.frame = 5;
+ break;
+
+ case ANIM_RUN:
+ self.frame = self.frame + 2;
+ if(self.frame > 25)
+ self.frame = 5;
+ break;
+
+ case ANIM_STRAFE_L:
+ if(self.frame < 35) self.frame = 35;
+ self.frame = self.frame + 1;
+ if(self.frame > 55) self.frame = 35;
+ break;
+
+ case ANIM_STRAFE_R:
+ if(self.frame < 65) self.frame = 65;
+ self.frame = self.frame + 1;
+ if(self.frame > 85) self.frame = 65;
+ break;
+
+ case ANIM_JUMP:
+ if(self.frame < 95) self.frame = 95;
+ if(self.frame > 100)
+ self.frame = self.frame + 1;
+
+ break;
+
+ case ANIM_LAND:
+ if(self.frame < 100) self.frame = 100;
+ self.frame = self.frame + 1;
+ if(self.frame > 107)
+ self.animflag = ANIM_NO;
+ break;
+
+ case ANIM_PAIN:
+ if(self.frame < 90) self.frame = 90;
+ self.frame = self.frame + 1;
+ if(self.frame > 95)
+ self.animflag = ANIM_NO;
+ break;
+
+ case ANIM_MEELE:
+ if(self.frame < 123) self.frame = 123;
+ self.frame = self.frame + 1;
+
+ if(self.frame == 133)
+ walker_meele_dmg();
+
+ if(self.frame > 140)
+ self.animflag = ANIM_NO;
+
+ }
+}
+
+
+
+
+
+void walker_rocket_explode()
+{
+ vector org2;
+
+ sound (self, CHAN_PROJECTILE, "weapons/rocket_impact.wav", 1, ATTN_NORM);
+ org2 = findbetterlocation (self.origin, 16);
+
+ WriteByte (MSG_BROADCAST, SVC_TEMPENTITY);
+ WriteByte (MSG_BROADCAST, 78);
+ WriteCoord (MSG_BROADCAST, org2_x);
+ WriteCoord (MSG_BROADCAST, org2_y);
+ WriteCoord (MSG_BROADCAST, org2_z);
+
+ self.event_damage = SUB_Null;
+
+ RadiusDamage (self, self.owner, cvar("g_turrets_unit_walker_std_rocket_dmg"), 0, cvar("g_turrets_unit_walker_std_rocket_radius"), world, cvar("g_turrets_unit_walker_std_rocket_force"), DEATH_TURRET, world);
+
+ remove (self);
+}
+
+void walker_rocket_damage (entity inflictor, entity attacker, float damage, float deathtype, vector hitloc, vector vforce)
+{
+ self.health = self.health - damage;
+ self.velocity = self.velocity + vforce;
+ if (self.health <= 0) walker_rocket_explode();
+}
+
+
+/*
+g_turrets_unit_walker_std_rocket_refire
+g_turrets_unit_walker_std_rocket_dmg
+g_turrets_unit_walker_std_rocket_radius
+g_turrets_unit_walker_std_rocket_force
+g_turrets_unit_walker_std_rocket_tunrate
+g_turrets_unit_walker_std_rocket_speed
+g_turrets_unit_walker_std_rocket_speed_add
+*/
+
+void walker_rocket_loop();
+void walker_rocket_think()
+{
+ vector olddir,newdir;
+ float edist;
+ float itime;
+ float m_speed;
+
+ self.nextthink = time + 0.1;
+
+ olddir = normalize(self.velocity);
+ edist = vlen(self.enemy.origin - self.origin);
+
+ // Simulate crudely guidance
+ if(self.cnt < time)
+ {
+ if(edist < 1000)
+ self.tur_shotorg = randomvec() * min(edist,64);
+ else
+ self.tur_shotorg = randomvec() * min(edist,256);
+ self.cnt = time + 0.5;
+ }
+ if(edist < 256)
+ self.tur_shotorg = '0 0 0';
+
+
+ if (self.tur_health < time)
+ {
+ self.think = walker_rocket_explode;
+ self.nextthink = time;
+ return;
+ }
+
+ if((random() < 0.01) && (self.shot_dmg != 1337))
+ {
+ walker_rocket_loop();
+ return;
+ }
+
+ olddir = normalize(self.velocity);
+
+ // Accelerate
+ m_speed = vlen(self.velocity) + cvar("g_turrets_unit_walker_std_rocket_speed_add");
+
+ // Enemy dead? just keep on the current heading then.
+ if ((self.enemy == world) || (self.enemy.deadflag != DEAD_NO))
+ {
+
+ // Make sure we dont return to tracking a respawned player
+ self.enemy = world;
+
+ // Turn model
+ self.angles = vectoangles(self.velocity);
+ }
+
+ if (self.enemy)
+ {
+ // Predict enemy position
+ itime = max(edist / m_speed,1);
+ newdir = normalize((self.enemy.origin + self.tur_shotorg) - self.origin);
+ }
+ else
+ {
+ //pre_pos = self.origin + olddir;
+ newdir = olddir;
+ }
+
+ // Turn
+ newdir = normalize(olddir + newdir * cvar("g_turrets_unit_walker_std_rocket_tunrate"));
+
+ self.velocity = newdir * m_speed;
+
+ // Turn model
+ self.angles = vectoangles(self.velocity);
+
+ if (time+itime < time+0.1)
+ {
+ self.think = turret_hellion_missile_explode;
+ self.nextthink = time + itime;
+ }
+}
+
+void walker_rocket_loop3()
+{
+ self.nextthink = time + 0.1;
+ if(vlen(self.origin - self.tur_shotorg) < 128 )
+ {
+ self.think = walker_rocket_think;
+ return;
+ }
+
+ vector newdir;
+ vector olddir;
+ float m_speed;
+
+ m_speed = vlen(self.velocity) + cvar("g_turrets_unit_walker_std_rocket_speed_add");
+
+ olddir = normalize(self.velocity);
+
+
+ newdir = normalize(self.tur_shotorg - self.origin);
+
+ newdir = normalize(olddir + newdir * cvar("g_turrets_unit_walker_std_rocket_tunrate"));
+
+
+ self.velocity = newdir * m_speed;
+ self.angles = vectoangles(self.velocity);
+}
+
+void walker_rocket_loop2()
+{
+ self.nextthink = time + 0;
+
+ if(vlen(self.origin - self.tur_shotorg) < 128 )
+ {
+ self.tur_shotorg = self.origin - '0 0 200';
+ self.think = walker_rocket_loop3;
+ return;
+ }
+
+ vector newdir;
+ vector olddir;
+ float m_speed;
+
+ m_speed = vlen(self.velocity) + cvar("g_turrets_unit_walker_std_rocket_speed_add");
+
+ olddir = normalize(self.velocity);
+
+ newdir = normalize(self.tur_shotorg - self.origin);
+
+ newdir = normalize(olddir + newdir * cvar("g_turrets_unit_walker_std_rocket_tunrate"));
+
+ self.velocity = newdir * m_speed;
+
+ self.angles = vectoangles(self.velocity);
+
+}
+
+void walker_rocket_loop()
+{
+
+ self.nextthink= time + 0;
+
+ self.tur_shotorg = self.origin + '0 0 400';
+
+ self.think = walker_rocket_loop2;
+
+ self.shot_dmg = 1337;
+}
+
+
+
+void walker_fire_rocket(vector org)
+{
+
+ entity rocket;
+
+
+ //self.angles_x *= -1;
+ makevectors(self.angles);
+ //self.angles_x *= -1;
+
+ rocket = spawn ();
+ setorigin(rocket, org);
+
+ sound (self, CHAN_WEAPON, "weapons/hagar_fire.wav", 1, ATTN_NORM);
+ sound (rocket, CHAN_PROJECTILE, "weapons/rocket_fly.wav", 0.4, ATTN_NORM);
+ setmodel (rocket, "models/turrets/rocket.md3"); // precision set below
+ setsize (rocket, '-3 -3 -3', '3 3 3'); // give it some size so it can be shot
+
+ rocket.classname = "walker_rocket";
+ rocket.owner = self;
+ rocket.bot_dodge = TRUE;
+ rocket.bot_dodgerating = 50;
+ rocket.takedamage = DAMAGE_YES;
+
+ rocket.damageforcescale = 2;
+ rocket.health = 10;
+ rocket.tur_shotorg = randomvec() * 512;
+ rocket.cnt = time + 1;
+ rocket.enemy = self.enemy;
+
+ if(random() < 0.01)
+ rocket.think = walker_rocket_loop;
+ else
+ rocket.think = walker_rocket_think;
+
+ rocket.nextthink = time + 0.2;
+ rocket.solid = SOLID_BBOX;
+ rocket.movetype = MOVETYPE_FLYMISSILE;
+ rocket.effects = EF_LOWPRECISION;
+ rocket.velocity = ((v_forward + v_up * 0.5) +(randomvec() * 0.15))* cvar("g_turrets_unit_walker_std_rocket_speed");
+ rocket.angles = vectoangles(rocket.velocity);
+ rocket.touch = walker_rocket_explode;
+ rocket.flags = FL_PROJECTILE;
+ rocket.solid = SOLID_BBOX;
+ rocket.tur_health = time + 9;
+
+ te_explosion (rocket.origin);
+
+}
+
+#define s_turn 10
+#define s_walk 100
+#define s_run 300
+#define s_accel1 8
+#define s_accel2 16
+#define s_decel 8
+
+void rv_think()
+{
+ float f;
+ vector org;
+
+ self.cnt = self.cnt -1;
+ if(self.cnt < 0)
+ {
+ remove(self);
+ return;
+ }
+
+ if(self.cnt> 1)
+ f = gettagindex(self.owner,"tag_rocket01");
+ else
+ f = gettagindex(self.owner,"tag_rocket02");
+
+ org = self.owner.origin + gettaginfo(self.owner,f);
+
+
+ self.nextthink = time + 0.2;
+
+ self = self.owner;
+ walker_fire_rocket(org);
+}
+
+void walker_postthink()
+{
+ vector wish_angle;
+ vector real_angle;
+ float turn_limit;
+
+
+
+ if(self.flags & FL_ONGROUND)
+ {
+ self.animflag = ANIM_NO;
+ }
+
+ if(self.enemy)
+ {
+ if(self.tur_head.attack_finished_single < time)
+ {
+ entity rv;
+ rv = spawn();
+ rv.think = rv_think;
+ rv.nextthink = time;
+ rv.cnt = 4;
+ rv.owner = self;
+
+ self.tur_head.attack_finished_single = time + cvar("g_turrets_unit_walker_std_rocket_refire");
+ }
+
+ }
+
+ if(self.goalcurrent)
+ {
+ //if(self.enemy && (self.tur_dist_enemy < self.target_range_fire))
+ // self.animflag = ANIM_TURN;
+ //else
+ //{
+ if(vlen(self.origin - self.goalcurrent.origin) < 64)
+ if(self.goalcurrent.goalcurrent == world)
+ self.goalcurrent = world; // Path endpoint reached, go roaming.
+ else
+ self.goalcurrent = self.goalcurrent.goalcurrent;
+
+ self.animflag = ANIM_WALK;
+ //}
+
+
+ }
+ else // Roaming mode
+ {
+
+ if(self.enemy)
+ {
+ wish_angle = angleofs(self,self.enemy); //normalize(self.origin-self.enemy.origin);
+
+ if(self.tur_dist_enemy < cvar("g_turrets_unit_walker_std_meele_range"))
+ {
+
+ if(fabs(wish_angle_y) < 15)
+ self.animflag = ANIM_MEELE;
+ }
+ else
+ {
+ if(fabs(wish_angle_y) < 15)
+ self.animflag = ANIM_RUN;
+ else if(fabs(wish_angle_y) < 30)
+ self.animflag = ANIM_WALK;
+ else
+ self.animflag = ANIM_TURN;
+ }
+
+ }
+ else
+ self.animflag = ANIM_NO;
+ }
+
+
+ float s_speed;
+
+ s_speed = vlen(self.velocity);
+
+ // Turn on the spot
+ if (self.animflag == ANIM_TURN) {
+ if(self.enemy)
+ wish_angle = normalize(self.enemy.origin - self.origin);
+ else
+ wish_angle = normalize(self.goalcurrent.origin - self.origin); wish_angle = vectoangles(wish_angle); // And make a angle
+
+ real_angle = wish_angle - self.angles;
+
+ if (real_angle_x < 0) real_angle_x += 360;
+ if (real_angle_x > 180) real_angle_x -= 360;
+
+ if (real_angle_y < 0) real_angle_y += 360;
+ if (real_angle_y > 180) real_angle_y -= 360;
+
+ turn_limit = cvar("g_turrets_unit_walker_turn_turnrate");
+ // Convert from dgr/sec to dgr/tic
+ turn_limit = turn_limit / (1 / self.ticrate);
+
+ //real_angle_x = bound((-1 * turn_limit),real_angle_x, turn_limit);
+ real_angle_y = bound((-1 * turn_limit),real_angle_y, turn_limit);
+
+ self.angles_y = self.angles_y + real_angle_y;
+
+ if(self.enemy)
+ v_forward = normalize(self.enemy.origin - self.origin);
+ else
+ v_forward = normalize(self.goalcurrent.origin - self.origin);
+
+ makevectors(self.angles);
+
+ if(s_speed > s_turn)
+ self.velocity = (v_forward * max((s_speed - s_decel),s_turn));
+ if(s_speed < s_turn)
+ self.velocity = (v_forward * min((s_speed + s_accel1),s_turn));
+ }
+ else if (self.animflag == ANIM_WALK) // Gg walking
+ {
+ if(self.goalcurrent)
+ wish_angle = normalize(self.goalcurrent.origin - self.origin);
+ else
+ if(self.enemy)
+ wish_angle = normalize(self.enemy.origin - self.origin);
+ else
+ wish_angle = self.angles;
+
+
+ wish_angle = vectoangles(wish_angle); // And make a angle
+ real_angle = wish_angle - self.angles;
+
+ if (real_angle_x < 0) real_angle_x += 360;
+ if (real_angle_x > 180) real_angle_x -= 360;
+
+ if (real_angle_y < 0) real_angle_y += 360;
+ if (real_angle_y > 180) real_angle_y -= 360;
+
+ turn_limit = cvar("g_turrets_unit_walker_walk_turnrate");
+ // Convert from dgr/sec to dgr/tic
+ turn_limit = turn_limit / (1 / self.ticrate);
+
+ //real_angle_x = bound((-1 * turn_limit),real_angle_x, turn_limit);
+ real_angle_y = bound((-1 * turn_limit),real_angle_y, turn_limit);
+
+ self.angles_y = self.angles_y + real_angle_y;
+
+ if(self.goalcurrent)
+ v_forward = normalize(self.goalcurrent.origin - self.origin);
+ else
+ if(self.enemy)
+ v_forward = normalize(self.enemy.origin - self.origin);
+
+ makevectors(self.angles);
+ //self.velocity = v_forward * s_walk;
+
+ //if(self.flags & FL_ONGROUND)
+ {
+ if(s_speed > s_walk)
+ self.velocity = (v_forward * max((s_speed - s_decel),s_walk));
+ if(s_speed <= s_walk)
+ self.velocity = (v_forward * min((s_speed + s_accel1),s_walk));
+ }
+
+
+ }
+ else if (self.animflag == ANIM_RUN) // Move fast, turn slow
+ {
+ if(self.goalcurrent)
+ wish_angle = normalize(self.goalcurrent.origin - self.origin);
+ else
+ if(self.enemy)
+ wish_angle = normalize(self.enemy.origin - self.origin);
+ else
+ wish_angle = self.angles;
+
+ wish_angle = vectoangles(wish_angle); // And make a angle
+ real_angle = wish_angle - self.angles;
+
+ if (real_angle_x < 0) real_angle_x += 360;
+ if (real_angle_x > 180) real_angle_x -= 360;
+
+ if (real_angle_y < 0) real_angle_y += 360;
+ if (real_angle_y > 180) real_angle_y -= 360;
+
+ turn_limit = cvar("g_turrets_unit_walker_run_turnrate");
+ // Convert from dgr/sec to dgr/tic
+ turn_limit = turn_limit / (1 / self.ticrate);
+
+ //real_angle_x = bound((-1 * turn_limit),real_angle_x, turn_limit);
+ real_angle_y = bound((-1 * turn_limit),real_angle_y, turn_limit);
+
+ self.angles_y = self.angles_y + real_angle_y;
+
+
+ if(self.enemy)
+ v_forward = normalize(self.enemy.origin - self.origin);
+ else
+ v_forward = normalize(self.goalcurrent.origin - self.origin);
+
+ makevectors(self.angles);
+
+ if(self.flags & FL_ONGROUND)
+ {
+ if(s_speed > s_run)
+ self.velocity = (v_forward * max((s_speed - s_decel),s_run));
+ if(s_speed <= s_run)
+ self.velocity = (v_forward * min((s_speed + s_accel2),s_run));
+ }
+ } else {
+
+ if(self.flags & FL_ONGROUND)
+ {
+ makevectors(self.angles);
+ if(s_speed > 0)
+ self.velocity = min(s_speed - s_decel,0) * v_forward;
+ }
+ }
+
+
+
+ walker_animate();
+
+
+}
+
+void walker_attack()
+{
+ entity flash;
+
+ //turret_do_updates(self);
+
+ self.tur_head.frame = self.tur_head.frame + 1;
+
+ sound (self, CHAN_WEAPON, "weapons/uzi_fire.wav", 1, ATTN_NORM);
+
+
+ fireBullet (self.tur_shotorg_updated, self.tur_shotdir_updated,self.shot_spread, self.shot_dmg, self.shot_force, DEATH_TURRET, FALSE);
+
+ te_smallflash(self.tur_shotorg_updated);
+
+ if(!(self.uzi_bulletcounter & 3))
+ {
+
+ trailparticles(self,particleeffectnum("EF_MGTURRETTRAIL"),self.tur_shotorg_updated,trace_endpos);
+ // te_lightning1(self,self.tur_shotorg_updated,trace_endpos);
+ flash = spawn();
+ setmodel(flash, "models/uziflash.md3"); // precision set below
+ setattachment(flash, self.tur_head, "tag_fire");
+ flash.scale = 3;
+ flash.think = W_Uzi_Flash_Go;
+ flash.nextthink = time + 0.02;
+ flash.frame = 2;
+ flash.angles_z = flash.v_angle_z + random() * 180;
+ flash.alpha = 1;
+ flash.effects = EF_ADDITIVE | EF_FULLBRIGHT | EF_LOWPRECISION;
+ }
+
+ self.uzi_bulletcounter = self.uzi_bulletcounter + 1;
+}
+
+void walker_respawnhook()
+{
+ vector vtmp;
+ self.origin = self.wkr_spawn.origin;
+ self.wkr_props.solid = SOLID_BBOX;
+ self.wkr_props.alpha = 1;
+
+ self.angles = self.wkr_spawn.angles;
+ vtmp = self.origin;
+ vtmp_z +=self.wkr_spawn.origin_z + self.wkr_spawn.maxs_z;
+ setorigin(self,vtmp);
+
+}
+void walker_diehook()
+{
+ self.wkr_props.solid = SOLID_NOT;
+ self.wkr_props.alpha = -1;
+}
+
+//.string target_start;
+void turret_walker_dinit()
+{
+ entity e;
+
+ if (self.netname == "") self.netname = "Walker Turret";
+
+ if(self.target != "")
+ {
+ e = find(world,targetname,self.target);
+ if(!e)
+ {
+ bprint("Warning! initital waypoint for Walker does NOT exsist!\n");
+ self.target = "";
+
+ //remove(self);
+ //return;
+ }
+
+ if(e.classname != "walker_checkpoint")
+ dprint("Warning: not a walker path\n");
+ else
+ self.goalcurrent = e;
+ }
+
+
+
+
+ self.wkr_props = spawn();
+ self.wkr_spawn = spawn();
+
+ self.ammo_flags = TFL_AMMO_BULLETS | TFL_AMMO_RECHARGE | TFL_AMMO_RECIVE;
+ self.turrcaps_flags = TFL_TURRCAPS_HITSCAN | TFL_TURRCAPS_PLAYERKILL | TFL_TURRCAPS_MOVE | TFL_TURRCAPS_ROAM | TFL_TURRCAPS_LINKED;
+ self.aim_flags = TFL_AIM_LEAD | TFL_AIM_ZEASE;
+
+ self.turret_respawnhook = walker_respawnhook;
+ self.turret_diehook = walker_diehook;
+
+ self.ticrate = 0.05;
+ if (turret_stdproc_init("walker_std") == 0)
+ {
+ remove(self);
+ return;
+ }
+ // self.scale = 1.5;
+ //setsize(self,'38 38 55','-38 -38 1');
+
+ self.target_select_flags = TFL_TARGETSELECT_PLAYERS | 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.flags = FL_CLIENT;
+ self.iscreature = TRUE;
+ self.movetype = MOVETYPE_WALK;
+ self.solid = SOLID_BBOX;// SOLID_SLIDEBOX;
+ self.takedamage = DAMAGE_AIM;
+
+ setmodel(self.wkr_props,"models/turrets/walker_props.md3");
+ setmodel(self.wkr_spawn,"models/turrets/walker_spawn.md3");
+ setorigin(self.wkr_spawn,self.origin);
+
+ self.wkr_spawn.angles = self.angles;
+ self.wkr_spawn.solid = SOLID_NOT;
+
+ traceline(self.wkr_spawn.origin + '0 0 10', self.wkr_spawn.origin - '0 0 10000', MOVE_NOMONSTERS, self);
+ setorigin(self.wkr_spawn,trace_endpos + '0 0 4');
+
+ setmodel(self,"models/turrets/walker_body.md3");
+ setmodel(self.tur_head,"models/turrets/walker_head_minigun.md3");
+
+ setattachment(self.tur_head,self,"tag_head");
+ setattachment(self.wkr_props,self,"tag_head");
+
+ vector v;
+ float f;
+ f = gettagindex(self.tur_head,"tag_fire");
+ v = gettaginfo(self.tur_head,f);
+ v_y = v_y * -1;
+
+ setsize(self,WALKER_MIN,WALKER_MAX);
+ //setsize(self,'-70 -70 0','70 70 55');
+
+ self.tur_shotorg = v;
+ self.tur_aimorg = v;
+
+ self.idle_aim = '0 0 0';
+
+// self.v_home = self.origin;
+
+ self.turret_firecheckfunc = walker_firecheck;
+
+ // Our fire routine
+ self.turret_firefunc = walker_attack;
+
+ self.turret_postthink = walker_postthink;
+
+}
+
+
+void spawnfunc_turret_walker()
+{
+ precache_model ("models/turrets/walker_head_minigun.md3");
+ precache_model ("models/turrets/walker_body.md3");
+ precache_model ("models/turrets/walker_props.md3");
+ precache_model ("models/turrets/walker_spawn.md3");
+ precache_model ( "models/turrets/rocket.md3");
+
+ self.think = turret_walker_dinit;
+ self.nextthink = time + 0.5;
+}
Property changes on: trunk/data/qcsrc/server/tturrets/units/unit_walker.qc
___________________________________________________________________
Name: svn:mergeinfo
+
More information about the nexuiz-commits
mailing list