using Opsive.Shared.Events;
using Opsive.Shared.Game;
using Opsive.UltimateCharacterController.Character;
using Opsive.UltimateCharacterController.Character.Abilities;
using Opsive.UltimateCharacterController.Items;
using Opsive.UltimateCharacterController.Items.Actions.PerspectiveProperties;
using Opsive.UltimateCharacterController.Traits;
using UnityEngine;
/// <summary>
/// The Suit Light Toggle ability allows the character toggle a light on their character on or off.
/// </summary>
[DefaultInputName("Flashlight")]
[DefaultStartType(AbilityStartType.ButtonDown)]
[DefaultStopType(AbilityStopType.Automatic)]
public class SuitLightToggle : Ability
{
[Tooltip("Is the ability a concurrent ability?")]
[SerializeField] protected bool m_ConcurrentAbility = true;
//[Tooltip("The name of the health attribute.")]
//[SerializeField] protected string m_HealthAttributeName = "Health";
[Tooltip("The battery attribute that should be modified when the flashlight is active.")]
[HideInInspector] [SerializeField] protected AttributeModifier m_BatteryModifier = new AttributeModifier("Battery", 0, Attribute.AutoUpdateValue.Decrease);
public AttributeModifier BatteryModifier { get { return m_BatteryModifier; } set { m_BatteryModifier = value; } }
private IFlashlightPerspectiveProperties m_FlashlightPerpectiveProperties;
protected ItemPerspectiveProperties m_ActivePerspectiveProperties;
protected ItemPerspectiveProperties m_FirstPersonPerspectiveProperties;
protected ItemPerspectiveProperties m_ThirdPersonPerspectiveProperties;
public bool ConcurrentAbility { get { return m_ConcurrentAbility; } set { m_ConcurrentAbility = value; } }
public override bool IsConcurrent { get { return m_ConcurrentAbility; } }
/// <summary>
/// Initialize the collider storage arrays.
/// </summary>
public override void Start()
{
base.Start();
m_CharacterLocomotion = m_GameObject.GetCachedComponent<UltimateCharacterLocomotion>();
Debug.Log(m_CharacterLocomotion.FirstPersonPerspective);
var perspectiveProperties = m_CharacterLocomotion.gameObject.GetComponents<ItemPerspectiveProperties>();
for (int i = 0; i < perspectiveProperties.Length; ++i) {
if (perspectiveProperties[i].FirstPersonItem) {
m_FirstPersonPerspectiveProperties = perspectiveProperties[i];
} else {
m_ThirdPersonPerspectiveProperties = perspectiveProperties[i];
}
}
m_ActivePerspectiveProperties = m_CharacterLocomotion.FirstPersonPerspective ? m_FirstPersonPerspectiveProperties : m_ThirdPersonPerspectiveProperties;
m_FlashlightPerpectiveProperties = m_ActivePerspectiveProperties as IFlashlightPerspectiveProperties;
if (m_BatteryModifier != null) {
if (m_BatteryModifier.Initialize(m_CharacterLocomotion.gameObject)) {
EventHandler.RegisterEvent(m_BatteryModifier.Attribute, "OnAttributeReachedDestinationValue", OnBatteryEmpty);
}
}
if (m_FlashlightPerpectiveProperties == null) {
m_FlashlightPerpectiveProperties = m_ActivePerspectiveProperties as IFlashlightPerspectiveProperties;
if (m_FlashlightPerpectiveProperties == null) {
Debug.LogError("Error: The First/Third Person Flashlight Item Properties component cannot be found ." +
"Ensure the component exists and the component's Action ID matches the Action ID )");
}
}
EventHandler.RegisterEvent<bool>(m_CharacterLocomotion.gameObject, "OnCharacterChangePerspectives", OnChangePerspectives);
}
/// <summary>
/// Called when the ablity is tried to be started. If false is returned then the ability will not be started.
/// </summary>
/// <returns>True if the ability can be started.</returns>
public override bool CanStartAbility()
{
// An attribute may prevent the ability from starting.
if (!base.CanStartAbility()) {
return false;
}
// The flashlight can't be used if there is no battery left.
if (m_BatteryModifier != null && !m_BatteryModifier.IsValid()) {
return false;
}
return true;
}
/// <summary>
/// The ability has started.
/// </summary>
protected override void AbilityStarted()
{
base.AbilityStarted();
//ToggleFlashlight(!m_FlashlightPerpectiveProperties.Light.activeSelf);
ToggleFlashlight(true);
}
/// <summary>
/// Can the ability be stopped?
/// </summary>
/// <returns>True if the ability can be stopped.</returns>
public override bool CanStopAbility()
{
return base.CanStopAbility();
}
/// <summary>
/// Called when another ability is attempting to start and the current ability is active.
/// Returns true or false depending on if the new ability should be blocked from starting.
/// </summary>
/// <param name="startingAbility">The ability that is starting.</param>
/// <returns>True if the ability should be blocked.</returns>
public override bool ShouldBlockAbilityStart(Ability startingAbility)
{
return false;
}
/// <summary>
/// Called when the current ability is attempting to start and another ability is active.
/// Returns true or false depending on if the active ability should be stopped.
/// </summary>
/// <param name="activeAbility">The ability that is currently active.</param>
public override bool ShouldStopActiveAbility(Ability activeAbility)
{
return false;
}
/// <summary>
/// The ability has stopped running.
/// </summary>
/// <param name="force">Was the ability force stopped?</param>
protected override void AbilityStopped(bool force)
{
AbilityStopped(force, true);
ToggleFlashlight(false);
}
/// <summary>
/// The ability has stopped running.
/// </summary>
/// <param name="force">Was the ability force stopped?</param>
/// <param name="resetStoredInputs">Should the capsule collider height be reset?</param>
protected void AbilityStopped(bool force, bool resetCapsuleColliderHeight)
{
base.AbilityStopped(force);
ToggleFlashlight(false);
}
/// <summary>
/// The flashlight battery is empty.
/// </summary>
private void OnBatteryEmpty()
{
AbilityStopped(true, false);
//ToggleFlashlight(false);
}
// <summary>
/// Activates or deactives the flashlight.
/// </summary>
/// <param name="active">Should the flashlight be activated?</param>
public void ToggleFlashlight(bool active)
{
m_FlashlightPerpectiveProperties.Light.SetActive(active);
#if ULTIMATE_CHARACTER_CONTROLLER_MULTIPLAYER
if (m_NetworkInfo != null) {
if (!m_NetworkInfo.IsLocalPlayer()) {
return;
}
m_NetworkCharacter.ToggleFlashlight(this, active);
}
#endif
if (m_BatteryModifier != null) {
m_BatteryModifier.EnableModifier(active);
}
}
/// <summary>
/// The character perspective between first and third person has changed.
/// </summary>
/// <param name="firstPersonPerspective">Is the character in a first person perspective?</param>
protected void OnChangePerspectives(bool firstPersonPerspective)
{
m_ActivePerspectiveProperties = firstPersonPerspective ? m_FirstPersonPerspectiveProperties : m_ThirdPersonPerspectiveProperties;
var active = m_FlashlightPerpectiveProperties.Light.activeSelf;
m_FlashlightPerpectiveProperties.Light.SetActive(false);
m_FlashlightPerpectiveProperties = m_ActivePerspectiveProperties as IFlashlightPerspectiveProperties;
if (active) {
m_FlashlightPerpectiveProperties.Light.SetActive(true);
}
}
}