Script:Files:script/deployables/mount.script
From Mod Wiki
object weapon_mount; object weapon_mounted; // ------------------------------------------------- // ------------------------------------------------- // Weapon mount point // ------------------------------------------------- object weapon_mount { void preinit(); void init(); void destroy(); void Idle(); void IdleEmpty(); void GoToIdle(); void OnBrokenChanged(); void OnWeaponDestroyed(); void OnWeaponRepaired(); void UpdateAngles( vector angles ); void vOnCockpitCreated(); void vOnCockpitDestroyed(); float OnUsed( entity p, float distance ); void OnEnter( entity user ); void OnExit( entity user ); void OnMountedWeaponSynced(); float OnUpdateCrosshairInfo( entity p ); float OnActivate( entity p, float distance ); void OnPostThink(); void Use( entity user ); boolean CanUse( entity user, boolean printToolTips ); void SetController( entity user ); void vRepair( float count, entity p ); boolean vCheckActionCode( entity p, float actionCode ); float vGetPliersProgressBarValue( float action ); void syncFields(); void BroadcastToolTip( entity user, float tip ); void vSetConstructed( boolean a ); void OnConstructedChanged(); float GetActivateCode( entity p, float distance ); string vGetQuickChatString( entity p ); void vOnContextDestroy( entity p ); void vOnContextConstruct( entity p ); float invalidWeaponToolTip; float invalidPlayerToolTip; float alreadyInUseToolTip; weapon_mounted mountedWeapon; float mountJoint; entity controller; boolean constructed; boolean broken; flashpoint_obj flashpoint; } // ------------------------------------------------- object weapon_mounted { void preinit(); void init(); void destroy(); void Idle(); void IdleEmpty(); void Fire(); void OnKilled( entity inflictor, entity attacker, float damage, vector direction, float location ); float OnUpdateCrosshairInfo( entity p ); float OnUsed( entity p, float distance ); float OnActivate( entity p, float distance ); void ShowBar( boolean s ); void SetBarValue( float v ); void vSetOwner( entity o ); // owner is the player directing the view and firing void vSetParent( entity p ); // parent is the base we're bound to boolean vCheckActionCode( entity p, float actionCode ); void vRepair( float count, entity p ); float vGetPliersProgressBarValue( float action ); void OnPostThink() { ; } void PlayBrokenAnim(); void PlayRepairedAnim(); void PlayLowerAnim(); void PlayRaiseAnim(); boolean NeedsRepair(); void GoToIdle(); float GetActivateCode( entity p, float distance ); float projectileIndex; float muzzleJoint; float fireRate; float spread; float reFireTime; float nextFire; float fireUsageRate; float fireReChargeTime; player playerEntity; float charge; float fireLowerBound; float fireLowerBoundDelay; weapon_mount parent; base_bar displayBar; handle objectName; handle GetObjectNameHandle() { return objectName; } string vGetQuickChatString( entity p ) { return parent.vGetQuickChatString( p ); } void vOnContextDestroy( entity p ) { parent.vOnContextDestroy( p ); } void vOnContextConstruct( entity p ) { parent.vOnContextConstruct( p ); } } void weapon_mounted::preinit() { displayBar = new base_bar; projectileIndex = GetEntityDef( getKey( "def_projectile" ) ); muzzleJoint = getJointHandle( getKey( "muzzle" ) ); if ( muzzleJoint == -1 ) { sys.error( "weapon_mounted::preinit invalid muzzle joint" ); } fireRate = getFloatKey( "fire_rate" ); spread = getFloatKey( "spread" ); if ( !getIntKey( "fire_notime" ) ) { fireUsageRate = getFloatKey( "fire_charge" ) / 100.f; fireReChargeTime = 1 / getFloatKey( "recharge_time" ); } else { fireUsageRate = 1.f; fireReChargeTime = fireRate; } addHelper( GetStringMap( getKey( "str_playerik" ) ) ); fireLowerBound = getFloatKey( "fire_lower_bound" ); fireLowerBoundDelay = getFloatKey( "fire_lower_bound_delay" ); charge = 1.0f; objectName = sys.localizeString( getKey( "object_name" ) ); } void weapon_mounted::init() { PlayLowerAnim(); GoToIdle(); } void weapon_mounted::GoToIdle() { if ( playerEntity != $null_entity ) { setState( "Idle" ); } } void weapon_mounted::destroy() { delete displayBar; } void weapon_mounted::ShowBar( boolean s ) { displayBar.ShowBar( s ); } void weapon_mounted::SetBarValue( float v ) { displayBar.SetBarValue( v ); } void weapon_mounted::vSetOwner( entity o ) { if ( playerEntity == sys.getLocalPlayer() && playerEntity != $null_entity ) { ShowBar( 0 ); } setIKTarget( o, 0 ); playerEntity = o; if ( playerEntity != $null_entity ) { playerEntity.proxyFiringWeapon = false; playerEntity.proxyFiringWeaponStart = false; } displayBar.SetOwner( o ); if ( playerEntity == sys.getLocalPlayer() && playerEntity != $null_entity ) { ShowBar( 1 ); if ( getFloatKey( "option_crosshair_interface" ) ) { sys.setGUIString( GUI_GLOBALS_HANDLE, "gameHud.weaponCrosshair", getKey( "crosshair" ) ); } sys.setGUIFloat( GUI_GLOBALS_HANDLE, "weapons.energySegments", 1 ); } GoToIdle(); } void weapon_mounted::vSetParent( entity p ) { parent = p; } void weapon_mounted::OnKilled( entity inflictor, entity attacker, float damage, vector direction, float location ) { parent.OnWeaponDestroyed(); setTakesDamage( false ); } void weapon_mounted::IdleEmpty() { } void weapon_mounted::PlayBrokenAnim() { playAnim( ANIMCHANNEL_ALL, "damaged" ); playEffect( "fx_damaged", "origin", true ); } void weapon_mounted::PlayRepairedAnim() { playAnim( ANIMCHANNEL_ALL, "repaired" ); stopEffect( "fx_damaged" ); } void weapon_mounted::PlayLowerAnim() { playAnim( ANIMCHANNEL_ALL, "lower" ); stopEffect( "fx_damaged" ); } void weapon_mounted::PlayRaiseAnim() { playAnim( ANIMCHANNEL_ALL, "raise" ); stopEffect( "fx_damaged" ); } void weapon_mounted::Idle() { while( true ) { sys.waitFrame(); boolean wantAttack = false; if ( playerEntity != $null_entity ) { wantAttack = playerEntity.getButton( PK_ATTACK ); } else { if ( charge == 1.f ) { setState( "IdleEmpty" ); } } float now = sys.getTime(); if ( playerEntity != $null_entity ) { playerEntity.proxyFiringWeaponStart = false; } if ( now >= nextFire && wantAttack ) { if ( playerEntity != $null_entity ) { playerEntity.proxyFiringWeaponStart = true; } if ( now >= reFireTime ) { Fire(); charge = charge - fireUsageRate; if ( charge <= fireLowerBound ) { startSound( "snd_overheat", SND_WEAPON_SIG ); nextFire = now + fireLowerBoundDelay; } if ( charge < 0 ) { charge = 0.f; } } } boolean recharge = true; if ( playerEntity != $null_entity ) { recharge = !playerEntity.proxyFiringWeaponStart; } if ( recharge ) { charge = charge + ( sys.getFrameTime() * fireReChargeTime ); if ( charge > 1.f ) { charge = 1.f; } } SetBarValue( charge ); } } void weapon_mounted::Fire() { if ( playerEntity != $null_entity ) { vector origin = playerEntity.getViewOrigin(); vector forward = sys.angToForward( playerEntity.getRenderViewAngles() ); launchBullet( playerEntity, self, projectileIndex, spread, origin, forward, TRACER_CHANCE, true ); } if ( !isHidden() ) { playJointEffect( "fx_muzzle_flash", muzzleJoint, 0 ); } playJointEffect( "fx_muzzle_tracer", muzzleJoint, 0 ); playJointEffect( "fx_muzzle_sound", muzzleJoint, 0 ); startSound( "snd_fire", SND_WEAPON_FIRE ); startSound( "snd_fire_far", SND_WEAPON_FIRE_FAR ); startSound( "snd_fire_local", SND_WEAPON_FIRE_LOCAL ); reFireTime = sys.getTime() + fireRate; } float weapon_mounted::OnUsed( entity p, float distance ) { return parent.OnUsed( p, distance ); } float weapon_mounted::OnActivate( entity p, float distance ) { return parent.OnActivate( p, distance ); } float weapon_mounted::OnUpdateCrosshairInfo( entity p ) { return parent.OnUpdateCrosshairInfo( p ); } void weapon_mounted::vRepair( float count, entity p ) { float maxHealth = getMaxHealth(); float health = getHealth(); if ( health < 0 ) { health = 0; } float lost = maxHealth - health; if ( count >= lost ) { count = lost; parent.OnWeaponRepaired(); } team_base team = p.getGameTeam(); if ( team != $null_entity ) { team.GiveRepairProficiency( p, $null_entity, count ); } float total = health + count; setHealth( total ); setTakesDamage( true ); } boolean weapon_mounted::vCheckActionCode( entity p, float actionCode ) { if ( actionCode == AC_REPAIR ) { if ( getEntityAllegiance( p ) != TA_FRIEND ) { return false; } return getHealth() < getMaxHealth(); } return false; } boolean weapon_mounted::NeedsRepair() { return getHealth() < getMaxHealth(); } float weapon_mounted::vGetPliersProgressBarValue( float action ) { if ( action == AC_REPAIR ) { return getHealth() / getMaxHealth(); } return 0.f; } float weapon_mounted::GetActivateCode( entity p, float distance ) { return parent.GetActivateCode( p, distance ); } // ================================================== void weapon_mount::syncFields() { syncBroadcast( "mountedWeapon" ); syncBroadcast( "constructed" ); syncBroadcast( "broken" ); syncCallback( "mountedWeapon", "OnMountedWeaponSynced" ); syncCallback( "constructed", "OnConstructedChanged" ); syncCallback( "broken", "OnBrokenChanged" ); } void weapon_mount::OnMountedWeaponSynced() { if ( mountedWeapon != $null_entity ) { mountedWeapon.vSetParent( self ); mountedWeapon.vSetOwner( controller ); if ( !constructed ) { mountedWeapon.hide(); } else { mountedWeapon.show(); if ( broken ) { mountedWeapon.PlayBrokenAnim(); } else { mountedWeapon.PlayLowerAnim(); } } } } void weapon_mount::preinit() { constructed = true; invalidWeaponToolTip = GetToolTip( getKey( "tt_invalid_weapon" ) ); invalidPlayerToolTip = GetToolTip( getKey( "tt_invalid_player" ) ); alreadyInUseToolTip = GetToolTip( getKey( "tt_already_in_use" ) ); string mountLocation = getKey( "mount_joint_weapon" ); mountJoint = getJointHandle( mountLocation ); if ( mountJoint == -1 ) { sys.error( "weapon_mount::preinit invalid joint " + mountLocation ); } string teamName = getKey( "start_team" ); if ( teamName == "" ) { sys.error( "weapon_mount::preinit no team specified" ); } setGameTeam( sys.getTeam( teamName ) ); } void weapon_mount::init() { sys.waitFrame(); string autoMount = getKey( "def_automount" ); if ( autoMount == "" ) { sys.error( "weapon_mount::init no mount specified" ); } if ( !sys.isClient() ) { mountedWeapon = sys.spawn( autoMount ); mountedWeapon.setOrigin( getJointPos( mountJoint ) ); mountedWeapon.vSetParent( self ); mountedWeapon.setGameTeam( getGameTeam() ); if ( !constructed ) { mountedWeapon.hide(); } } GoToIdle(); } void weapon_mount::destroy() { vSetOwner( $null_entity ); if ( flashpoint != $null ) { delete flashpoint; } } void weapon_mount::BroadcastToolTip( entity user, float tip ) { if ( tip != -1 ) { sys.broadcastToolTip( tip, user, wstr_empty, wstr_empty, wstr_empty, wstr_empty ); } else { sys.warning( "weapon_mount::BroadcastToolTip: invalid tooltip" ); } } void weapon_mount::GoToIdle() { if ( controller == $null_entity ) { setState( "IdleEmpty" ); } else { setState( "Idle" ); } } void weapon_mount::UpdateAngles( vector angles ) { if ( mountedWeapon != $null_entity ) { mountedWeapon.setAngles( angles ); mountedWeapon.forceRunPhysics(); } } void weapon_mount::IdleEmpty() { UpdateAngles( getAngles() ); } void weapon_mount::Idle() { } void weapon_mount::OnPostThink() { if ( controller != $null_entity ) { UpdateAngles( sys.rotateAngles( controller.getViewAngles(), getAngles() ) ); } } boolean weapon_mount::CanUse( entity user, boolean printToolTips ) { if ( broken ) { return false; } if ( controller != $null_entity ) { if( printToolTips ) { BroadcastToolTip( user, alreadyInUseToolTip ); } return false; } if( getEntityAllegiance( user ) == TA_ENEMY ) { if( printToolTips ) { BroadcastToolTip( user, invalidPlayerToolTip ); } return false; } vector dist = getWorldOrigin() - user.getWorldOrigin(); float lengthSqr = sys.vecLengthSquared( dist ); if( lengthSqr > ( 128 * 128 )) { return false; } // keep players from using a mounted weapon from the wrong side dist_z = 0; dist = sys.vecNormalize( dist ); vector myAngles = getWorldAxis( 0 ); myAngles_z = 0; myAngles = sys.vecNormalize( myAngles ); float dot = dist * myAngles; if ( dot < 0.75 ) { return false; } return true; } void weapon_mount::Use( entity user ) { entity team = user.getGameTeam(); if ( team == $null_entity ) { return; } user.enter( self ); } void weapon_mount::SetController( entity user ) { if ( controller == user ) { return; } controller = user; if ( mountedWeapon != $null_entity ) { mountedWeapon.vSetOwner( controller ); } GoToIdle(); } float weapon_mount::OnUsed( entity p, float distance ) { if ( broken ) { return 0.f; } entity other = p.getProxyEntity(); if ( other != $null_entity ) { sys.assert( self == other ); if ( !sys.isClient() ) { removeBoundPlayer( p ); } return 1.f; } if ( !CanUse( p, true ) ) { return 1.f; } if ( !sys.isClient() ) { Use( p ); } return 1.f; } void weapon_mount::OnEnter( entity user ) { if ( user.isDisguised() ) { user.disguise( $null_entity ); } mountedWeapon.PlayRaiseAnim(); SetController( user ); user.vHideNormalChargeBar( true ); } void weapon_mount::OnExit( entity user ) { if ( !broken ) { mountedWeapon.PlayLowerAnim(); } SetController( $null_entity ); user.vHideNormalChargeBar( false ); } float weapon_mount::OnUpdateCrosshairInfo( entity p ) { if ( isHidden() ) { return 0.f; } if ( mountedWeapon == $null_entity ) { return 0.f; } if ( controller == p ) { return 0.f; } if ( sys.getLocalPlayer() == $null_entity ) { return 1.f; } chSetNumLines( 0 ); float distance = chGetDistance(); float range = InchesToMetres( distance ); float allegiance = getEntityAllegiance( p ); vector color = GetAllegianceColor( allegiance ); float index; // see if theres a valid action to perform float code = GetActivateCode( p, distance ); if ( code != AK_NONE && p.vHasActionItem( code ) ) { index = chAddLine(); chSetLineMaterial( index, p.vGetActionIcon( code ) ); chSetLineType( index, CI_IMAGE ); chSetLineSize( index, 64, 64 ); chSetLineColor( index, g_colorWhite, 0.9f ); } if ( range < 25 ) { index = chAddLine(); chSetLineTextIndex( index, mountedWeapon.GetObjectNameHandle() ); chSetLineColor( index, color, 1.f ); chSetLineType( index, CI_TEXT ); chSetLineSize( index, 0, 0 ); index = chAddLine(); chSetLineColor( index, color, 0.5f ); chSetLineType( index, CI_BAR ); chSetLineFraction( index, mountedWeapon.getHealth() / mountedWeapon.getMaxHealth() ); chSetLineSize( index, 150, CROSSHAIR_INFO_BAR_HEIGHT ); } return 1.f; } float weapon_mount::OnActivate( entity p, float distance ) { if ( distance > 128.f ) { return 0.f; } if ( p.getViewingEntity() != p ) { return 0.f; } player other = p; float allegiance = getEntityAllegiance( p ); if ( allegiance == TA_FRIEND ) { if ( mountedWeapon.getHealth() < mountedWeapon.getMaxHealth() ) { p.setWeapon( p.vGetActionItem( AK_REPAIR ), 0 ); } } return 1.f; } void weapon_mount::vRepair( float count, entity p ) { if ( mountedWeapon != $null_entity ) { mountedWeapon.vRepair( count, p ); } } boolean weapon_mount::vCheckActionCode( entity p, float actionCode ) { if ( mountedWeapon != $null_entity ) { return mountedWeapon.vCheckActionCode( p, actionCode ); } return false; } float weapon_mount::vGetPliersProgressBarValue( float action ) { if ( mountedWeapon != $null_entity ) { return mountedWeapon.vGetPliersProgressBarValue( action ); } return 0.f; } void weapon_mount::vSetConstructed( boolean a ) { constructed = a; OnConstructedChanged(); } void weapon_mount::OnConstructedChanged() { if ( constructed ) { show(); if ( mountedWeapon != $null_entity ) { mountedWeapon.show(); } forceEnableClip(); if ( !sys.isClient() ) { objManager.setBotActionStateForEvent( ACTION_STATE_GUN_READY, self ); //mal: the weapon is repaired } } else { broken = false; OnBrokenChanged(); hide(); if ( mountedWeapon != $null_entity ) { mountedWeapon.hide(); mountedWeapon.setHealth( mountedWeapon.getMaxHealth() ); } forceDisableClip(); } } float weapon_mount::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_FRIEND ) { if ( p.vHasActionItem( AK_REPAIR ) ) { if ( mountedWeapon.NeedsRepair() ) { return AK_REPAIR; } } } } if ( CanUse( p, false ) ) { return AK_USEVEHICLE; } return AK_NONE; } void weapon_mount::OnBrokenChanged() { if ( broken ) { if ( mountedWeapon != $null_entity ) { mountedWeapon.PlayBrokenAnim(); } } else { if ( mountedWeapon != $null_entity ) { mountedWeapon.PlayRepairedAnim(); } } } void weapon_mount::OnWeaponDestroyed() { broken = true; OnBrokenChanged(); if ( controller != $null_entity ) { controller.setProxyEntity( $null_entity, 0 ); // kick the player SetController( $null_entity ); } GoToIdle(); if ( !sys.isClient() ) { objManager.setBotActionStateForEvent( ACTION_STATE_GUN_DESTROYED, self ); //mal: the weapon is destroyed } } void weapon_mount::OnWeaponRepaired() { if ( !broken ) { return; } if ( !sys.isClient() ) { objManager.setBotActionStateForEvent( ACTION_STATE_GUN_READY, self ); //mal: the weapon is repaired } mountedWeapon.PlayRepairedAnim(); broken = false; } string weapon_mount::vGetQuickChatString( entity p ) { if ( getEntityAllegiance( p ) == TA_ENEMY ) { if ( !broken ) { return "quickchat/context/destroy/mg_nest"; } } else { if ( mountedWeapon.NeedsRepair() ) { return "quickchat/context/repair/mg_nest"; } } return ""; } void weapon_mount::vOnCockpitCreated() { mountedWeapon.hideInLocalView(); } void weapon_mount::vOnCockpitDestroyed() { mountedWeapon.showInLocalView(); } void weapon_mount::vOnContextDestroy( entity p ) { player local = sys.getLocalViewPlayer(); if ( local == $null_entity || p == $null_entity ) { return; } if ( flashpoint != $null ) { delete flashpoint; } flashpoint = new flashpoint_obj; flashpoint.SetOwner( self ); flashpoint.SetMaterial( getKey( "mtr_icon_flash_destroy" ) ); } void weapon_mount::vOnContextConstruct( entity p ) { player local = sys.getLocalViewPlayer(); if ( local == $null_entity || p == $null_entity ) { return; } if ( flashpoint != $null ) { delete flashpoint; } flashpoint = new flashpoint_obj; flashpoint.SetOwner( self ); flashpoint.SetMaterial( getKey( "mtr_icon_flash" ) ); }