using System; using System.Collections.Generic; using System.Linq; using BITFALL.Cosmetic; using BITFALL.Entities.Equipment; using BITFALL.Player.Movement; using BITKit.PlayerCamera; using UnityEngine; using UnityEngine.Rendering; namespace BITKit.Entities.Player.Character { public class EntityCharacter : EntityPlayerBehavior { [DictionaryReferenceConfig(nameof(Player_Mesh_Type_FPV))] public const string Player_Mesh_Type_FPV = nameof(Player_Mesh_Type_FPV); [DictionaryReferenceConfig(nameof(Player_Mesh_Type_TPV))] public const string Player_Mesh_Type_TPV = nameof(Player_Mesh_Type_TPV); [DictionaryReferenceConfig(nameof(Player_Mesh_Type_FPVOverride))] public const string Player_Mesh_Type_FPVOverride = nameof(Player_Mesh_Type_FPVOverride); [DictionaryReferenceConfig(nameof(Player_Mesh_Type_TPV_Group))] public const string Player_Mesh_Type_TPV_Group = nameof(Player_Mesh_Type_TPV_Group); private readonly List fpvRenderer = new(); private readonly List tpvRenderer = new(); private readonly List fpvOverrideRenderers = new(); private readonly List tpvRendererGroup = new(); [Header(Constant.Header.Reference)] [SerializeReference, SubclassSelector] public IReference getDamage; [Inject(true)] private ICosmeticService cosmeticService; [Inject(true)] private IHealth _health; [Inject(true)] private IPlayerCameraService _cameraService; [Inject(true)] private IEntityOverride _entityOverride; [Inject(true)] private IEntityEquipment _equipment; [Inject(true)] private IEntityMovement _movement; private Renderer[] _tpvRendererGroup; private readonly ValidHandle allowFPVOverride = new(); public override void OnAwake() { base.OnAwake(); if(cosmeticService is not null) cosmeticService.OnCosmeticsChanged += Rebuild; } public override void OnStart() { if (_health is not null) { _health.OnSetAlive += _ => UpdateMeshState(); _health.OnDamageRelease += OnDamageRelease; } if (_cameraService is not null) _cameraService.OnCameraActivated += _ => UpdateMeshState(); if (_entityOverride is not null) _entityOverride.OnOverride += _ => { UpdateMeshState(); allowFPVOverride.SetElements(_entityOverride,_); }; _tpvRendererGroup = tpvRendererGroup.SelectMany(x => x.GetComponentsInChildren(true)).ToArray(); if (_equipment is not null) { _equipment.OnEquipAddressable += _ => { allowFPVOverride.RemoveElement(_equipment); }; _equipment.OnUnEquipAddressable += _ => { allowFPVOverride.AddElement(_equipment); }; } if (_movement is not null) { _movement.OnStateChanged += OnNewState; OnNewState(null,_movement.CurrentState); void OnNewState(IEntityMovementState oldState, IEntityMovementState newState) { allowFPVOverride.SetDisableElements(_movement, newState switch { IPlayerEdgeClimbState => false, IPlayerClimbState => false, IPlayerVaultState => false, IPlayerKnockdownState => false, IPlayerSlideState => false, IPlayerFixedState => false, IPlayerLinkState => false, _ => true, }); } } allowFPVOverride.AddListener(value => { foreach (var x in fpvOverrideRenderers) { x.enabled = value; } }); allowFPVOverride.AddElement(_equipment); Rebuild(); } public override void OnPlayerInitialized() { UpdateMeshState(); } public override void OnPlayerDispose() { SetFPV(false); } // private void OnSetHP(int hp) // { // UnityEntity.Invoke(Constant.Animation.Play, getDamage.Value); // } private void OnDamageRelease(DamageMessage damageMessage) { UnityEntity.Invoke(Constant.Animation.Play, getDamage.Value); } private void UpdateMeshState() { switch (_health, _cameraService) { case (null, null): SetFPV(true); break; case (null, not null): SetFPV(_cameraService.IsCameraActivated); break; case (not null, null): SetFPV(_health.IsAlive); break; case (not null, not null): SetFPV(_health.IsAlive && _cameraService.IsCameraActivated); break; } allowFPVOverride.Invoke(); } private void SetFPV(bool isFpv) { var shadowMode = isFpv ? ShadowCastingMode.ShadowsOnly : ShadowCastingMode.On; foreach (var x in fpvRenderer) { x.enabled = isFpv; } foreach (var x in tpvRenderer) { x.shadowCastingMode = shadowMode; } foreach (var x in _tpvRendererGroup) { x.shadowCastingMode = _entityOverride is not null ? _entityOverride.IsOvering ? ShadowCastingMode.On : shadowMode : shadowMode; } } [BIT] private void Rebuild() { fpvRenderer.Clear(); tpvRenderer.Clear(); fpvOverrideRenderers.Clear(); tpvRendererGroup.Clear(); foreach (var _tag in GetComponentsInChildren(true)) { if (_tag.TryGetComponent(out var _renderer) is false) continue; var tags = _tag.GetTags(); if (tags.Contains(Player_Mesh_Type_FPV)) fpvRenderer.Add(_renderer); if (tags.Contains(Player_Mesh_Type_TPV)) tpvRenderer.Add(_renderer); if (tags.Contains(Player_Mesh_Type_FPVOverride)) fpvOverrideRenderers.Add(_renderer); if (tags.Contains(Player_Mesh_Type_TPV_Group)) tpvRendererGroup.Add(_renderer); } UpdateMeshState(); allowFPVOverride.Invoke(); } } }