Script:Files:script/deployables/base.script
From Mod Wiki
#include <script/deployables/base_defines.include> object deployable_base { void syncFields(); void init(); void preinit(); void destroy(); void DoDeploy(); void vOnDeploy(); void vDoneDeploy(); void OnDeployedChanged(); void OnOwnerChanged(); void OnDisableEndTimeChanged(); void IncreaseUseCount(); void SetupStats(); void SetDisableEndTime( float t ); void Base_TargetSetTarget( vector targetPos, entity targetEnt ); void OnPostDamage( entity attacker, float oldHealth, float newHealth ); void UpdateDisabledStats( entity attacker, boolean oldDisabled ); void UpdateState( float health ); void UpdateGui(); void SetDeployableState( float newState ); void SetupRequestIcon( string key, string requirement ); void FreeRequestIcon(); void RequestIconThread( float timeout ); float OnActivate( entity p, float distance ); float GetActivateCode( entity p, float distance ); void OnStateDisabled(); void OnStateDamaged(); void OnStateNormal(); void DeployableBase_OnStateNormal(); void DeployableBase_OnStateDamaged(); void DeployableBase_OnStateDisabled(); void DeployableBase_OnKilled( entity attacker, entity inflictor ); void DeployableBase_Deploy(); void DoHack( entity hacker, float time ); float GetChargePerUse(); float OnUpdateCrosshairInfo( entity p ); float vGetPliersProgressBarValue( float action ); boolean vCheckActionCode( entity p, float actionCode ); void vRepair( float count, entity p ); vector vGetLastRepairOrigin(); void SelfDestruct(); boolean IsDeployed(); boolean IsDisabled(); float vGetFiringStatus( object traceObject ); void vUpdateFiringStatusObject( entity localPlayer ); float GetCoolDownFraction(); float vGetTimerState(); float vGetChargeTime(); float GetLockTime(); float GetLockGraceTime(); void SetupCommandMap(); void FreeCommandMap(); void vDismantle( entity p ); void vHack( entity p ); boolean vIsDeployed(); void SetDeployingFinished(); void vCheckProficiency(); void vApplyEmpDamage( entity attacker, float time, float weaponTime ); entity vGetDeployableOwner(); entity GetOwner(); void vSetDeployableOwner( entity other ); void DeployableBase_CheckProficiency(); void OnSpotted( entity spotter ); void OnSetTeam( object oldTeam, object newTeam ); void OnKilled( entity inflictor, entity attacker, float damage, vector direction, float location ); void InitDestroyTask( boolean highCommand ); void FreeDestroyTask(); void CompleteDestroyTask(); void InitDisableTask( boolean highCommand ); void FreeDisableTask(); void CompleteDisableTask(); void InitRepairTask( boolean highCommand ); void FreeRepairTask(); void CompleteRepairTask(); boolean NeedsRepair(); void vOnContextKill( entity p ); void vOnContextRepair( entity p ); void vOnRemovePlayersKillTask( player p ); void UpdateDisabled(); void CreateDisableThread(); void KillDisableThread(); void DisableThread(); boolean DeployableBase_CalculateDisabledState(); boolean CalculateDisabledState(); void SetDisabled( boolean newDisabledState ); void OnDisabled(); void OnReEnabled(); string vGetQuickChatString( entity p ); void FlashCMIcon( entity p, float requiredTeam ); float currentState; boolean isDeploying; handle objectTitle; float hackCount; float maxHackCount; float hackDisableTime; task disableTask; task destroyTask; task repairTask; player killTaskRequestee; boolean manualDeploy; float commandMapHandle; float fireSupportState; boolean finishedDeploying; boolean playTracerFX; string localFireSound; float disableEndTime; float repairMultiplier; float disableProficiency; float hackProficiency; // variables for the repair drone float orbitUnderneath; float orbitRadius; boolean vCustomOrbitRadius(); float vGetOrbitRadius(); boolean vOrbitUnderneath(); player owner; boolean OverridePreventDeployment( entity p ) { return p == owner; } float timerHandle; // Gordon: FIXME: These should not be a part of the base float timerStartHandle; float timerLength; float gracePeriod; float commandMapRequest; void DestroyThread(); void CreateDestroyThread(); void DoBoundsDamageThread(); void KillBoundsDamageThread(); float useMeToolTip1_Hack; float useMeToolTip2_Hack; // Gordon: why on earth is this here? string colorMaterial; string desatMaterial; boolean disabledState; handle statTimeUsed; handle statUseCount; handle statNumDestroyed; handle statNumDisabled; float deployFinishedTime; fireSupportStatus fsStatus; } void deployable_base::syncFields() { syncBroadcast( "isDeploying" ); syncBroadcast( "finishedDeploying" ); syncBroadcast( "owner" ); syncBroadcast( "disableEndTime" ); syncCallback( "disableEndTime", "OnDisableEndTimeChanged" ); syncCallback( "isDeploying", "OnDeployedChanged" ); syncCallback( "owner", "OnOwnerChanged" ); sync( "hackCount" ); } void deployable_base::OnOwnerChanged() { if ( owner != $null_entity ) { owner.SetTargetingItem( self ); } setXPShareInfo( owner, 0.5f ); vCheckProficiency(); if ( owner == sys.getLocalPlayer() ) { sys.killThread( "UpdateGui_" + getName() ); thread UpdateGui(); } } void deployable_base::destroy() { if ( owner != $null_entity ) { if ( owner == sys.getLocalPlayer() ) { sys.setGUIFloat( GUI_GLOBALS_HANDLE, "deployables.state", DS_REMOVED ); } owner.binRemove( self ); } KillBoundsDamageThread(); FreeCommandMap(); FreeDestroyTask(); FreeDisableTask(); FreeRequestIcon(); FreeRepairTask(); if ( deployFinishedTime != -1 && owner != $null_entity ) { sys.increaseStatInt( statTimeUsed, owner.getEntityNumber(), sys.getTime() - deployFinishedTime ); } object team = getGameTeam(); team.unRegisterDeployable( self ); } void deployable_base::vSetDeployableOwner( entity other ) { owner = other; OnOwnerChanged(); } entity deployable_base::vGetDeployableOwner() { return owner; } entity deployable_base::GetOwner() { return owner; } void deployable_base::vSetManualDeploy() { manualDeploy = true; } void deployable_base::SetupCommandMap() { commandMapHandle = sys.allocCMIcon( self, 10 ); sys.setCMIconShaderParm( commandMapHandle, 5, 1 ); float commandMapSize = getFloatKey( "icon_size_cm" ); sys.setCMIconSize( commandMapHandle, commandMapSize ); sys.setCMIconColorMode( commandMapHandle, CM_ALLEGIANCE ); sys.setCMIconMaterial( commandMapHandle, GetMaterial( getKey( "mtr_commandmap" ) ) ); sys.setCMIconUnknownMaterial( commandMapHandle, GetMaterial( getKey( "mtr_commandmap_unknown" ) ) ); sys.setCMIconUnknownSize( commandMapHandle, getFloatKeyWithDefault( "icon_unknown_size_cm", commandMapSize ) ); sys.setCMIconFlag( commandMapHandle, CMF_FOLLOWROTATION ); sys.setCMIconDrawMode( commandMapHandle, DM_ROTATED_MATERIAL ); } void deployable_base::FreeCommandMap() { if( commandMapHandle != -1 ) { sys.freeCMIcon( self, commandMapHandle ); commandMapHandle = -1; } } void deployable_base::OnDeployedChanged() { vOnDeploy(); } void deployable_base::OnDisableEndTimeChanged() { SetDisableEndTime( disableEndTime ); } void deployable_base::OnSpotted( entity spotter ) { if ( IsDeployed() ) { killTaskRequestee = $null_entity; InitDestroyTask( true ); InitDisableTask( true ); G_GiveSpottingProficiency( spotter ); } } void deployable_base::preinit() { objectTitle = sys.localizeString( getKeyWithDefault( "ch_name", getKey( "task_name" ) ) ); playTracerFX = getFloatKey( "use_tracers" ) != 0; repairMultiplier = getFloatKeyWithDefault( "repair_multiplier", 1.f ); maxHackCount = getFloatKeyWithDefault( "max_hack_count", 40 ); hackDisableTime = getFloatKeyWithDefault( "hack_disable_time", 60 ); localFireSound = getKey( "snd_fire_local" ); fireSupportState = MPS_NONE_ACTIVE; orbitUnderneath = getFloatKey( "drone_orbit_underneath" ); orbitRadius = getFloatKey( "drone_orbit_radius" ); currentState = DS_NORMAL; colorMaterial = getKey( "mtr_color" ); desatMaterial = getKey( "mtr_desat" ); timerHandle = sys.allocTargetTimer( FIRESUPPORT_TIMER_NAME ); timerStartHandle = sys.allocTargetTimer( FIRESUPPORT_TIMER_START_NAME ); timerLength = getFloatKey( "target_length" ); gracePeriod = getFloatKey( "target_lostgraceperiod" ); useMeToolTip1_Hack = GetToolTip( getKey( "tt_intro_use_me_1_hack" ) ); useMeToolTip2_Hack = GetToolTip( getKey( "tt_intro_use_me_2_hack" ) ); disableProficiency = GetProficiency( getKey( "prof_disable" ) ); hackProficiency = GetProficiency( getKey( "prof_hack" ) ); commandMapRequest = -1; SetupStats(); SetupCommandMap(); if ( getFloatKey( "freeze_on_spawn" ) != 0.0f ) { setComeToRest( true ); } } void deployable_base::IncreaseUseCount() { if ( owner == $null_entity ) { return; } sys.increaseStatInt( statUseCount, owner.getEntityNumber(), 1 ); } void deployable_base::SetupStats() { statTimeUsed = -1; statNumDestroyed = -1; statNumDisabled = -1; statUseCount = -1; deployFinishedTime = -1; string statName = getKey( "stat_name" ); if ( statName == "" ) { return; } statTimeUsed = sys.allocStatInt( statName + "_time_used" ); statNumDestroyed = sys.allocStatInt( statName + "_killed" ); statNumDisabled = sys.allocStatInt( statName + "_disabled" ); statUseCount = sys.allocStatInt( statName + "_uses" ); } float deployable_base::OnActivate( entity p, float distance ) { if ( distance > 128.f ) { return 0.f; } float code = GetActivateCode( p, distance ); if ( code == AK_HACK ) { if ( p.isDisguised() ) { p.disguise( $null_entity ); } } if ( p.vSelectActionItem( code ) ) { return 1.f; } return 0.f; } void deployable_base::vOnContextRepair( entity p ) { if ( currentState == DS_NORMAL ) { SetupRequestIcon( "mtr_cm_icon_need_repair", "require_view_repair" ); thread RequestIconThread( 5.f ); } InitRepairTask( false ); } void deployable_base::vOnContextKill( entity p ) { if ( IsDeployed() ) { if ( destroyTask == $null && disableTask == $null ) { killTaskRequestee = $null_entity; InitDestroyTask( true ); InitDisableTask( true ); } FlashCMIcon( p, TA_ENEMY ); } } void deployable_base::vOnRemovePlayersKillTask( player p ) { if ( p == killTaskRequestee ) { FreeDestroyTask(); FreeDisableTask(); } } float deployable_base::GetActivateCode( entity p, float distance ) { if ( p.getViewingEntity() != p ) { return AK_NONE; } if ( p.getHealth() <= 0 ) { return AK_NONE; } if ( p.getVehicle() != $null_entity ) { return AK_NONE; } float allegiance = getEntityAllegiance( p ); if ( distance < DISTANCE_FOR_ACTION ) { if ( allegiance == TA_ENEMY ) { if ( !disabledState ) { if ( p.hasAbility( "hack" ) ) { return AK_HACK; } } if ( p.vHasActionItem( AK_PLANT ) ) { return AK_PLANT; } } else { if ( p.vHasActionItem( AK_REPAIR ) ) { float health = getHealth(); if ( ( health > 0 ) && ( health < getMaxHealth() ) ) { return AK_REPAIR; } } } } return AK_NONE; } void deployable_base::InitDestroyTask( boolean highCommand ) { if ( sys.isClient() ) { return; } if ( destroyTask != $null_entity ) { if ( !highCommand ) { return; } if ( !destroyTask.isUserCreated() ) { return; } destroyTask.free(); } float taskHandle = GetPlayerTask( getKey( "task_destroy" ) ); if ( taskHandle != -1 ) { destroyTask = taskManager.allocEntityTask( taskHandle, self ); if ( !highCommand ) { destroyTask.setUserCreated(); } } } void deployable_base::FreeDestroyTask() { killTaskRequestee = $null_entity; if ( destroyTask != $null_entity ) { destroyTask.free(); } } void deployable_base::CompleteDestroyTask() { if ( destroyTask != $null_entity ) { destroyTask.complete(); destroyTask.setTimeout( 1.f ); destroyTask = $null_entity; } } void deployable_base::InitRepairTask( boolean highCommand ) { if ( sys.isClient() ) { return; } if ( getHealth() <= 0 ) { FreeRepairTask(); return; } if ( repairTask != $null_entity ) { if ( !highCommand ) { return; } if ( !repairTask.isUserCreated() ) { return; } repairTask.free(); } float taskHandle = GetPlayerTask( getKey( "task_repair" ) ); if ( taskHandle != -1 ) { repairTask = taskManager.allocEntityTask( taskHandle, self ); if ( !highCommand ) { repairTask.setUserCreated(); } } } void deployable_base::FreeRepairTask() { if ( repairTask != $null ) { repairTask.free(); } } void deployable_base::CompleteRepairTask() { if ( repairTask != $null_entity ) { repairTask.complete(); repairTask.setTimeout( 1.f ); repairTask = $null_entity; } } void deployable_base::InitDisableTask( boolean highCommand ) { if ( sys.isClient() ) { return; } if ( disableEndTime > sys.getTime() ) { return; } if ( disableTask != $null_entity ) { if ( !highCommand ) { return; } if ( !disableTask.isUserCreated() ) { return; } disableTask.free(); } float taskHandle = GetPlayerTask( getKey( "task_hack" ) ); if ( taskHandle != -1 ) { disableTask = taskManager.allocEntityTask( taskHandle, self ); if ( !highCommand ) { disableTask.setUserCreated(); } } } void deployable_base::FreeDisableTask() { killTaskRequestee = $null_entity; if ( disableTask != $null_entity ) { disableTask.free(); } } void deployable_base::CompleteDisableTask() { if ( disableTask != $null_entity ) { disableTask.complete(); disableTask.setTimeout( 1.f ); disableTask = $null_entity; } } void deployable_base::DeployableBase_OnKilled( entity attacker, entity inflictor ) { FreeRepairTask(); if ( !sys.isClient() ) { CompleteDestroyTask(); // need to check for things like HE/Plasma charges still being on the deployable float c = entitiesInBounds( getAbsMins(), getAbsMaxs(), MASK_ALL, 1 ); float i = 0; for ( i = 0; i < c; i++ ) { entity e = getBoundsCacheEntity( i ); if ( e.getMaster() == self ) { e.vOnTargetDestroyed(); } } } player attackPlayer = attacker; if ( attackPlayer != $null_entity ) { if ( getEntityAllegiance( inflictor ) == TA_ENEMY ) { sys.increaseStatInt( statNumDestroyed, attackPlayer.getEntityNumber(), 1 ); } } CreateDestroyThread(); } void deployable_base::init() { string teamName = getKey( "team" ); if ( teamName != "" ) { setGameTeam( sys.getTeam( teamName ) ); } setTakesDamage( 0.f ); playAnim( ANIMCHANNEL_ALL, "undeployed" ); if ( !sys.isClient() ) { if ( !manualDeploy ) { vOnDeploy(); } else { thread DoBoundsDamageThread(); } } } float deployable_base::OnUpdateCrosshairInfo( entity p ) { if ( sys.getLocalPlayer() == $null_entity ) { 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; } team_base team; // 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 ( 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 ) { G_StringForFireSupportState( fireSupportState ); 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; } float deployable_base::vGetPliersProgressBarValue( float action ) { if ( action == AC_HACK ) { return hackCount / maxHackCount; } if ( action == AC_REPAIR ) { return getHealth() / getMaxHealth(); } return 0.f; } boolean deployable_base::vCheckActionCode( entity p, float actionCode ) { if ( actionCode == AC_HACK ) { if ( getEntityAllegiance( p ) != TA_ENEMY ) { return false; } if ( disabledState ) { return false; } return true; } if ( actionCode == AC_REPAIR ) { if ( getEntityAllegiance( p ) != TA_FRIEND ) { return false; } float health = getHealth(); return ( health > 0 ) && ( health < getMaxHealth() ); } if ( actionCode == AC_ENEMY_REPAIR ) { if ( getEntityAllegiance( p ) != TA_FRIEND ) { return true; } } if ( actionCode == AC_DISMANTLE ) { if ( getEntityAllegiance( p ) != TA_FRIEND ) { return false; } return true; } return false; } boolean deployable_base::NeedsRepair() { return getHealth() < getMaxHealth(); } void deployable_base::vHack( entity p ) { if ( hackCount >= maxHackCount ) { hackCount = 0; } float count = 1; team_base team = p.getGameTeam(); if ( team.HasFastHackBonus( p ) ) { count = count * 1.25f; } hackCount = hackCount + count; if ( hackCount >= maxHackCount ) { boolean oldDisabled = disabledState; DoHack( p, hackDisableTime ); sys.increaseStatInt( sys.allocStatInt( team.getName() + "_hack_uses" ), p.getEntityNumber(), 1 ); if ( hackProficiency != -1 ) { p.giveProficiency( hackProficiency, 1.f, disableTask, "hack success" ); } UpdateDisabledStats( p, oldDisabled ); } } void deployable_base::SelfDestruct() { // sys.wait( 4.f ); setTakesDamage( 1.f ); applyDamage( $null_entity, $null_entity, vec3_up, GetDamage( "damage_deployable_destruct" ), 1.f, $null_entity ); } void deployable_base::vDismantle( entity p ) { thread SelfDestruct(); } void deployable_base::vRepair( float count, entity p ) { count = count * repairMultiplier; float maxHealth = getMaxHealth(); float health = getHealth(); float lost = maxHealth - health; if ( count > lost ) { count = lost; } float teamDamageCount = getTeamDamageDone(); float repairCount = count - teamDamageCount; if ( repairCount > 0 ) { team_base team = p.getGameTeam(); if ( team != $null_entity ) { team.GiveRepairProficiency( p, repairTask, repairCount ); } } setTeamDamageDone( teamDamageCount - count ); float total = health + count; setHealth( total ); if ( total >= getMaxHealth() ) { CompleteRepairTask(); } } vector deployable_base::vGetLastRepairOrigin() { vector mins = getAbsMins(); vector maxs = getAbsMaxs(); return (mins + maxs) * 0.5; } boolean deployable_base::vOrbitUnderneath() { return orbitUnderneath; } boolean deployable_base::vCustomOrbitRadius() { return true; } float deployable_base::vGetOrbitRadius() { if ( orbitRadius == 0 ) { vector size = getAbsMaxs() - getAbsMins(); orbitRadius = 0.7 * sys.sqrt( size_x * size_x + size_y * size_x ); } return orbitRadius; } void deployable_base::DoHack( entity hacker, float time ) { CompleteDisableTask(); float newEndTime = sys.getTime() + time; if ( newEndTime > disableEndTime ) { SetDisableEndTime( newEndTime ); } } void deployable_base::DeployableBase_Deploy() { if ( !sys.isClient() ) { if ( owner != $null_entity ) { // add self to the bin owner.binAdd( self ); G_GiveDeployBonus( owner, self ); } if ( isSpotted() ) { killTaskRequestee = $null_entity; InitDisableTask( true ); InitDestroyTask( true ); } } vDoneDeploy(); } void deployable_base::vDoneDeploy() { SetDeployingFinished(); } void deployable_base::vOnDeploy() { thread DoDeploy(); } void deployable_base::DoDeploy() { // Gordon: only do this if we haven't been spawned from the console if ( manualDeploy ) { // if the territory has been captured since we were called in, shouldn't deploy if ( sys.getTerritoryForPoint( getWorldOrigin(), getGameTeam(), 1.f, 0.f ) == $null_entity ) { vDismantle( $null_entity ); return; } } if ( !sys.isClient() ) { isDeploying = true; } float hitGroundEffect = getFloatKey( "play_hitground_effect" ); if ( hitGroundEffect ) { startSound( "snd_drop", SND_DEPLOYABLE_IDLE ); playEffect( "fx_hitground", "origin", false ); } preventDeployment( 1.f ); KillBoundsDamageThread(); forceAnimUpdate( true ); float i; float numHelpers = getFloatKeyWithDefault( "num_ik", 0.f ); if ( numHelpers > 0.f ) { playAnim( ANIMCHANNEL_ALL, "pre_ik" ); while ( isAnimating() ) { sys.waitFrame(); } playAnim( ANIMCHANNEL_ALL, "post_ik" ); for( i = 0; i < numHelpers; i++ ) { addHelper( GetStringMap( getKey( "str_ik" + i ) ) ); } while ( isAnimating() ) { sys.waitFrame(); } } else { playAnim( ANIMCHANNEL_ALL, "deploy" ); while ( isAnimating() ) { sys.waitFrame(); } } forceAnimUpdate( false ); DeployableBase_Deploy(); } void deployable_base::vApplyEmpDamage( entity attacker, float time, float weaponTime ) { boolean oldDisabled = disabledState; DoHack( attacker, time ); UpdateDisabledStats( attacker, oldDisabled ); if ( disableProficiency != -1 ) { attacker.giveProficiency( disableProficiency, 1.f, disableTask, "emp on deployable" ); } } void deployable_base::OnSetTeam( object oldTeam, object newTeam ) { if ( oldTeam != $null ) { oldTeam.unRegisterDeployable( self ); } if ( newTeam != $null ) { newTeam.registerDeployable( self ); } } boolean deployable_base::vIsDeployed() { return IsDeployed(); } boolean deployable_base::IsDeployed() { return finishedDeploying; } void deployable_base::SetDeployingFinished() { finishedDeploying = true; deployFinishedTime = sys.getTime(); fireSupportState = MPS_READY; if ( getHealth() > 0 ) { setTakesDamage( 1.f ); // ao: only do this if we haven't been spawned from the console if ( manualDeploy ) { // if the territory has been captured since we were called in, shouldn't deploy if ( sys.getTerritoryForPoint( getWorldOrigin(), getGameTeam(), 1.f, 0.f ) == $null_entity ) { vDismantle( $null_entity ); return; } } } if ( owner != $null_entity ) { if ( owner.isLocalPlayer() ) { owner.sendToolTip( GetToolTip( getKey( "tt_deploy_finished" ) ) ); } } } void deployable_base::UpdateDisabledStats( entity attacker, boolean oldDisabled ) { if ( !sys.isClient() ) { if ( !oldDisabled && disabledState ) { player attackerPlayer = attacker; if ( attackerPlayer != $null_entity ) { sys.increaseStatInt( statNumDisabled, attackerPlayer.getEntityNumber(), 1 ); } } } } void deployable_base::OnPostDamage( entity attacker, float oldHealth, float newHealth ) { boolean oldDisabled = disabledState; UpdateState( newHealth ); UpdateDisabledStats( attacker, oldDisabled ); } void deployable_base::UpdateState( float health ) { float maxHealth = getMaxHealth(); if ( maxHealth == 0.f ) { return; } float frac = health / maxHealth; float newState; player p = sys.getLocalPlayer(); boolean showHealthStatus = false; if ( p != $null_entity ) { team_base team = p.getGameTeam(); float allegiance = getEntityAllegiance( p ); if ( allegiance == TA_FRIEND ) { showHealthStatus = true; } } float healthStatusParm = 0; healthStatusParm = frac; if ( frac < ( 1.f / 3.f ) ) { newState = DS_DISABLED; } else if ( frac < ( 2.f / 3.f ) ) { newState = DS_DAMAGED; } else { newState = DS_NORMAL; } if ( showHealthStatus && !disabledState ) { sys.setCMIconShaderParm( commandMapHandle, 5, healthStatusParm ); } SetDeployableState( newState ); } void deployable_base::SetDeployableState( float newState ) { if ( currentState == newState ) { return; } if ( newState == DS_NORMAL ) { OnStateNormal(); } else if ( newState == DS_DAMAGED ) { OnStateDamaged(); InitRepairTask( true ); } else if ( newState == DS_DISABLED ) { OnStateDisabled(); InitRepairTask( true ); } currentState = newState; UpdateDisabled(); } void deployable_base::DeployableBase_OnStateNormal() { playAnim( ANIMCHANNEL_ALL, "base" ); stopEffect( "fx_damaged" ); FreeRequestIcon(); if ( owner == sys.getLocalPlayer() && disableEndTime <= sys.getTime() ) { sys.setGUIFloat( GUI_GLOBALS_HANDLE, "deployables.state", DS_NORMAL ); } } void deployable_base::DeployableBase_OnStateDamaged() { float numDamageJoints; string jointName; playAnim( ANIMCHANNEL_ALL, "damaged" ); // Is it being damage or being repaired? if ( currentState == DS_NORMAL ) { numDamageJoints = getFloatKeyWithDefault( "numDamageJoints", 0 ); if ( numDamageJoints ) { jointName = getKey( "damageJoint" + int( sys.random( numDamageJoints ) ) ); playEffect( "fx_damaged", jointName, true ); } } else { stopEffect( "fx_damaged" ); } SetupRequestIcon( "mtr_cm_icon_need_repair", "require_view_repair" ); thread RequestIconThread( 5.f ); if( owner == sys.getLocalPlayer() ) { sys.setGUIFloat( GUI_GLOBALS_HANDLE, "deployables.state", DS_DISABLED ); } } void deployable_base::DeployableBase_OnStateDisabled() { float numDamageJoints; string jointName; playAnim( ANIMCHANNEL_ALL, "destroyed" ); numDamageJoints = getFloatKeyWithDefault( "numDamageJoints", 0 ); if ( numDamageJoints ) { jointName = getKey( "damageJoint" + int( sys.random( numDamageJoints ) ) ); playEffect( "fx_damaged", jointName, true ); } } void deployable_base::OnStateNormal() { DeployableBase_OnStateNormal(); } void deployable_base::OnStateDamaged() { DeployableBase_OnStateDamaged(); } void deployable_base::OnStateDisabled() { DeployableBase_OnStateDisabled(); } void deployable_base::OnKilled( entity inflictor, entity attacker, float damage, vector direction, float location ) { DeployableBase_OnKilled( attacker, inflictor ); } void deployable_base::CreateDestroyThread() { thread DestroyThread(); } void deployable_base::DestroyThread() { playEffect( "fx_death", "" , 0 ); hide(); forceDisableClip(); sys.wait( 5.0f ); if( !sys.isClient() ) { remove(); } } void deployable_base::UpdateGui() { sys.setGUIString( GUI_GLOBALS_HANDLE, "deployables.statusMaterial", colorMaterial ); sys.setGUIString( GUI_GLOBALS_HANDLE, "deployables.statusDesatMaterial", desatMaterial ); sys.setGUIString( GUI_GLOBALS_HANDLE, "deployables.deployableName", getKey( "title" ) ); sys.setGUIFloat( GUI_GLOBALS_HANDLE, "deployables.maxHealth", getMaxHealth() ); sys.setGUIFloat( GUI_GLOBALS_HANDLE, "deployables.state", DS_NORMAL ); while( true ) { sys.setGUIFloat( GUI_GLOBALS_HANDLE, "deployables.health", getHealth() ); sys.waitFrame(); } } float deployable_base::GetChargePerUse() { if ( owner != $null_entity ) { team_base team = owner.getGameTeam(); if ( team != $null ) { if ( team.HasFastFireSupportRecharge( owner ) ) { return 0.80f; } } } return 1.f; } void deployable_base::Base_TargetSetTarget( vector targetPos, entity targetEnt ) { if( !sys.isClient() ) { owner.EnergyBar_Remove( GetChargePerUse() ); G_DelayFireSupport( owner, self, timerLength ); } IncreaseUseCount(); } // Gordon: FIXME: This stuff doesn't even make sense float deployable_base::vGetFiringStatus( object traceObject ) { if ( disabledState ) { return MPS_DISABLED; } float state = MPS_DISABLED; float thisState = fireSupportState; if ( thisState == MPS_FIRING_PREPARE || thisState == MPS_FIRING ) { return MPS_FIRING; } if ( thisState == MPS_READY ) { if( traceObject == $null ) { state = MPS_READY; } else if ( vTargetGetValid( traceObject.getTraceEndPos() ) ) { state = MPS_READY; } else { thisState = MPS_OUT_OF_RANGE; } } if ( state != MPS_OUT_OF_RANGE && thisState > state ) { state = thisState; } if ( GetCoolDownFraction() > 0.f ) { return MPS_RELOADING; } if ( state == MPS_READY ) { if ( !owner.EnergyBar_CanRemove( GetChargePerUse() ) ) { state = MPS_WAITING; } } return state; } float deployable_base::GetCoolDownFraction() { float coolDownTime = sys.getTargetTimerValue( timerHandle, owner ); float coolDownStartTime = sys.getTargetTimerValue( timerStartHandle, owner ); float temp = ( coolDownTime - sys.getTime() ); if ( temp > 0.f ) { return temp / ( coolDownTime - coolDownStartTime ); } return 0.f; } float deployable_base::vGetTimerState() { return GetCoolDownFraction(); } float deployable_base::vGetChargeTime() { float coolDownTime = sys.getTargetTimerValue( timerHandle, owner ); float coolDownStartTime = sys.getTargetTimerValue( timerStartHandle, owner ); float temp = ( coolDownTime - coolDownStartTime ); if ( temp > 0.f ) { return temp; } return 0.f; } float deployable_base::GetLockTime() { float lockTime = getFloatKey( "target_locktime" ); team_base team = owner.getGameTeam(); if ( team.HasFastFireSupportLock( owner ) ) { lockTime = lockTime * 0.8f; } return lockTime; } float deployable_base::GetLockGraceTime() { return gracePeriod; } /* ===================== deployable_base::SetupRequestIcon ===================== */ void deployable_base::SetupRequestIcon( string key, string requirement ) { FreeRequestIcon(); commandMapRequest = sys.allocCMIcon( self, getFloatKey( "icon_sort_cm" ) ); sys.setCMIconMaterial( commandMapRequest, GetMaterial( getKey( key ) ) ); sys.setCMIconUnknownMaterial( commandMapRequest, GetMaterial( getKey( key ) ) ); sys.addCMIconRequirement( commandMapRequest, getKey( requirement ) ); sys.setCMIconColorMode( commandMapRequest, CM_NORMAL ); sys.setCMIconDrawMode( commandMapRequest, DM_ROTATED_MATERIAL ); sys.setCMIconSize( commandMapRequest, 24.0f ); sys.setCMIconUnknownSize( commandMapRequest, 16.0f ); sys.setCMIconColor( commandMapRequest, '1 1 1', 1.0f ); sys.flashCMIcon( commandMapRequest, -1, SPOTTED_FLASH_TIME, -1 ); } /* ===================== deployable_base::FreeRequestIcon ===================== */ void deployable_base::FreeRequestIcon() { if( commandMapRequest != -1 ) { sys.freeCMIcon( self, commandMapRequest ); commandMapRequest = -1; } sys.killThread( "RequestIconThread_" + getName() ); } /* ===================== deployable_base::RequestIconThread ===================== */ void deployable_base::RequestIconThread( float timeout ) { sys.wait( timeout ); FreeRequestIcon(); } /* ===================== deployable_base::vCheckProficiency ===================== */ void deployable_base::vCheckProficiency() { DeployableBase_CheckProficiency(); } /* ===================== deployable_base::DeployableBase_CheckProficiency ===================== */ void deployable_base::DeployableBase_CheckProficiency() { } /* ===================== deployable_base::SetDisableEndTime ===================== */ void deployable_base::SetDisableEndTime( float t ) { disableEndTime = t; KillDisableThread(); if ( disableEndTime > sys.getTime() ) { CreateDisableThread(); } UpdateDisabled(); } /* ===================== deployable_base::DeployableBase_CalculateDisabledState ===================== */ boolean deployable_base::DeployableBase_CalculateDisabledState() { boolean newDisabledState = false; if ( currentState != DS_NORMAL ) { newDisabledState = true; } else if ( disableEndTime > sys.getTime() ) { newDisabledState = true; } return newDisabledState; } /* ===================== deployable_base::CalculateDisabledState ===================== */ boolean deployable_base::CalculateDisabledState() { return DeployableBase_CalculateDisabledState(); } /* ===================== deployable_base::UpdateDisabled ===================== */ void deployable_base::UpdateDisabled() { SetDisabled( CalculateDisabledState() ); } /* ===================== deployable_base::IsDisabled ===================== */ boolean deployable_base::IsDisabled() { return disabledState; } /* ===================== deployable_base::SetDisabled ===================== */ void deployable_base::SetDisabled( boolean newDisabledState ) { if ( disabledState == newDisabledState ) { return; } disabledState = newDisabledState; if ( disabledState ) { OnDisabled(); FreeDisableTask(); } else { OnReEnabled(); if ( isSpotted() ) { killTaskRequestee = $null_entity; InitDisableTask( true ); } } } /* ===================== deployable_base::OnDisabled ===================== */ void deployable_base::OnDisabled() { sys.setCMIconShaderParm( commandMapHandle, 5, 0 ); if ( owner != $null_entity ) { if ( owner.isLocalPlayer() ) { sys.setGUIFloat( GUI_GLOBALS_HANDLE, "deployables.state", DS_DISABLED ); } } } /* ===================== deployable_base::OnReEnabled ===================== */ void deployable_base::OnReEnabled() { sys.setCMIconShaderParm( commandMapHandle, 5, 1 ); if ( owner != $null_entity ) { if ( owner.isLocalPlayer() ) { sys.setGUIFloat( GUI_GLOBALS_HANDLE, "deployables.state", DS_NORMAL ); } } } /* ===================== deployable_base::KillDisableThread ===================== */ void deployable_base::KillDisableThread() { sys.killThread( "DisableThread_" + getName() ); } /* ===================== deployable_base::CreateDisableThread ===================== */ void deployable_base::CreateDisableThread() { KillDisableThread(); thread DisableThread(); } /* ===================== deployable_base::DisableThread ===================== */ void deployable_base::DisableThread() { float delay = disableEndTime - sys.getTime(); if ( delay > 0.f ) { sys.wait( delay ); } sys.waitFrame(); sys.threadName( "DisableThreadDead" ); UpdateDisabled(); } /* ===================== deployable_base::DoBoundsDamageThread ===================== */ void deployable_base::DoBoundsDamageThread() { float dmgIndex = GetDamage( getKey( "dmg_falling" ) ); while ( 1 ) { vector mins = self.getAbsMins(); vector maxs = self.getAbsMaxs(); mins_z = mins_z - 64; //sys.debugBounds( g_colorRed, mins, maxs, 0 ); float count = self.entitiesInBounds( mins, maxs, MASK_SHOT_RENDERMODEL | MASK_SHOT_BOUNDINGBOX, 1 ); float index; for ( index = 0; index < count; index++ ) { entity other = self.getBoundsCacheEntity( index ); if ( other == self ) { continue; } if ( other != $null_entity ) { if ( self.touchesBounds( other ) ) { other.applyDamage( $null_entity, self, vec3_down, dmgIndex, 1.f, $null_entity ); if ( other.inCollection( "mcp" ) ) { SelfDestruct(); } } } } sys.waitFrame(); } } /* ===================== deployable_base::KillBoundsDamageThread ===================== */ void deployable_base::KillBoundsDamageThread() { sys.killThread( "DoBoundsDamageThread_" + getName() ); } /* ===================== deployable_base::vGetQuickChatString ===================== */ string deployable_base::vGetQuickChatString( entity p ) { if ( getEntityAllegiance( p ) == TA_FRIEND ) { return getKey( "contextmenu_quickchat_friendly" ); } return getKey( "contextmenu_quickchat_enemy" ); } /* ===================== deployable_base::vUpdateFiringStatusObject ===================== */ void deployable_base::vUpdateFiringStatusObject( entity localPlayer ) { if( fsStatus != $null ) { fsStatus.Update( localPlayer, $null, TARGET_LOCK_NOT_LOCKED, 0 ); sys.setGUIFloat( GUI_GLOBALS_HANDLE, "deployables.timerValue", fsStatus.timerStatus ); sys.setGUIFloat( GUI_GLOBALS_HANDLE, "deployables.guiState", fsStatus.guiStatus ); } } /* ===================== deployable_base::FlashCMIcon ===================== */ void deployable_base::FlashCMIcon( entity p, float requiredTeam ) { entity local = sys.getLocalViewPlayer(); if ( local == $null_entity ) { return; } if ( getEntityAllegiance( local ) == requiredTeam ) { float flags = sys.getCMIconFlags( commandMapHandle ); if ( requiredTeam == TA_ENEMY ) { flags = flags | CMF_ENEMYALWAYSKNOWN; } sys.flashCMIcon( commandMapHandle, -1, SPOTTED_FLASH_TIME, flags ); } }