using System.Collections.Generic; using System.Threading; using Cysharp.Threading.Tasks; using SepCore.Components; using SepCore.Event; using SepCore.Definition; using SepCore.Entity; using SepCore.CustomUtility; using SepCore.AsyncTask; namespace SepCore.Entity { public class Player : TargetableObject { protected override TargetableObjectData _targetableObjectData => _playerData; private InputComponent _inputComponent; private MovementComponent _movementComponent; private AbsorbComponent _absorbComponent; private StatComponent _statComponent; private BackpackComponent _backpackComponent; private PlayerData _playerData; /// /// 当前金币。 /// private int _coin; /// /// 当前经验。 /// private int _exp; /// /// 每级所需的经验。 /// tip: _expRequires[1] 表示 Lv 0 -> Lv 1 需要的经验 /// private int[] _expRequires; /// /// 当前的角色等级。 /// private int _currentLevel; /// /// 玩家是否启用。 /// private bool _enable; private bool _weaponEnabled = true; public int Coin { get => _coin; set { GameEntry.Event.Fire(this, PlayerCoinChangeEventArgs.Create(value - _coin, value)); _coin = value; } } public int Exp { get => _exp; set { if (_currentLevel + 1 < _expRequires.Length && value >= _expRequires[_currentLevel + 1]) { value -= _expRequires[_currentLevel + 1]; _currentLevel++; PendingLevelPoints++; GameEntry.Event.Fire(this, PlayerLevelUpEventArgs.Create()); } int requiredExp = _currentLevel + 1 < _expRequires.Length ? _expRequires[_currentLevel + 1] : _expRequires[^1]; GameEntry.Event.Fire(this, PlayerExpChangeEventArgs.Create(value, requiredExp)); _exp = value; } } public int CurrentLevel => _currentLevel; public int PendingLevelPoints { get; set; } public StatComponent StatComponent => _statComponent; public IReadOnlyList Weapons => _backpackComponent.Weapons; public IReadOnlyList Props => _backpackComponent.Props; public int WeaponCapacity => _backpackComponent.WeaponCapacity; public bool AddProp(PropItem prop) { if (prop == null) return false; return _backpackComponent.AttachProp(prop); } public async UniTask AddWeaponAsync(WeaponData weaponData, float? timeout = null) { if (weaponData == null) { return null; } float actualTimeout = timeout ?? (GameEntry.Luban.Global.EntityAsyncTimeout / 1000f); WeaponBase weapon = await GameEntry.Entity.ShowWeaponAsync(weaponData, actualTimeout); if (weapon == null) { return null; } if (!_backpackComponent.AttachWeapon(weapon)) { GameEntry.Entity.HideEntity(weapon); return null; } return weapon; } public bool RemoveWeapon(WeaponBase weapon) { if (weapon == null) { return false; } if (!_backpackComponent.DetachWeapon(weapon)) { return false; } GameEntry.Entity.HideEntity(weapon); return true; } public bool Enable { get => _enable; set { if (value == _enable) return; _enable = value; _movementComponent.SetMove(value); _backpackComponent.SetWeaponState(value && _weaponEnabled); _inputComponent.SetListening(value); } } public bool WeaponEnabled => _weaponEnabled; public void SetWeaponEnabled(bool enabled) { _weaponEnabled = enabled; _backpackComponent.SetWeaponState(_enable && _weaponEnabled); } public void InitRole(RoleConfig role, LevelExperienceConfig expConfig) { // MovementComponent _movementComponent.OnInit(role.Speed, this.CachedTransform, _statComponent); _movementComponent.SetMove(true); // HealthComponent _healthComponent.OnInit(role.MaxHealth, _statComponent); // BackpackComponent Coin = role.Coin; _backpackComponent.OnInit(this); AddWeaponAsync(EntityDataFactory.Create(GameEntry.Entity.NextId(), WeaponType.Knife, Id, _playerData.Camp)).Forget(); // StatComponent foreach (var modifier in role.StatModifierConfigs) { _statComponent.AddModifier(modifier); } _expRequires = expConfig.ToTargetLevelArray(); // Fire Events GameEntry.Event.Fire(this, PlayerHealthChangeEventArgs.Create(0, _healthComponent.CurrentHealth, _healthComponent.MaxHealth)); GameEntry.Event.Fire(this, PlayerExpChangeEventArgs.Create(0, _expRequires[1])); GameEntry.Event.Fire(this, PlayerCoinChangeEventArgs.Create(Coin, Coin)); } #region FSM public override ImpactData GetImpactData() { return new ImpactData(_playerData.Camp, 0, _statComponent.Pipeline); } protected override void OnInit(object userData) { base.OnInit(userData); _inputComponent = GetComponent(); _movementComponent = GetComponent(); _absorbComponent = GetComponent(); _statComponent = GetComponent(); _backpackComponent = GetComponent(); } protected override void OnShow(object userData) { base.OnShow(userData); _statComponent.OnInit(); if (userData is PlayerData playerData) { _playerData = playerData; } _inputComponent.OnInit(); _inputComponent.SetListening(true); _absorbComponent.OnInit(this); _weaponEnabled = true; _currentLevel = 0; } protected override void OnUpdate(float elapseSeconds, float realElapseSeconds) { base.OnUpdate(elapseSeconds, realElapseSeconds); _movementComponent.SetDirection(_inputComponent.Direction); _absorbComponent.OnUpdate(elapseSeconds, realElapseSeconds); } protected override void OnHide(bool isShutdown, object userData) { _inputComponent.OnReset(); _movementComponent.OnReset(); _healthComponent.OnReset(); _statComponent.OnReset(); _backpackComponent.OnReset(); _absorbComponent.OnReset(); base.OnHide(isShutdown, userData); } #endregion } }