etqw-sdk/base/script/deployables/turret.script
2008-05-29 00:00:00 +00:00

542 lines
14 KiB
Text

object deployable_turret : deployable_base {
void preinit();
void init();
void destroy();
// states
float OnUsed( entity p, float distance );
void OnDisabled();
void OnReEnabled();
void OnBeginAttack();
void OnEndAttack();
boolean InRange( vector targetPos );
boolean InFiringRange( vector targetPos );
void KillAttackThread();
void AttackThread();
void vCheckProficiency();
boolean TargetIsValid( entity targetEnt ) { return false; }
void FireMissile();
void FreeArcIcon();
void SetupFiringArc();
void vOnDeploy();
float GetTurretMaxRange();
float GetTurretMinRange();
boolean TraceCheck( entity other );
void OnEnter( entity user );
void OnExit( entity user );
void OnKilled( entity inflictor, entity attacker, float damage, vector dir, float location );
float OnValidateTarget();
float OnUpdateCrosshairInfo( entity p );
void CreateDestroyThread();
void UpdateCharge() { }
float vGetFiringStatus( object traceObject );
float numTracerJoints;
float minRange;
float maxRange;
float firingRange;
float angleRange;
float jointBarrel;
float projectileIndex;
float projectileSpeed;
float spread;
float fireRate;
float reFire;
float commandmapVisibleArcHandle;
float checkMask;
vector traceCheckOffset;
boolean playingBrassSound;
entity myUser;
// overheating/power bar stuff
boolean CanFire() { return true; }
void Fired() { }
boolean attacking;
float retributionDelay;
};
void deployable_turret::preinit() {
projectileIndex = GetEntityDef( getKey( "def_projectile" ) );
projectileSpeed = getFloatKey( "missile_velocity" );
minRange = MetresToInches( getFloatKey( "range_min" ) );
maxRange = MetresToInches( getFloatKey( "range_max" ) );
firingRange = MetresToInches( getFloatKeyWithDefault( "range_firing", InchesToMetres( maxRange ) ) );
fireRate = getFloatKey( "fireRate" );
spread = getFloatKey( "spread" );
reFire = 0;
jointBarrel = getJointHandle( getKey( "joint_barrel" ) );
numTracerJoints = getFloatKey( "num_tracerjoints" );
retributionDelay = getFloatKeyWithDefault( "retribution_delay", 0.0f );
checkMask = MASK_SHOT_RENDERMODEL | MASK_SHOT_BOUNDINGBOX;
vector mins = getMins();
vector maxs = getMaxs();
traceCheckOffset_z = mins_z + ( ( maxs_z - mins_z ) * ( getFloatKeyWithDefault( "trace_offset_pct", 75.f ) * 0.01f ) );
commandmapVisibleArcHandle = -1;
}
void deployable_turret::FreeArcIcon() {
if ( commandmapVisibleArcHandle != -1 ) {
sys.freeCMIcon( self, commandmapVisibleArcHandle );
commandmapVisibleArcHandle = -1;
}
}
void deployable_turret::SetupFiringArc() {
FreeArcIcon();
angleRange = getFloatKey( "angle_range" );
if ( angleRange <= 0 ) {
angleRange = 135;
}
vector ang = getAngles();
commandmapVisibleArcHandle = sys.allocCMIcon( self, 100 );
sys.setCMIconAngle( commandmapVisibleArcHandle, -ang_y );
sys.setCMIconSizeMode( commandmapVisibleArcHandle, SM_WORLD );
sys.setCMIconColor( commandmapVisibleArcHandle, g_colorRed, 0.25f );
sys.setCMIconSides( commandmapVisibleArcHandle, 24 );
sys.setCMIconDrawMode( commandmapVisibleArcHandle, DM_ARC );
sys.setCMIconMaterial( commandmapVisibleArcHandle, GetMaterial( "_white_depth" ) );
sys.setCMIconUnknownMaterial( commandmapVisibleArcHandle, GetMaterial( "_white_depth" ) );
sys.setCMIconSize( commandmapVisibleArcHandle, maxRange );
sys.setCMIconUnknownSize( commandmapVisibleArcHandle, maxRange );
sys.setCMIconFlag( commandmapVisibleArcHandle, CMF_ENEMYONLY | CMF_ONLYSHOWKNOWN );
sys.setCMIconArcAngle( commandmapVisibleArcHandle, angleRange );
sys.setCMIconFlag( commandmapVisibleArcHandle, CMF_FOLLOWROTATION );
angleRange = sys.cos( angleRange * 0.5f );
}
void deployable_turret::vOnDeploy() {
SetupFiringArc();
thread DoDeploy();
}
void deployable_turret::init() {
startSound( "snd_turret_yaw", SND_DEPLOYABLE_YAW );
startSound( "snd_turret_pitch", SND_DEPLOYABLE_PITCH );
fadeSound( SND_DEPLOYABLE_YAW, -60.f, 0.f );
fadeSound( SND_DEPLOYABLE_PITCH, -60.f, 0.f );
}
void deployable_turret::destroy() {
FreeArcIcon();
KillAttackThread();
}
boolean deployable_turret::TraceCheck( entity other ) {
vector targetPos = getTargetPosition( other );
sys.tracePoint( getWorldOrigin() + traceCheckOffset, targetPos, checkMask, self );
if ( sys.getTraceFraction() == 1.f ) {
return true;
}
if ( sys.getTraceEntity() != other ) {
return false;
}
return true;
}
void deployable_turret::KillAttackThread() {
sys.killThread( "AttackThread_" + getName() );
}
void deployable_turret::AttackThread() {
float delay = reFire - sys.getTime();
if ( delay > 0 ) {
sys.wait( delay );
}
while ( true ) {
if ( CanFire() ) {
FireMissile();
}
delay = fireRate;
reFire = sys.getTime() + delay;
sys.wait( delay );
}
}
// ==========================================
// Utility Funcs
// ==========================================
void deployable_turret::FireMissile() {
entity target;
entity controller = getBoundPlayer( 0 );
if ( controller != $null_entity ) {
target = controller.getEnemy();
} else {
if ( owner != $null_entity ) {
controller = owner;
} else {
controller = self;
}
target = getEnemy();
}
launchMissileSimple( controller, self, target, projectileIndex, -1, spread, getJointPos( jointBarrel ), getJointAxis( jointBarrel, 0 ) * projectileSpeed );
playJointEffect( "fx_fire", jointBarrel, 0 );
float muzzleJoint;
if ( playTracerFX ) {
if( numTracerJoints > 1 ) {
muzzleJoint = int( sys.random( numTracerJoints ) ) + 1;
} else {
muzzleJoint = numTracerJoints;
}
playEffect( "fx_tracer", getKey( "joint_tracer" + muzzleJoint ), 0 );
}
playEffect( "fx_muzzle", getKey( "joint_tracer" + muzzleJoint ), 0 );
Fired();
}
float deployable_turret::OnValidateTarget() {
entity target = getEnemy();
if ( !TargetIsValid( target ) ) {
return 0.f;
}
if ( !InRange( target.getWorldOrigin() ) ) {
return 0.f;
}
return 1.f;
}
float deployable_turret::OnUpdateCrosshairInfo( entity p ) {
if ( !sys.doClientSideStuff() ) {
return 1.f;
}
float allegiance = getEntityAllegiance( p );
vector color = GetAllegianceColor( allegiance );
float distance = chGetDistance();
float range = InchesToMetres( distance );
float health = getHealth();
chSetNumLines( 0 );
float index;
// define length of health bar
float healthBarLength;
float maxHealth = getMaxHealth();
if ( maxHealth >= 2000.f ) {
healthBarLength = 150.f;
} else if ( maxHealth >= 1000.f ) {
healthBarLength = 100.f;
} else {
healthBarLength = 75.f;
}
if ( p != $null_entity ) {
// see if theres a valid action to perform
float code = GetActivateCode( p, distance );
if ( code != AK_NONE ) {
index = chAddLine();
chSetLineMaterial( index, p.vGetActionIcon( code ) );
chSetLineType( index, CI_IMAGE );
chSetLineSize( index, 64, 64 );
chSetLineColor( index, g_colorWhite, 0.9f );
if ( p.isLocalPlayer() ) {
if ( !p.isToolTipPlaying() ) {
if ( sys.getTime() - p.getCrosshairStartTime() > 1.f ) {
if ( p.getCurrentWeapon() != p.vGetActionItem( code ) ) {
if ( code == AK_HACK ) {
p.sendToolTip( useMeToolTip1_Hack );
}
} else {
if ( code == AK_HACK ) {
p.sendToolTip( useMeToolTip2_Hack );
}
}
}
}
}
}
}
vector disabledColor;
if ( allegiance == TA_ENEMY || allegiance == TA_FRIEND ) {
disabledColor = g_colorYellow;
} else {
disabledColor = color;
}
index = chAddLine();
chSetLineTextIndex( index, objectTitle );
chSetLineColor( index, color, 1.f );
chSetLineType( index, CI_TEXT );
chSetLineSize( index, 0, 0 );
if ( owner != $null_entity ) {
if ( allegiance == TA_FRIEND ) {
index = chAddLine();
sys.pushLocString( sys.toWStr( owner.getCleanUserName() ) );
chSetLineText( index, sys.localizeStringArgs( "game/deployable_owner" ) );
chSetLineColor( index, color, 1.f );
chSetLineType( index, CI_TEXT );
chSetLineSize( index, 0, 0 );
}
}
if ( health <= 0 ) {
if ( maxHealth != 0.f ) {
index = chAddLine();
chSetLineTextIndex( index, g_locStr_Destroyed );
chSetLineColor( index, color, 1.f );
chSetLineType( index, CI_TEXT );
chSetLineSize( index, 0, 0 );
}
} else {
if ( disabledState ) {
index = chAddLine();
float diff = disableEndTime - sys.getTime();
if ( diff > 0 ) {
sys.pushLocString( int( diff ) );
chSetLineText( index, sys.localizeStringArgs( "game/disabled_info" ) );
} else {
chSetLineTextIndex( index, g_locStr_Disabled );
}
chSetLineColor( index, disabledColor, 1.f );
chSetLineType( index, CI_TEXT );
chSetLineSize( index, 0, 0 );
}
index = chAddLine();
chSetLineColor( index, color, 0.5f );
chSetLineType( index, CI_BAR );
chSetLineFraction( index, getHealth() / getMaxHealth() );
chSetLineSize( index, healthBarLength, CROSSHAIR_INFO_BAR_HEIGHT );
if ( !disabledState ) {
float fsState = vGetFiringStatus( $null_entity );
G_StringForFireSupportState( fsState );
index = chAddLine();
chSetLineTextIndex( index, g_fireSupportStateStr );
chSetLineColor( index, color, 1.f );
chSetLineType( index, CI_TEXT );
chSetLineSize( index, 0, 0 );
}
if ( range <= 100 ) {
index = chAddLine();
chSetLineText( index, G_BuildRangeStr( range ) );
chSetLineColor( index, color, 1.f );
chSetLineType( index, CI_TEXT );
chSetLineSize( index, 0, 0 );
}
}
return 1.f;
}
boolean deployable_turret::InRange( vector targetPos ) {
float len = sys.vecLength( targetPos - getWorldOrigin() );
return ( ( len >= minRange ) && ( len <= maxRange ) );
}
boolean deployable_turret::InFiringRange( vector targetPos ) {
float len = sys.vecLength( targetPos - getWorldOrigin() );
return ( ( len >= minRange ) && ( len <= firingRange ) );
}
// ==========================================
// ==========================================
float deployable_turret::OnUsed( entity p, float distance ) {
entity team = p.getGameTeam();
if ( team == $null_entity ) {
return 0.f;
}
if ( p.getHealth() <= 0 ) {
return 0.f;
}
if ( distance > 128.f ) {
return 0.f;
}
if ( getEntityAllegiance( p ) != TA_FRIEND ) {
return 1.f;
}
entity other = p.getProxyEntity();
if ( other != $null_entity ) {
sys.assert( self == other );
if ( !sys.isClient() ) {
removeBoundPlayer( p );
}
return 1.f;
}
if ( getBoundPlayer( 0 ) != $null_entity ) {
return 1.f;
}
if ( !sys.isClient() ) {
p.enter( self );
}
return 1.f;
}
void deployable_turret::OnKilled( entity inflictor, entity attacker, float damage, vector dir, float location ) {
entity currentUser = getBoundPlayer( 0 );
if( currentUser != $null_entity ) {
currentUser.applyDamage( inflictor, attacker, dir, GetDamage( "damage_deployable_turret_user" ), 1.f, $null_entity );
}
DeployableBase_OnKilled( attacker, inflictor );
}
void deployable_turret::OnEnter( entity user ) {
sys.assert( false );
if ( user.isDisguised() ) {
user.disguise( $null_entity );
}
myUser = user;
user.vHideNormalChargeBar( true );
if ( user == sys.getLocalPlayer() ) {
sys.setGUIString( GUI_GLOBALS_HANDLE, "gameHud.weaponCrosshair", getKey( "crosshair" ) );
sys.setGUIFloat( GUI_GLOBALS_HANDLE, "gameHud.weaponShowAllAmmo", 1 );
sys.setGUIFloat( GUI_GLOBALS_HANDLE, "gameHud.weaponShowClip", 0 );
sys.setGUIFloat( GUI_GLOBALS_HANDLE, "gameHud.weaponHideAmmo", 0 );
sys.setGUIFloat( GUI_GLOBALS_HANDLE, "gameHud.weaponShowCharge", 1 );
sys.setGUIFloat( GUI_GLOBALS_HANDLE, "weapons.energySegments", 1 );
sys.setGUIFloat( GUI_GLOBALS_HANDLE, "gameHud.weaponShowCustom", 0 );
sys.setGUIFloat( GUI_GLOBALS_HANDLE, "weapons.showHeat", 1.f );
thread UpdateCharge();
}
}
void deployable_turret::OnExit( entity user ) {
sys.assert( false );
myUser = $null_entity;
user.vHideNormalChargeBar( false );
if ( user == sys.getLocalPlayer() ) {
sys.setGUIFloat( GUI_GLOBALS_HANDLE, "weapons.showHeat", 0 );
sys.setGUIFloat( GUI_GLOBALS_HANDLE, "weapons.energyAvailable", 1 );
sys.setGUIFloat( GUI_GLOBALS_HANDLE, "weapons.energyBarCharge", 1 );
sys.setGUIFloat( GUI_GLOBALS_HANDLE, "weapons.cooling", 0 );
}
}
void deployable_turret::CreateDestroyThread() {
sys.freeCMIcon( self, commandmapVisibleArcHandle );
commandmapVisibleArcHandle = -1;
thread DestroyThread();
}
void deployable_turret::OnBeginAttack() {
attacking = true;
KillAttackThread();
thread AttackThread();
}
void deployable_turret::OnEndAttack() {
attacking = false;
KillAttackThread();
}
void deployable_turret::vCheckProficiency() {
SetupFiringArc();
}
void deployable_turret::OnDisabled() {
setDisabled( true );
sys.setCMIconShaderParm( commandMapHandle, 5, 0 );
if ( owner != $null_entity ) {
if ( owner.isLocalPlayer() ) {
sys.setGUIFloat( GUI_GLOBALS_HANDLE, "deployables.state", DS_DISABLED );
}
}
}
void deployable_turret::OnReEnabled() {
setDisabled( false );
sys.setCMIconShaderParm( commandMapHandle, 5, 1 );
if ( owner != $null_entity ) {
if ( owner.isLocalPlayer() ) {
sys.setGUIFloat( GUI_GLOBALS_HANDLE, "deployables.state", DS_NORMAL );
}
}
}
float deployable_turret::GetTurretMaxRange() {
return firingRange;
}
float deployable_turret::GetTurretMinRange() {
return minRange;
}
float deployable_turret::vGetFiringStatus( object traceObject ) {
if ( attacking ) {
return MPS_FIRING;
}
if ( !finishedDeploying ) {
return MPS_NONE_ACTIVE;
}
return MPS_READY;
}