Initial Commit
This commit is contained in:
@@ -0,0 +1,202 @@
|
||||
using System.Collections.Generic;
|
||||
using Controllers;
|
||||
using Kitchen;
|
||||
using Kitchen.Modules;
|
||||
using KitchenMods;
|
||||
using MessagePack;
|
||||
using Pets.Components;
|
||||
using Pets.Components.Menu;
|
||||
using Pets.Menus;
|
||||
using Unity.Collections;
|
||||
using Unity.Entities;
|
||||
using UnityEngine;
|
||||
|
||||
namespace Pets.Views
|
||||
{
|
||||
public class PetEditorView : ResponsiveObjectView<PetEditorView.ViewData, PetEditorView.ResponseData>, IInputConsumer
|
||||
{
|
||||
public class UpdateView : ResponsiveViewSystemBase<ViewData, ResponseData>, IModSystem
|
||||
{
|
||||
EntityQuery Views;
|
||||
protected override void Initialise()
|
||||
{
|
||||
base.Initialise();
|
||||
Views = GetEntityQuery(typeof(CPetEditorInfo), typeof(CLinkedView));
|
||||
}
|
||||
|
||||
protected override void OnUpdate()
|
||||
{
|
||||
using NativeArray<Entity> entities = Views.ToEntityArray(Allocator.Temp);
|
||||
using NativeArray<CLinkedView> views = Views.ToComponentDataArray<CLinkedView>(Allocator.Temp);
|
||||
using NativeArray<CPetEditorInfo> infos = Views.ToComponentDataArray<CPetEditorInfo>(Allocator.Temp);
|
||||
|
||||
foreach (Entity entity in entities)
|
||||
{
|
||||
if (!Require(entity, out CLinkedView cLinkedView)) continue;
|
||||
if (!Require(entity, out CPetEditorInfo cPetEditorInfo)) continue;
|
||||
|
||||
SendUpdate(cLinkedView.Identifier, new ViewData
|
||||
{
|
||||
Player = cPetEditorInfo.Player.PlayerID
|
||||
});
|
||||
|
||||
ResponseData result = default(ResponseData);
|
||||
|
||||
if (ApplyUpdates(cLinkedView, (data) => { result = data; }, only_final_update: true))
|
||||
{
|
||||
cPetEditorInfo.IsComplete = result.IsComplete;
|
||||
Set(entity, cPetEditorInfo);
|
||||
|
||||
Entity stateRequest = EntityManager.CreateEntity();
|
||||
EntityManager.AddComponentData(stateRequest, new CRequestStateChange
|
||||
{
|
||||
PlayerID = result.PlayerID,
|
||||
StateID = result.Option
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[MessagePackObject(false)]
|
||||
public struct ViewData : IViewData, IViewResponseData, IViewData.ICheckForChanges<ViewData>
|
||||
{
|
||||
[Key(0)]
|
||||
public int Player;
|
||||
|
||||
public bool IsChangedFrom(ViewData check)
|
||||
{
|
||||
return Player != check.Player;
|
||||
}
|
||||
}
|
||||
|
||||
[MessagePackObject(false)]
|
||||
public struct ResponseData : IResponseData, IViewResponseData
|
||||
{
|
||||
[Key(0)]
|
||||
public bool IsComplete;
|
||||
[Key(1)]
|
||||
public int Option;
|
||||
[Key(2)]
|
||||
public int PlayerID;
|
||||
}
|
||||
|
||||
private struct MenuStackElement
|
||||
{
|
||||
public GridMenuEditorConfig Config;
|
||||
|
||||
public int Index;
|
||||
}
|
||||
|
||||
public GridMenuEditorConfig rootMenuConfig;
|
||||
public Transform container;
|
||||
private EditorGridMenu _gridMenu;
|
||||
private int _playerID;
|
||||
private InputLock.Lock _lock;
|
||||
private bool _isComplete;
|
||||
private readonly Stack<MenuStackElement> _menuStack = new Stack<MenuStackElement>();
|
||||
private int _option;
|
||||
|
||||
private void CloseMenu()
|
||||
{
|
||||
if (_menuStack.Count > 1)
|
||||
{
|
||||
int index = _menuStack.Pop().Index;
|
||||
MenuStackElement menuStackElement = _menuStack.Pop();
|
||||
SetNewMenu(menuStackElement.Config, index, menuStackElement.Index);
|
||||
}
|
||||
else
|
||||
{
|
||||
Remove();
|
||||
}
|
||||
}
|
||||
|
||||
private void SetNewMenu(GridMenuEditorConfig menu, int newIndex, int previousIndex)
|
||||
{
|
||||
_gridMenu?.Destroy();
|
||||
_gridMenu = menu.Instantiate(delegate (int result)
|
||||
{
|
||||
_option = result;
|
||||
CloseMenu();
|
||||
}, container, _playerID, _menuStack.Count > 0);
|
||||
_gridMenu.OnRequestMenu += delegate (GridMenuConfig c)
|
||||
{
|
||||
if (c is GridMenuEditorConfig cApp)
|
||||
SetNewMenu(cApp, 0, _gridMenu?.SelectedIndex() ?? 0);
|
||||
};
|
||||
_gridMenu.OnGoBack += CloseMenu;
|
||||
_gridMenu.SelectByIndex(newIndex);
|
||||
_menuStack.Push(new MenuStackElement
|
||||
{
|
||||
Config = menu,
|
||||
Index = previousIndex
|
||||
});
|
||||
}
|
||||
|
||||
protected override void UpdateData(ViewData data)
|
||||
{
|
||||
if (InputSourceIdentifier.DefaultInputSource == null) return;
|
||||
if (!Players.Main.Get(data.Player).IsLocalUser)
|
||||
{
|
||||
gameObject.SetActive(value: false);
|
||||
return;
|
||||
}
|
||||
gameObject.SetActive(value: true);
|
||||
_option = 0;
|
||||
InitialiseForPlayer(data.Player);
|
||||
}
|
||||
|
||||
private void InitialiseForPlayer(int player)
|
||||
{
|
||||
LocalInputSourceConsumers.Register(this);
|
||||
if (_lock.Type != 0)
|
||||
InputSourceIdentifier.DefaultInputSource.ReleaseLock(_playerID, _lock);
|
||||
_playerID = player;
|
||||
SetNewMenu(rootMenuConfig, 0, 0);
|
||||
_lock = InputSourceIdentifier.DefaultInputSource.SetInputLock(_playerID, PlayerLockState.NonPause);
|
||||
}
|
||||
|
||||
public override void Remove()
|
||||
{
|
||||
_isComplete = true;
|
||||
InputSourceIdentifier.DefaultInputSource.ReleaseLock(_playerID, _lock);
|
||||
base.Remove();
|
||||
}
|
||||
|
||||
private void OnDestroy()
|
||||
{
|
||||
LocalInputSourceConsumers.Remove(this);
|
||||
}
|
||||
|
||||
public InputConsumerState TakeInput(int playerID, InputState state)
|
||||
{
|
||||
if (_playerID == 0 || playerID != _playerID) return InputConsumerState.NotConsumed;
|
||||
if (state.MenuTrigger == ButtonState.Pressed)
|
||||
{
|
||||
_isComplete = true;
|
||||
InputSourceIdentifier.DefaultInputSource.ReleaseLock(_playerID, _lock);
|
||||
return InputConsumerState.Terminated;
|
||||
}
|
||||
if (_gridMenu != null && !_gridMenu.HandleInteraction(state) && state.MenuCancel == ButtonState.Pressed)
|
||||
{
|
||||
CloseMenu();
|
||||
}
|
||||
return !_isComplete ? InputConsumerState.Consumed : InputConsumerState.Terminated;
|
||||
}
|
||||
|
||||
public override bool HasStateUpdate(out IResponseData state)
|
||||
{
|
||||
state = null;
|
||||
if (_isComplete)
|
||||
{
|
||||
state = new ResponseData
|
||||
{
|
||||
IsComplete = _isComplete,
|
||||
Option = _option,
|
||||
PlayerID = _playerID
|
||||
};
|
||||
}
|
||||
return _isComplete;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,88 @@
|
||||
using System;
|
||||
using Kitchen;
|
||||
using KitchenMods;
|
||||
using MessagePack;
|
||||
using Pets.Components;
|
||||
using Pets.Systems;
|
||||
using Unity.Collections;
|
||||
using Unity.Entities;
|
||||
|
||||
namespace Pets.Views
|
||||
{
|
||||
public class PetRequestView : UpdatableObjectView<PetRequestView.ViewData>, ISpecificViewResponse
|
||||
{
|
||||
public class UpdateView : ResponsiveViewSystemBase<ViewData, ResponseData>, IModSystem
|
||||
{
|
||||
EntityQuery Query;
|
||||
protected override void Initialise()
|
||||
{
|
||||
base.Initialise();
|
||||
Query = GetEntityQuery(typeof(CLinkedView), typeof(SPetRequestView));
|
||||
}
|
||||
|
||||
protected override void OnUpdate()
|
||||
{
|
||||
using NativeArray<CLinkedView> linkedViews = Query.ToComponentDataArray<CLinkedView>(Allocator.Temp);
|
||||
|
||||
foreach (CLinkedView view in linkedViews)
|
||||
{
|
||||
SendUpdate(view.Identifier, new ViewData());
|
||||
if (ApplyUpdates(view.Identifier, PerformUpdateWithResponse, only_final_update: false)) { }
|
||||
}
|
||||
}
|
||||
|
||||
private void PerformUpdateWithResponse(ResponseData data)
|
||||
{
|
||||
PetSelector.Main.CreatePlayerRequest(data.PlayerID, data.PetID);
|
||||
}
|
||||
}
|
||||
|
||||
[MessagePackObject(false)]
|
||||
public class ViewData : ISpecificViewData, IViewData.ICheckForChanges<ViewData>
|
||||
{
|
||||
public IUpdatableObject GetRelevantSubview(IObjectView view)
|
||||
{
|
||||
return view.GetSubView<PetRequestView>();
|
||||
}
|
||||
|
||||
public bool IsChangedFrom(ViewData check)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
[MessagePackObject(false)]
|
||||
public class ResponseData : IResponseData, IViewResponseData
|
||||
{
|
||||
[Key(0)]
|
||||
public int PlayerID;
|
||||
[Key(1)]
|
||||
public int PetID;
|
||||
}
|
||||
|
||||
private Action<IResponseData, Type> Callback;
|
||||
|
||||
public static int PlayerID = 0;
|
||||
public static int PetID = 0;
|
||||
|
||||
public ResponseData Cache;
|
||||
|
||||
protected override void UpdateData(ViewData data)
|
||||
{
|
||||
Cache ??= new ResponseData();
|
||||
|
||||
if (Cache.PlayerID != PlayerID || Cache.PetID != PetID)
|
||||
{
|
||||
Cache.PlayerID = PlayerID;
|
||||
Cache.PetID = PetID;
|
||||
if (Callback != null)
|
||||
Callback.Invoke(Cache, typeof(ResponseData));
|
||||
}
|
||||
}
|
||||
|
||||
public void SetCallback(Action<IResponseData, Type> callback)
|
||||
{
|
||||
Callback = callback;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,231 @@
|
||||
using System;
|
||||
using Controllers;
|
||||
using Kitchen;
|
||||
using KitchenData;
|
||||
using KitchenMods;
|
||||
using MessagePack;
|
||||
using Pets.Components;
|
||||
using Pets.Enums;
|
||||
using TMPro;
|
||||
using Unity.Collections;
|
||||
using Unity.Entities;
|
||||
using UnityEngine;
|
||||
using UnityEngine.AI;
|
||||
using UnityEngine.VFX;
|
||||
|
||||
namespace Pets.Views
|
||||
{
|
||||
public class PetView : UpdatableObjectView<PetView.ViewData>, ISpecificViewResponse
|
||||
{
|
||||
public NavMeshAgent agent;
|
||||
public Animator animator;
|
||||
public VisualEffect vfx;
|
||||
public GameObject warningIcon;
|
||||
public TextMeshPro label;
|
||||
|
||||
public override void SetPosition(UpdateViewPositionData pos)
|
||||
{
|
||||
if (!pos.Force && !((transform.localPosition - pos.Position).Chebyshev() > 0.5f)) return;
|
||||
base.SetPosition(pos);
|
||||
agent.Warp(pos.Position);
|
||||
}
|
||||
|
||||
protected override void UpdatePosition() { }
|
||||
|
||||
public class UpdateView : ResponsiveViewSystemBase<ViewData, ResponseData>, IModSystem
|
||||
{
|
||||
private EntityQuery _pets;
|
||||
|
||||
protected override void Initialise()
|
||||
{
|
||||
base.Initialise();
|
||||
_pets = GetEntityQuery(typeof(CLinkedView), typeof(CPet));
|
||||
}
|
||||
|
||||
protected override void OnUpdate()
|
||||
{
|
||||
NativeArray<Entity> pets = _pets.ToEntityArray(Allocator.Temp);
|
||||
|
||||
foreach (Entity pet in pets)
|
||||
{
|
||||
if (!Require(pet, out CLinkedView cLinkedView) || !Require(pet, out CPet cPet) || !Require(pet, out CPosition cPosition)) continue;
|
||||
|
||||
Vector3 TargetPosition = Vector3.zero;
|
||||
Vector3 PreferedFacingDirection = Vector3.zero;
|
||||
float StopDistance = 0;
|
||||
bool ShouldMove = false;
|
||||
int RequestingInputSource = 0;
|
||||
|
||||
if (Require(pet, out CMoveToLocation cMoveToLocation))
|
||||
{
|
||||
TargetPosition = cMoveToLocation.Location;
|
||||
PreferedFacingDirection = cMoveToLocation.DesiredFacing;
|
||||
StopDistance = cMoveToLocation.StoppingDistance;
|
||||
ShouldMove = true;
|
||||
}
|
||||
|
||||
|
||||
if (Require(pet, out CRequestNameChange cRequestNameChange) && !cRequestNameChange.IsTriggered)
|
||||
{
|
||||
RequestingInputSource = cRequestNameChange.Source;
|
||||
cRequestNameChange.IsTriggered = true;
|
||||
EntityManager.AddComponentData(pet, cRequestNameChange);
|
||||
}
|
||||
|
||||
|
||||
SendUpdate(cLinkedView, new ViewData
|
||||
{
|
||||
TargetPosition = TargetPosition,
|
||||
StopDistance = StopDistance,
|
||||
IsMoving = ShouldMove,
|
||||
PreferedFacingDirection = PreferedFacingDirection,
|
||||
State = cPet.State,
|
||||
RequestingInputSource = RequestingInputSource,
|
||||
PetName = cPet.PetName.Value
|
||||
});
|
||||
if (ApplyUpdates(cLinkedView, (data) =>
|
||||
{
|
||||
EntityManager.AddComponentData(pet, new CCurrentSpeed
|
||||
{
|
||||
speed = data.Speed
|
||||
});
|
||||
|
||||
if (data.UpdateName)
|
||||
{
|
||||
if (!Require(pet, out CPet cPet)) return;
|
||||
cPet.PetName = data.PetName;
|
||||
if (Require(pet, out CDefaultState cDefaultState))
|
||||
cPet.State = cDefaultState.State;
|
||||
|
||||
EntityManager.AddComponentData(pet, cPet);
|
||||
}
|
||||
|
||||
if (Has<CRequestNameChange>(pet))
|
||||
{
|
||||
EntityManager.RemoveComponent<CRequestNameChange>(pet);
|
||||
}
|
||||
}, only_final_update: false)) { }
|
||||
}
|
||||
|
||||
pets.Dispose();
|
||||
}
|
||||
}
|
||||
|
||||
[MessagePackObject(false)]
|
||||
public class ViewData : ISpecificViewData, IViewData.ICheckForChanges<ViewData>
|
||||
{
|
||||
public IUpdatableObject GetRelevantSubview(IObjectView view)
|
||||
{
|
||||
return view.GetSubView<PetView>();
|
||||
}
|
||||
|
||||
public bool IsChangedFrom(ViewData check)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
[Key(0)] public bool IsMoving;
|
||||
[Key(1)] public Vector3 TargetPosition;
|
||||
[Key(2)] public float StopDistance;
|
||||
[Key(3)] public Vector3 PreferedFacingDirection;
|
||||
[Key(4)] public PetState State;
|
||||
[Key(5)] public int RequestingInputSource;
|
||||
[Key(6)] public string PetName;
|
||||
}
|
||||
|
||||
[MessagePackObject(false)]
|
||||
public class ResponseData : IResponseData, IViewResponseData
|
||||
{
|
||||
[Key(0)] public float Speed;
|
||||
[Key(1)] public string PetName;
|
||||
[Key(2)] public bool UpdateName;
|
||||
}
|
||||
|
||||
private static readonly int Speed = Animator.StringToHash("Speed");
|
||||
private static readonly int Eating = Animator.StringToHash("Eating");
|
||||
private static readonly int Sleeping = Animator.StringToHash("Sleeping");
|
||||
|
||||
private ViewData Data;
|
||||
|
||||
protected override void UpdateData(ViewData viewData)
|
||||
{
|
||||
Data = viewData;
|
||||
|
||||
if (Data == null) return;
|
||||
|
||||
if (Data.RequestingInputSource == InputSourceIdentifier.Identifier)
|
||||
{
|
||||
TextInputView.RequestTextInput(base.Localisation["INPUT_TITLE_RENAME_RESTAURANT"], "", 24, HandleNewName);
|
||||
}
|
||||
}
|
||||
|
||||
private void HandleNewName(TextInputView.TextInputState state, string result)
|
||||
{
|
||||
if (state != TextInputView.TextInputState.TextEntryComplete) return;
|
||||
|
||||
Cache ??= new ResponseData();
|
||||
Cache.PetName = result;
|
||||
Cache.UpdateName = true;
|
||||
if (Callback != null)
|
||||
Callback?.Invoke(Cache, typeof(ResponseData));
|
||||
}
|
||||
|
||||
private Action<IResponseData, Type> Callback;
|
||||
public void SetCallback(Action<IResponseData, Type> callback)
|
||||
{
|
||||
Callback = callback;
|
||||
}
|
||||
|
||||
public ResponseData Cache;
|
||||
|
||||
private void Update()
|
||||
{
|
||||
if (Data == null) return;
|
||||
|
||||
Cache ??= new ResponseData();
|
||||
|
||||
if (Data.PetName == Cache.PetName)
|
||||
Cache.UpdateName = false;
|
||||
|
||||
if (agent != null)
|
||||
{
|
||||
if (Cache.Speed != agent.velocity.magnitude)
|
||||
{
|
||||
Cache.Speed = agent.velocity.magnitude;
|
||||
if (Callback != null)
|
||||
Callback.Invoke(Cache, typeof(ResponseData));
|
||||
}
|
||||
|
||||
if (Data.TargetPosition != Vector3.zero && Data.IsMoving)
|
||||
{
|
||||
agent.stoppingDistance = Data.StopDistance;
|
||||
agent.SetDestination(Data.TargetPosition);
|
||||
}
|
||||
|
||||
if (agent.remainingDistance <= agent.stoppingDistance && Data.PreferedFacingDirection != Vector3.zero)
|
||||
{
|
||||
transform.rotation = Quaternion.LookRotation(Data.PreferedFacingDirection - transform.position, Vector3.up);
|
||||
}
|
||||
}
|
||||
|
||||
if (animator != null && agent != null)
|
||||
{
|
||||
animator.SetFloat(Speed, agent.velocity.magnitude);
|
||||
animator.SetBool(Eating, Data.State == PetState.Eat && agent.velocity.magnitude < Mod.MinimumSpeedThreshold);
|
||||
animator.SetBool(Sleeping, Data.State == PetState.Sleep && agent.velocity.magnitude < Mod.MinimumSpeedThreshold);
|
||||
}
|
||||
|
||||
if (vfx != null)
|
||||
vfx.enabled = Data.State == PetState.Sleep && agent.velocity.magnitude < Mod.MinimumSpeedThreshold;
|
||||
|
||||
if (warningIcon != null)
|
||||
warningIcon.SetActive(Data.State is PetState.Error);
|
||||
|
||||
if (label != null)
|
||||
{
|
||||
label.font = GameData.Main.GlobalLocalisation.Fonts[KitchenData.Font.Default];
|
||||
label.text = Data.PetName;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user