add drop sync

This commit is contained in:
Mister_Nebula 2021-02-25 13:52:49 +00:00
parent 75fdc85fff
commit d34eeda44d
16 changed files with 298 additions and 27 deletions

View File

@ -5,6 +5,7 @@ using QSB.DeathSync.Events;
using QSB.ElevatorSync.Events; using QSB.ElevatorSync.Events;
using QSB.FrequencySync.Events; using QSB.FrequencySync.Events;
using QSB.GeyserSync.Events; using QSB.GeyserSync.Events;
using QSB.ItemSync.Events;
using QSB.LogSync.Events; using QSB.LogSync.Events;
using QSB.OrbSync.Events; using QSB.OrbSync.Events;
using QSB.Player.Events; using QSB.Player.Events;
@ -56,6 +57,7 @@ namespace QSB.Events
new MoonStateChangeEvent(), new MoonStateChangeEvent(),
new EnterLeaveEvent(), new EnterLeaveEvent(),
new QuantumAuthorityEvent(), new QuantumAuthorityEvent(),
new DropItemEvent(),
// Conversation/dialogue/exploration // Conversation/dialogue/exploration
new ConversationEvent(), new ConversationEvent(),
new ConversationStartEndEvent(), new ConversationStartEndEvent(),
@ -122,5 +124,35 @@ namespace QSB.Events
} }
GlobalMessenger<T, U, V>.FireEvent(eventName, arg1, arg2, arg3); GlobalMessenger<T, U, V>.FireEvent(eventName, arg1, arg2, arg3);
} }
public static void FireEvent<T, U, V, W>(string eventName, T arg1, U arg2, V arg3, W arg4)
{
if (!QSBCore.IsInMultiplayer)
{
DebugLog.ToConsole($"Warning - Tried to send event {eventName} while not connected to/hosting server.", MessageType.Warning);
return;
}
GlobalMessenger<T, U, V, W>.FireEvent(eventName, arg1, arg2, arg3, arg4);
}
public static void FireEvent<T, U, V, W, X>(string eventName, T arg1, U arg2, V arg3, W arg4, X arg5)
{
if (!QSBCore.IsInMultiplayer)
{
DebugLog.ToConsole($"Warning - Tried to send event {eventName} while not connected to/hosting server.", MessageType.Warning);
return;
}
GlobalMessenger<T, U, V, W, X>.FireEvent(eventName, arg1, arg2, arg3, arg4, arg5);
}
public static void FireEvent<T, U, V, W, X, Y>(string eventName, T arg1, U arg2, V arg3, W arg4, X arg5, Y arg6)
{
if (!QSBCore.IsInMultiplayer)
{
DebugLog.ToConsole($"Warning - Tried to send event {eventName} while not connected to/hosting server.", MessageType.Warning);
return;
}
GlobalMessenger<T, U, V, W, X, Y>.FireEvent(eventName, arg1, arg2, arg3, arg4, arg5, arg6);
}
} }
} }

View File

@ -11,27 +11,26 @@ namespace QSB.ItemSync.Events
public override QSB.Events.EventType Type => QSB.Events.EventType.DropItem; public override QSB.Events.EventType Type => QSB.Events.EventType.DropItem;
public override void SetupListener() public override void SetupListener()
=> GlobalMessenger<int, Vector3, Vector3, Transform, Sector, DetachableFragment>.AddListener(EventNames.QSBDropItem, Handler); => GlobalMessenger<int, Vector3, Vector3, Sector>.AddListener(EventNames.QSBDropItem, Handler);
public override void CloseListener() public override void CloseListener()
=> GlobalMessenger<int, Vector3, Vector3, Transform, Sector, DetachableFragment>.RemoveListener(EventNames.QSBDropItem, Handler); => GlobalMessenger<int, Vector3, Vector3, Sector>.RemoveListener(EventNames.QSBDropItem, Handler);
private void Handler(int objectId, Vector3 position, Vector3 normal, Transform parent, Sector sector, DetachableFragment fragment) private void Handler(int objectId, Vector3 position, Vector3 normal, Sector sector)
=> SendEvent(CreateMessage(objectId, position, normal, parent, sector, fragment)); => SendEvent(CreateMessage(objectId, position, normal, sector));
private DropItemMessage CreateMessage(int objectId, Vector3 position, Vector3 normal, Transform parent, Sector sector, DetachableFragment fragment) => new DropItemMessage private DropItemMessage CreateMessage(int objectId, Vector3 position, Vector3 normal, Sector sector) => new DropItemMessage
{ {
ObjectId = objectId, ObjectId = objectId,
Position = position, Position = position,
Normal = normal, Normal = normal,
Parent = parent,
Sector = sector, Sector = sector,
DetachableFragment = fragment
}; };
public override void OnReceiveRemote(bool server, DropItemMessage message) public override void OnReceiveRemote(bool server, DropItemMessage message)
{ {
var worldObject = QSBWorldSync.GetWorldFromId<IQSBOWItem>(message.ObjectId); var worldObject = QSBWorldSync.GetWorldFromId<IQSBOWItem>(message.ObjectId);
worldObject.DropItem(message.Position, message.Normal, message.Sector);
} }
} }
} }

View File

@ -11,9 +11,7 @@ namespace QSB.ItemSync.Events
public int ObjectId { get; set; } public int ObjectId { get; set; }
public Vector3 Position { get; set; } public Vector3 Position { get; set; }
public Vector3 Normal { get; set; } public Vector3 Normal { get; set; }
public Transform Parent { get; set; }
public Sector Sector { get; set; } public Sector Sector { get; set; }
public DetachableFragment DetachableFragment { get; set; }
public override void Deserialize(QNetworkReader reader) public override void Deserialize(QNetworkReader reader)
{ {

View File

@ -2,6 +2,7 @@
using QSB.ItemSync.WorldObjects; using QSB.ItemSync.WorldObjects;
using QSB.Utility; using QSB.Utility;
using QSB.WorldSync; using QSB.WorldSync;
using System.Collections.Generic;
using UnityEngine; using UnityEngine;
namespace QSB.ItemSync namespace QSB.ItemSync
@ -10,6 +11,8 @@ namespace QSB.ItemSync
{ {
public static ItemManager Instance { get; private set; } public static ItemManager Instance { get; private set; }
private List<ScrollItem> _oldScrollList = new List<ScrollItem>();
public void Awake() public void Awake()
{ {
Instance = this; Instance = this;
@ -21,8 +24,61 @@ namespace QSB.ItemSync
public void RebuildItems(OWScene scene) public void RebuildItems(OWScene scene)
{ {
DebugLog.DebugWrite("Rebuilding OWItems...", MessageType.Warning); DebugLog.DebugWrite("Rebuilding OWItems...", MessageType.Warning);
QSBWorldSync.Init<QSBScrollItem, ScrollItem>(); _oldScrollList = QSBWorldSync.Init<QSBScrollItem, ScrollItem>();
QSBWorldSync.Init<QSBScrollSocket, ScrollSocket>(); QSBWorldSync.Init<QSBScrollSocket, ScrollSocket>();
} }
public static IQSBOWItem GetObject(OWItem unityObject)
{
IQSBOWItem worldObj = null;
if (unityObject.GetType() == typeof(ScrollItem))
{
worldObj = QSBWorldSync.GetWorldFromUnity<QSBScrollItem, ScrollItem>((ScrollItem)unityObject);
}
else if (unityObject.GetType() == typeof(NomaiConversationStone))
{
//worldObj = QSBWorldSync.GetWorldFromUnity<QSBMultiStateQuantumObject, MultiStateQuantumObject>((MultiStateQuantumObject)unityObject);
}
else if (unityObject.GetType() == typeof(SharedStone))
{
//worldObj = QSBWorldSync.GetWorldFromUnity<QSBQuantumShuffleObject, QuantumShuffleObject>((QuantumShuffleObject)unityObject);
}
else if (unityObject.GetType() == typeof(WarpCoreItem))
{
//worldObj = QSBWorldSync.GetWorldFromUnity<QSBQuantumShuffleObject, QuantumShuffleObject>((QuantumShuffleObject)unityObject);
}
else
{
DebugLog.ToConsole($"Warning - couldn't work out type of OWITem {unityObject.name}.", MessageType.Warning);
}
return worldObj;
}
public static IQSBOWItemSocket GetObject(OWItemSocket unityObject)
{
IQSBOWItemSocket worldObj = null;
if (unityObject.GetType() == typeof(ScrollItem))
{
worldObj = QSBWorldSync.GetWorldFromUnity<QSBScrollSocket, ScrollSocket>((ScrollSocket)unityObject);
}
else
{
DebugLog.ToConsole($"Warning - couldn't work out type of OWITemSocket {unityObject.name}.", MessageType.Warning);
}
return worldObj;
}
public void OnRenderObject()
{
if (!QSBCore.HasWokenUp || !QSBCore.DebugMode || !QSBCore.ShowLinesInDebug)
{
return;
}
foreach (var item in _oldScrollList)
{
Popcron.Gizmos.Cube(item.transform.position, item.transform.rotation, Vector3.one, Color.blue);
}
}
} }
} }

View File

@ -1,5 +1,7 @@
using QSB.Patches; using QSB.Events;
using QSB.Patches;
using QSB.Utility; using QSB.Utility;
using QSB.WorldSync;
using System.Reflection; using System.Reflection;
using UnityEngine; using UnityEngine;
@ -24,6 +26,7 @@ namespace QSB.ItemSync.Patches
public static bool ItemTool_SocketItem(OWItem ____heldItem, OWItemSocket socket) public static bool ItemTool_SocketItem(OWItem ____heldItem, OWItemSocket socket)
{ {
DebugLog.DebugWrite($"Socket item {____heldItem.name} into socket {socket.name}."); DebugLog.DebugWrite($"Socket item {____heldItem.name} into socket {socket.name}.");
var objectId = QSBWorldSync.GetIdFromTypeSubset(ItemManager.GetObject(socket));
return true; return true;
} }
@ -62,10 +65,19 @@ namespace QSB.ItemSync.Patches
var parent = (detachableFragment != null) var parent = (detachableFragment != null)
? detachableFragment.transform ? detachableFragment.transform
: targetRigidbody.transform; : targetRigidbody.transform;
var objectId = QSBWorldSync.GetIdFromTypeSubset(ItemManager.GetObject(____heldItem));
____heldItem.DropItem(hit.point, hit.normal, parent, sector, detachableFragment); ____heldItem.DropItem(hit.point, hit.normal, parent, sector, detachableFragment);
____heldItem = null; ____heldItem = null;
Locator.GetToolModeSwapper().UnequipTool(); Locator.GetToolModeSwapper().UnequipTool();
DebugLog.DebugWrite($"Drop item at point:{hit.point}, normal:{hit.normal}, parent:{parent.name}, sector:{sector.name}, fragment:{detachableFragment?.name}."); var parentSector = parent.GetComponentInChildren<Sector>();
if (parentSector != null)
{
var localPos = parentSector.transform.InverseTransformPoint(hit.point);
QSBEventManager.FireEvent(EventNames.QSBDropItem, objectId, localPos, hit.normal, parentSector);
return false;
}
var localPosition = sector.transform.InverseTransformPoint(hit.point);
QSBEventManager.FireEvent(EventNames.QSBDropItem, objectId, localPosition, hit.normal, sector);
return false; return false;
} }
} }

View File

@ -1,9 +1,10 @@
using QSB.WorldSync; using QSB.WorldSync;
using UnityEngine;
namespace QSB.ItemSync.WorldObjects namespace QSB.ItemSync.WorldObjects
{ {
public interface IQSBOWItem : IWorldObjectTypeSubset public interface IQSBOWItem : IWorldObjectTypeSubset
{ {
uint HoldingPlayer { get; set; } void DropItem(Vector3 position, Vector3 normal, Sector sector);
} }
} }

View File

@ -1,7 +1,6 @@
namespace QSB.ItemSync.WorldObjects using QSB.WorldSync;
{
public interface IQSBOWItemSocket
{
} namespace QSB.ItemSync.WorldObjects
{
public interface IQSBOWItemSocket : IWorldObjectTypeSubset { }
} }

View File

@ -1,12 +1,25 @@
using QSB.WorldSync; using OWML.Utils;
using QSB.WorldSync;
using UnityEngine;
namespace QSB.ItemSync.WorldObjects namespace QSB.ItemSync.WorldObjects
{ {
internal class QSBOWItem<T> : WorldObject<T>, IQSBOWItem internal class QSBOWItem<T> : WorldObject<T>, IQSBOWItem
where T : OWItem where T : OWItem
{ {
public uint HoldingPlayer { get; set; }
public override void Init(T attachedObject, int id) { } public override void Init(T attachedObject, int id) { }
public virtual void DropItem(Vector3 position, Vector3 normal, Sector sector)
{
AttachedObject.transform.SetParent(sector.transform);
AttachedObject.transform.localScale = Vector3.one;
var localDropNormal = AttachedObject.GetValue<Vector3>("_localDropNormal");
var lhs = Quaternion.FromToRotation(AttachedObject.transform.TransformDirection(localDropNormal), normal);
AttachedObject.transform.rotation = lhs * AttachedObject.transform.rotation;
var localDropOffset = AttachedObject.GetValue<Vector3>("_localDropOffset");
AttachedObject.transform.position = sector.transform.TransformPoint(position) + AttachedObject.transform.TransformDirection(localDropOffset);
AttachedObject.SetSector(sector);
AttachedObject.SetColliderActivation(true);
}
} }
} }

View File

@ -1,4 +1,6 @@
namespace QSB.ItemSync.WorldObjects using UnityEngine;
namespace QSB.ItemSync.WorldObjects
{ {
internal class QSBScrollItem : QSBOWItem<ScrollItem> internal class QSBScrollItem : QSBOWItem<ScrollItem>
{ {

View File

@ -43,8 +43,6 @@ namespace QSB.OrbSync
foreach (var orb in QSBWorldSync.OldOrbList) foreach (var orb in QSBWorldSync.OldOrbList)
{ {
Popcron.Gizmos.Cube(orb.transform.position, orb.transform.rotation, Vector3.one / 3);
var rails = orb.GetValue<OWRail[]>("_safetyRails"); var rails = orb.GetValue<OWRail[]>("_safetyRails");
if (rails.Length > 0) if (rails.Length > 0)
{ {

View File

@ -221,10 +221,12 @@
<Compile Include="SectorSync\WorldObjects\QSBSector.cs" /> <Compile Include="SectorSync\WorldObjects\QSBSector.cs" />
<Compile Include="SectorSync\QSBSectorManager.cs" /> <Compile Include="SectorSync\QSBSectorManager.cs" />
<Compile Include="TransformSync\TransformSync.cs" /> <Compile Include="TransformSync\TransformSync.cs" />
<Compile Include="Utility\Callback6Args.cs" /> <Compile Include="Utility\CustomCallbacks.cs" />
<Compile Include="Utility\DebugBoxManager.cs" /> <Compile Include="Utility\DebugBoxManager.cs" />
<Compile Include="Utility\DebugZOverride.cs" /> <Compile Include="Utility\DebugZOverride.cs" />
<Compile Include="Utility\Extensions.cs" /> <Compile Include="Utility\Extensions.cs" />
<Compile Include="Utility\GlobalMessenger4Args.cs" />
<Compile Include="Utility\GlobalMessenger5Args.cs" />
<Compile Include="Utility\GlobalMessenger6Args.cs" /> <Compile Include="Utility\GlobalMessenger6Args.cs" />
<Compile Include="Utility\IRepeating.cs" /> <Compile Include="Utility\IRepeating.cs" />
<Compile Include="Utility\OnEnableDisableTracker.cs" /> <Compile Include="Utility\OnEnableDisableTracker.cs" />

View File

@ -59,7 +59,6 @@ namespace QSB.TransformSync
{ {
return; return;
} }
Popcron.Gizmos.Cube(Player.Body.transform.position, Player.Body.transform.rotation, new Vector3(1, 2, 1));
Popcron.Gizmos.Line(ReferenceSector.Position, Player.Body.transform.position, Color.blue, true); Popcron.Gizmos.Line(ReferenceSector.Position, Player.Body.transform.position, Color.blue, true);
Popcron.Gizmos.Sphere(ReferenceSector.Position, 5f, Color.cyan); Popcron.Gizmos.Sphere(ReferenceSector.Position, 5f, Color.cyan);
} }

View File

@ -1 +0,0 @@
public delegate void Callback<T, U, V, W, X, Y>(T arg1, U arg2, V arg3, W arg4, X arg5, Y arg6);

View File

@ -0,0 +1,3 @@
public delegate void Callback<T, U, V, W>(T arg1, U arg2, V arg3, W arg4);
public delegate void Callback<T, U, V, W, X>(T arg1, U arg2, V arg3, W arg4, X arg5);
public delegate void Callback<T, U, V, W, X, Y>(T arg1, U arg2, V arg3, W arg4, X arg5, Y arg6);

View File

@ -0,0 +1,79 @@
using OWML.Common;
using System;
using System.Collections.Generic;
namespace QSB.Utility
{
public static class GlobalMessenger<T, U, V, W>
{
public static void AddListener(string eventType, Callback<T, U, V, W> handler)
{
object obj = _eventTable;
lock (obj)
{
if (!_eventTable.TryGetValue(eventType, out var eventData))
{
eventData = new EventData();
_eventTable.Add(eventType, eventData);
}
eventData.Callbacks.Add(handler);
}
}
public static void RemoveListener(string eventType, Callback<T, U, V, W> handler)
{
object obj = _eventTable;
lock (obj)
{
if (_eventTable.TryGetValue(eventType, out var eventData))
{
var num = eventData.Callbacks.IndexOf(handler);
if (num >= 0)
{
eventData.Callbacks[num] = eventData.Callbacks[eventData.Callbacks.Count - 1];
eventData.Callbacks.RemoveAt(eventData.Callbacks.Count - 1);
}
}
}
}
public static void FireEvent(string eventType, T arg1, U arg2, V arg3, W arg4)
{
object obj = _eventTable;
lock (obj)
{
if (_eventTable.TryGetValue(eventType, out var eventData))
{
if (eventData.IsInvoking)
{
throw new InvalidOperationException("GlobalMessenger does not support recursive FireEvent calls to the same eventType.");
}
eventData.IsInvoking = true;
eventData.Temp.AddRange(eventData.Callbacks);
for (var i = 0; i < eventData.Temp.Count; i++)
{
try
{
eventData.Temp[i](arg1, arg2, arg3, arg4);
}
catch (Exception exception)
{
DebugLog.ToConsole($"Error - {exception.Message}", MessageType.Error);
}
}
eventData.Temp.Clear();
eventData.IsInvoking = false;
}
}
}
private static IDictionary<string, EventData> _eventTable = new Dictionary<string, EventData>(ComparerLibrary.stringEqComparer);
private class EventData
{
public List<Callback<T, U, V, W>> Callbacks = new List<Callback<T, U, V, W>>();
public List<Callback<T, U, V, W>> Temp = new List<Callback<T, U, V, W>>();
public bool IsInvoking;
}
}
}

View File

@ -0,0 +1,79 @@
using OWML.Common;
using System;
using System.Collections.Generic;
namespace QSB.Utility
{
public static class GlobalMessenger<T, U, V, W, X>
{
public static void AddListener(string eventType, Callback<T, U, V, W, X> handler)
{
object obj = _eventTable;
lock (obj)
{
if (!_eventTable.TryGetValue(eventType, out var eventData))
{
eventData = new EventData();
_eventTable.Add(eventType, eventData);
}
eventData.Callbacks.Add(handler);
}
}
public static void RemoveListener(string eventType, Callback<T, U, V, W, X> handler)
{
object obj = _eventTable;
lock (obj)
{
if (_eventTable.TryGetValue(eventType, out var eventData))
{
var num = eventData.Callbacks.IndexOf(handler);
if (num >= 0)
{
eventData.Callbacks[num] = eventData.Callbacks[eventData.Callbacks.Count - 1];
eventData.Callbacks.RemoveAt(eventData.Callbacks.Count - 1);
}
}
}
}
public static void FireEvent(string eventType, T arg1, U arg2, V arg3, W arg4, X arg5)
{
object obj = _eventTable;
lock (obj)
{
if (_eventTable.TryGetValue(eventType, out var eventData))
{
if (eventData.IsInvoking)
{
throw new InvalidOperationException("GlobalMessenger does not support recursive FireEvent calls to the same eventType.");
}
eventData.IsInvoking = true;
eventData.Temp.AddRange(eventData.Callbacks);
for (var i = 0; i < eventData.Temp.Count; i++)
{
try
{
eventData.Temp[i](arg1, arg2, arg3, arg4, arg5);
}
catch (Exception exception)
{
DebugLog.ToConsole($"Error - {exception.Message}", MessageType.Error);
}
}
eventData.Temp.Clear();
eventData.IsInvoking = false;
}
}
}
private static IDictionary<string, EventData> _eventTable = new Dictionary<string, EventData>(ComparerLibrary.stringEqComparer);
private class EventData
{
public List<Callback<T, U, V, W, X>> Callbacks = new List<Callback<T, U, V, W, X>>();
public List<Callback<T, U, V, W, X>> Temp = new List<Callback<T, U, V, W, X>>();
public bool IsInvoking;
}
}
}