Files
vampire-like/Assets/GameMain/Scripts/Runtime/EntityLogic/Player.cs
T

248 lines
7.4 KiB
C#

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;
/// <summary>
/// 当前金币。
/// </summary>
private int _coin;
/// <summary>
/// 当前经验。
/// </summary>
private int _exp;
/// <summary>
/// 每级所需的经验。
/// tip: _expRequires[1] 表示 Lv 0 -> Lv 1 需要的经验
/// </summary>
private int[] _expRequires;
/// <summary>
/// 当前的角色等级。
/// </summary>
private int _currentLevel;
/// <summary>
/// 玩家是否启用。
/// </summary>
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 IReadOnlyList<WeaponBase> Weapons => _backpackComponent.Weapons;
public IReadOnlyList<PropItem> 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<WeaponBase> 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.Modifiers)
{
_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, null, _healthComponent.DefenseStat, _healthComponent.DodgeStat);
}
protected override void OnInit(object userData)
{
base.OnInit(userData);
_inputComponent = GetComponent<InputComponent>();
_movementComponent = GetComponent<MovementComponent>();
_absorbComponent = GetComponent<AbsorbComponent>();
_statComponent = GetComponent<StatComponent>();
_backpackComponent = GetComponent<BackpackComponent>();
}
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, _statComponent);
_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
}
}