This commit is contained in:
CortexCore
2023-10-20 19:31:12 +08:00
parent 5cd094ed9a
commit a160813262
1878 changed files with 630581 additions and 4485 deletions

View File

@@ -0,0 +1,18 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class EntitiesAnimationController : MonoBehaviour
{
// Start is called before the first frame update
void Start()
{
}
// Update is called once per frame
void Update()
{
}
}

View File

@@ -1,5 +1,5 @@
{
"name": "BITFALL.Entities",
"name": "BITFALL.Entities.Runtime",
"rootNamespace": "",
"references": [
"GUID:14fe60d984bf9f84eac55c6ea033a8f4",
@@ -11,7 +11,10 @@
"GUID:30cdc242b1ac6a944a460f4ab0b77b88",
"GUID:677cd05ca06c46b4395470200b1acdad",
"GUID:9e24947de15b9834991c9d8411ea37cf",
"GUID:84651a3751eca9349aac36a66bba901b"
"GUID:84651a3751eca9349aac36a66bba901b",
"GUID:f6155d9ae143f3949ac54e8355593d6c",
"GUID:b355af20142c0c541ba9588ab1d0f64e",
"GUID:ef0bb553b58b90b488bdbe8672e3be0b"
],
"includePlatforms": [],
"excludePlatforms": [],

View File

@@ -6,22 +6,29 @@ using BITKit.Animations;
using BITKit.Entities;
namespace BITFALL.Entites
{
public class EntityProxyCharacter : EntityComponent, IHealthCallback
public class EntityProxyCharacter : EntityComponent
{
public UnityAnimator animator;
[SerializeReference, SubclassSelector] public References _getDamage;
[SerializeField] private Optional<Collider> aliveCollider = new();
[Inject]
private IHealth _health;
public override void OnStart()
{
base.OnStart();
entity.RegisterCallback<IHealthCallback>(this);
_health.OnSetAlive += OnSetAlive;
_health.OnSetHealthPoint += OnSetHP;
}
public void OnSetAlive(bool alive)
{
if (aliveCollider.Allow)
aliveCollider.Value.enabled = alive;
}
public void OnSetHP(int hp)
{
if (_getDamage is null || animator is null) return;
animator.animator.Play(_getDamage,-1,0);
}
}

View File

@@ -5,7 +5,6 @@ using UnityEngine;
using BITKit;
using BITKit.Entities;
using UnityEngine.InputSystem;
using static UnityEditor.Progress;
using System.Diagnostics;
using System.Linq;
@@ -16,8 +15,6 @@ namespace BITFALL
/// </summary>
public interface IPlayerEquipSelector
{
event Action<IBasicItem> OnEquip;
event Action<IBasicItem> OnDeEquip;
event Action<IDictionary<int, IBasicItem>> OnUpdateEquip;
bool TryDeEquip(IBasicItem item);
}

View File

@@ -0,0 +1,20 @@
{
"name": "BITFALL.Entities.Inventory",
"rootNamespace": "",
"references": [
"GUID:14fe60d984bf9f84eac55c6ea033a8f4",
"GUID:709caf8d7fb6ef24bbba0ab9962a3ad0",
"GUID:677cd05ca06c46b4395470200b1acdad",
"GUID:f51ebe6a0ceec4240a699833d6309b23",
"GUID:ef0bb553b58b90b488bdbe8672e3be0b"
],
"includePlatforms": [],
"excludePlatforms": [],
"allowUnsafeCode": false,
"overrideReferences": false,
"precompiledReferences": [],
"autoReferenced": true,
"defineConstraints": [],
"versionDefines": [],
"noEngineReferences": false
}

View File

@@ -0,0 +1,12 @@
using System.Collections;
using System.Collections.Generic;
using BITKit;
using UnityEngine;
namespace BITFALL.Entities.Inventory
{
public interface IEntityInventory : IBasicItemContainer
{
bool UseItem(IBasicItem item);
}
}

View File

@@ -1,78 +0,0 @@
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using BITKit;
using System.Threading.Tasks;
using UnityEngine.UIElements;
using System.Text;
using BITKit.Entities;
using System.Linq;
using BITFALL.Player.Inventory;
namespace BITFALL
{
[CustomType(typeof(IPlayerInventory))]
public class PlayerInventory : EntityInventory,ISelectableCallback,IPlayerInventory
{
public override void OnStart()
{
base.OnStart();
entity.RegisterCallback<ISelectableCallback>(this);
}
/// <summary>咋整啊这个</summary>
void ISelectableCallback.OnActive(ISelectable selectable)
{
var trans = selectable.GetTransform();
if (trans.TryGetComponentAny<WorldableItem>(out var item))
{
if (Add(item.Pick()))
{
item.Picked();
}
}
else if(trans.TryGetComponentAny<IBasicItemContainer>(out _))
{
}
}
void ISelectableCallback.OnHover(ISelectable selectable)
{
}
void ISelectableCallback.OnInactive(ISelectable selectable)
{
}
public bool TryUseItem(IBasicItem item)
{
if (OnUseItem is null) return false;
if (!OnUseItem.CastAsFunc().Any(func => func.Invoke(item))) return false;
Remove(item);
return true;
}
public event Func<IBasicItem, bool> OnUseItem;
}
#if UNITY_EDITOR
[UnityEditor.CustomEditor(typeof(PlayerInventory))]
public class EntityPlayerInventoryInsepctor : BITInspector<PlayerInventory>
{
public override VisualElement CreateInspectorGUI()
{
FillDefaultInspector();
CreateSubTitle(Constant.Header.Debug);
var serializeLabel = root.Create<Label>();
StringBuilder stringBuilder = new StringBuilder();
foreach (var x in agent.GetItems())
{
stringBuilder.AppendLine($"{x.Id}@{x.Name}");
}
serializeLabel.text=stringBuilder.ToString();
return root;
}
}
#endif
}

View File

@@ -1,40 +0,0 @@
using System.Collections;
using System.Collections.Generic;
using BITKit;
using BITKit.Entities;
using UnityEngine;
#if GameDesigner && UNITY
namespace BITFALL
{
/// <summary>
/// 玩家背包服务
/// </summary>
public class PlayerInventoryService : MonoBehaviour
{
public bool ServerAddItem(IEntity entity,IBasicItem item)
{
var unityEntity = entity as Entity;
//如果获取到entity包括了物品容器背包组件
//在服务器上处理添加物品的行为
if (!unityEntity!.TryGetComponent<IBasicItemContainer>(out var inventory)) return false;
if (!inventory.Add(item)) return false;
RpcAddItem(entity, item);
return true;
}
public bool RpcAddItem(IEntity entity, IBasicItem item)
{
var unityEntity = entity as Entity;
//在客户端上处理添加物品的行为
if (unityEntity!.TryGetComponent<IBasicItemContainer>(out var inventory))
{
inventory.Add(item);
return true;
}
return false;
}
}
}
#endif

View File

@@ -14,7 +14,10 @@
"GUID:d525ad6bd40672747bde77962f1c401e",
"GUID:49b49c76ee64f6b41bf28ef951cb0e50",
"GUID:9354affc93e0f3e4a904785e7d4c0f59",
"GUID:ef0bb553b58b90b488bdbe8672e3be0b"
"GUID:ef0bb553b58b90b488bdbe8672e3be0b",
"GUID:f6155d9ae143f3949ac54e8355593d6c",
"GUID:d9ed46adfa0436d42b5f66480c967c74",
"GUID:f51ebe6a0ceec4240a699833d6309b23"
],
"includePlatforms": [],
"excludePlatforms": [],

View File

@@ -5,50 +5,117 @@ using UnityEngine;
using BITKit;
using BITKit.Entities;
using UnityEngine.InputSystem;
using static UnityEditor.Progress;
using System.Diagnostics;
using System.Linq;
using System.Threading.Tasks;
using BITFALL.Entities;
using BITFALL.Entities.Improvised;
using BITFALL.Player.Inventory;
using BITKit.Entities.Player;
using Cysharp.Threading.Tasks;
using JetBrains.Annotations;
using UnityEditor;
using UnityEngine.InputSystem.Interactions;
using Debug = UnityEngine.Debug;
namespace BITFALL
namespace BITFALL.Entities.Equipment
{
[CustomType(typeof(IPlayerEquipSelector))]
public class PlayerEquipSelector : EntityComponent,IEntityInventoryCallback,IPlayerEquipSelector
public class PlayerEquipSelector : EntityComponent,IPlayerEquipSelector
{
[Header(Constant.Header.Components)]
public EntityEquipment equipment;
[Header(Constant.Header.InternalVariables)]
private readonly Dictionary<int, IBasicItem> equips=new();
private IBasicItemContainer inventory;
public event Action<IBasicItem> OnEquip;
public event Action<IBasicItem> OnDeEquip;
public event Action<IDictionary<int, IBasicItem>> OnUpdateEquip;
[Inject(true)]
private IPlayerInventory _playerInventory;
[Inject]
private IBasicItemContainer _inventory;
[Inject(true)]
private IKnockdown _knockdown;
[Inject]
private IHealth _health;
private IBasicItem currentEquip;
[Inject(true)]
private IEntityEquipment _equipment;
[Inject(true)]
private ImprovisedServiceInterface _improvisedService;
private readonly DoubleBuffer<IBasicItem> _cachedItem=new();
private readonly List<int> _blockList=new();
public override void OnAwake()
{
var health = entity.Get<IHealth>();
health.OnSetAlive += OnSetAlive;
OnDeEquip += DeEquip;
OnEquip += Equip;
_health.OnSetAlive += OnSetAlive;
if (_knockdown is not null)
{
_knockdown.OnKnockdown +=()=>
{
Equip(null);
};
}
if (_improvisedService is not null)
{
_improvisedService.OnEquipImprovisedItem += OnEquipImprovisedItem;
_improvisedService.OnUnEquipImprovisedItem += OnUnEquipImprovisedItem;
_improvisedService.OnTryEquipImprovisedItem += OnTryEquipImprovisedItem;
_improvisedService.OnTryUnEquipImprovisedItem += OnTryUnEquipImprovisedItem;
}
}
public override void OnStart()
{
base.OnStart();
entity.Get<IPlayerInventory>().OnUseItem += TryExecute;
inventory = entity.Get<IBasicItemContainer>();
if (_playerInventory is not null)
{
_playerInventory.OnUseItem += TryExecute;
_playerInventory.OnUseItemCustom += TryUseItemCustom;
_inventory.OnUsed += OnUsed;
_inventory.OnAdd += OnAdd;
_inventory.OnRemove += OnRemove;
}
}
private bool OnTryUnEquipImprovisedItem(IBasicItem arg)
{
return true;
}
private bool OnTryEquipImprovisedItem(IBasicItem arg)
{
return true;
}
private void OnUnEquipImprovisedItem(IBasicItem obj)
{
Equip(null);
if (_cachedItem.TryGetRelease(out var item))
{
Equip(item);
}
}
private void OnEquipImprovisedItem(IBasicItem obj)
{
if (currentEquip is not null)
{
_cachedItem.Release(currentEquip);
}
Equip(obj);
}
public void OnPrimary(InputAction.CallbackContext context)
{
if (context is not {interaction:PressInteraction ,performed:true}) return;
Equip(1);
Equip(1);
}
public void OnSecondary(InputAction.CallbackContext context)
{
@@ -78,7 +145,7 @@ namespace BITFALL
if (alive) return;
foreach (var x in equips.ToArray())
{
inventory.Add(x.Value);
_inventory.Add(x.Value);
}
equips.Clear();
UpdateEquip();
@@ -86,40 +153,103 @@ namespace BITFALL
}
private bool TryExecute(IBasicItem value)
{
if (_knockdown is not null && _knockdown.IsKnockdown) return false;
var asset = value.GetAssetable();
if (IsSupportItem(value) is false) return false;
if (_equipment.IsSupportItem(value) is false) return false;
switch (asset)
{
case var _ when asset.TryGetProperty<EquipmentAsWeapon>(out _):
if (equips.TryAdd(1, value) || equips.TryAdd(2,value))
{
OnEquip?.Invoke(value);
_equipment.EntryEquip(value);
UpdateEquip();
_improvisedService?.TryUnEquipImprovised(out _);
currentEquip = value;
return true;
}
break;
}
return false;
}
public void OnAdd(IBasicItem item)
private bool TryUseItemCustom(IBasicItem value)
{
if (_knockdown is not null && _knockdown.IsKnockdown) return false;
var asset = value.GetAssetable();
if (_equipment.IsSupportItem(value) is false) return false;
switch (asset)
{
case var _ when asset.TryGetProperty<EquipmentUseItem>(out _):
_equipment.EntryEquip(value);
_improvisedService?.TryUnEquipImprovised(out _);
currentEquip = value;
return true;
}
return false;
}
public async void OnAdd(IBasicItem item)
{
if (_blockList.Contains(item.Id)) return;
if(currentEquip is not null && currentEquip.AddressablePath == item.AddressablePath)
{
if(equips.TryGetAny(x=>x.Value.AddressablePath == item.AddressablePath,out var pair))
{
equips.Remove(pair.Key);
UpdateEquip();
}
currentEquip = null;
_equipment.EntryEquip((IBasicItem)null);
}
else
{
try
{
for (var i = 0; i < 8; i++)
{
await UniTask.NextFrame();
}
if (_equipment.IsSupportItem(item))
{
_playerInventory.TryUseItem(item);
}
}
catch(OperationCanceledException){}
}
}
public void Throw(InputAction.CallbackContext context)
{
if (context is not { interaction: HoldInteraction, performed: true }) return;
if(currentEquip is null) return;
if(equips.TryGetAny(x=>x.Value.AddressablePath == currentEquip.AddressablePath,out var pair))
{
if (_inventory.DropOrSpawn(currentEquip))
{
equips.Remove(pair.Key);
_equipment.EntryEquip((IBasicItem)null);
currentEquip = null;
UpdateEquip();
}
}
}
public void OnRemove(IBasicItem item)
{
if (IsSupportItem(item) is false)
if (_equipment.IsSupportItem(item) is false)
{
UpdateEquip();
}
_blockList.Add(item.Id);
}
private bool IsSupportItem(IBasicItem item)
private void OnUsed(IBasicItem obj)
{
return equipment.equips.list.Any(x => x.AddressablePath == item.AddressablePath);
_blockList.Remove(obj.Id);
}
private void UpdateEquip()
{
OnUpdateEquip?.Invoke(new Dictionary<int, IBasicItem>(equips));
_cachedItem.Clear();
}
public bool TryDeEquip(IBasicItem item)
@@ -128,36 +258,25 @@ namespace BITFALL
if (equips.Any(x => x.Value.AddressablePath == item.AddressablePath) is false) return false;
var index = equips.Single(x=>x.Value.AddressablePath==item.AddressablePath).Key;
if (equips.TryRemove(index) is false) return false;
if (!inventory.Add(item)) return false;
OnDeEquip?.Invoke(item);
if (!_inventory.Add(item)) return false;
UpdateEquip();
return true;
}
private void Equip(IBasicItem item)
{
if (item is null)
{
equipment.equips.Entry(-1);
}
else
{
equipment.equips.Entry(x=>x.AddressablePath == item.AddressablePath);
}
_equipment.EntryEquip(item);
currentEquip = item;
}
private bool Equip(int index)
{
if (!equips.TryGetValue(index, out var x) && index is not -1) return false;
if (index is -1)
{
OnEquip?.Invoke(x);
}
if (_knockdown is not null && _knockdown.IsKnockdown) return false;
currentEquip = x;
_improvisedService?.TryUnEquipImprovised(out _);
_equipment.EntryEquip(x);
return true;
}
private void DeEquip(IBasicItem item)
{
equipment.equips.Entry(-1);
}
}
}

View File

@@ -0,0 +1,27 @@
{
"name": "BITFALL.Entities.Equipment.Runtime",
"rootNamespace": "",
"references": [
"GUID:14fe60d984bf9f84eac55c6ea033a8f4",
"GUID:4307f53044263cf4b835bd812fc161a4",
"GUID:709caf8d7fb6ef24bbba0ab9962a3ad0",
"GUID:96f476e982d6fb945bfc9140ba094b7f",
"GUID:84d565da37ad40546a118cfb3c3509f3",
"GUID:677cd05ca06c46b4395470200b1acdad",
"GUID:f51ebe6a0ceec4240a699833d6309b23",
"GUID:0a8b74b3309f0cc44bdd9a796253baef",
"GUID:d525ad6bd40672747bde77962f1c401e",
"GUID:49b49c76ee64f6b41bf28ef951cb0e50",
"GUID:d8b63aba1907145bea998dd612889d6b",
"GUID:30cdc242b1ac6a944a460f4ab0b77b88"
],
"includePlatforms": [],
"excludePlatforms": [],
"allowUnsafeCode": false,
"overrideReferences": false,
"precompiledReferences": [],
"autoReferenced": true,
"defineConstraints": [],
"versionDefines": [],
"noEngineReferences": false
}

View File

@@ -4,7 +4,9 @@
"references": [
"GUID:14fe60d984bf9f84eac55c6ea033a8f4",
"GUID:d525ad6bd40672747bde77962f1c401e",
"GUID:49b49c76ee64f6b41bf28ef951cb0e50"
"GUID:49b49c76ee64f6b41bf28ef951cb0e50",
"GUID:677cd05ca06c46b4395470200b1acdad",
"GUID:709caf8d7fb6ef24bbba0ab9962a3ad0"
],
"includePlatforms": [],
"excludePlatforms": [],

View File

@@ -12,5 +12,6 @@ namespace BITFALL
[System.Serializable]
public record EquipmentAsWeapon: IEquipmentAsArms { }
[System.Serializable]
public record EquipmentAsMelee : IEquipmentAsArms { }
public record EquipmentUseItem: IEquipmentAsArms { }
}

View File

@@ -0,0 +1,27 @@
using System;
using System.Collections;
using System.Collections.Generic;
using BITKit;
using BITKit.Core.Entites;
using UnityEngine;
namespace BITFALL.Entities.Equipment
{
public interface IEntityEquipment
{
event Action<IBasicItem> OnEquip;
event Action<IBasicItem> OnDeEquip;
bool IsSupportItem(IBasicItem item);
void EntryEquip(int index);
void EntryEquip(Func<string,bool> item);
void EntryEquip(IBasicItem item);
}
public interface IEquipBase : IEntryElement, IAwake, IStart, IUpdate
{
string AddressablePath { get; }
IEntity Entity { get; set; }
IBasicItem Item { get; set; }
bool IsSupportItem(IBasicItem item);
void PlayAudio(string name);
}
}

View File

@@ -0,0 +1,184 @@
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using BITKit;
using BITKit.Animations;
using BITKit.StateMachine;
using System.Linq;
using BITFALL;
using BITFALL.Entities.Equipment;
using BITFALL.Player.Equip;
using BITKit.Entities.Melee;
using Cinemachine;
using Cysharp.Threading.Tasks;
namespace BITKit.Entities
{
public abstract class BITEquipBase<T> : StateBasedMonoBehaviour<T>, IEquipBase where T : IState
{
[Header(Constant.Header.Settings)]
[SerializeField] protected AssetableEquip item;
[Header(Constant.Header.Components)]
public UnityAnimator animator;
[SerializeField] private Renderer[] renderers;
[Header(Constant.Header.Services)]
[SerializeReference,SubclassSelector] protected IMeleeService meleeService;
public Core.Entites.IEntity Entity { get; set; }
public IBasicItem Item { get; set; }
public readonly InputActionGroup inputActionGroup = new()
{
allowGlobalActivation = true
};
protected readonly ValidHandle AllowRendering = new();
public virtual string AddressablePath => throw new System.NotImplementedException();
protected virtual Vector3 meleeForce => Transform.forward;
public bool IsEntered { get; set; }
public virtual void Entry()
{
AllowRendering.AddElement(this);
inputActionGroup.allowInput.AddElement(this);
}
public virtual UniTask EntryAsync()
{
return UniTask.CompletedTask;
}
public virtual void Exit()
{
inputActionGroup.allowInput.AddElement(this);
}
public virtual UniTask ExitAsync()
{
AllowRendering.RemoveElement(this);
return UniTask.CompletedTask;
}
public virtual void OnAwake()
{
AllowRendering.AddListener(x=>renderers.ForEach(y=>y.enabled = x));
AllowRendering.Invoke();
Initialize();
}
public virtual void OnDestroy()
{
inputActionGroup.Dispose();
}
public virtual void OnStart() { }
public virtual void OnUpdate(float deltaTime) { }
public virtual bool IsSupportItem(IBasicItem item) =>item is not null && item.AddressablePath == AddressablePath;
public virtual void PlayAudio(string eventName) { }
public virtual void EquipEvent(string eventName){}
public virtual void AnimationEvent(string eventName)
{
if (IsEntered is false) return;
switch (eventName)
{
case "Melee":
case "Attack":
meleeService.Melee(new MeleeCommand
{
PlayerId = Entity.Id,
Position = Transform.position,
Force = meleeForce * item.MeleeForce,
Range = item.MeleeRange,
Damage = item.MeleeDamage
});
break;
case "HeavyAttack":
meleeService.Melee(new MeleeCommand
{
PlayerId = Entity.Id,
Position = Transform.position,
Force = meleeForce * item.HeavyMeleeForce,
Range = item.HeavyMeleeRange,
Damage = item.HeavyMeleeDamage,
});
break;
}
}
}
[CustomType(typeof(IEquipService))]
[CustomType(typeof(IEntityEquipment))]
public class EntityEquipment : EntityComponent,IEquipService,IEntityEquipment
{
public EntryGroup<IEquipBase> equips = new();
public IOptional<float> Zoom { get; } = new Optional<float>(){Value = 1};
public float InitialFov;
[SerializeField] private CinemachineVirtualCamera virtualCamera;
public event Action<IBasicItem> OnEquip;
public event Action<IBasicItem> OnDeEquip;
protected IEquipBase entryComplete;
private PlayerConfig playerConfig;
private IBasicItem _currentItem;
public override void OnStart()
{
base.OnStart();
equips.list = GetComponentsInChildren<IEquipBase>(true).ToList();
equips.OnEntry += OnEntry;
equips.OnExit += OnExit;
foreach (var x in equips.list)
{
x.Entity = entity;
x.OnAwake();
}
foreach (var x in equips.list)
{
x.OnStart();
}
}
private void OnExit(IEquipBase obj)
{
obj.Item = null;
OnDeEquip?.Invoke(obj.Item);
}
private void OnEntry(IEquipBase obj)
{
obj.Item = _currentItem;
OnEquip?.Invoke(obj.Item);
}
public override void OnUpdate(float deltaTime)
{
if (equips.TryGetEntried(out entryComplete))
{
entryComplete.OnUpdate(deltaTime);
}
if (virtualCamera is not null)
{
var current = virtualCamera.m_Lens.FieldOfView;
current= Mathf.Lerp(current,Zoom.Allow ? InitialFov / Zoom.Value : PlayerConfig.Singleton.Fov , deltaTime * 5);
current = Mathf.Clamp(current, 10, PlayerConfig.Singleton.Fov);
virtualCamera.m_Lens.FieldOfView = current;
}
}
public bool IsSupportItem(IBasicItem item)=> equips.list.Any(x => x.IsSupportItem(item));
public void EntryEquip(int index)=> equips.Entry(index);
public void EntryEquip(Func<string,bool> factory)=>equips.Entry(x=>factory.Invoke(x.AddressablePath));
public void EntryEquip(IBasicItem item)
{
_currentItem = item;
equips.Entry(x=>x.IsSupportItem(item));
}
}
}

View File

@@ -0,0 +1,25 @@
{
"name": "BITFALL.Entities.Improvised.Runtime",
"rootNamespace": "",
"references": [
"GUID:14fe60d984bf9f84eac55c6ea033a8f4",
"GUID:709caf8d7fb6ef24bbba0ab9962a3ad0",
"GUID:d9ed46adfa0436d42b5f66480c967c74",
"GUID:7efac18f239530141802fb139776f333",
"GUID:d525ad6bd40672747bde77962f1c401e",
"GUID:49b49c76ee64f6b41bf28ef951cb0e50",
"GUID:677cd05ca06c46b4395470200b1acdad",
"GUID:30cdc242b1ac6a944a460f4ab0b77b88",
"GUID:f6155d9ae143f3949ac54e8355593d6c",
"GUID:75469ad4d38634e559750d17036d5f7c"
],
"includePlatforms": [],
"excludePlatforms": [],
"allowUnsafeCode": false,
"overrideReferences": false,
"precompiledReferences": [],
"autoReferenced": true,
"defineConstraints": [],
"versionDefines": [],
"noEngineReferences": false
}

View File

@@ -0,0 +1,90 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using BITKit;
using BITKit.Entities;
using JetBrains.Annotations;
using UnityEngine;
using UnityEngine.InputSystem;
using UnityEngine.InputSystem.Interactions;
namespace BITFALL.Entities.Improvised
{
[CustomType(typeof(ImprovisedServiceInterface))]
public class ImprovisedService : EntityComponent,ImprovisedServiceInterface
{
[Inject] private IHealth _health;
[Inject(true)] private IKnockdown _knockdown;
private IBasicItem _improvisedItem;
public event Func<IBasicItem, bool> OnTryEquipImprovisedItem;
public event Func<IBasicItem, bool> OnTryUnEquipImprovisedItem;
public event Action<IBasicItem> OnEquipImprovisedItem;
public event Action<IBasicItem> OnUnEquipImprovisedItem;
public override void OnAwake()
{
_health.OnSetAlive += _ =>
{
TryUnEquipImprovised(out var _);
};
if (_knockdown is not null)
{
_knockdown.OnKnockdown += () =>
{
TryUnEquipImprovised(out _);
};
}
}
public bool IsImprovised => _improvisedItem is not null;
public bool TryGetImprovisedItem(out IBasicItem item)
{
item = _improvisedItem;
return item is not null;
}
public bool TryEquipImprovisedItem(IBasicItem weapon)
{
if (OnTryEquipImprovisedItem.CastAsFunc().Any(func => func.Invoke(weapon) is false))
{
return false;
}
_improvisedItem = weapon;
OnEquipImprovisedItem?.Invoke(weapon);
return true;
}
public void TryUnEquipImprovised()=>
TryUnEquipImprovised(out var _);
public void TryUnEquipImprovised(InputAction.CallbackContext context)
{
if (context is { interaction: PressInteraction, performed: true })
//if (context is { interaction: HoldInteraction, performed: true })
{
TryUnEquipImprovised(out var _);
}
}
public bool TryUnEquipImprovised(out IBasicItem weapon)
{
if (_improvisedItem is null)
{
weapon = null;
return false;
}
if (OnTryUnEquipImprovisedItem.CastAsFunc().Any(x => x.Invoke(_improvisedItem) is false))
{
weapon = null;
return false;
}
weapon = _improvisedItem;
_improvisedItem = null;
OnUnEquipImprovisedItem?.Invoke(weapon);
return true;
}
}
}

View File

@@ -1,5 +1,5 @@
{
"name": "BITFALL.Entities.Core.Inventory",
"name": "BITFALL.Entities.Inventory.Runtime",
"rootNamespace": "",
"references": [
"GUID:14fe60d984bf9f84eac55c6ea033a8f4",
@@ -13,7 +13,11 @@
"GUID:f51ebe6a0ceec4240a699833d6309b23",
"GUID:d525ad6bd40672747bde77962f1c401e",
"GUID:49b49c76ee64f6b41bf28ef951cb0e50",
"GUID:ef0bb553b58b90b488bdbe8672e3be0b"
"GUID:ef0bb553b58b90b488bdbe8672e3be0b",
"GUID:d9ed46adfa0436d42b5f66480c967c74",
"GUID:f6155d9ae143f3949ac54e8355593d6c",
"GUID:f32d23892f67f544299b53ae07475659",
"GUID:48ef04d98836e2640bf90b524bdff904"
],
"includePlatforms": [],
"excludePlatforms": [],

View File

@@ -7,28 +7,32 @@ using System;
using System.Linq;
using System.Threading;
using AYellowpaper.SerializedCollections;
using BITFALL.Entities.Inventory;
using BITKit.Entities.Slot;
using Cysharp.Threading.Tasks;
using UnityEngine.AddressableAssets;
namespace BITFALL
{
public interface IEntityInventoryCallback
{
void OnAdd(IBasicItem item);
void OnRemove(IBasicItem item);
}
[CustomType(typeof(IEntityInventory))]
[CustomType(typeof(IBasicItemContainer))]
public abstract class EntityInventory : EntityComponent, IBasicItemContainer
public abstract class EntityInventory : EntityComponent, IEntityInventory
{
public SerializedDictionary<string, GameObject> itemAnchor = new();
/// <summary>
/// 数据字典
/// </summary>
private readonly Dictionary<int, IBasicItem> dictionary = new();
protected readonly Dictionary<int, IBasicItem> dictionary = new();
/// <summary>
/// 隐式接口实现
/// </summary>
public int Id => (int)entity.Id;
public bool DropOrSpawn(IBasicItem item)
{
Drop(item);
return true;
}
/// <summary>
/// 工厂方法
/// </summary>
@@ -37,14 +41,28 @@ namespace BITFALL
public event Func<IBasicItem, bool> DropFactory;
// 回调
public event Action<IBasicItem> OnAdd;
public event Action<IBasicItem> OnUsed;
public event Action<IBasicItem> OnRemove;
public event Action<IBasicItem> OnSet;
public event Action<IBasicItem> OnDrop;
public event Action<IBasicItemContainer> OnRebuild;
private IHealth _health;
public bool UseItem(IBasicItem item)
{
if (dictionary.ContainsKey(item.Id) is false)
{
return false;
}
dictionary.Remove(item.Id);
OnUsed?.Invoke(item);
return true;
}
[Inject]
protected IHealth _health;
[Inject]
protected IEntitySlot<Transform> _modelSlots;
public override void OnAwake()
{
_health = entity.Get<IHealth>();
_health.OnSetAlive += OnSetAlive;
}
private void OnSetAlive(bool alive)
@@ -71,11 +89,6 @@ namespace BITFALL
if (!dictionary.TryAdd(item.Id, item)) return false;
{
OnAdd?.Invoke(item);
foreach (var x in entity.GetCallbacks<IEntityInventoryCallback>())
{
x.OnAdd(item);
}
return true;
}
}
@@ -96,10 +109,6 @@ namespace BITFALL
}
dictionary.Remove(id);
foreach (var x in entity.GetCallbacks<IEntityInventoryCallback>())
{
x.OnRemove(item);
}
OnRemove?.Invoke(item);
return true;
}
@@ -135,17 +144,17 @@ namespace BITFALL
return true;
}
private void Drop(IBasicItem item)
protected void Drop(IBasicItem item)
{
OnDrop?.Invoke(item);
var prefab = Addressables.LoadAssetAsync<AssetableItem>(item.AddressablePath).WaitForCompletion();
var _transform = transform;
var position = _transform.position;
var rotation = _transform.rotation;
if (itemAnchor.TryGetValue(prefab.Name, out var anchor))
if (_modelSlots.Slots.TryGetValue(prefab.AddressablePath, out var anchor))
{
position = anchor.transform.position;
rotation = anchor.transform.rotation;
position = anchor.position;
rotation = anchor.rotation;
}
var instance = Instantiate(prefab.GetPrefab(), position, rotation);
instance.CopyItemsFrom(item);

View File

@@ -24,6 +24,7 @@ namespace BITFALL
container = entity.Get<IBasicItemContainer>();
container.AddFactory += AddFactory;
container.OnAdd += OnAdd;
container.OnUsed += OnRemove;
container.OnRemove += OnRemove;
var playerEquipContainer = entity.Get<IPlayerEquipContainer>();

View File

@@ -6,8 +6,6 @@ using BITFALL.Player.Inventory;
using UnityEngine;
using BITKit;
using BITKit.Entities;
using static UnityEditor.Progress;
using Google.Apis.Sheets.v4.Data;
namespace BITFALL
{
@@ -24,6 +22,7 @@ namespace BITFALL
public class PlayerEquipContainer : EntityComponent, IPlayerEquipContainer
{
private readonly Dictionary<IEquipmentSlot, IBasicItem> dictionary = new();
[Inject]
private IBasicItemContainer inventory;
public override void OnAwake()
{

View File

@@ -0,0 +1,100 @@
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using BITKit;
using System.Threading.Tasks;
using UnityEngine.UIElements;
using System.Text;
using BITKit.Entities;
using System.Linq;
using BITFALL.Entities;
using BITFALL.Entities.Improvised;
using BITFALL.Player.Inventory;
using BITKit.Selection;
namespace BITFALL
{
[CustomType(typeof(IPlayerInventory))]
public class PlayerInventory : EntityInventory,IPlayerInventory
{
[Inject]
private ISelector _selector;
[Inject(true)]
private ImprovisedServiceInterface _improvisedService;
[Inject(true)]
private IKnockdown _knockdown;
public override void OnStart()
{
base.OnStart();
_selector.OnActive += OnActive;
if (_improvisedService is not null)
{
_improvisedService.OnUnEquipImprovisedItem += OnUnEquipImprovisedItem;
}
}
private void OnUnEquipImprovisedItem(IBasicItem obj)
{
Drop(obj);
}
private void OnActive(ISelectable obj)
{
if (obj.Transform.TryGetComponentAny<WorldableItem>(out var item))
{
var _item = item.Pick();
if(item.GetAssetable().TryGetProperty<Improvisable>(out _))
{
if (_knockdown is not null && _knockdown.IsKnockdown)
{
return;
}
if (_improvisedService.TryEquipImprovisedItem(_item))
{
item.Picked();
}
}
else if (Add(_item))
{
item.Picked();
}
}
// else if(obj.Transform.TryGetComponentAny<IBasicItemContainer>(out _))
// {
//
// }
}
public bool TryUseItem(IBasicItem item)
{
if (OnUseItem is null) return false;
return OnUseItem.CastAsFunc().Any(func => func.Invoke(item)) && UseItem(item);
}
public event Func<IBasicItem, bool> OnUseItem;
public bool TryUseItemCustom(IBasicItem item)
{
return OnUseItemCustom is not null && OnUseItemCustom.CastAsFunc().Any(func => func.Invoke(item));
}
public event Func<IBasicItem, bool> OnUseItemCustom;
}
#if UNITY_EDITOR
[UnityEditor.CustomEditor(typeof(PlayerInventory))]
public class EntityPlayerInventoryInsepctor : BITInspector<PlayerInventory>
{
public override VisualElement CreateInspectorGUI()
{
FillDefaultInspector();
CreateSubTitle(Constant.Header.Debug);
var serializeLabel = root.Create<Label>();
StringBuilder stringBuilder = new StringBuilder();
foreach (var x in agent.GetItems())
{
stringBuilder.AppendLine($"{x.Id}@{x.Name}");
}
serializeLabel.text=stringBuilder.ToString();
return root;
}
}
#endif
}

View File

@@ -0,0 +1,77 @@
using System;
using System.Collections;
using System.Collections.Generic;
using BITFALL.Items;
using BITFALL.Player.Inventory;
using BITKit;
using BITKit.Entities;
using UnityEditor;
using UnityEngine;
namespace BITFALL.Entities
{
[CustomType(typeof(IKnockdown))]
public sealed class EntityKnockdown :EntityComponent,IKnockdown
{
[SerializeField] private int knockedHealth;
[SerializeField] private int initialKnockedHealth;
public int KnockedHealth=>knockedHealth;
public int InitialKnockedHealth
{
get => initialKnockedHealth;
set => initialKnockedHealth = value;
}
public event Action OnKnockdown;
public event Action OnRevive;
public bool IsKnockdown { get;private set; }
private readonly Optional<int> knockedHeal=new();
[Inject]
private IHealth _health;
[Inject]
private IPlayerInventory _inventory;
public override void OnStart()
{
_health.OnDamage += OnDamage;
_health.OnSetAlive += OnSetAlive;
_health.OnSetHealthPoint += OnSetHealthPoint;
_inventory.OnUseItem += OnUseItem;
}
private void OnSetHealthPoint(int obj)
{
if (obj > 0 && IsKnockdown && _health.IsAlive)
{
IsKnockdown = false;
OnRevive?.Invoke();
}
}
private bool OnUseItem(IBasicItem arg)
{
if (IsKnockdown is false || arg.GetAssetable().TryGetProperty<PlayerReviveItem>(out var reviveItem) is false) return false;
OnRevive?.Invoke();
IsKnockdown = false;
return true;
}
private void OnSetAlive(bool obj)
{
IsKnockdown = false;
}
private int OnDamage(DamageMessage arg,int currentDamage)
{
if (IsKnockdown || _health.HealthPoint - currentDamage >=0 ) return currentDamage;
IsKnockdown = true;
OnKnockdown?.Invoke();
_health.HealthPoint = 0;
return 0;
}
}
}

View File

@@ -0,0 +1,21 @@
{
"name": "BITFALL.Entities.Melee.Runtime",
"rootNamespace": "",
"references": [
"GUID:14fe60d984bf9f84eac55c6ea033a8f4",
"GUID:709caf8d7fb6ef24bbba0ab9962a3ad0",
"GUID:0a8b74b3309f0cc44bdd9a796253baef",
"GUID:d525ad6bd40672747bde77962f1c401e",
"GUID:49b49c76ee64f6b41bf28ef951cb0e50",
"GUID:d8b63aba1907145bea998dd612889d6b"
],
"includePlatforms": [],
"excludePlatforms": [],
"allowUnsafeCode": false,
"overrideReferences": false,
"precompiledReferences": [],
"autoReferenced": true,
"defineConstraints": [],
"versionDefines": [],
"noEngineReferences": false
}

View File

@@ -0,0 +1,46 @@
using System.Collections;
using System.Collections.Generic;
using System.Xml;
using BITKit.Entities.Melee;
using Unity.Mathematics;
using UnityEngine;
namespace BITKit.Entities
{
public interface IEntityMelee
{
void Execute();
}
public class EntityMelee : EntityComponent
{
[Header(Constant.Header.Settings)]
public int damage=50;
public bool singleTarget;
[SerializeReference, SubclassSelector, Inject(true)] private IMeleeService meleeService;
public override void OnStart()
{
entity.AddListener<int>("Melee", Melee);
entity.AddListener<string>(AIAction);
}
private void AIAction(string actionName)
{
switch (actionName)
{
case "Melee":
break;
}
}
private void Melee(int _damage)
{
meleeService.Melee(new MeleeCommand()
{
PlayerId = Entity.Id,
Position = Transform.position + Vector3.up,
Force = Transform.forward * 128,
Range = 1.6f,
Damage = _damage,
});
entity.Invoke(Constant.Animation.Play, "Melee");
}
}
}

View File

@@ -3,6 +3,7 @@ using BITKit.Entities;
using System.Collections.Generic;
using UnityEngine;
using AYellowpaper.SerializedCollections;
using BITFALL.Entities.Equipment;
namespace BITFALL
{
@@ -11,17 +12,19 @@ namespace BITFALL
[SerializeField] private SerializedDictionary<string, GameObject> equipments = new();
[SerializeField] private SerializedDictionary<string, GameObject> unEquipDictionary = new();
[SerializeField] private SerializedDictionary<string, GameObject> equipDictionary = new();
[Inject] private IEntityEquipment _entityEquipment;
[Inject] private IPlayerEquipContainer _playerEquipContainer;
[Inject] private IPlayerEquipSelector _playerEquipSelector;
public override void OnStart()
{
var playerEquipContainer = entity.Get<IPlayerEquipContainer>();
var equipSelector = entity.Get<IPlayerEquipSelector>();
_playerEquipContainer.OnEquip += OnEquip;
_playerEquipContainer.OnDeEquip += OnDeEquip;
playerEquipContainer.OnEquip += OnEquip;
playerEquipContainer.OnDeEquip += OnDeEquip;
equipSelector.OnEquip += OnEquip;
equipSelector.OnDeEquip += OnDeEquip;
equipSelector.OnUpdateEquip += OnUpdateEquip;
_entityEquipment.OnEquip += OnEquip;
_entityEquipment.OnDeEquip += OnDeEquip;
_playerEquipSelector.OnUpdateEquip += OnUpdateEquip;
foreach (var x in equipments)
{