class OdaEmergencyListener extends CustomValueStatPoolsListener { var m_owner : weak< NPCPuppet >; var m_healNumber : Int32; private var m_heal1HealthPercentage : Float; default m_heal1HealthPercentage = 70.f; private var m_heal2HealthPercentage : Float; default m_heal2HealthPercentage = 55.f; private var m_heal3HealthPercentage : Float; default m_heal3HealthPercentage = 40.f; private var m_heal4HealthPercentage : Float; default m_heal4HealthPercentage = 25.f; private var m_heal5HealthPercentage : Float; default m_heal5HealthPercentage = 10.f; public override function OnStatPoolValueChanged( oldValue : Float, newValue : Float, percToPoints : Float ) { CheckHPValue( oldValue, newValue, percToPoints ); } public function CheckHPValue( oldValue : Float, newValue : Float, percToPoints : Float ) { if( ( ( oldValue > m_heal1HealthPercentage ) && ( newValue <= m_heal1HealthPercentage ) ) && ( m_healNumber == 0 ) ) { SetRoamingBehaviorAuthorization(); } else if( ( ( oldValue > m_heal2HealthPercentage ) && ( newValue <= m_heal2HealthPercentage ) ) && ( m_healNumber == 1 ) ) { SetRoamingBehaviorAuthorization(); } if( ( ( oldValue > m_heal3HealthPercentage ) && ( newValue <= m_heal3HealthPercentage ) ) && ( m_healNumber == 2 ) ) { SetRoamingBehaviorAuthorization(); } else if( ( ( oldValue > m_heal4HealthPercentage ) && ( newValue <= m_heal4HealthPercentage ) ) && ( m_healNumber == 3 ) ) { SetRoamingBehaviorAuthorization(); } if( ( ( oldValue > m_heal5HealthPercentage ) && ( newValue <= m_heal5HealthPercentage ) ) && ( m_healNumber == 4 ) ) { SetRoamingBehaviorAuthorization(); } } public function SetRoamingBehaviorAuthorization() { m_healNumber += 1; StatusEffectHelper.ApplyStatusEffect( m_owner, T"Oda.Emergency", m_owner.GetEntityID() ); } } class OdaComponent extends ScriptableComponent { private var m_owner : weak< NPCPuppet >; private var m_owner_id : EntityID; private var m_odaAIComponent : AIHumanComponent; private var m_actionBlackBoard : weak< IBlackboard >; private var m_statPoolSystem : StatPoolsSystem; private var m_statPoolType : gamedataStatPoolType; private var m_healthListener : OdaEmergencyListener; private var m_statusEffect_emergency : TweakDBID; private var m_targetTrackerComponent : TargetTrackerComponent; private var m_weakspotDestroyed : Bool; private function OnGameAttach() { m_owner = ( ( NPCPuppet )( GetOwner() ) ); m_owner_id = m_owner.GetEntityID(); m_odaAIComponent = m_owner.GetAIControllerComponent(); m_actionBlackBoard = m_odaAIComponent.GetActionBlackboard(); m_statPoolSystem = GameInstance.GetStatPoolsSystem( m_owner.GetGame() ); m_healthListener = new OdaEmergencyListener; m_healthListener.SetValue( 70.0 ); m_healthListener.m_owner = m_owner; m_statPoolSystem.RequestRegisteringListener( m_owner_id, gamedataStatPoolType.Health, m_healthListener ); StatusEffectHelper.ApplyStatusEffect( m_owner, T"Oda.Masked", m_owner_id ); m_targetTrackerComponent = m_owner.GetTargetTrackerComponent(); m_statPoolSystem = GameInstance.GetStatPoolsSystem( m_owner.GetGame() ); m_weakspotDestroyed = false; } public function OnGameDetach() { m_statPoolSystem.RequestUnregisteringListener( m_owner_id, gamedataStatPoolType.Health, m_healthListener ); m_healthListener = NULL; } protected event OnDefeated( evt : DefeatedEvent ) { StatusEffectHelper.ApplyStatusEffect( m_owner, T"AdamSmasher.InvulnerableDefeated", m_owner_id ); } public function GetCombatTarget() : weak< NPCPuppet > { return ( ( weak< weak< NPCPuppet > > )( m_odaAIComponent.GetBehaviorArgument( 'CombatTarget' ) ) ); } protected event OnAIEvent( aiEvent : AIEvent ) { if( aiEvent.name == 'BladesOn' ) { GameObject.StartReplicatedEffectEvent( m_owner, 'blade_light_on' ); GameObject.BreakReplicatedEffectLoopEvent( m_owner, 'screen_swipe' ); } if( aiEvent.name == 'BladesOff' ) { GameObject.BreakReplicatedEffectLoopEvent( m_owner, 'blade_light_on' ); GameObject.StartReplicatedEffectEvent( m_owner, 'screen_swipe' ); } if( aiEvent.name == 'StealthMode' ) { GameObject.BreakReplicatedEffectLoopEvent( m_owner, 'screen_swipe' ); } } protected event OnStatusEffectApplied( evt : ApplyStatusEffectEvent ) { var tags : array< CName >; tags = evt.staticData.GameplayTags(); if( StatusEffectSystem.ObjectHasStatusEffect( m_owner, T"BaseStatusEffect.Defeated" ) ) { GameObject.BreakReplicatedEffectLoopEvent( m_owner, 'blade_light_on' ); } if( tags.Contains( 'BossSuicide' ) ) { StatusEffectHelper.ApplyStatusEffect( m_owner, T"BaseStatusEffect.SuicideWithWeapon", m_owner.GetEntityID() ); StatusEffectHelper.ApplyStatusEffect( m_owner, T"Sasquatch.ForceStaggerSuicide", m_owner_id ); } if( tags.Contains( 'BossGrenadeHackEffect' ) ) { StatusEffectHelper.ApplyStatusEffect( m_owner, T"BaseStatusEffect.OdaSuicideWithGrenade", m_owner_id ); } if( tags.Contains( 'WeakspotDestruction' ) ) { StatusEffectHelper.RemoveStatusEffect( m_owner, T"Oda.CloakedOda" ); StatusEffectHelper.RemoveStatusEffect( m_owner, T"Oda.Cloaked" ); } if( tags.Contains( 'OdaStatusEffect' ) ) { EvaluateAppearance(); } if( tags.Contains( 'Cloak' ) ) { ApplyBlockStaggerStatusEffect(); } if( tags.Contains( 'Heal' ) ) { RemoveBlockStaggerStatusEffect(); ApplyForceStaggerStatusEffect(); } if( tags.Contains( 'OdaStealthWrappers' ) ) { AnimationControllerComponent.SetAnimWrapperWeight( m_owner, 'OdaSearchingCustom', 1.0 ); } if( StatusEffectSystem.ObjectHasStatusEffect( m_owner, T"Oda.Main_boss_oda_allow_knockdown" ) ) { StatusEffectHelper.ApplyStatusEffect( m_owner, T"BaseStatusEffect.Knockdown", m_owner.GetEntityID() ); } } private function DestroyAllWeakspots() { var weakspots : array< weak< WeakspotObject > >; var scriptWeakspot : ScriptedWeakspotObject; var i : Int32; m_owner.GetWeakspotComponent().GetWeakspots( weakspots ); if( weakspots.Size() > 0 ) { for( i = 0; i < weakspots.Size(); i += 1 ) { scriptWeakspot = ( ( ScriptedWeakspotObject )( weakspots[ i ] ) ); scriptWeakspot.DestroyWeakspot( m_owner ); ScriptedWeakspotObject.Kill( weakspots[ i ] ); } } } protected event OnStatusEffectRemoved( evt : RemoveStatusEffect ) { var tags : array< CName >; tags = evt.staticData.GameplayTags(); if( tags.Contains( 'OdaStatusEffect' ) ) { EvaluateAppearance(); } if( tags.Contains( 'Cloak' ) ) { RemoveForceStaggerStatusEffect(); if( StatusEffectSystem.ObjectHasStatusEffect( m_owner, T"BaseStatusEffect.Cloaked_Exit" ) ) { PlayMalfunctionFX(); } GameObject.StartReplicatedEffectEvent( m_owner, 'exit_cloak' ); } if( evt.staticData.GetID() == T"Oda.Masked" ) { SetFactValue( m_owner.GetGame(), 'q112_oda_mask_destroyed', 1 ); } if( tags.Contains( 'OdaStealthWrappers' ) ) { AnimationControllerComponent.SetAnimWrapperWeight( m_owner, 'OdaSearchingCustom', 0.0 ); } if( tags.Contains( 'Madness' ) ) { StatusEffectHelper.ApplyStatusEffect( m_owner, T"BaseStatusEffect.SuicideWithWeapon", m_owner.GetEntityID() ); StatusEffectHelper.ApplyStatusEffect( m_owner, T"Sasquatch.ForceStaggerSuicide", m_owner_id ); } } protected event OnNonStealthQuickHackVictimEvent( evt : NonStealthQuickHackVictimEvent ) { NPCStatesComponent.AlertPuppet( m_owner ); } public function ApplyForceStaggerStatusEffect() { StatusEffectHelper.ApplyStatusEffect( m_owner, T"Oda.ForceStaggerOda", m_owner.GetEntityID() ); } public function ApplyBlockStaggerStatusEffect() { StatusEffectHelper.ApplyStatusEffect( m_owner, T"Oda.BlockStaggerOda", m_owner.GetEntityID() ); } public function RemoveForceStaggerStatusEffect() { StatusEffectHelper.RemoveStatusEffect( m_owner, T"Oda.ForceStaggerOda" ); } public function RemoveBlockStaggerStatusEffect() { StatusEffectHelper.RemoveStatusEffect( m_owner, T"Oda.BlockStaggerOda" ); } public function PlayMalfunctionFX() { GameObject.StartReplicatedEffectEvent( m_owner, 'hacks_cyberware_malfunction' ); } public function EvaluateAppearance() { if( !( StatusEffectSystem.ObjectHasStatusEffect( m_owner, T"Oda.Masked" ) ) ) { m_owner.ScheduleAppearanceChange( 'oda_oda_mask_damage' ); } else { m_owner.ScheduleAppearanceChange( 'oda_oda' ); } } protected event OnSmartBulletDeflectedEvent( evt : SmartBulletDeflectedEvent ) { SetFactValue( m_owner.GetGame(), 'q112_oda_mask_deflected_bullet', 1 ); } protected event OnHit( evt : gameHitEvent ) { if( StatusEffectSystem.ObjectHasStatusEffect( m_owner, T"Oda.Healing" ) ) { StatusEffectHelper.RemoveStatusEffect( m_owner, T"Oda.CloakedOda" ); StatusEffectHelper.RemoveStatusEffect( m_owner, T"Oda.Cloaked" ); } } protected event OnLookedAtEvent( evt : LookedAtEvent ) {} protected function OnDeactivate() {} protected event OnDamageDealt( evt : gameTargetDamageEvent ) { var weapon : weak< WeaponObject >; weapon = ScriptedPuppet.GetActiveWeapon( m_owner ); if( weapon && WeaponObject.IsOfType( weapon.GetItemID(), gamedataItemType.Cyb_MantisBlades ) ) { SetFactValue( m_owner.GetGame(), 'q112_oda_dealt_damage_with_mantis', 1 ); } } }