using System; using System.Collections; using System.Collections.Generic; using System.Linq; using System.Runtime.Remoting; using BITKit; using BITKit.Entities; using BITKit.Pool; using Cysharp.Threading.Tasks; using Net.Project.B.Health; using Net.Project.B.Inventory; using Net.Project.B.Weapon; using NodeCanvas.Framework; using Project.B.Item; using UnityEngine; using UnityEngine.Rendering; namespace Project.B.CharacterController { public class PlayerModelController:IDisposable { private readonly IEntitiesService _entitiesService; private readonly Animator _animator; private readonly IPlayerInventory _playerInventory; private readonly IPlayerWeaponInventory _weaponInventory; private readonly IPlayerCharacterController _playerCharacterController; private readonly IHealthService _healthService; private readonly IBlackboard _blackboard; private readonly IEntity _entity; private readonly GameObject _gameObject; private readonly IPoolService _poolService; private readonly IFixedTicker _fixedTicker; private readonly ValidHandle _allowArm = new(); private readonly ValidHandle _allowModel = new(); private readonly Renderer[] _armMeshes; private Vector3 _savedVelocity; private readonly GameObject _parachuteModel; private readonly Dictionary _items; private GameObject PlayerModel =>_blackboard.GetVariable("player_model").value; public PlayerModelController(IBlackboard blackboard, IHealthService healthService, IEntity entity, IPlayerCharacterController playerCharacterController, IPlayerWeaponInventory weaponInventory, IPoolService poolService, GameObject gameObject, IFixedTicker fixedTicker, Animator animator, IPlayerInventory playerInventory, IEntitiesService entitiesService) { _blackboard = blackboard; _healthService = healthService; _entity = entity; _playerCharacterController = playerCharacterController; _weaponInventory = weaponInventory; _poolService = poolService; _gameObject = gameObject; _fixedTicker = fixedTicker; _animator = animator; _playerInventory = playerInventory; _entitiesService = entitiesService; playerCharacterController.AllowTpsCamera.AddListener(OnToggleTPSCamera); OnToggleTPSCamera(playerCharacterController.AllowTpsCamera.Allow); _parachuteModel = _blackboard.GetVariable("model_parachute")?.value; _armMeshes = _blackboard.GetVariable>("player_arm_model").value.ToArray(); _allowArm.AddListener(x => { foreach (var renderer in _armMeshes) { renderer.enabled = x; } }); _allowModel.AddListener(PlayerModel.SetActive); _allowModel.Invoke(); _fixedTicker.Add(OnTick); _healthService.OnHealthChanged += OnHealthChanged; _playerCharacterController.CharacterController.OnStateChanged += OnStateChanged; _playerCharacterController.DisableModel.AddListener(x=>_allowModel.SetDisableElements(1651,x)); _weaponInventory.StateMachine.OnStateChanged += OnWeaponChanged; OnStateChanged(null, playerCharacterController.CharacterController.CurrentState); _items = _entitiesService.QueryComponents().ToArray().ToDictionary(x => x.Id, x => x); } private void OnWeaponChanged(IPlayerWeaponController arg1, IPlayerWeaponController arg2) { _allowArm.SetElements(_weaponInventory,arg2 is not null); var disable = false; if (arg2 is not null && _playerInventory.Container is RuntimeItemContainer runtimeItemContainer && runtimeItemContainer.Items.TryGetValue(arg2.Identifier,out var item)) { if (_items.TryGetValue(item.ScriptableId, out var scriptableItem)) { if (scriptableItem.ControllerClass is PlayerHandheldControllerClass) { disable = true; } } } _allowArm.SetDisableElements(1231123,disable); } private void OnTick(float obj) { if (_playerCharacterController.CharacterController.CurrentState is not null) { _savedVelocity = _playerCharacterController.CharacterController.Velocity; } } private void OnStateChanged(ICharacterState arg1, ICharacterState arg2) { var hidePlayer = arg2 is ICharacterSeating { SeatNode: { HidePlayer: true } }; _allowModel.SetDisableElements(6415651568,hidePlayer); _allowArm.SetDisableElements(6415651568,hidePlayer); _allowModel.SetElements(_playerCharacterController, arg2 is not null); if(_parachuteModel) _parachuteModel.SetActive(arg2 is ICharacterParachute); if (_weaponInventory.StateMachine.CurrentState is null) _allowArm.SetElements(this, arg2 switch { ICharacterStateStepUp=>false, ICharacterStateCrouched => false, ICharacterKnocked => false, _ => true, }); } private async void OnHealthChanged(int arg1, int arg2, int arg3, object arg4) { if(arg1!=_entity.Id)return; _allowModel.SetDisableElements(_healthService,arg3<0); var _hipsGameObject = _animator.GetBoneTransform(HumanBodyBones.Hips).gameObject; if (arg3 >= 0) { _hipsGameObject.gameObject.SetActive(true); _blackboard.RemoveVariable("player_ragdoll"); } else { _hipsGameObject.gameObject.SetActive(false); var myRenderer = PlayerModel.GetComponentsInChildren(true).ToDictionary(x => x.name, x=>x); var ragdoll =await _poolService.Spawn("player_ragdoll"); ragdoll.transform.SetPositionAndRotation(_gameObject.transform.position, _gameObject.transform.rotation); var ragdollTransforms = ragdoll.GetComponentsInChildren().ToDictionary(x => x.name, x => x); foreach (var (name, sourceTransform) in _hipsGameObject.GetComponentsInChildren() .ToDictionary(x => x.name, x => x)) { if (ragdollTransforms.TryGetValue(name, out var targetTransform)) { targetTransform.position = sourceTransform.position; targetTransform.rotation = sourceTransform.rotation; } } var ragdollRenderer = ragdoll.GetComponentsInChildren().ToDictionary(x => x.name, x=>x); foreach (var (name,myMeshRenderer) in myRenderer) { if (ragdollRenderer.TryGetValue(name, out var ragdollMeshRenderer)) { ragdollMeshRenderer.material = myMeshRenderer.material; } } _blackboard.SetVariableValue("player_ragdoll", ragdoll); await UniTask.NextFrame(); if(!ragdoll)return; if (ragdoll.TryGetComponent(out var ragdollRigidbody) && ragdollRigidbody is {isKinematic:false}) { ragdollRigidbody.velocity = _savedVelocity; } } } private void OnToggleTPSCamera(bool obj) { foreach (var x in _blackboard.GetVariable>("fps_model").GetValue()) { x.enabled = !obj; } foreach (var x in _blackboard.GetVariable>("tps_model").GetValue()) { x.shadowCastingMode = obj ? ShadowCastingMode.On : ShadowCastingMode.ShadowsOnly; } } public void Dispose() { _healthService.OnHealthChanged -= OnHealthChanged; _fixedTicker.Remove(OnTick); } } }