243 lines
9.1 KiB
C#
243 lines
9.1 KiB
C#
using System;
|
|
using System.Collections;
|
|
using System.Collections.Concurrent;
|
|
using System.Collections.Generic;
|
|
using BITKit;
|
|
using BITKit.Entities;
|
|
using BITKit.UX;
|
|
using Cysharp.Threading.Tasks;
|
|
using Cysharp.Threading.Tasks.Triggers;
|
|
using Net.BITKit.BitMask;
|
|
using Net.BITKit.Localization;
|
|
using Net.BITKit.UX;
|
|
using Net.Project.B.AI;
|
|
using Net.Project.B.Faction;
|
|
using Net.Project.B.Item;
|
|
using Net.Project.B.Mark;
|
|
using Net.Project.B.Quest;
|
|
using Net.Project.B.WorldNode;
|
|
using Project.B.Entities;
|
|
using Project.B.Item;
|
|
using Project.B.Player;
|
|
using Project.B.UX;
|
|
using UnityEngine;
|
|
using UnityEngine.InputSystem;
|
|
using UnityEngine.UIElements;
|
|
|
|
namespace Net.Project.B.UX
|
|
{
|
|
public static class UXMarkUtils{
|
|
|
|
public static void SetUp(int id,Func<VisualElement> createFactor,bool forceCreate=false)
|
|
{
|
|
BITApp.ServiceProvider.QueryComponents(out IManagedItemService itemService,out IEntitiesService entitiesService,out ILocalizationService localizationService);
|
|
|
|
if (itemService.Items.TryGetValue(id, out var item) && forceCreate)
|
|
{
|
|
var ve = createFactor();
|
|
UXInventoryUtils.Setup(ve, item).Forget();
|
|
return;
|
|
}
|
|
|
|
if (entitiesService.TryGetEntity(id, out var entity))
|
|
{
|
|
var serviceProvider = entity.ServiceProvider;
|
|
try
|
|
{
|
|
var className = (serviceProvider) switch
|
|
{
|
|
not null when serviceProvider.QueryComponents(out NameMark nameMark)=>nameMark.Name,
|
|
not null when serviceProvider.QueryComponents(out IMarkComponent markComponent) && forceCreate =>
|
|
markComponent.GetType().Name,
|
|
not null when serviceProvider.QueryComponents(out LandMark landMark) && string.IsNullOrEmpty(landMark.IconName) is false=>
|
|
landMark.IconName,
|
|
not null when serviceProvider.QueryComponents(out UnitySubwayNode _)=>
|
|
nameof(UnitySubwayNode),
|
|
not null when serviceProvider.QueryComponents(out IRuntimeItemContainer _) && forceCreate=>
|
|
nameof(IRuntimeItemContainer),
|
|
not null when serviceProvider.QueryComponents(out UnityVehicleNode vehicleNode)&& forceCreate=>
|
|
vehicleNode.GetType().Name,
|
|
not null when serviceProvider.QueryComponents(out UnityEvacuateNode evacuateNode)=>
|
|
evacuateNode.GetType().Name,
|
|
not null when serviceProvider.QueryComponents(out IFactionType factionType) && forceCreate =>
|
|
factionType.GetType().Name,
|
|
not null when serviceProvider.QueryComponents(out UnityDoorNode doorNode) && forceCreate =>
|
|
doorNode.GetType().Name,
|
|
not null when serviceProvider.QueryComponents(out UnityBuyStationNode buyStationNode) =>
|
|
buyStationNode.GetType().Name,
|
|
not null when serviceProvider.QueryComponents(out IQuestNode questNode) => questNode.GetType()
|
|
.Name,
|
|
_ => throw new OperationCanceledException()
|
|
};
|
|
var ve = createFactor();
|
|
ve.AddToClassList(className);
|
|
ve.viewDataKey = ve[0].viewDataKey = className;
|
|
ve.tooltip = ve[0].tooltip = localizationService.GetLocalizedString(className);
|
|
ve.AddToClassList(UXLocalization.USS);
|
|
ve[0].AddToClassList(UXLocalization.USS);
|
|
return;
|
|
}
|
|
catch (OperationCanceledException)
|
|
{
|
|
}
|
|
}
|
|
|
|
if (forceCreate)
|
|
{
|
|
createFactor();
|
|
}
|
|
}
|
|
}
|
|
public class UXMark<TPanel> : UIToolkitSubPanel<TPanel>,IUXMark, IDisposable where TPanel : IUXPanel
|
|
{
|
|
private readonly IPlayerFactory _playerFactory;
|
|
|
|
private readonly IMarkService _markService;
|
|
|
|
private readonly IEntitiesService _entitiesService;
|
|
|
|
private readonly IAfterTicker _ticker;
|
|
|
|
private readonly ConcurrentDictionary<int, VisualElement> _visualElements = new();
|
|
|
|
private readonly Dictionary<int, Vector2> _visualElementPositions = new();
|
|
|
|
private readonly IManagedItemService _itemService;
|
|
|
|
private readonly ScriptableBitMask _factionMask;
|
|
|
|
private readonly Dictionary<int, ScriptableItem> _scriptableItems=new();
|
|
|
|
private readonly IPlayerKeyMap<InputAction> _playerKey;
|
|
|
|
private readonly InputActionGroup _inputActionGroup=new();
|
|
|
|
private IFactionType _playerFaction;
|
|
|
|
public UXMark(IServiceProvider serviceProvider, IMarkService markService, IAfterTicker ticker, IEntitiesService entitiesService, IManagedItemService itemService, IPlayerKeyMap<InputAction> playerKey, IPlayerFactory playerFactory) : base(serviceProvider)
|
|
{
|
|
_markService = markService;
|
|
_ticker = ticker;
|
|
_entitiesService = entitiesService;
|
|
_itemService = itemService;
|
|
_playerKey = playerKey;
|
|
_playerFactory = playerFactory;
|
|
_markService.OnMark += OnMark;
|
|
|
|
_ticker.Add(OnAfterTick);
|
|
|
|
foreach (var item in _entitiesService.QueryComponents<ScriptableItem>())
|
|
{
|
|
_scriptableItems[item.Id] = item;
|
|
}
|
|
|
|
foreach (var mask in _entitiesService.QueryComponents<ScriptableBitMask>())
|
|
{
|
|
if(mask.Type != typeof(IFactionType))continue;
|
|
_factionMask = mask;
|
|
}
|
|
|
|
_playerFactory.OnEntityCreated += OnEntityCreated;
|
|
}
|
|
|
|
private UniTask OnEntityCreated(string arg1, IEntity arg2)
|
|
{
|
|
arg2.ServiceProvider.QueryComponents(out _playerFaction);
|
|
return UniTask.CompletedTask;
|
|
}
|
|
|
|
|
|
[UXBindPath("mark-container")] private VisualElement _markContainer;
|
|
|
|
private VisualTreeAsset _template;
|
|
|
|
protected override void OnInitiated()
|
|
{
|
|
base.OnInitiated();
|
|
_template = _markContainer.Q<TemplateContainer>().templateSource;
|
|
if (_template is null)
|
|
{
|
|
throw new Exception("mark-container is null");
|
|
}
|
|
_markContainer.Clear();
|
|
|
|
_inputActionGroup.RegisterCallback(_playerKey.MarkKey, OnMark);
|
|
|
|
_inputActionGroup.allowInput.AddElement(this);
|
|
}
|
|
|
|
private void OnMark(InputAction.CallbackContext obj)
|
|
{
|
|
if (obj.JustPressed() is false)return;
|
|
|
|
var center = _markContainer.layout.size/2;
|
|
foreach (var (id,pos) in _visualElementPositions)
|
|
{
|
|
var centersPos =pos + _visualElements[id].layout.size / 2;
|
|
|
|
if (Vector2.Distance(center, centersPos) < 32)
|
|
{
|
|
_markService.CancelMark(id);
|
|
return;
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
private void OnMark(int arg1, bool arg2)
|
|
{
|
|
if (arg2)
|
|
{
|
|
UXMarkUtils.SetUp(arg1,Create,true);
|
|
VisualElement Create()
|
|
{
|
|
return _visualElements[arg1] = _markContainer.Create(_template);
|
|
}
|
|
}
|
|
else if (_visualElements.TryRemove(arg1, out var container))
|
|
{
|
|
container.RemoveFromHierarchy();
|
|
_visualElementPositions.TryRemove(arg1);
|
|
}
|
|
}
|
|
|
|
private void OnAfterTick(float obj)
|
|
{
|
|
foreach (var (id,visualElement) in _visualElements)
|
|
{
|
|
if(_entitiesService.TryGetEntity(id,out var entity) is false)continue;
|
|
var serviceProvider = entity.ServiceProvider;
|
|
if (serviceProvider.QueryComponents(out Transform transform) is false || !transform)
|
|
{
|
|
continue;
|
|
}
|
|
|
|
if (serviceProvider.QueryComponents(out AIBlackBoard blackBoard))
|
|
{
|
|
_visualElements[id].Get<VisualElement>(1).style.height =
|
|
new StyleLength(Length.Percent(blackBoard.AlertValue*100));
|
|
}
|
|
|
|
var pos =
|
|
|
|
visualElement.SetPosition(entity.ServiceProvider.QueryComponents(out Collider collider)
|
|
?
|
|
collider.bounds.center+Vector3.up*(collider.bounds.extents.y*1.2f)
|
|
:
|
|
transform.position);
|
|
|
|
_visualElementPositions[id] = pos;
|
|
}
|
|
}
|
|
|
|
public void Dispose()
|
|
{
|
|
_markService.OnMark -= OnMark;
|
|
|
|
_inputActionGroup.Dispose();
|
|
|
|
_ticker.Remove(OnAfterTick);
|
|
}
|
|
}
|
|
}
|