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 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 : UIToolkitSubPanel,IUXMark, IDisposable where TPanel : IUXPanel { private readonly IPlayerFactory _playerFactory; private readonly IMarkService _markService; private readonly IEntitiesService _entitiesService; private readonly IAfterTicker _ticker; private readonly ConcurrentDictionary _visualElements = new(); private readonly Dictionary _visualElementPositions = new(); private readonly IManagedItemService _itemService; private readonly ScriptableBitMask _factionMask; private readonly Dictionary _scriptableItems=new(); private readonly IPlayerKeyMap _playerKey; private readonly InputActionGroup _inputActionGroup=new(); private IFactionType _playerFaction; public UXMark(IServiceProvider serviceProvider, IMarkService markService, IAfterTicker ticker, IEntitiesService entitiesService, IManagedItemService itemService, IPlayerKeyMap 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()) { _scriptableItems[item.Id] = item; } foreach (var mask in _entitiesService.QueryComponents()) { 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().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(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); } } }