mirror of
https://github.com/misternebula/quantum-space-buddies.git
synced 2025-02-23 06:40:56 +00:00
Merge pull request #448 from misternebula/solanum-mask-sync
Solanum mask sync, persistent condition sync, better log sync, aaaaa
This commit is contained in:
commit
cdb2e96e5e
@ -16,10 +16,6 @@ namespace QSB.Animation.NPC
|
||||
QSBWorldSync.Init<QSBSolanumAnimController, SolanumAnimController>();
|
||||
QSBWorldSync.Init<QSBHearthianRecorderEffects, HearthianRecorderEffects>();
|
||||
QSBWorldSync.Init<QSBTravelerEyeController, TravelerEyeController>();
|
||||
|
||||
//MOVE : this is the wrong place to put this... move it to Conversations?
|
||||
QSBWorldSync.OldDialogueTrees.Clear();
|
||||
QSBWorldSync.OldDialogueTrees.AddRange(QSBWorldSync.GetUnityObjects<CharacterDialogueTree>());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -6,7 +6,7 @@ using QSB.ConversationSync;
|
||||
using QSB.Messaging;
|
||||
using QSB.Patches;
|
||||
using QSB.Player;
|
||||
using QSB.Player.Messages;
|
||||
using QSB.TriggerSync.WorldObjects;
|
||||
using QSB.Utility;
|
||||
using QSB.WorldSync;
|
||||
using System.Linq;
|
||||
@ -26,12 +26,18 @@ namespace QSB.Animation.NPC.Patches
|
||||
{
|
||||
if (!WorldObjectManager.AllObjectsReady || ConversationManager.Instance == null)
|
||||
{
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
var playerId = ConversationManager.Instance.GetPlayerTalkingToTree(__instance._dialogueTree);
|
||||
var player = QSBPlayerManager.GetPlayer(playerId);
|
||||
var qsbObj = __instance.GetWorldObject<QSBCharacterAnimController>(); // OPTIMIZE : maybe cache this somewhere... or assess how slow this is
|
||||
|
||||
if (__instance.playerTrackingZone == null)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
var qsbObj = __instance.playerTrackingZone.GetWorldObject<QSBCharacterTrigger>(); // OPTIMIZE : maybe cache this somewhere... or assess how slow this is
|
||||
|
||||
PlayerInfo playerToUse = null;
|
||||
if (__instance._inConversation)
|
||||
@ -48,9 +54,9 @@ namespace QSB.Animation.NPC.Patches
|
||||
: player;
|
||||
}
|
||||
}
|
||||
else if (!__instance.lookOnlyWhenTalking && qsbObj.GetPlayersInHeadZone().Count != 0) // IDEA : maybe this would be more fun if characters looked between players at random times? :P
|
||||
else if (!__instance.lookOnlyWhenTalking && qsbObj.Occupants.Count != 0) // IDEA : maybe this would be more fun if characters looked between players at random times? :P
|
||||
{
|
||||
playerToUse = QSBPlayerManager.GetClosestPlayerToWorldPoint(qsbObj.GetPlayersInHeadZone(), __instance.transform.position);
|
||||
playerToUse = QSBPlayerManager.GetClosestPlayerToWorldPoint(qsbObj.Occupants, __instance.transform.position);
|
||||
}
|
||||
else if (QSBPlayerManager.PlayerList.Count != 0)
|
||||
{
|
||||
@ -65,16 +71,16 @@ namespace QSB.Animation.NPC.Patches
|
||||
if (__instance.lookOnlyWhenTalking)
|
||||
{
|
||||
if (!__instance._inConversation
|
||||
|| qsbObj.GetPlayersInHeadZone().Count == 0
|
||||
|| !qsbObj.GetPlayersInHeadZone().Contains(playerToUse))
|
||||
|| qsbObj.Occupants.Count == 0
|
||||
|| !qsbObj.Occupants.Contains(playerToUse))
|
||||
{
|
||||
targetWeight *= 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (qsbObj.GetPlayersInHeadZone().Count == 0
|
||||
|| !qsbObj.GetPlayersInHeadZone().Contains(playerToUse))
|
||||
if (qsbObj.Occupants.Count == 0
|
||||
|| !qsbObj.Occupants.Contains(playerToUse))
|
||||
{
|
||||
targetWeight *= 0;
|
||||
}
|
||||
@ -88,32 +94,6 @@ namespace QSB.Animation.NPC.Patches
|
||||
|
||||
}
|
||||
|
||||
[HarmonyPrefix]
|
||||
[HarmonyPatch(typeof(CharacterAnimController), nameof(CharacterAnimController.OnZoneExit))]
|
||||
public static bool HeadZoneExit(CharacterAnimController __instance, GameObject input)
|
||||
{
|
||||
if (input.CompareTag("PlayerDetector"))
|
||||
{
|
||||
var qsbObj = __instance.GetWorldObject<QSBCharacterAnimController>();
|
||||
new EnterLeaveMessage(EnterLeaveType.ExitNonNomaiHeadZone, qsbObj.ObjectId).Send();
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
[HarmonyPrefix]
|
||||
[HarmonyPatch(typeof(CharacterAnimController), nameof(CharacterAnimController.OnZoneEntry))]
|
||||
public static bool HeadZoneEntry(CharacterAnimController __instance, GameObject input)
|
||||
{
|
||||
if (input.CompareTag("PlayerDetector"))
|
||||
{
|
||||
var qsbObj = __instance.GetWorldObject<QSBCharacterAnimController>();
|
||||
new EnterLeaveMessage(EnterLeaveType.EnterNonNomaiHeadZone, qsbObj.ObjectId).Send();
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
[HarmonyPrefix]
|
||||
[HarmonyPatch(typeof(FacePlayerWhenTalking), nameof(FacePlayerWhenTalking.OnStartConversation))]
|
||||
public static bool OnStartConversation(FacePlayerWhenTalking __instance)
|
||||
|
@ -1,9 +1,7 @@
|
||||
using HarmonyLib;
|
||||
using QSB.Animation.NPC.WorldObjects;
|
||||
using QSB.Messaging;
|
||||
using QSB.Patches;
|
||||
using QSB.Player;
|
||||
using QSB.Player.Messages;
|
||||
using QSB.WorldSync;
|
||||
using System.Linq;
|
||||
using UnityEngine;
|
||||
@ -26,7 +24,7 @@ namespace QSB.Animation.NPC.Patches
|
||||
}
|
||||
|
||||
var qsbObj = __instance.GetWorldObject<QSBSolanumAnimController>();
|
||||
var playersInHeadZone = qsbObj.GetPlayersInHeadZone();
|
||||
var playersInHeadZone = qsbObj.Trigger.Occupants;
|
||||
|
||||
var targetCamera = playersInHeadZone == null || playersInHeadZone.Count == 0
|
||||
? __instance._playerCameraTransform
|
||||
@ -41,38 +39,12 @@ namespace QSB.Animation.NPC.Patches
|
||||
return false;
|
||||
}
|
||||
|
||||
[HarmonyPrefix]
|
||||
[HarmonyPatch(typeof(NomaiConversationManager), nameof(NomaiConversationManager.OnEnterWatchVolume))]
|
||||
public static bool EnterWatchZone(NomaiConversationManager __instance, GameObject hitObj)
|
||||
{
|
||||
if (hitObj.CompareTag("PlayerDetector"))
|
||||
{
|
||||
var qsbObj = __instance._solanumAnimController.GetWorldObject<QSBSolanumAnimController>();
|
||||
new EnterLeaveMessage(EnterLeaveType.EnterNomaiHeadZone, qsbObj.ObjectId).Send();
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
[HarmonyPrefix]
|
||||
[HarmonyPatch(typeof(NomaiConversationManager), nameof(NomaiConversationManager.OnExitWatchVolume))]
|
||||
public static bool ExitWatchZone(NomaiConversationManager __instance, GameObject hitObj)
|
||||
{
|
||||
if (hitObj.CompareTag("PlayerDetector"))
|
||||
{
|
||||
var qsbObj = __instance._solanumAnimController.GetWorldObject<QSBSolanumAnimController>();
|
||||
new EnterLeaveMessage(EnterLeaveType.ExitNomaiHeadZone, qsbObj.ObjectId).Send();
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
[HarmonyPrefix]
|
||||
[HarmonyPatch(typeof(NomaiConversationManager), nameof(NomaiConversationManager.Update))]
|
||||
public static bool ReplacementUpdate(NomaiConversationManager __instance)
|
||||
{
|
||||
var qsbObj = __instance._solanumAnimController.GetWorldObject<QSBSolanumAnimController>();
|
||||
__instance._playerInWatchVolume = qsbObj.GetPlayersInHeadZone().Any();
|
||||
__instance._playerInWatchVolume = qsbObj.Trigger.Occupants.Any();
|
||||
|
||||
if (!__instance._initialized)
|
||||
{
|
||||
|
@ -1,35 +1,7 @@
|
||||
using QSB.Player;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace QSB.Animation.NPC.WorldObjects
|
||||
namespace QSB.Animation.NPC.WorldObjects
|
||||
{
|
||||
internal class QSBCharacterAnimController : NpcAnimController<CharacterAnimController>
|
||||
{
|
||||
private readonly List<PlayerInfo> _playersInHeadZone = new();
|
||||
|
||||
public List<PlayerInfo> GetPlayersInHeadZone()
|
||||
=> _playersInHeadZone;
|
||||
|
||||
public void AddPlayerToHeadZone(PlayerInfo player)
|
||||
{
|
||||
if (_playersInHeadZone.Contains(player))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
_playersInHeadZone.Add(player);
|
||||
}
|
||||
|
||||
public void RemovePlayerFromHeadZone(PlayerInfo player)
|
||||
{
|
||||
if (!_playersInHeadZone.Contains(player))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
_playersInHeadZone.Remove(player);
|
||||
}
|
||||
|
||||
public override CharacterDialogueTree GetDialogueTree()
|
||||
=> AttachedObject._dialogueTree;
|
||||
|
||||
|
@ -1,34 +1,12 @@
|
||||
using QSB.Player;
|
||||
using QSB.TriggerSync.WorldObjects;
|
||||
using QSB.WorldSync;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
namespace QSB.Animation.NPC.WorldObjects
|
||||
{
|
||||
internal class QSBSolanumAnimController : WorldObject<SolanumAnimController>
|
||||
{
|
||||
private readonly List<PlayerInfo> _playersInHeadZone = new();
|
||||
|
||||
public List<PlayerInfo> GetPlayersInHeadZone()
|
||||
=> _playersInHeadZone;
|
||||
|
||||
public void AddPlayerToHeadZone(PlayerInfo player)
|
||||
{
|
||||
if (_playersInHeadZone.Contains(player))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
_playersInHeadZone.Add(player);
|
||||
}
|
||||
|
||||
public void RemovePlayerFromHeadZone(PlayerInfo player)
|
||||
{
|
||||
if (!_playersInHeadZone.Contains(player))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
_playersInHeadZone.Remove(player);
|
||||
}
|
||||
private QSBSolanumTrigger _trigger;
|
||||
public QSBSolanumTrigger Trigger => _trigger ??= QSBWorldSync.GetWorldObjects<QSBSolanumTrigger>().Single();
|
||||
}
|
||||
}
|
||||
|
@ -2,12 +2,12 @@
|
||||
{
|
||||
public enum AnimationType
|
||||
{
|
||||
Chert = 0,
|
||||
Esker = 1,
|
||||
Feldspar = 2,
|
||||
Gabbro = 3,
|
||||
PlayerSuited = 4,
|
||||
PlayerUnsuited = 5,
|
||||
Riebeck = 6
|
||||
Chert,
|
||||
Esker,
|
||||
Feldspar,
|
||||
Gabbro,
|
||||
PlayerSuited,
|
||||
PlayerUnsuited,
|
||||
Riebeck
|
||||
}
|
||||
}
|
@ -45,6 +45,7 @@ namespace QSB.Audio
|
||||
bool randomize)
|
||||
{
|
||||
var go = new GameObject(name);
|
||||
go.SetActive(false);
|
||||
go.transform.parent = parent;
|
||||
go.transform.localPosition = Vector3.zero;
|
||||
go.transform.localScale = Vector3.one;
|
||||
@ -66,6 +67,8 @@ namespace QSB.Audio
|
||||
owAudioSource._track = track;
|
||||
owAudioSource._randomizePlayheadOnAwake = randomize;
|
||||
|
||||
go.SetActive(true);
|
||||
|
||||
return owAudioSource;
|
||||
}
|
||||
}
|
||||
|
@ -7,7 +7,6 @@
|
||||
AliveInSolarSystem,
|
||||
DeadInSolarSystem,
|
||||
AliveInEye,
|
||||
WaitingForOthersToDie,
|
||||
WaitingForOthersToBeReady,
|
||||
WatchingLongCredits,
|
||||
WatchingShortCredits
|
||||
|
@ -2,9 +2,9 @@
|
||||
{
|
||||
public enum ConversationType
|
||||
{
|
||||
Character = 0,
|
||||
Player = 1,
|
||||
CloseCharacter = 2,
|
||||
ClosePlayer = 3
|
||||
Character,
|
||||
Player,
|
||||
CloseCharacter,
|
||||
ClosePlayer
|
||||
}
|
||||
}
|
@ -1,5 +1,4 @@
|
||||
using QSB.Messaging;
|
||||
using QSB.Player.TransformSync;
|
||||
using QSB.WorldSync;
|
||||
using QuantumUNET.Transport;
|
||||
|
||||
@ -7,16 +6,6 @@ namespace QSB.ConversationSync.Messages
|
||||
{
|
||||
public class DialogueConditionMessage : QSBMessage
|
||||
{
|
||||
static DialogueConditionMessage() => GlobalMessenger<string, bool>.AddListener(OWEvents.DialogueConditionChanged, Handler);
|
||||
|
||||
private static void Handler(string name, bool state)
|
||||
{
|
||||
if (PlayerTransformSync.LocalInstance)
|
||||
{
|
||||
new DialogueConditionMessage(name, state).Send();
|
||||
}
|
||||
}
|
||||
|
||||
private string ConditionName;
|
||||
private bool ConditionState;
|
||||
|
||||
@ -47,7 +36,32 @@ namespace QSB.ConversationSync.Messages
|
||||
QSBWorldSync.SetDialogueCondition(ConditionName, ConditionState);
|
||||
}
|
||||
|
||||
DialogueConditionManager.SharedInstance.SetConditionState(ConditionName, ConditionState);
|
||||
var sharedInstance = DialogueConditionManager.SharedInstance;
|
||||
|
||||
var flag = true;
|
||||
if (sharedInstance.ConditionExists(ConditionName))
|
||||
{
|
||||
if (sharedInstance._dictConditions[ConditionName] == ConditionState)
|
||||
{
|
||||
flag = false;
|
||||
}
|
||||
|
||||
sharedInstance._dictConditions[ConditionName] = ConditionState;
|
||||
}
|
||||
else
|
||||
{
|
||||
sharedInstance.AddCondition(ConditionName, ConditionState);
|
||||
}
|
||||
|
||||
if (flag)
|
||||
{
|
||||
GlobalMessenger<string, bool>.FireEvent("DialogueConditionChanged", ConditionName, ConditionState);
|
||||
}
|
||||
|
||||
if (ConditionName == "LAUNCH_CODES_GIVEN")
|
||||
{
|
||||
PlayerData.LearnLaunchCodes();
|
||||
}
|
||||
}
|
||||
|
||||
public override void OnReceiveLocal()
|
||||
|
73
QSB/ConversationSync/Messages/PersistentConditionMessage.cs
Normal file
73
QSB/ConversationSync/Messages/PersistentConditionMessage.cs
Normal file
@ -0,0 +1,73 @@
|
||||
using QSB.Messaging;
|
||||
using QSB.Utility;
|
||||
using QSB.WorldSync;
|
||||
using QuantumUNET.Transport;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace QSB.ConversationSync.Messages
|
||||
{
|
||||
internal class PersistentConditionMessage : QSBMessage
|
||||
{
|
||||
private string _conditionName;
|
||||
private bool _conditionState;
|
||||
|
||||
public PersistentConditionMessage(string condition, bool state)
|
||||
{
|
||||
_conditionName = condition;
|
||||
_conditionState = state;
|
||||
}
|
||||
|
||||
public override void Serialize(QNetworkWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
writer.Write(_conditionName);
|
||||
writer.Write(_conditionState);
|
||||
}
|
||||
|
||||
public override void Deserialize(QNetworkReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
_conditionName = reader.ReadString();
|
||||
_conditionState = reader.ReadBoolean();
|
||||
}
|
||||
|
||||
public override void OnReceiveRemote()
|
||||
{
|
||||
if (QSBCore.IsHost)
|
||||
{
|
||||
QSBWorldSync.SetPersistentCondition(_conditionName, _conditionState);
|
||||
}
|
||||
|
||||
var gameSave = PlayerData._currentGameSave;
|
||||
if (gameSave.dictConditions.ContainsKey(_conditionName))
|
||||
{
|
||||
gameSave.dictConditions[_conditionName] = _conditionState;
|
||||
}
|
||||
else
|
||||
{
|
||||
gameSave.dictConditions.Add(_conditionName, _conditionState);
|
||||
}
|
||||
|
||||
if (_conditionName
|
||||
is not "LAUNCH_CODES_GIVEN"
|
||||
and not "PLAYER_ENTERED_TIMELOOPCORE"
|
||||
and not "PROBE_ENTERED_TIMELOOPCORE"
|
||||
and not "PLAYER_ENTERED_TIMELOOPCORE_MULTIPLE")
|
||||
{
|
||||
PlayerData.SaveCurrentGame();
|
||||
}
|
||||
}
|
||||
|
||||
public override void OnReceiveLocal()
|
||||
{
|
||||
if (QSBCore.IsHost)
|
||||
{
|
||||
QSBWorldSync.SetPersistentCondition(_conditionName, _conditionState);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -7,6 +7,7 @@ using QSB.Patches;
|
||||
using QSB.Player;
|
||||
using QSB.Utility;
|
||||
using QSB.WorldSync;
|
||||
using System.Linq;
|
||||
|
||||
namespace QSB.ConversationSync.Patches
|
||||
{
|
||||
@ -15,6 +16,23 @@ namespace QSB.ConversationSync.Patches
|
||||
{
|
||||
public override QSBPatchTypes Type => QSBPatchTypes.OnClientConnect;
|
||||
|
||||
public static readonly string[] PersistentConditionsToSync =
|
||||
{
|
||||
"MET_SOLANUM",
|
||||
"MET_PRISONER",
|
||||
"TALKED_TO_GABBRO",
|
||||
"GABBRO_MERGE_TRIGGERED",
|
||||
"KNOWS_MEDITATION"
|
||||
};
|
||||
|
||||
[HarmonyPrefix]
|
||||
[HarmonyPatch(typeof(DialogueConditionManager), nameof(DialogueConditionManager.SetConditionState))]
|
||||
public static bool SetConditionState(string conditionName, bool conditionState)
|
||||
{
|
||||
new DialogueConditionMessage(conditionName, conditionState).Send();
|
||||
return true;
|
||||
}
|
||||
|
||||
[HarmonyPrefix]
|
||||
[HarmonyPatch(typeof(CharacterDialogueTree), nameof(CharacterDialogueTree.StartConversation))]
|
||||
public static void CharacterDialogueTree_StartConversation(CharacterDialogueTree __instance)
|
||||
@ -144,5 +162,15 @@ namespace QSB.ConversationSync.Patches
|
||||
__result = true;
|
||||
return false;
|
||||
}
|
||||
|
||||
[HarmonyPostfix]
|
||||
[HarmonyPatch(typeof(GameSave), nameof(GameSave.SetPersistentCondition))]
|
||||
public static void SetPersistentCondition(string condition, bool state)
|
||||
{
|
||||
if (PersistentConditionsToSync.Contains(condition))
|
||||
{
|
||||
new PersistentConditionMessage(condition, state).Send();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -28,7 +28,9 @@ namespace QSB.ElevatorSync.WorldObjects
|
||||
_owAudioSourceOneShot = AttachedObject._owAudioSourceOneShot;
|
||||
_owAudioSourceLP = AttachedObject._owAudioSourceLP;
|
||||
|
||||
var boxShape = AttachedObject.gameObject.AddComponent<BoxShape>();
|
||||
// BUG : This won't work for the log lift! need to make a different trigger for that
|
||||
|
||||
var boxShape = AttachedObject.gameObject.GetAddComponent<BoxShape>();
|
||||
boxShape.center = new Vector3(0, 1.75f, 0.25f);
|
||||
boxShape.size = new Vector3(3, 3.5f, 3);
|
||||
|
||||
@ -74,5 +76,16 @@ namespace QSB.ElevatorSync.WorldObjects
|
||||
_owAudioSourceLP.FadeIn(0.5f);
|
||||
_interactVolume.DisableInteraction();
|
||||
}
|
||||
|
||||
public override void DisplayLines()
|
||||
{
|
||||
var boxShape = (BoxShape)_elevatorTrigger._shape;
|
||||
Popcron.Gizmos.Cube(
|
||||
ShapeUtil.Box.CalcWorldSpaceCenter(boxShape),
|
||||
boxShape.transform.rotation,
|
||||
ShapeUtil.Box.CalcWorldSpaceSize(boxShape),
|
||||
_elevatorTrigger.IsTrackingObject(Locator.GetPlayerDetector()) ? Color.green : Color.white
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
@ -1,127 +0,0 @@
|
||||
using QSB.Messaging;
|
||||
using QSB.Player;
|
||||
using QSB.Player.Messages;
|
||||
using QSB.Utility;
|
||||
using QSB.WorldSync;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using UnityEngine;
|
||||
|
||||
namespace QSB.EyeOfTheUniverse.CosmicInflation
|
||||
{
|
||||
internal class InflationManager : WorldObjectManager
|
||||
{
|
||||
public static InflationManager Instance { get; private set; }
|
||||
|
||||
private readonly List<PlayerInfo> _playersInFog = new();
|
||||
private CosmicInflationController _controller;
|
||||
|
||||
public override WorldObjectType WorldObjectType => WorldObjectType.Eye;
|
||||
|
||||
public override void Awake()
|
||||
{
|
||||
base.Awake();
|
||||
Instance = this;
|
||||
|
||||
QSBPlayerManager.OnRemovePlayer += OnPlayerLeave;
|
||||
}
|
||||
|
||||
private void OnPlayerLeave(uint id)
|
||||
{
|
||||
_playersInFog.Remove(QSBPlayerManager.GetPlayer(id));
|
||||
|
||||
// wait 1 frame for player to be removed
|
||||
QSBCore.UnityEvents.FireOnNextUpdate(() =>
|
||||
{
|
||||
if (QSBCore.IsInMultiplayer && _playersInFog.Count == QSBPlayerManager.PlayerList.Count)
|
||||
{
|
||||
StartCollapse();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
protected override void RebuildWorldObjects(OWScene scene)
|
||||
{
|
||||
_playersInFog.Clear();
|
||||
|
||||
if (_controller != null)
|
||||
{
|
||||
_controller._smokeSphereTrigger.OnEntry -= OnEntry;
|
||||
}
|
||||
|
||||
_controller = QSBWorldSync.GetUnityObjects<CosmicInflationController>().First();
|
||||
_controller._smokeSphereTrigger.OnEntry -= _controller.OnEnterFogSphere;
|
||||
|
||||
_controller._smokeSphereTrigger.OnEntry += OnEntry;
|
||||
}
|
||||
|
||||
private void OnEntry(GameObject hitObj)
|
||||
{
|
||||
if (hitObj.CompareTag("PlayerCameraDetector") && _controller._state == CosmicInflationController.State.ReadyToCollapse)
|
||||
{
|
||||
_controller._smokeSphereTrigger.SetTriggerActivation(false);
|
||||
_controller._probeDestroyTrigger.SetTriggerActivation(false);
|
||||
new EnterLeaveMessage(EnterLeaveType.EnterCosmicFog).Send();
|
||||
|
||||
DebugLog.DebugWrite("disable input, wait for other players to enter");
|
||||
|
||||
var repelVolume = (WhiteHoleFluidVolume)_controller._repelVolume;
|
||||
repelVolume._flowSpeed = -repelVolume._flowSpeed;
|
||||
repelVolume._massiveFlowSpeed = -repelVolume._massiveFlowSpeed;
|
||||
repelVolume.SetVolumeActivation(true);
|
||||
QSBPlayerManager.HideAllPlayers();
|
||||
|
||||
ReticleController.Hide();
|
||||
Locator.GetFlashlight().TurnOff(false);
|
||||
Locator.GetPromptManager().SetPromptsVisible(false);
|
||||
OWInput.ChangeInputMode(InputMode.None);
|
||||
}
|
||||
}
|
||||
|
||||
public void Enter(PlayerInfo player)
|
||||
{
|
||||
_playersInFog.Add(player);
|
||||
|
||||
if (player != QSBPlayerManager.LocalPlayer)
|
||||
{
|
||||
DebugLog.DebugWrite($"fade out player {player.PlayerId}");
|
||||
player.DitheringAnimator.SetVisible(false, 3);
|
||||
}
|
||||
|
||||
if (_playersInFog.Count == QSBPlayerManager.PlayerList.Count)
|
||||
{
|
||||
StartCollapse();
|
||||
}
|
||||
}
|
||||
|
||||
private void StartCollapse()
|
||||
{
|
||||
DebugLog.DebugWrite("fade in everyone, fog sphere collapse");
|
||||
|
||||
var repelVolume = (WhiteHoleFluidVolume)_controller._repelVolume;
|
||||
repelVolume.SetVolumeActivation(false);
|
||||
QSBPlayerManager.ShowAllPlayers();
|
||||
|
||||
_controller._state = CosmicInflationController.State.Collapsing;
|
||||
_controller._stateChangeTime = Time.time;
|
||||
_controller._collapseStartPos = _controller._possibilitySphereRoot.localPosition;
|
||||
_controller._smokeSphereTrigger.SetTriggerActivation(false);
|
||||
_controller._inflationLight.FadeTo(1f, 1f);
|
||||
_controller._possibilitySphereController.OnCollapse();
|
||||
if (_controller._campsiteController.GetUseAltPostCollapseSocket())
|
||||
{
|
||||
_controller._playerPostCollapseSocket = _controller._altPlayerPostCollapseSocket;
|
||||
_controller._altTravelerToHidePostCollapse.SetActive(false);
|
||||
}
|
||||
|
||||
Locator.GetPlayerBody().SetPosition(_controller._playerPostCollapseSocket.position);
|
||||
Locator.GetPlayerBody().SetRotation(_controller._playerPostCollapseSocket.rotation);
|
||||
Locator.GetPlayerBody().SetVelocity(-_controller._playerPostCollapseSocket.forward);
|
||||
Locator.GetPlayerTransform().GetRequiredComponent<PlayerLockOnTargeting>().LockOn(_controller._possibilitySphereRoot, 2f);
|
||||
foreach (var particles in _controller._smokeSphereParticles)
|
||||
{
|
||||
particles.Stop();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -1,9 +0,0 @@
|
||||
using QSB.Patches;
|
||||
|
||||
namespace QSB.EyeOfTheUniverse.CosmicInflation.Patches
|
||||
{
|
||||
internal class InflationPatches : QSBPatch
|
||||
{
|
||||
public override QSBPatchTypes Type => QSBPatchTypes.OnClientConnect;
|
||||
}
|
||||
}
|
@ -1,6 +1,5 @@
|
||||
using QSB.Messaging;
|
||||
using QSB.Player.TransformSync;
|
||||
using QSB.Utility;
|
||||
using QSB.WorldSync;
|
||||
using QuantumUNET.Transport;
|
||||
using System;
|
||||
@ -10,10 +9,18 @@ namespace QSB.EyeOfTheUniverse.EyeStateSync.Messages
|
||||
{
|
||||
internal class FlickerMessage : QSBMessage
|
||||
{
|
||||
public static bool IgnoreNextMessage;
|
||||
|
||||
static FlickerMessage() => GlobalMessenger<float, float>.AddListener(OWEvents.FlickerOffAndOn, Handler);
|
||||
|
||||
private static void Handler(float offDuration, float onDuration)
|
||||
{
|
||||
if (IgnoreNextMessage)
|
||||
{
|
||||
IgnoreNextMessage = false;
|
||||
return;
|
||||
}
|
||||
|
||||
if (PlayerTransformSync.LocalInstance)
|
||||
{
|
||||
new FlickerMessage(offDuration, onDuration).Send();
|
||||
|
@ -5,6 +5,6 @@ namespace QSB.EyeOfTheUniverse.InstrumentSync.Messages
|
||||
{
|
||||
internal class GatherInstrumentMessage : QSBWorldObjectMessage<QSBQuantumInstrument>
|
||||
{
|
||||
public override void OnReceiveRemote() => WorldObject.AttachedObject.Gather();
|
||||
public override void OnReceiveRemote() => WorldObject.Gather();
|
||||
}
|
||||
}
|
||||
|
@ -1,8 +1,21 @@
|
||||
using QSB.WorldSync;
|
||||
using QSB.Player;
|
||||
using QSB.WorldSync;
|
||||
using System.Linq;
|
||||
|
||||
namespace QSB.EyeOfTheUniverse.InstrumentSync.WorldObjects
|
||||
{
|
||||
internal class QSBQuantumInstrument : WorldObject<QuantumInstrument>
|
||||
{
|
||||
public void Gather()
|
||||
{
|
||||
AttachedObject.Gather();
|
||||
|
||||
var maskZoneController = QSBWorldSync.GetUnityObjects<MaskZoneController>().First();
|
||||
if (maskZoneController._maskInstrument == AttachedObject)
|
||||
{
|
||||
// remote gathering solanum mask - make all players visible
|
||||
QSBPlayerManager.ShowAllPlayers();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
46
QSB/EyeOfTheUniverse/MaskSync/MaskManager.cs
Normal file
46
QSB/EyeOfTheUniverse/MaskSync/MaskManager.cs
Normal file
@ -0,0 +1,46 @@
|
||||
using QSB.EyeOfTheUniverse.EyeStateSync.Messages;
|
||||
using QSB.Messaging;
|
||||
using QSB.Player;
|
||||
using QSB.Utility;
|
||||
using QSB.WorldSync;
|
||||
using System.Linq;
|
||||
using UnityEngine;
|
||||
|
||||
namespace QSB.EyeOfTheUniverse.MaskSync
|
||||
{
|
||||
internal class MaskManager : MonoBehaviour
|
||||
{
|
||||
private static bool _flickering;
|
||||
private static float _flickerOutTime;
|
||||
|
||||
public void Awake() => QSBSceneManager.OnSceneLoaded += OnSceneLoaded;
|
||||
|
||||
private static void OnSceneLoaded(OWScene oldScene, OWScene newScene, bool inUniverse)
|
||||
{
|
||||
_flickering = false;
|
||||
_flickerOutTime = 0f;
|
||||
}
|
||||
|
||||
public static void FlickerOutShuttle()
|
||||
{
|
||||
FlickerMessage.IgnoreNextMessage = true;
|
||||
GlobalMessenger<float, float>.FireEvent(OWEvents.FlickerOffAndOn, 0.5f, 0.5f);
|
||||
_flickerOutTime = Time.time + 0.5f;
|
||||
_flickering = true;
|
||||
|
||||
// hide all players in shuttle
|
||||
QSBPlayerManager.PlayerList.Where(x => x.IsInEyeShuttle).ForEach(x => x.DitheringAnimator.SetVisibleImmediate(false));
|
||||
}
|
||||
|
||||
private void Update()
|
||||
{
|
||||
if (_flickering && Time.time > _flickerOutTime)
|
||||
{
|
||||
var controller = QSBWorldSync.GetUnityObjects<EyeShuttleController>().First();
|
||||
controller._shuttleObject.SetActive(false);
|
||||
_flickering = false;
|
||||
_flickerOutTime = 0f;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
25
QSB/EyeOfTheUniverse/MaskSync/Patches/MaskPatches.cs
Normal file
25
QSB/EyeOfTheUniverse/MaskSync/Patches/MaskPatches.cs
Normal file
@ -0,0 +1,25 @@
|
||||
using HarmonyLib;
|
||||
using QSB.Patches;
|
||||
|
||||
namespace QSB.EyeOfTheUniverse.MaskSync.Patches
|
||||
{
|
||||
internal class MaskPatches : QSBPatch
|
||||
{
|
||||
public override QSBPatchTypes Type => QSBPatchTypes.OnClientConnect;
|
||||
|
||||
[HarmonyPrefix]
|
||||
[HarmonyPatch(typeof(EyeShuttleController), nameof(EyeShuttleController.OnLaunchSlotActivated))]
|
||||
public static bool DontLaunch(EyeShuttleController __instance)
|
||||
{
|
||||
if (__instance._isPlayerInside)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
MaskManager.FlickerOutShuttle();
|
||||
__instance.enabled = false;
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
@ -1,80 +0,0 @@
|
||||
using QSB.Messaging;
|
||||
using QSB.Player;
|
||||
using QSB.Player.Messages;
|
||||
using QSB.WorldSync;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using UnityEngine;
|
||||
|
||||
namespace QSB.EyeOfTheUniverse.VesselSync
|
||||
{
|
||||
internal class VesselManager : WorldObjectManager
|
||||
{
|
||||
public static VesselManager Instance { get; private set; }
|
||||
|
||||
private readonly List<PlayerInfo> _playersInCage = new();
|
||||
private VesselWarpController _warpController;
|
||||
|
||||
public override WorldObjectType WorldObjectType => WorldObjectType.Both;
|
||||
|
||||
public override void Awake()
|
||||
{
|
||||
base.Awake();
|
||||
Instance = this;
|
||||
}
|
||||
|
||||
protected override void RebuildWorldObjects(OWScene scene)
|
||||
{
|
||||
_playersInCage.Clear();
|
||||
|
||||
if (_warpController != null)
|
||||
{
|
||||
_warpController._cageTrigger.OnEntry -= OnEntry;
|
||||
_warpController._cageTrigger.OnExit -= OnExit;
|
||||
}
|
||||
|
||||
_warpController = QSBWorldSync.GetUnityObjects<VesselWarpController>().First();
|
||||
_warpController._cageTrigger.OnExit -= _warpController.OnExitCageTrigger;
|
||||
|
||||
_warpController._cageTrigger.OnEntry += OnEntry;
|
||||
_warpController._cageTrigger.OnExit += OnExit;
|
||||
}
|
||||
|
||||
private static void OnEntry(GameObject hitObj)
|
||||
{
|
||||
if (hitObj.CompareTag("PlayerDetector"))
|
||||
{
|
||||
new EnterLeaveMessage(EnterLeaveType.EnterVesselCage).Send();
|
||||
}
|
||||
}
|
||||
|
||||
private static void OnExit(GameObject hitObj)
|
||||
{
|
||||
if (hitObj.CompareTag("PlayerDetector"))
|
||||
{
|
||||
new EnterLeaveMessage(EnterLeaveType.ExitVesselCage).Send();
|
||||
}
|
||||
}
|
||||
|
||||
public void Enter(PlayerInfo player)
|
||||
{
|
||||
_playersInCage.Add(player);
|
||||
}
|
||||
|
||||
public void Exit(PlayerInfo player)
|
||||
{
|
||||
_playersInCage.Remove(player);
|
||||
|
||||
if (_playersInCage.Count == 0 && _warpController._hasPower)
|
||||
{
|
||||
var obj = _warpController;
|
||||
obj._cageClosed = true;
|
||||
obj._cageAnimator.TranslateToLocalPosition(new Vector3(0f, -8.1f, 0f), 5f);
|
||||
obj._cageAnimator.RotateToLocalEulerAngles(new Vector3(0f, 180f, 0f), 5f);
|
||||
obj._cageAnimator.OnTranslationComplete -= obj.OnCageAnimationComplete;
|
||||
obj._cageAnimator.OnTranslationComplete += obj.OnCageAnimationComplete;
|
||||
obj._cageLoopingAudio.FadeIn(1f);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -2,7 +2,7 @@
|
||||
{
|
||||
public enum CameraMode
|
||||
{
|
||||
FirstPerson = 0,
|
||||
ThirdPerson = 1
|
||||
FirstPerson,
|
||||
ThirdPerson
|
||||
}
|
||||
}
|
@ -56,9 +56,9 @@ namespace QSB.ItemSync.WorldObjects.Items
|
||||
|
||||
public override void OnRemoval() => QSBPlayerManager.OnRemovePlayer -= OnPlayerLeave;
|
||||
|
||||
private void OnPlayerLeave(uint player)
|
||||
private void OnPlayerLeave(PlayerInfo player)
|
||||
{
|
||||
if (HoldingPlayer != player)
|
||||
if (HoldingPlayer != player.PlayerId)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
@ -5,6 +5,7 @@ using QSB.SaveSync.Messages;
|
||||
using QSB.Utility;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Text.RegularExpressions;
|
||||
using UnityEngine;
|
||||
using UnityEngine.Networking;
|
||||
using UnityEngine.UI;
|
||||
@ -151,6 +152,7 @@ namespace QSB.Menus
|
||||
{
|
||||
IPPopup = MenuApi.MakeInputFieldPopup("IP Address", "IP Address", "Connect", "Cancel");
|
||||
IPPopup.OnPopupConfirm += Connect;
|
||||
IPPopup.OnPopupValidate += Validate;
|
||||
|
||||
InfoPopup = MenuApi.MakeInfoPopup("", "");
|
||||
InfoPopup.OnDeactivateMenu += OnCloseInfoPopup;
|
||||
@ -222,15 +224,11 @@ namespace QSB.Menus
|
||||
CreateCommonPopups();
|
||||
|
||||
ClientButton = MenuApi.TitleScreen_MakeMenuOpenButton("CONNECT TO MULTIPLAYER", _ClientButtonIndex, IPPopup);
|
||||
var loadEye = MenuApi.TitleScreen_MakeSceneLoadButton("debug load eye", _ClientButtonIndex + 1, SubmitActionLoadScene.LoadableScenes.EYE);
|
||||
|
||||
_loadingText = ClientButton.transform.GetChild(0).GetChild(1).GetComponent<Text>();
|
||||
|
||||
ResumeGameButton = GameObject.Find("MainMenuLayoutGroup/Button-ResumeGame");
|
||||
NewGameButton = GameObject.Find("MainMenuLayoutGroup/Button-NewGame");
|
||||
|
||||
SetButtonActive(loadEye, QSBCore.DebugMode);
|
||||
|
||||
if (QSBCore.IsInMultiplayer)
|
||||
{
|
||||
SetButtonActive(ClientButton, false);
|
||||
@ -310,13 +308,16 @@ namespace QSB.Menus
|
||||
DisconnectPopup._labelText.text = popupText;
|
||||
}
|
||||
|
||||
private bool Validate()
|
||||
{
|
||||
var inputText = ((PopupInputMenu)IPPopup).GetInputText();
|
||||
var regex = new Regex(@"\A(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\z");
|
||||
return inputText == "localhost" || regex.Match(inputText).Success;
|
||||
}
|
||||
|
||||
private void Connect()
|
||||
{
|
||||
var address = string.Concat(((PopupInputMenu)IPPopup).GetInputText().Where(c => !char.IsWhiteSpace(c)));
|
||||
if (address.Length == 0)
|
||||
{
|
||||
address = QSBCore.DefaultServerIP;
|
||||
}
|
||||
var address = ((PopupInputMenu)IPPopup).GetInputText();
|
||||
|
||||
QSBNetworkManager.Instance.networkAddress = address;
|
||||
QSBNetworkManager.Instance.StartClient();
|
||||
|
@ -19,7 +19,6 @@
|
||||
public const string EquipTranslator = nameof(EquipTranslator);
|
||||
public const string UnequipTranslator = nameof(UnequipTranslator);
|
||||
public const string WakeUp = nameof(WakeUp);
|
||||
public const string DialogueConditionChanged = nameof(DialogueConditionChanged);
|
||||
public const string PlayerEnterQuantumMoon = nameof(PlayerEnterQuantumMoon);
|
||||
public const string PlayerExitQuantumMoon = nameof(PlayerExitQuantumMoon);
|
||||
public const string EnterRoastingMode = nameof(EnterRoastingMode);
|
||||
|
@ -59,12 +59,14 @@ namespace QSB.OrbSync.TransformSync
|
||||
_attachedBody = AttachedObject.GetAttachedOWRigidbody();
|
||||
SetReferenceTransform(_attachedBody.GetOrigParent());
|
||||
|
||||
/*
|
||||
if (_attachedBody.GetOrigParent() == Locator.GetRootTransform())
|
||||
{
|
||||
DebugLog.DebugWrite($"{LogName} with AttachedObject {AttachedObject.name} had it's original parent as SolarSystemRoot - Disabling...");
|
||||
enabled = false;
|
||||
return;
|
||||
}
|
||||
*/
|
||||
|
||||
if (QSBCore.IsHost)
|
||||
{
|
||||
|
@ -2,9 +2,9 @@
|
||||
{
|
||||
public enum QSBPatchTypes
|
||||
{
|
||||
OnClientConnect = 0,
|
||||
OnNonServerClientConnect = 1,
|
||||
OnServerClientConnect = 2,
|
||||
RespawnTime = 3
|
||||
OnClientConnect,
|
||||
OnNonServerClientConnect,
|
||||
OnServerClientConnect,
|
||||
RespawnTime
|
||||
}
|
||||
}
|
@ -2,20 +2,11 @@
|
||||
{
|
||||
public enum EnterLeaveType
|
||||
{
|
||||
EnterMoon = 0,
|
||||
ExitMoon = 1,
|
||||
EnterShrine = 2,
|
||||
ExitShrine = 3,
|
||||
EnterPlatform = 4,
|
||||
ExitPlatform = 5,
|
||||
EnterNonNomaiHeadZone = 6,
|
||||
ExitNonNomaiHeadZone = 7,
|
||||
EnterShip = 8,
|
||||
ExitShip = 9,
|
||||
EnterNomaiHeadZone = 10,
|
||||
ExitNomaiHeadZone = 11,
|
||||
EnterVesselCage = 12,
|
||||
ExitVesselCage = 13,
|
||||
EnterCosmicFog = 14,
|
||||
EnterMoon,
|
||||
ExitMoon,
|
||||
EnterPlatform,
|
||||
ExitPlatform,
|
||||
EnterShip,
|
||||
ExitShip,
|
||||
}
|
||||
}
|
||||
|
@ -2,7 +2,6 @@
|
||||
{
|
||||
public enum GamePlatform
|
||||
{
|
||||
None,
|
||||
Steam,
|
||||
Epic
|
||||
}
|
||||
|
@ -1,7 +1,4 @@
|
||||
using OWML.Common;
|
||||
using QSB.Animation.NPC.WorldObjects;
|
||||
using QSB.EyeOfTheUniverse.CosmicInflation;
|
||||
using QSB.EyeOfTheUniverse.VesselSync;
|
||||
using QSB.Messaging;
|
||||
using QSB.Player.TransformSync;
|
||||
using QSB.PoolSync;
|
||||
@ -65,12 +62,6 @@ namespace QSB.Player.Messages
|
||||
case EnterLeaveType.ExitMoon:
|
||||
player.IsInMoon = false;
|
||||
break;
|
||||
case EnterLeaveType.EnterShrine:
|
||||
player.IsInShrine = true;
|
||||
break;
|
||||
case EnterLeaveType.ExitShrine:
|
||||
player.IsInShrine = false;
|
||||
break;
|
||||
case EnterLeaveType.EnterPlatform:
|
||||
CustomNomaiRemoteCameraPlatform.CustomPlatformList[ObjectId]
|
||||
.OnRemotePlayerEnter(From);
|
||||
@ -79,33 +70,12 @@ namespace QSB.Player.Messages
|
||||
CustomNomaiRemoteCameraPlatform.CustomPlatformList[ObjectId]
|
||||
.OnRemotePlayerExit(From);
|
||||
break;
|
||||
case EnterLeaveType.EnterNonNomaiHeadZone:
|
||||
ObjectId.GetWorldObject<QSBCharacterAnimController>().AddPlayerToHeadZone(player);
|
||||
break;
|
||||
case EnterLeaveType.ExitNonNomaiHeadZone:
|
||||
ObjectId.GetWorldObject<QSBCharacterAnimController>().RemovePlayerFromHeadZone(player);
|
||||
break;
|
||||
case EnterLeaveType.EnterNomaiHeadZone:
|
||||
ObjectId.GetWorldObject<QSBSolanumAnimController>().AddPlayerToHeadZone(player);
|
||||
break;
|
||||
case EnterLeaveType.ExitNomaiHeadZone:
|
||||
ObjectId.GetWorldObject<QSBSolanumAnimController>().RemovePlayerFromHeadZone(player);
|
||||
break;
|
||||
case EnterLeaveType.EnterShip:
|
||||
ShipManager.Instance.AddPlayerToShip(player);
|
||||
break;
|
||||
case EnterLeaveType.ExitShip:
|
||||
ShipManager.Instance.RemovePlayerFromShip(player);
|
||||
break;
|
||||
case EnterLeaveType.EnterVesselCage:
|
||||
VesselManager.Instance.Enter(player);
|
||||
break;
|
||||
case EnterLeaveType.ExitVesselCage:
|
||||
VesselManager.Instance.Exit(player);
|
||||
break;
|
||||
case EnterLeaveType.EnterCosmicFog:
|
||||
InflationManager.Instance.Enter(player);
|
||||
break;
|
||||
default:
|
||||
DebugLog.ToConsole($"Warning - Unknown EnterLeaveType : {Value}", MessageType.Warning);
|
||||
break;
|
||||
|
@ -16,6 +16,8 @@ using QSB.Tools.TranslatorTool.TranslationSync.Messages;
|
||||
using QSB.Tools.TranslatorTool.TranslationSync.WorldObjects;
|
||||
using QSB.TornadoSync.Messages;
|
||||
using QSB.TornadoSync.WorldObjects;
|
||||
using QSB.TriggerSync.Messages;
|
||||
using QSB.TriggerSync.WorldObjects;
|
||||
using QSB.Utility;
|
||||
using QSB.WorldSync;
|
||||
using System.Linq;
|
||||
@ -126,6 +128,9 @@ namespace QSB.Player.Messages
|
||||
|
||||
QSBWorldSync.GetWorldObjects<QSBTornado>().ForEach(tornado
|
||||
=> tornado.SendMessage(new TornadoFormStateMessage(tornado.FormState) { To = From }));
|
||||
|
||||
QSBWorldSync.GetWorldObjects<IQSBTrigger>().ForEach(trigger
|
||||
=> trigger.SendMessage(new TriggerResyncMessage(trigger.Occupants) { To = From }));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -39,6 +39,7 @@ namespace QSB.Player
|
||||
public bool IsReady { get; set; }
|
||||
public bool IsInMoon { get; set; }
|
||||
public bool IsInShrine { get; set; }
|
||||
public bool IsInEyeShuttle { get; set; }
|
||||
public IQSBQuantumObject EntangledObject { get; set; }
|
||||
public QSBPlayerAudioController AudioController { get; set; }
|
||||
public DitheringAnimator DitheringAnimator { get; set; }
|
||||
@ -97,7 +98,7 @@ namespace QSB.Player
|
||||
// Tools
|
||||
public GameObject ProbeBody { get; set; }
|
||||
public QSBProbe Probe { get; set; }
|
||||
public QSBFlashlight FlashLight => CameraBody?.GetComponentInChildren<QSBFlashlight>();
|
||||
public QSBFlashlight FlashLight => CameraBody == null ? null : CameraBody.GetComponentInChildren<QSBFlashlight>();
|
||||
public QSBTool Signalscope => GetToolByType(ToolType.Signalscope);
|
||||
public QSBTool Translator => GetToolByType(ToolType.Translator);
|
||||
public QSBProbeLauncherTool ProbeLauncher => (QSBProbeLauncherTool)GetToolByType(ToolType.ProbeLauncher);
|
||||
|
@ -32,11 +32,11 @@ namespace QSB.Player
|
||||
/// <summary>
|
||||
/// called right after player is added
|
||||
/// </summary>
|
||||
public static Action<uint> OnAddPlayer;
|
||||
public static Action<PlayerInfo> OnAddPlayer;
|
||||
/// <summary>
|
||||
/// called right before player is removed
|
||||
/// </summary>
|
||||
public static Action<uint> OnRemovePlayer;
|
||||
public static Action<PlayerInfo> OnRemovePlayer;
|
||||
|
||||
public static readonly List<PlayerInfo> PlayerList = new();
|
||||
|
||||
|
@ -50,7 +50,7 @@ namespace QSB.Player.TransformSync
|
||||
var player = new PlayerInfo(this);
|
||||
QSBPlayerManager.PlayerList.SafeAdd(player);
|
||||
base.Start();
|
||||
QSBPlayerManager.OnAddPlayer?.Invoke(Player.PlayerId);
|
||||
QSBPlayerManager.OnAddPlayer?.Invoke(Player);
|
||||
DebugLog.DebugWrite($"Create Player : id<{Player.PlayerId}>", MessageType.Info);
|
||||
}
|
||||
|
||||
@ -87,7 +87,7 @@ namespace QSB.Player.TransformSync
|
||||
protected override void OnDestroy()
|
||||
{
|
||||
// TODO : Maybe move this to a leave event...? Would ensure everything could finish up before removing the player
|
||||
QSBPlayerManager.OnRemovePlayer?.Invoke(Player.PlayerId);
|
||||
QSBPlayerManager.OnRemovePlayer?.Invoke(Player);
|
||||
base.OnDestroy();
|
||||
Player.HudMarker?.Remove();
|
||||
QSBPlayerManager.PlayerList.Remove(Player);
|
||||
@ -169,6 +169,12 @@ namespace QSB.Player.TransformSync
|
||||
REMOTE_Player_Body.AddComponent<PlayerHUDMarker>().Init(Player);
|
||||
REMOTE_Player_Body.AddComponent<PlayerMapMarker>().PlayerName = Player.Name;
|
||||
Player.DitheringAnimator = REMOTE_Player_Body.AddComponent<DitheringAnimator>();
|
||||
// get inactive renderers too
|
||||
QSBCore.UnityEvents.FireOnNextUpdate(() =>
|
||||
Player.DitheringAnimator._renderers = Player.DitheringAnimator
|
||||
.GetComponentsInChildren<Renderer>(true)
|
||||
.Select(x => x.gameObject.GetAddComponent<OWRenderer>())
|
||||
.ToArray());
|
||||
Player.AudioController = PlayerAudioManager.InitRemote(REMOTE_Player_Body.transform);
|
||||
|
||||
/*
|
||||
|
@ -673,14 +673,13 @@ namespace QSB.PoolSync
|
||||
|
||||
public bool IsPlatformActive() => _platformActive;
|
||||
|
||||
public void OnRemovePlayer(uint id)
|
||||
public void OnRemovePlayer(PlayerInfo player)
|
||||
{
|
||||
if (id == QSBPlayerManager.LocalPlayerId)
|
||||
if (player == QSBPlayerManager.LocalPlayer)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var player = QSBPlayerManager.GetPlayer(id);
|
||||
if (!_playerToHologram.Any(x => x.Key == player))
|
||||
{
|
||||
return;
|
||||
@ -689,7 +688,7 @@ namespace QSB.PoolSync
|
||||
var hologram = _playerToHologram.First(x => x.Key == player).Value;
|
||||
if (hologram.activeSelf)
|
||||
{
|
||||
OnRemotePlayerExit(id);
|
||||
OnRemotePlayerExit(player.PlayerId);
|
||||
}
|
||||
|
||||
_playerToHologram.Remove(player);
|
||||
|
@ -63,10 +63,10 @@ copy /y "$(OwmlDir)\OWML.Abstractions.dll" "$(UnityAssetsDir)"
|
||||
</None>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<PackageReference Include="OuterWildsGameLibs" Version="*" IncludeAssets="compile" />
|
||||
<PackageReference Include="OuterWildsGameLibs" Version="1.1.12.125" IncludeAssets="compile" />
|
||||
<ProjectReference Include="..\QuantumUNET\QuantumUNET.csproj" />
|
||||
<PackageReference Include="HarmonyX" Version="2.*" IncludeAssets="compile" />
|
||||
<PackageReference Include="OWML" Version="2.*" IncludeAssets="compile" />
|
||||
<PackageReference Include="HarmonyX" Version="2.8.0" IncludeAssets="compile" />
|
||||
<PackageReference Include="OWML" Version="2.3.1" IncludeAssets="compile" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Update="AssetBundles\*">
|
||||
|
@ -2,6 +2,7 @@
|
||||
using OWML.ModHelper;
|
||||
using OWML.ModHelper.Input;
|
||||
using QSB.EyeOfTheUniverse.GalaxyMap;
|
||||
using QSB.EyeOfTheUniverse.MaskSync;
|
||||
using QSB.Inputs;
|
||||
using QSB.Menus;
|
||||
using QSB.Patches;
|
||||
@ -109,6 +110,7 @@ namespace QSB
|
||||
gameObject.AddComponent<StatueManager>();
|
||||
gameObject.AddComponent<GalaxyMapManager>();
|
||||
gameObject.AddComponent<DebugCameraSettings>();
|
||||
gameObject.AddComponent<MaskManager>();
|
||||
|
||||
// WorldObject managers
|
||||
foreach (var type in typeof(WorldObjectManager).GetDerivedTypes())
|
||||
|
@ -174,6 +174,7 @@ namespace QSB
|
||||
if (QSBSceneManager.IsInUniverse)
|
||||
{
|
||||
WorldObjectManager.Rebuild(QSBSceneManager.CurrentScene);
|
||||
QSBWorldSync.Init();
|
||||
}
|
||||
|
||||
var specificType = QNetworkServer.active ? QSBPatchTypes.OnServerClientConnect : QSBPatchTypes.OnNonServerClientConnect;
|
||||
@ -205,9 +206,7 @@ namespace QSB
|
||||
QSBPlayerManager.PlayerList.ForEach(player => player.HudMarker?.Remove());
|
||||
|
||||
RemoveWorldObjects();
|
||||
QSBWorldSync.DialogueConditions.Clear();
|
||||
QSBWorldSync.OldDialogueTrees.Clear();
|
||||
QSBWorldSync.ShipLogFacts.Clear();
|
||||
QSBWorldSync.Reset();
|
||||
|
||||
if (WakeUpSync.LocalInstance != null)
|
||||
{
|
||||
@ -236,10 +235,10 @@ namespace QSB
|
||||
DebugLog.DebugWrite("OnServerDisconnect", MessageType.Info);
|
||||
|
||||
// revert authority from ship
|
||||
if (ShipTransformSync.LocalInstance)
|
||||
if (ShipTransformSync.LocalInstance != null)
|
||||
{
|
||||
var identity = ShipTransformSync.LocalInstance.NetIdentity;
|
||||
if (identity.ClientAuthorityOwner == conn)
|
||||
if (identity != null && identity.ClientAuthorityOwner == conn)
|
||||
{
|
||||
identity.SetAuthority(QSBPlayerManager.LocalPlayerId);
|
||||
}
|
||||
@ -248,6 +247,12 @@ namespace QSB
|
||||
// stop dragging for the orbs this player was dragging
|
||||
foreach (var qsbOrb in QSBWorldSync.GetWorldObjects<QSBOrb>())
|
||||
{
|
||||
if (qsbOrb.TransformSync == null)
|
||||
{
|
||||
DebugLog.ToConsole($"{qsbOrb.LogName} TransformSync == null??????????", MessageType.Warning);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!qsbOrb.TransformSync.enabled)
|
||||
{
|
||||
continue;
|
||||
|
@ -28,6 +28,8 @@ namespace QSB
|
||||
{
|
||||
// So objects have time to be deleted, made, whatever
|
||||
QSBCore.UnityEvents.FireOnNextUpdate(() => WorldObjectManager.Rebuild(newScene));
|
||||
|
||||
QSBWorldSync.Init();
|
||||
}
|
||||
|
||||
OnSceneLoaded?.SafeInvoke(oldScene, newScene, universe);
|
||||
|
27
QSB/QuantumSync/Messages/MoveSkeletonMessage.cs
Normal file
27
QSB/QuantumSync/Messages/MoveSkeletonMessage.cs
Normal file
@ -0,0 +1,27 @@
|
||||
using QSB.Messaging;
|
||||
using QSB.QuantumSync.WorldObjects;
|
||||
using QuantumUNET.Transport;
|
||||
|
||||
namespace QSB.QuantumSync.Messages
|
||||
{
|
||||
internal class MoveSkeletonMessage : QSBWorldObjectMessage<QSBQuantumSkeletonTower>
|
||||
{
|
||||
private int _index;
|
||||
|
||||
public MoveSkeletonMessage(int index) => _index = index;
|
||||
|
||||
public override void Serialize(QNetworkWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
writer.Write(_index);
|
||||
}
|
||||
|
||||
public override void Deserialize(QNetworkReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
_index = reader.ReadInt32();
|
||||
}
|
||||
|
||||
public override void OnReceiveRemote() => WorldObject.MoveSkeleton(_index);
|
||||
}
|
||||
}
|
12
QSB/QuantumSync/Messages/SetIsQuantumMessage.cs
Normal file
12
QSB/QuantumSync/Messages/SetIsQuantumMessage.cs
Normal file
@ -0,0 +1,12 @@
|
||||
using QSB.Messaging;
|
||||
using QSB.QuantumSync.WorldObjects;
|
||||
|
||||
namespace QSB.QuantumSync.Messages
|
||||
{
|
||||
public class SetIsQuantumMessage : QSBBoolWorldObjectMessage<IQSBQuantumObject>
|
||||
{
|
||||
public SetIsQuantumMessage(bool isQuantum) => Value = isQuantum;
|
||||
|
||||
public override void OnReceiveRemote() => WorldObject.SetIsQuantum(Value);
|
||||
}
|
||||
}
|
@ -3,7 +3,6 @@ using OWML.Common;
|
||||
using QSB.Messaging;
|
||||
using QSB.Patches;
|
||||
using QSB.Player;
|
||||
using QSB.Player.Messages;
|
||||
using QSB.QuantumSync.Messages;
|
||||
using QSB.QuantumSync.WorldObjects;
|
||||
using QSB.Utility;
|
||||
@ -28,6 +27,16 @@ namespace QSB.QuantumSync.Patches
|
||||
return false;
|
||||
}
|
||||
|
||||
[HarmonyPostfix]
|
||||
[HarmonyPatch(typeof(QuantumObject), nameof(QuantumObject.SetIsQuantum))]
|
||||
public static void QuantumObject_SetIsQuantum(QuantumObject __instance)
|
||||
{
|
||||
if (WorldObjectManager.AllObjectsReady)
|
||||
{
|
||||
__instance.GetWorldObject<IQSBQuantumObject>().SendMessage(new SetIsQuantumMessage(__instance.IsQuantum()));
|
||||
}
|
||||
}
|
||||
|
||||
[HarmonyPrefix]
|
||||
[HarmonyPatch(typeof(SocketedQuantumObject), nameof(SocketedQuantumObject.ChangeQuantumState))]
|
||||
public static bool SocketedQuantumObject_ChangeQuantumState(
|
||||
@ -354,48 +363,6 @@ namespace QSB.QuantumSync.Patches
|
||||
return isInControl;
|
||||
}
|
||||
|
||||
[HarmonyPrefix]
|
||||
[HarmonyPatch(typeof(QuantumShrine), nameof(QuantumShrine.OnEntry))]
|
||||
public static bool QuantumShrine_OnEntry(
|
||||
QuantumShrine __instance,
|
||||
GameObject hitObj)
|
||||
{
|
||||
if (hitObj.CompareTag("PlayerDetector"))
|
||||
{
|
||||
__instance._isPlayerInside = true;
|
||||
__instance._fading = true;
|
||||
__instance._exteriorLightController.FadeTo(0f, 1f);
|
||||
new EnterLeaveMessage(EnterLeaveType.EnterShrine).Send();
|
||||
}
|
||||
else if (hitObj.CompareTag("ProbeDetector"))
|
||||
{
|
||||
__instance._isProbeInside = true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
[HarmonyPrefix]
|
||||
[HarmonyPatch(typeof(QuantumShrine), nameof(QuantumShrine.OnExit))]
|
||||
public static bool QuantumShrine_OnExit(
|
||||
QuantumShrine __instance,
|
||||
GameObject hitObj)
|
||||
{
|
||||
if (hitObj.CompareTag("PlayerDetector"))
|
||||
{
|
||||
__instance._isPlayerInside = false;
|
||||
__instance._fading = true;
|
||||
__instance._exteriorLightController.FadeTo(1f, 1f);
|
||||
new EnterLeaveMessage(EnterLeaveType.ExitShrine).Send();
|
||||
}
|
||||
else if (hitObj.CompareTag("ProbeDetector"))
|
||||
{
|
||||
__instance._isProbeInside = false;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
[HarmonyPrefix]
|
||||
[HarmonyPatch(typeof(QuantumMoon), nameof(QuantumMoon.CheckPlayerFogProximity))]
|
||||
public static bool QuantumMoon_CheckPlayerFogProximity(QuantumMoon __instance)
|
||||
@ -462,5 +429,50 @@ namespace QSB.QuantumSync.Patches
|
||||
__instance._shipLandingCamFogBubble.SetFogAlpha(fogAlpha);
|
||||
return false;
|
||||
}
|
||||
|
||||
[HarmonyPrefix]
|
||||
[HarmonyPatch(typeof(QuantumSkeletonTower), nameof(QuantumSkeletonTower.ChangeQuantumState))]
|
||||
public static bool QuantumSkeletonTower_ChangeQuantumState(QuantumSkeletonTower __instance, ref bool __result)
|
||||
{
|
||||
if (!WorldObjectManager.AllObjectsReady)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
var qsbQuantumSkeletonTower = __instance.GetWorldObject<QSBQuantumSkeletonTower>();
|
||||
if (qsbQuantumSkeletonTower.ControllingPlayer != QSBPlayerManager.LocalPlayerId)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (__instance._waitForPlayerToLookAtTower)
|
||||
{
|
||||
__result = false;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (__instance._index < __instance._towerSkeletons.Length)
|
||||
{
|
||||
for (var i = 0; i < __instance._pointingSkeletons.Length; i++)
|
||||
{
|
||||
if (__instance._pointingSkeletons[i].gameObject.activeInHierarchy &&
|
||||
(!__instance._pointingSkeletons[i].IsVisible() || !__instance._pointingSkeletons[i].IsIlluminated()))
|
||||
{
|
||||
__instance._pointingSkeletons[i].gameObject.SetActive(false);
|
||||
|
||||
__instance._towerSkeletons[__instance._index].SetActive(true);
|
||||
__instance._index++;
|
||||
__instance._waitForPlayerToLookAtTower = true;
|
||||
qsbQuantumSkeletonTower.SendMessage(new MoveSkeletonMessage(i));
|
||||
__result = true;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
__result = false;
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -40,13 +40,14 @@ namespace QSB.QuantumSync
|
||||
QSBWorldSync.Init<QSBQuantumShuffleObject, QuantumShuffleObject>();
|
||||
QSBWorldSync.Init<QSBQuantumMoon, QuantumMoon>();
|
||||
QSBWorldSync.Init<QSBEyeProxyQuantumMoon, EyeProxyQuantumMoon>();
|
||||
QSBWorldSync.Init<QSBQuantumSkeletonTower, QuantumSkeletonTower>();
|
||||
if (scene == OWScene.SolarSystem)
|
||||
{
|
||||
Shrine = QSBWorldSync.GetUnityObjects<QuantumShrine>().First();
|
||||
}
|
||||
}
|
||||
|
||||
public void PlayerLeave(uint playerId)
|
||||
public void PlayerLeave(PlayerInfo player)
|
||||
{
|
||||
if (!QSBCore.IsHost)
|
||||
{
|
||||
@ -55,7 +56,7 @@ namespace QSB.QuantumSync
|
||||
|
||||
foreach (var obj in QSBWorldSync.GetWorldObjects<IQSBQuantumObject>())
|
||||
{
|
||||
if (obj.ControllingPlayer == playerId)
|
||||
if (obj.ControllingPlayer == player.PlayerId)
|
||||
{
|
||||
obj.SendMessage(new QuantumAuthorityMessage(obj.IsEnabled ? QSBPlayerManager.LocalPlayerId : 0u));
|
||||
}
|
||||
@ -64,7 +65,7 @@ namespace QSB.QuantumSync
|
||||
|
||||
public void OnRenderObject()
|
||||
{
|
||||
if (!QSBCore.ShowLinesInDebug || !AllObjectsReady)
|
||||
if (!QSBCore.ShowLinesInDebug)
|
||||
{
|
||||
return;
|
||||
}
|
||||
@ -73,25 +74,6 @@ namespace QSB.QuantumSync
|
||||
{
|
||||
Popcron.Gizmos.Sphere(Shrine.transform.position, 10f, Color.magenta);
|
||||
}
|
||||
|
||||
foreach (var quantumObject in QSBWorldSync.GetWorldObjects<IQSBQuantumObject>())
|
||||
{
|
||||
if (quantumObject.ControllingPlayer == 0)
|
||||
{
|
||||
if (quantumObject.IsEnabled)
|
||||
{
|
||||
Popcron.Gizmos.Line(quantumObject.ReturnObject().transform.position,
|
||||
QSBPlayerManager.LocalPlayer.Body.transform.position,
|
||||
Color.magenta * 0.25f);
|
||||
}
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
Popcron.Gizmos.Line(quantumObject.ReturnObject().transform.position,
|
||||
QSBPlayerManager.GetPlayer(quantumObject.ControllingPlayer).Body.transform.position,
|
||||
Color.magenta);
|
||||
}
|
||||
}
|
||||
|
||||
public static Tuple<bool, List<PlayerInfo>> IsVisibleUsingCameraFrustum(ShapeVisibilityTracker tracker, bool ignoreLocalCamera)
|
||||
|
@ -6,9 +6,10 @@ namespace QSB.QuantumSync.WorldObjects
|
||||
public interface IQSBQuantumObject : IWorldObject
|
||||
{
|
||||
uint ControllingPlayer { get; set; }
|
||||
bool IsEnabled { get; set; }
|
||||
bool IsEnabled { get; }
|
||||
|
||||
List<ShapeVisibilityTracker> GetVisibilityTrackers();
|
||||
List<Shape> GetAttachedShapes();
|
||||
|
||||
void SetIsQuantum(bool isQuantum);
|
||||
}
|
||||
}
|
||||
|
@ -1,15 +1,7 @@
|
||||
using QSB.Player;
|
||||
using System.Linq;
|
||||
|
||||
namespace QSB.QuantumSync.WorldObjects
|
||||
namespace QSB.QuantumSync.WorldObjects
|
||||
{
|
||||
internal class QSBEyeProxyQuantumMoon : QSBQuantumObject<EyeProxyQuantumMoon>
|
||||
{
|
||||
public override void Init()
|
||||
{
|
||||
// smallest player id is the host
|
||||
ControllingPlayer = QSBPlayerManager.PlayerList.Min(x => x.PlayerId);
|
||||
base.Init();
|
||||
}
|
||||
protected override bool HostControls => true;
|
||||
}
|
||||
}
|
||||
|
@ -1,15 +1,7 @@
|
||||
using QSB.Player;
|
||||
using System.Linq;
|
||||
|
||||
namespace QSB.QuantumSync.WorldObjects
|
||||
namespace QSB.QuantumSync.WorldObjects
|
||||
{
|
||||
internal class QSBQuantumMoon : QSBQuantumObject<QuantumMoon>
|
||||
{
|
||||
public override void Init()
|
||||
{
|
||||
// smallest player id is the host
|
||||
ControllingPlayer = QSBPlayerManager.PlayerList.Min(x => x.PlayerId);
|
||||
base.Init();
|
||||
}
|
||||
protected override bool HostControls => true;
|
||||
}
|
||||
}
|
||||
|
@ -7,17 +7,28 @@ using QSB.WorldSync;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using UnityEngine;
|
||||
using Object = UnityEngine.Object;
|
||||
|
||||
namespace QSB.QuantumSync.WorldObjects
|
||||
{
|
||||
internal abstract class QSBQuantumObject<T> : WorldObject<T>, IQSBQuantumObject
|
||||
where T : QuantumObject
|
||||
{
|
||||
/// <summary>
|
||||
/// whether the controlling player is always the host <br/>
|
||||
/// also means this object is considered always enabled
|
||||
/// </summary>
|
||||
protected virtual bool HostControls => false;
|
||||
public uint ControllingPlayer { get; set; }
|
||||
public bool IsEnabled { get; set; }
|
||||
public bool IsEnabled { get; private set; }
|
||||
|
||||
public override void OnRemoval()
|
||||
{
|
||||
if (HostControls)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
foreach (var shape in GetAttachedShapes())
|
||||
{
|
||||
shape.OnShapeActivated -= OnEnable;
|
||||
@ -25,38 +36,31 @@ namespace QSB.QuantumSync.WorldObjects
|
||||
}
|
||||
}
|
||||
|
||||
public override bool ShouldDisplayLabel() => ControllingPlayer != 0;
|
||||
|
||||
public override void Init()
|
||||
{
|
||||
var debugBundle = QSBCore.DebugAssetBundle;
|
||||
var sphere = debugBundle.LoadAsset<GameObject>("Assets/Prefabs/Sphere.prefab");
|
||||
var cube = debugBundle.LoadAsset<GameObject>("Assets/Prefabs/Cube.prefab");
|
||||
var capsule = debugBundle.LoadAsset<GameObject>("Assets/Prefabs/Capsule.prefab");
|
||||
|
||||
if (cube == null)
|
||||
if (QSBCore.ShowQuantumVisibilityObjects)
|
||||
{
|
||||
DebugLog.DebugWrite($"CUBE IS NULL");
|
||||
}
|
||||
var debugBundle = QSBCore.DebugAssetBundle;
|
||||
var sphere = debugBundle.LoadAsset<GameObject>("Assets/Prefabs/Sphere.prefab");
|
||||
var cube = debugBundle.LoadAsset<GameObject>("Assets/Prefabs/Cube.prefab");
|
||||
var capsule = debugBundle.LoadAsset<GameObject>("Assets/Prefabs/Capsule.prefab");
|
||||
|
||||
if (sphere == null)
|
||||
{
|
||||
DebugLog.DebugWrite($"SPHERE IS NULL");
|
||||
}
|
||||
|
||||
if (capsule == null)
|
||||
{
|
||||
DebugLog.DebugWrite($"CAPSULE IS NULL");
|
||||
}
|
||||
|
||||
foreach (var shape in GetAttachedShapes())
|
||||
{
|
||||
if (shape == null)
|
||||
if (cube == null)
|
||||
{
|
||||
break;
|
||||
DebugLog.DebugWrite($"CUBE IS NULL");
|
||||
}
|
||||
|
||||
if (QSBCore.ShowQuantumVisibilityObjects)
|
||||
if (sphere == null)
|
||||
{
|
||||
DebugLog.DebugWrite($"SPHERE IS NULL");
|
||||
}
|
||||
|
||||
if (capsule == null)
|
||||
{
|
||||
DebugLog.DebugWrite($"CAPSULE IS NULL");
|
||||
}
|
||||
|
||||
foreach (var shape in GetAttachedShapes())
|
||||
{
|
||||
if (shape is BoxShape boxShape)
|
||||
{
|
||||
@ -92,20 +96,28 @@ namespace QSB.QuantumSync.WorldObjects
|
||||
private void LateInit()
|
||||
{
|
||||
FinishDelayedReady();
|
||||
foreach (var shape in GetAttachedShapes())
|
||||
|
||||
if (HostControls)
|
||||
{
|
||||
shape.OnShapeActivated += OnEnable;
|
||||
shape.OnShapeDeactivated += OnDisable;
|
||||
// smallest player id is the host
|
||||
ControllingPlayer = QSBPlayerManager.PlayerList.Min(x => x.PlayerId);
|
||||
IsEnabled = true;
|
||||
return;
|
||||
}
|
||||
|
||||
var attachedShapes = GetAttachedShapes();
|
||||
|
||||
if (attachedShapes.Count == 0)
|
||||
{
|
||||
IsEnabled = false;
|
||||
return;
|
||||
}
|
||||
|
||||
foreach (var shape in attachedShapes)
|
||||
{
|
||||
shape.OnShapeActivated += OnEnable;
|
||||
shape.OnShapeDeactivated += OnDisable;
|
||||
}
|
||||
|
||||
if (attachedShapes.All(x => x.enabled && x.gameObject.activeInHierarchy && x.active))
|
||||
{
|
||||
IsEnabled = true;
|
||||
@ -117,11 +129,6 @@ namespace QSB.QuantumSync.WorldObjects
|
||||
}
|
||||
}
|
||||
|
||||
public List<ShapeVisibilityTracker> GetVisibilityTrackers()
|
||||
=> AttachedObject?._visibilityTrackers == null
|
||||
? new()
|
||||
: AttachedObject._visibilityTrackers.Select(x => (ShapeVisibilityTracker)x).ToList();
|
||||
|
||||
public List<Shape> GetAttachedShapes()
|
||||
{
|
||||
if (AttachedObject == null)
|
||||
@ -150,13 +157,16 @@ namespace QSB.QuantumSync.WorldObjects
|
||||
continue;
|
||||
}
|
||||
|
||||
var shapes = tracker._shapes;
|
||||
totalShapes.AddRange(shapes);
|
||||
// if the tracker is not active, this won't have been set, so just do it ourselves
|
||||
tracker._shapes ??= tracker.GetComponents<Shape>();
|
||||
totalShapes.AddRange(tracker._shapes.Where(x => x != null));
|
||||
}
|
||||
|
||||
return totalShapes;
|
||||
}
|
||||
|
||||
public void SetIsQuantum(bool isQuantum) => AttachedObject._isQuantum = isQuantum;
|
||||
|
||||
private void OnEnable(Shape s)
|
||||
{
|
||||
if (IsEnabled)
|
||||
@ -209,5 +219,57 @@ namespace QSB.QuantumSync.WorldObjects
|
||||
// send event to other players that we're releasing authority
|
||||
((IQSBQuantumObject)this).SendMessage(new QuantumAuthorityMessage(0u));
|
||||
});
|
||||
|
||||
public override void DisplayLines()
|
||||
{
|
||||
if (AttachedObject == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var localPlayer = QSBPlayerManager.LocalPlayer;
|
||||
|
||||
if (localPlayer == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var body = localPlayer.Body;
|
||||
|
||||
if (body == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (ControllingPlayer == 0)
|
||||
{
|
||||
if (IsEnabled)
|
||||
{
|
||||
Popcron.Gizmos.Line(AttachedObject.transform.position,
|
||||
body.transform.position,
|
||||
Color.magenta * 0.25f);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
var player = QSBPlayerManager.GetPlayer(ControllingPlayer);
|
||||
|
||||
if (player == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var playerBody = player.Body;
|
||||
|
||||
if (playerBody == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
Popcron.Gizmos.Line(AttachedObject.transform.position,
|
||||
playerBody.transform.position,
|
||||
Color.magenta);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
18
QSB/QuantumSync/WorldObjects/QSBQuantumSkeletonTower.cs
Normal file
18
QSB/QuantumSync/WorldObjects/QSBQuantumSkeletonTower.cs
Normal file
@ -0,0 +1,18 @@
|
||||
namespace QSB.QuantumSync.WorldObjects
|
||||
{
|
||||
internal class QSBQuantumSkeletonTower : QSBQuantumObject<QuantumSkeletonTower>
|
||||
{
|
||||
public override string ReturnLabel() => $"{base.ReturnLabel()}\n"
|
||||
+ $"{AttachedObject._index} {AttachedObject._waitForPlayerToLookAtTower}\n"
|
||||
+ $"{AttachedObject._waitForFlicker} {AttachedObject._flickering}";
|
||||
|
||||
public void MoveSkeleton(int index)
|
||||
{
|
||||
AttachedObject._pointingSkeletons[index].gameObject.SetActive(false);
|
||||
|
||||
AttachedObject._towerSkeletons[AttachedObject._index].SetActive(true);
|
||||
AttachedObject._index++;
|
||||
AttachedObject._waitForPlayerToLookAtTower = true;
|
||||
}
|
||||
}
|
||||
}
|
@ -4,5 +4,6 @@ namespace QSB.QuantumSync.WorldObjects
|
||||
{
|
||||
internal class QSBQuantumSocket : WorldObject<QuantumSocket>
|
||||
{
|
||||
public override bool ShouldDisplayDebug() => false;
|
||||
}
|
||||
}
|
||||
|
@ -11,5 +11,7 @@ namespace QSB.QuantumSync.WorldObjects
|
||||
IsMeantToBeEnabled = visible;
|
||||
AttachedObject.SetVisible(visible);
|
||||
}
|
||||
|
||||
public override bool ShouldDisplayDebug() => false;
|
||||
}
|
||||
}
|
||||
|
@ -31,6 +31,7 @@ namespace QSB.SaveSync.Messages
|
||||
KnownSignals = gameSave.knownSignals;
|
||||
}
|
||||
|
||||
|
||||
public override void Serialize(QNetworkWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
@ -46,10 +47,10 @@ namespace QSB.SaveSync.Messages
|
||||
}
|
||||
|
||||
writer.Write(KnownSignals.Count);
|
||||
foreach (var (key, value) in KnownSignals)
|
||||
foreach (var (name, discovered) in KnownSignals)
|
||||
{
|
||||
writer.Write(key);
|
||||
writer.Write(value);
|
||||
writer.Write(name);
|
||||
writer.Write(discovered);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,4 +1,7 @@
|
||||
using QSB.Messaging;
|
||||
using QSB.ConversationSync.Messages;
|
||||
using QSB.ConversationSync.Patches;
|
||||
using QSB.Messaging;
|
||||
using System.Linq;
|
||||
|
||||
namespace QSB.SaveSync.Messages
|
||||
{
|
||||
@ -9,6 +12,24 @@ namespace QSB.SaveSync.Messages
|
||||
{
|
||||
public RequestGameStateMessage() => To = 0;
|
||||
|
||||
public override void OnReceiveRemote() => new GameStateMessage(From).Send();
|
||||
public override void OnReceiveRemote()
|
||||
{
|
||||
new GameStateMessage(From).Send();
|
||||
|
||||
var gameSave = StandaloneProfileManager.SharedInstance.currentProfileGameSave;
|
||||
|
||||
var factSaves = gameSave.shipLogFactSaves;
|
||||
foreach (var item in factSaves)
|
||||
{
|
||||
new ShipLogFactSaveMessage(item.Value).Send();
|
||||
}
|
||||
|
||||
var dictConditions = gameSave.dictConditions;
|
||||
var dictConditionsToSend = dictConditions.Where(x => ConversationPatches.PersistentConditionsToSync.Contains(x.Key));
|
||||
foreach (var item in dictConditionsToSend)
|
||||
{
|
||||
new PersistentConditionMessage(item.Key, item.Value).Send();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
54
QSB/SaveSync/Messages/ShipLogFactSaveMessage.cs
Normal file
54
QSB/SaveSync/Messages/ShipLogFactSaveMessage.cs
Normal file
@ -0,0 +1,54 @@
|
||||
using QSB.Messaging;
|
||||
using QuantumUNET.Transport;
|
||||
|
||||
namespace QSB.SaveSync.Messages
|
||||
{
|
||||
internal class ShipLogFactSaveMessage : QSBMessage
|
||||
{
|
||||
private string _id;
|
||||
private int _revealOrder;
|
||||
private bool _read;
|
||||
private bool _newlyRevealed;
|
||||
|
||||
public ShipLogFactSaveMessage(ShipLogFactSave save)
|
||||
{
|
||||
_id = save.id;
|
||||
_revealOrder = save.revealOrder;
|
||||
_read = save.read;
|
||||
_newlyRevealed = save.newlyRevealed;
|
||||
}
|
||||
|
||||
public override void Serialize(QNetworkWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
writer.Write(_id);
|
||||
writer.Write(_revealOrder);
|
||||
writer.Write(_read);
|
||||
writer.Write(_newlyRevealed);
|
||||
}
|
||||
|
||||
public override void Deserialize(QNetworkReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
_id = reader.ReadString();
|
||||
_revealOrder = reader.ReadInt32();
|
||||
_read = reader.ReadBoolean();
|
||||
_newlyRevealed = reader.ReadBoolean();
|
||||
}
|
||||
|
||||
public override void OnReceiveRemote()
|
||||
{
|
||||
var save = PlayerData.GetShipLogFactSave(_id);
|
||||
|
||||
if (save == null)
|
||||
{
|
||||
save = new ShipLogFactSave(_id);
|
||||
PlayerData.AddShipLogFactSave(save);
|
||||
}
|
||||
|
||||
save.revealOrder = _revealOrder;
|
||||
save.read = _read;
|
||||
save.newlyRevealed = _newlyRevealed;
|
||||
}
|
||||
}
|
||||
}
|
@ -1,10 +0,0 @@
|
||||
namespace QSB.ShipSync
|
||||
{
|
||||
public enum ComponentType
|
||||
{
|
||||
None = 0,
|
||||
Hull = 1,
|
||||
Component = 2,
|
||||
SatelliteNode = 3
|
||||
}
|
||||
}
|
@ -8,7 +8,6 @@ using QSB.ShipSync.TransformSync;
|
||||
using QSB.ShipSync.WorldObjects;
|
||||
using QSB.Utility;
|
||||
using QSB.WorldSync;
|
||||
using System;
|
||||
using UnityEngine;
|
||||
|
||||
namespace QSB.ShipSync.Patches
|
||||
@ -60,7 +59,7 @@ namespace QSB.ShipSync.Patches
|
||||
|
||||
[HarmonyReversePatch]
|
||||
[HarmonyPatch(typeof(SingleInteractionVolume), nameof(SingleInteractionVolume.UpdateInteractVolume))]
|
||||
public static void SingleInteractionVolume_UpdateInteractVolume_Stub(object instance) => throw new NotImplementedException();
|
||||
public static void SingleInteractionVolume_UpdateInteractVolume_Stub(object instance) { }
|
||||
|
||||
[HarmonyPrefix]
|
||||
[HarmonyPatch(typeof(InteractZone), nameof(InteractZone.UpdateInteractVolume))]
|
||||
@ -96,7 +95,7 @@ namespace QSB.ShipSync.Patches
|
||||
|
||||
[HarmonyReversePatch]
|
||||
[HarmonyPatch(typeof(ShipComponent), nameof(ShipComponent.OnEnterShip))]
|
||||
public static void ShipComponent_OnEnterShip_Stub(object instance) => throw new NotImplementedException();
|
||||
public static void ShipComponent_OnEnterShip_Stub(object instance) { }
|
||||
|
||||
[HarmonyPrefix]
|
||||
[HarmonyPatch(typeof(ShipElectricalComponent), nameof(ShipElectricalComponent.OnEnterShip))]
|
||||
@ -109,7 +108,7 @@ namespace QSB.ShipSync.Patches
|
||||
|
||||
[HarmonyReversePatch]
|
||||
[HarmonyPatch(typeof(ShipComponent), nameof(ShipComponent.OnExitShip))]
|
||||
public static void ShipComponent_OnExitShip_Stub(object instance) => throw new NotImplementedException();
|
||||
public static void ShipComponent_OnExitShip_Stub(object instance) { }
|
||||
|
||||
[HarmonyPrefix]
|
||||
[HarmonyPatch(typeof(ShipElectricalComponent), nameof(ShipElectricalComponent.OnExitShip))]
|
||||
|
@ -1,5 +1,4 @@
|
||||
using OWML.Common;
|
||||
using QSB.Player;
|
||||
using QSB.SectorSync;
|
||||
using QSB.SectorSync.WorldObjects;
|
||||
using QSB.Utility;
|
||||
@ -127,6 +126,13 @@ namespace QSB.Syncs.Sectored
|
||||
{
|
||||
if (IsPlayerObject)
|
||||
{
|
||||
if (Player == null)
|
||||
{
|
||||
// happens once right when you start hosting
|
||||
writer.Write(-1);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!Player.IsReady)
|
||||
{
|
||||
writer.Write(-1);
|
||||
|
@ -57,7 +57,7 @@ namespace QSB.Syncs
|
||||
public T AttachedObject { get; set; }
|
||||
public Transform ReferenceTransform { get; set; }
|
||||
|
||||
public string LogName => $"{(IsPlayerObject ? Player.PlayerId : "<non player object>")}.{NetId.Value}:{GetType().Name}";
|
||||
public string LogName => (IsPlayerObject ? $"{Player.PlayerId}." : string.Empty) + $"{NetId.Value}:{GetType().Name}";
|
||||
protected virtual float DistanceLeeway { get; } = 5f;
|
||||
private float _previousDistance;
|
||||
protected const float SmoothTime = 0.1f;
|
||||
@ -157,12 +157,20 @@ namespace QSB.Syncs
|
||||
return;
|
||||
}
|
||||
|
||||
if (ReferenceTransform != null && ReferenceTransform.position == Vector3.zero)
|
||||
if (!AttachedObject.gameObject.activeInHierarchy && !IgnoreDisabledAttachedObject)
|
||||
{
|
||||
DebugLog.ToConsole($"Warning - {LogName}'s ReferenceTransform is at (0,0,0). ReferenceTransform:{ReferenceTransform.name}, AttachedObject:{AttachedObject.name}", MessageType.Warning);
|
||||
base.Update();
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (ReferenceTransform != null && ReferenceTransform.position == Vector3.zero && ReferenceTransform != Locator.GetRootTransform())
|
||||
{
|
||||
DebugLog.ToConsole($"Warning - {LogName}'s ReferenceTransform is at (0,0,0). ReferenceTransform:{ReferenceTransform.name}, AttachedObject:{AttachedObject.name}", MessageType.Warning);
|
||||
}
|
||||
}
|
||||
|
||||
if (!AttachedObject.gameObject.activeInHierarchy && !IgnoreDisabledAttachedObject)
|
||||
if (ReferenceTransform == Locator.GetRootTransform())
|
||||
{
|
||||
base.Update();
|
||||
return;
|
||||
|
@ -2,7 +2,6 @@
|
||||
{
|
||||
public enum FastForwardReason
|
||||
{
|
||||
None,
|
||||
TooFarBehind
|
||||
}
|
||||
}
|
||||
|
@ -2,7 +2,6 @@
|
||||
{
|
||||
public enum PauseReason
|
||||
{
|
||||
None,
|
||||
TooFarAhead,
|
||||
ServerNotStarted,
|
||||
WaitingForAllPlayersToDie,
|
||||
|
@ -2,8 +2,8 @@
|
||||
{
|
||||
public enum TimeSyncType
|
||||
{
|
||||
None = 0,
|
||||
Pausing = 1,
|
||||
Fastforwarding = 2
|
||||
None,
|
||||
Pausing,
|
||||
FastForwarding
|
||||
}
|
||||
}
|
@ -90,7 +90,7 @@ namespace QSB.TimeSync
|
||||
var text = "";
|
||||
switch (_currentType)
|
||||
{
|
||||
case TimeSyncType.Fastforwarding:
|
||||
case TimeSyncType.FastForwarding:
|
||||
switch ((FastForwardReason)_currentReason)
|
||||
{
|
||||
case FastForwardReason.TooFarBehind:
|
||||
|
@ -192,7 +192,7 @@ namespace QSB.TimeSync
|
||||
OWTime.SetMaxDeltaTime(0.033333335f);
|
||||
OWTime.SetFixedTimestep(0.033333335f);
|
||||
TimeSyncUI.TargetTime = _serverTime;
|
||||
TimeSyncUI.Start(TimeSyncType.Fastforwarding, FastForwardReason.TooFarBehind);
|
||||
TimeSyncUI.Start(TimeSyncType.FastForwarding, FastForwardReason.TooFarBehind);
|
||||
}
|
||||
|
||||
private void StartPausing(PauseReason reason)
|
||||
|
@ -2,11 +2,11 @@
|
||||
{
|
||||
public enum ProbeEvent
|
||||
{
|
||||
Invalid = 0,
|
||||
Launch = 1,
|
||||
Anchor = 2,
|
||||
Unanchor = 3,
|
||||
Retrieve = 4,
|
||||
Destroy = 5
|
||||
Invalid,
|
||||
Launch,
|
||||
Anchor,
|
||||
Unanchor,
|
||||
Retrieve,
|
||||
Destroy
|
||||
}
|
||||
}
|
@ -2,8 +2,8 @@
|
||||
{
|
||||
public enum ToolType
|
||||
{
|
||||
Signalscope = 0,
|
||||
ProbeLauncher = 1,
|
||||
Translator = 2
|
||||
Signalscope,
|
||||
ProbeLauncher,
|
||||
Translator
|
||||
}
|
||||
}
|
26
QSB/TriggerSync/Messages/TriggerMessage.cs
Normal file
26
QSB/TriggerSync/Messages/TriggerMessage.cs
Normal file
@ -0,0 +1,26 @@
|
||||
using QSB.Messaging;
|
||||
using QSB.Player;
|
||||
using QSB.TriggerSync.WorldObjects;
|
||||
|
||||
namespace QSB.TriggerSync.Messages
|
||||
{
|
||||
public class TriggerMessage : QSBBoolWorldObjectMessage<IQSBTrigger>
|
||||
{
|
||||
public TriggerMessage(bool entered) => Value = entered;
|
||||
|
||||
public override void OnReceiveLocal() => OnReceiveRemote();
|
||||
|
||||
public override void OnReceiveRemote()
|
||||
{
|
||||
var player = QSBPlayerManager.GetPlayer(From);
|
||||
if (Value)
|
||||
{
|
||||
WorldObject.Enter(player);
|
||||
}
|
||||
else
|
||||
{
|
||||
WorldObject.Exit(player);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
52
QSB/TriggerSync/Messages/TriggerResyncMessage.cs
Normal file
52
QSB/TriggerSync/Messages/TriggerResyncMessage.cs
Normal file
@ -0,0 +1,52 @@
|
||||
using QSB.Messaging;
|
||||
using QSB.Player;
|
||||
using QSB.TriggerSync.WorldObjects;
|
||||
using QSB.Utility;
|
||||
using QuantumUNET.Transport;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
namespace QSB.TriggerSync.Messages
|
||||
{
|
||||
/// <summary>
|
||||
/// always sent by host
|
||||
/// </summary>
|
||||
public class TriggerResyncMessage : QSBWorldObjectMessage<IQSBTrigger>
|
||||
{
|
||||
private uint[] _playerIds;
|
||||
|
||||
public TriggerResyncMessage(IEnumerable<PlayerInfo> occupants) =>
|
||||
_playerIds = occupants.Select(x => x.PlayerId).ToArray();
|
||||
|
||||
public override void Serialize(QNetworkWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
writer.Write(_playerIds.Length);
|
||||
_playerIds.ForEach(writer.Write);
|
||||
}
|
||||
|
||||
public override void Deserialize(QNetworkReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
_playerIds = new uint[reader.ReadInt32()];
|
||||
for (var i = 0; i < _playerIds.Length; i++)
|
||||
{
|
||||
_playerIds[i] = reader.ReadUInt32();
|
||||
}
|
||||
}
|
||||
|
||||
public override void OnReceiveRemote()
|
||||
{
|
||||
var serverOccupants = _playerIds.Select(QSBPlayerManager.GetPlayer).ToList();
|
||||
foreach (var added in serverOccupants.Except(WorldObject.Occupants))
|
||||
{
|
||||
WorldObject.Enter(added);
|
||||
}
|
||||
|
||||
foreach (var removed in WorldObject.Occupants.Except(serverOccupants))
|
||||
{
|
||||
WorldObject.Exit(removed);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
20
QSB/TriggerSync/TriggerManager.cs
Normal file
20
QSB/TriggerSync/TriggerManager.cs
Normal file
@ -0,0 +1,20 @@
|
||||
using QSB.TriggerSync.WorldObjects;
|
||||
using QSB.WorldSync;
|
||||
|
||||
namespace QSB.TriggerSync
|
||||
{
|
||||
public class TriggerManager : WorldObjectManager
|
||||
{
|
||||
public override WorldObjectType WorldObjectType => WorldObjectType.Both;
|
||||
|
||||
protected override void RebuildWorldObjects(OWScene scene)
|
||||
{
|
||||
QSBWorldSync.Init<QSBCharacterTrigger, CharacterAnimController>(x => x.playerTrackingZone);
|
||||
QSBWorldSync.Init<QSBSolanumTrigger, NomaiConversationManager>(x => x._watchPlayerVolume);
|
||||
QSBWorldSync.Init<QSBShrineTrigger, QuantumShrine>(x => x._triggerVolume);
|
||||
QSBWorldSync.Init<QSBVesselCageTrigger, VesselWarpController>(x => x._cageTrigger);
|
||||
QSBWorldSync.Init<QSBInflationTrigger, CosmicInflationController>(x => x._smokeSphereTrigger);
|
||||
QSBWorldSync.Init<QSBMaskZoneTrigger, MaskZoneController>(x => x._maskZoneTrigger);
|
||||
}
|
||||
}
|
||||
}
|
12
QSB/TriggerSync/WorldObjects/QSBCharacterTrigger.cs
Normal file
12
QSB/TriggerSync/WorldObjects/QSBCharacterTrigger.cs
Normal file
@ -0,0 +1,12 @@
|
||||
namespace QSB.TriggerSync.WorldObjects
|
||||
{
|
||||
public class QSBCharacterTrigger : QSBTrigger<CharacterAnimController>
|
||||
{
|
||||
public override void Init()
|
||||
{
|
||||
base.Init();
|
||||
AttachedObject.OnEntry -= TriggerOwner.OnZoneEntry;
|
||||
AttachedObject.OnExit -= TriggerOwner.OnZoneExit;
|
||||
}
|
||||
}
|
||||
}
|
20
QSB/TriggerSync/WorldObjects/QSBEyeShuttleTrigger.cs
Normal file
20
QSB/TriggerSync/WorldObjects/QSBEyeShuttleTrigger.cs
Normal file
@ -0,0 +1,20 @@
|
||||
using QSB.Player;
|
||||
|
||||
namespace QSB.TriggerSync.WorldObjects
|
||||
{
|
||||
public class QSBEyeShuttleTrigger : QSBTrigger<EyeShuttleController>
|
||||
{
|
||||
public override void Init()
|
||||
{
|
||||
base.Init();
|
||||
AttachedObject.OnEntry -= TriggerOwner.OnEnterShuttle;
|
||||
AttachedObject.OnExit -= TriggerOwner.OnExitShuttle;
|
||||
}
|
||||
|
||||
protected override void OnEnter(PlayerInfo player)
|
||||
=> player.IsInEyeShuttle = true;
|
||||
|
||||
protected override void OnExit(PlayerInfo player)
|
||||
=> player.IsInEyeShuttle = false;
|
||||
}
|
||||
}
|
98
QSB/TriggerSync/WorldObjects/QSBInflationTrigger.cs
Normal file
98
QSB/TriggerSync/WorldObjects/QSBInflationTrigger.cs
Normal file
@ -0,0 +1,98 @@
|
||||
using QSB.Player;
|
||||
using QSB.Utility;
|
||||
using UnityEngine;
|
||||
|
||||
namespace QSB.TriggerSync.WorldObjects
|
||||
{
|
||||
public class QSBInflationTrigger : QSBTrigger<CosmicInflationController>
|
||||
{
|
||||
protected override string CompareTag => "PlayerCameraDetector";
|
||||
|
||||
public override void Init()
|
||||
{
|
||||
base.Init();
|
||||
AttachedObject.OnEntry -= TriggerOwner.OnEnterFogSphere;
|
||||
}
|
||||
|
||||
protected override void OnEnter(PlayerInfo player)
|
||||
{
|
||||
if (TriggerOwner._state != CosmicInflationController.State.ReadyToCollapse)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (player == QSBPlayerManager.LocalPlayer)
|
||||
{
|
||||
AttachedObject.OnEntry -= OnEnterEvent;
|
||||
|
||||
AttachedObject.SetTriggerActivation(false);
|
||||
TriggerOwner._probeDestroyTrigger.SetTriggerActivation(false);
|
||||
|
||||
DebugLog.DebugWrite("disable input, wait for other players to enter");
|
||||
|
||||
var repelVolume = (WhiteHoleFluidVolume)TriggerOwner._repelVolume;
|
||||
repelVolume._flowSpeed = -repelVolume._flowSpeed;
|
||||
repelVolume._massiveFlowSpeed = -repelVolume._massiveFlowSpeed;
|
||||
repelVolume.SetVolumeActivation(true);
|
||||
QSBPlayerManager.HideAllPlayers();
|
||||
|
||||
ReticleController.Hide();
|
||||
Locator.GetFlashlight().TurnOff(false);
|
||||
Locator.GetPromptManager().SetPromptsVisible(false);
|
||||
OWInput.ChangeInputMode(InputMode.None);
|
||||
}
|
||||
else
|
||||
{
|
||||
DebugLog.DebugWrite($"fade out player {player.PlayerId}");
|
||||
player.DitheringAnimator.SetVisible(false, 3);
|
||||
}
|
||||
|
||||
if (Occupants.Count == QSBPlayerManager.PlayerList.Count)
|
||||
{
|
||||
StartCollapse();
|
||||
}
|
||||
}
|
||||
|
||||
protected override void OnExit(PlayerInfo player)
|
||||
{
|
||||
// wait 1 frame for player to be removed
|
||||
QSBCore.UnityEvents.FireOnNextUpdate(() =>
|
||||
{
|
||||
if (QSBCore.IsInMultiplayer && Occupants.Count == QSBPlayerManager.PlayerList.Count)
|
||||
{
|
||||
StartCollapse();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void StartCollapse()
|
||||
{
|
||||
DebugLog.DebugWrite("fade in everyone, fog sphere collapse");
|
||||
|
||||
var repelVolume = (WhiteHoleFluidVolume)TriggerOwner._repelVolume;
|
||||
repelVolume.SetVolumeActivation(false);
|
||||
QSBPlayerManager.ShowAllPlayers();
|
||||
|
||||
TriggerOwner._state = CosmicInflationController.State.Collapsing;
|
||||
TriggerOwner._stateChangeTime = Time.time;
|
||||
TriggerOwner._collapseStartPos = TriggerOwner._possibilitySphereRoot.localPosition;
|
||||
AttachedObject.SetTriggerActivation(false);
|
||||
TriggerOwner._inflationLight.FadeTo(1f, 1f);
|
||||
TriggerOwner._possibilitySphereController.OnCollapse();
|
||||
if (TriggerOwner._campsiteController.GetUseAltPostCollapseSocket())
|
||||
{
|
||||
TriggerOwner._playerPostCollapseSocket = TriggerOwner._altPlayerPostCollapseSocket;
|
||||
TriggerOwner._altTravelerToHidePostCollapse.SetActive(false);
|
||||
}
|
||||
|
||||
Locator.GetPlayerBody().SetPosition(TriggerOwner._playerPostCollapseSocket.position);
|
||||
Locator.GetPlayerBody().SetRotation(TriggerOwner._playerPostCollapseSocket.rotation);
|
||||
Locator.GetPlayerBody().SetVelocity(-TriggerOwner._playerPostCollapseSocket.forward);
|
||||
Locator.GetPlayerTransform().GetRequiredComponent<PlayerLockOnTargeting>().LockOn(TriggerOwner._possibilitySphereRoot, 2f);
|
||||
foreach (var particles in TriggerOwner._smokeSphereParticles)
|
||||
{
|
||||
particles.Stop();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
38
QSB/TriggerSync/WorldObjects/QSBMaskZoneTrigger.cs
Normal file
38
QSB/TriggerSync/WorldObjects/QSBMaskZoneTrigger.cs
Normal file
@ -0,0 +1,38 @@
|
||||
using QSB.Player;
|
||||
|
||||
namespace QSB.TriggerSync.WorldObjects
|
||||
{
|
||||
public class QSBMaskZoneTrigger : QSBTrigger<MaskZoneController>
|
||||
{
|
||||
public override void Init()
|
||||
{
|
||||
base.Init();
|
||||
AttachedObject.OnEntry -= TriggerOwner.OnEnterMaskZone;
|
||||
AttachedObject.OnExit -= TriggerOwner.OnExitMaskZone;
|
||||
}
|
||||
|
||||
protected override void OnEnter(PlayerInfo player)
|
||||
{
|
||||
if (Occupants.Count == 1)
|
||||
{
|
||||
TriggerOwner._whiteSphere.SetActive(true);
|
||||
TriggerOwner._groundSignal.SetSignalActivation(false);
|
||||
TriggerOwner._skySignal.SetSignalActivation(true);
|
||||
TriggerOwner._skeletonTower.SetIsQuantum(TriggerOwner._hasPlayerLookedAtSky);
|
||||
TriggerOwner.enabled = true;
|
||||
}
|
||||
}
|
||||
|
||||
protected override void OnExit(PlayerInfo player)
|
||||
{
|
||||
if (Occupants.Count == 0 && !TriggerOwner._shuttle.HasLaunched())
|
||||
{
|
||||
TriggerOwner._whiteSphere.SetActive(false);
|
||||
TriggerOwner._skeletonTower.SetIsQuantum(false);
|
||||
TriggerOwner._groundSignal.SetSignalActivation(true);
|
||||
TriggerOwner._skySignal.SetSignalActivation(false);
|
||||
TriggerOwner.enabled = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
11
QSB/TriggerSync/WorldObjects/QSBShrineTrigger.cs
Normal file
11
QSB/TriggerSync/WorldObjects/QSBShrineTrigger.cs
Normal file
@ -0,0 +1,11 @@
|
||||
using QSB.Player;
|
||||
|
||||
namespace QSB.TriggerSync.WorldObjects
|
||||
{
|
||||
public class QSBShrineTrigger : QSBTrigger<QuantumShrine>
|
||||
{
|
||||
protected override void OnEnter(PlayerInfo player) => player.IsInShrine = true;
|
||||
|
||||
protected override void OnExit(PlayerInfo player) => player.IsInShrine = false;
|
||||
}
|
||||
}
|
12
QSB/TriggerSync/WorldObjects/QSBSolanumTrigger.cs
Normal file
12
QSB/TriggerSync/WorldObjects/QSBSolanumTrigger.cs
Normal file
@ -0,0 +1,12 @@
|
||||
namespace QSB.TriggerSync.WorldObjects
|
||||
{
|
||||
public class QSBSolanumTrigger : QSBTrigger<NomaiConversationManager>
|
||||
{
|
||||
public override void Init()
|
||||
{
|
||||
base.Init();
|
||||
AttachedObject.OnEntry -= TriggerOwner.OnEnterWatchVolume;
|
||||
AttachedObject.OnExit -= TriggerOwner.OnExitWatchVolume;
|
||||
}
|
||||
}
|
||||
}
|
106
QSB/TriggerSync/WorldObjects/QSBTrigger.cs
Normal file
106
QSB/TriggerSync/WorldObjects/QSBTrigger.cs
Normal file
@ -0,0 +1,106 @@
|
||||
using QSB.Messaging;
|
||||
using QSB.Player;
|
||||
using QSB.TriggerSync.Messages;
|
||||
using QSB.WorldSync;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using UnityEngine;
|
||||
|
||||
namespace QSB.TriggerSync.WorldObjects
|
||||
{
|
||||
public interface IQSBTrigger : IWorldObject
|
||||
{
|
||||
List<PlayerInfo> Occupants { get; }
|
||||
|
||||
void Enter(PlayerInfo player);
|
||||
|
||||
void Exit(PlayerInfo player);
|
||||
}
|
||||
|
||||
public abstract class QSBTrigger<TO> : WorldObject<OWTriggerVolume>, IQSBTrigger
|
||||
{
|
||||
public TO TriggerOwner { get; init; }
|
||||
|
||||
public List<PlayerInfo> Occupants { get; } = new();
|
||||
|
||||
protected virtual string CompareTag => "PlayerDetector";
|
||||
|
||||
public override void Init()
|
||||
{
|
||||
AttachedObject.OnEntry += OnEnterEvent;
|
||||
AttachedObject.OnExit += OnExitEvent;
|
||||
|
||||
QSBPlayerManager.OnRemovePlayer += OnPlayerLeave;
|
||||
|
||||
QSBCore.UnityEvents.RunWhen(() => WorldObjectManager.AllObjectsReady, () =>
|
||||
{
|
||||
if (AttachedObject._trackedObjects != null && AttachedObject._trackedObjects.Any(x => x.CompareTag(CompareTag)))
|
||||
{
|
||||
((IQSBTrigger)this).SendMessage(new TriggerMessage(true));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public override void OnRemoval()
|
||||
{
|
||||
AttachedObject.OnEntry -= OnEnterEvent;
|
||||
AttachedObject.OnExit -= OnExitEvent;
|
||||
|
||||
QSBPlayerManager.OnRemovePlayer -= OnPlayerLeave;
|
||||
}
|
||||
|
||||
protected void OnEnterEvent(GameObject hitObj)
|
||||
{
|
||||
if (hitObj.CompareTag(CompareTag))
|
||||
{
|
||||
((IQSBTrigger)this).SendMessage(new TriggerMessage(true));
|
||||
}
|
||||
}
|
||||
|
||||
protected void OnExitEvent(GameObject hitObj)
|
||||
{
|
||||
if (hitObj.CompareTag(CompareTag))
|
||||
{
|
||||
((IQSBTrigger)this).SendMessage(new TriggerMessage(false));
|
||||
}
|
||||
}
|
||||
|
||||
private void OnPlayerLeave(PlayerInfo player)
|
||||
{
|
||||
if (Occupants.Contains(player))
|
||||
{
|
||||
Exit(player);
|
||||
}
|
||||
}
|
||||
|
||||
public void Enter(PlayerInfo player)
|
||||
{
|
||||
if (!Occupants.SafeAdd(player))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
OnEnter(player);
|
||||
}
|
||||
|
||||
public void Exit(PlayerInfo player)
|
||||
{
|
||||
if (!Occupants.QuickRemove(player))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
OnExit(player);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// called when a player enters this trigger
|
||||
/// </summary>
|
||||
protected virtual void OnEnter(PlayerInfo player) { }
|
||||
|
||||
/// <summary>
|
||||
/// called when a player exits this trigger or leaves the game
|
||||
/// </summary>
|
||||
protected virtual void OnExit(PlayerInfo player) { }
|
||||
}
|
||||
}
|
27
QSB/TriggerSync/WorldObjects/QSBVesselCageTrigger.cs
Normal file
27
QSB/TriggerSync/WorldObjects/QSBVesselCageTrigger.cs
Normal file
@ -0,0 +1,27 @@
|
||||
using QSB.Player;
|
||||
using UnityEngine;
|
||||
|
||||
namespace QSB.TriggerSync.WorldObjects
|
||||
{
|
||||
public class QSBVesselCageTrigger : QSBTrigger<VesselWarpController>
|
||||
{
|
||||
public override void Init()
|
||||
{
|
||||
base.Init();
|
||||
AttachedObject.OnExit -= TriggerOwner.OnExitCageTrigger;
|
||||
}
|
||||
|
||||
protected override void OnExit(PlayerInfo player)
|
||||
{
|
||||
if (Occupants.Count == 0 && TriggerOwner._hasPower)
|
||||
{
|
||||
TriggerOwner._cageClosed = true;
|
||||
TriggerOwner._cageAnimator.TranslateToLocalPosition(new Vector3(0f, -8.1f, 0f), 5f);
|
||||
TriggerOwner._cageAnimator.RotateToLocalEulerAngles(new Vector3(0f, 180f, 0f), 5f);
|
||||
TriggerOwner._cageAnimator.OnTranslationComplete -= TriggerOwner.OnCageAnimationComplete;
|
||||
TriggerOwner._cageAnimator.OnTranslationComplete += TriggerOwner.OnCageAnimationComplete;
|
||||
TriggerOwner._cageLoopingAudio.FadeIn(1f);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -47,7 +47,7 @@ namespace QSB.Utility
|
||||
* 3 - Destroy probe
|
||||
* 4 - Damage ship electricals
|
||||
* 5 - Trigger supernova
|
||||
* 6 -
|
||||
* 6 - Set MET_SOLANUM
|
||||
* 7 - Warp to vessel
|
||||
* 8 - Place warp core into vessel
|
||||
* 9 - Load eye scene
|
||||
@ -83,6 +83,14 @@ namespace QSB.Utility
|
||||
new DebugTriggerSupernovaMessage().Send();
|
||||
}
|
||||
|
||||
if (Keyboard.current[Key.Numpad6].wasPressedThisFrame)
|
||||
{
|
||||
PlayerData.SetPersistentCondition("MET_SOLANUM", true);
|
||||
PlayerData.SetPersistentCondition("MET_PRISONER", true);
|
||||
DialogueConditionManager.SharedInstance.SetConditionState("MET_SOLANUM", true);
|
||||
DialogueConditionManager.SharedInstance.SetConditionState("MET_PRISONER", true);
|
||||
}
|
||||
|
||||
if (Keyboard.current[Key.Numpad7].wasPressedThisFrame)
|
||||
{
|
||||
GoToVessel();
|
||||
@ -95,8 +103,17 @@ namespace QSB.Utility
|
||||
|
||||
if (Keyboard.current[Key.Numpad9].wasPressedThisFrame)
|
||||
{
|
||||
PlayerData.SaveWarpedToTheEye(60);
|
||||
LoadManager.LoadSceneAsync(OWScene.EyeOfTheUniverse, true, LoadManager.FadeType.ToWhite);
|
||||
if (Keyboard.current[Key.LeftShift].isPressed)
|
||||
{
|
||||
PlayerData._currentGameSave.warpedToTheEye = false;
|
||||
PlayerData.SaveCurrentGame();
|
||||
LoadManager.LoadSceneAsync(OWScene.SolarSystem, true, LoadManager.FadeType.ToBlack);
|
||||
}
|
||||
else
|
||||
{
|
||||
PlayerData.SaveWarpedToTheEye(60);
|
||||
LoadManager.LoadSceneAsync(OWScene.EyeOfTheUniverse, true, LoadManager.FadeType.ToWhite);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -251,6 +251,8 @@ namespace QSB.Utility
|
||||
DrawWorldObjectLabels();
|
||||
}
|
||||
|
||||
public void OnRenderObject() => DrawWorldObjectLines();
|
||||
|
||||
private static void DrawWorldObjectLabels()
|
||||
{
|
||||
if (!QSBCore.ShowDebugLabels)
|
||||
@ -265,13 +267,34 @@ namespace QSB.Utility
|
||||
return;
|
||||
}
|
||||
|
||||
if (obj.ShouldDisplayLabel())
|
||||
if (obj.ShouldDisplayDebug())
|
||||
{
|
||||
DrawLabel(obj.ReturnObject().transform, obj.ReturnLabel());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void DrawWorldObjectLines()
|
||||
{
|
||||
if (!QSBCore.ShowLinesInDebug)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
foreach (var obj in QSBWorldSync.GetWorldObjects())
|
||||
{
|
||||
if (obj.ReturnObject() == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (obj.ShouldDisplayDebug())
|
||||
{
|
||||
obj.DisplayLines();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void DrawLabel(Transform obj, string label)
|
||||
{
|
||||
var camera = Locator.GetPlayerCamera();
|
||||
|
@ -37,6 +37,6 @@ namespace QSB.Utility
|
||||
private static string GetCallingType(StackTrace frame) =>
|
||||
frame.GetFrames()!
|
||||
.Select(x => x.GetMethod().DeclaringType!.Name)
|
||||
.First(x => x == nameof(DebugLog));
|
||||
.First(x => x != nameof(DebugLog));
|
||||
}
|
||||
}
|
@ -9,7 +9,8 @@ namespace QSB.WorldSync
|
||||
|
||||
void OnRemoval();
|
||||
MonoBehaviour ReturnObject();
|
||||
bool ShouldDisplayLabel();
|
||||
bool ShouldDisplayDebug();
|
||||
string ReturnLabel();
|
||||
void DisplayLines();
|
||||
}
|
||||
}
|
||||
|
@ -1,5 +1,7 @@
|
||||
using OWML.Common;
|
||||
using QSB.ConversationSync.Patches;
|
||||
using QSB.LogSync;
|
||||
using QSB.TriggerSync.WorldObjects;
|
||||
using QSB.Utility;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
@ -10,13 +12,53 @@ namespace QSB.WorldSync
|
||||
{
|
||||
public static class QSBWorldSync
|
||||
{
|
||||
public static readonly List<CharacterDialogueTree> OldDialogueTrees = new();
|
||||
public static readonly Dictionary<string, bool> DialogueConditions = new();
|
||||
public static readonly List<FactReveal> ShipLogFacts = new();
|
||||
public static List<CharacterDialogueTree> OldDialogueTrees { get; private set; } = new();
|
||||
public static Dictionary<string, bool> DialogueConditions { get; private set; } = new();
|
||||
public static Dictionary<string, bool> PersistentConditions { get; private set; } = new();
|
||||
public static List<FactReveal> ShipLogFacts { get; private set; } = new();
|
||||
|
||||
private static readonly List<IWorldObject> WorldObjects = new();
|
||||
private static readonly Dictionary<MonoBehaviour, IWorldObject> WorldObjectsToUnityObjects = new();
|
||||
|
||||
public static void Init()
|
||||
{
|
||||
DebugLog.DebugWrite($"Init QSBWorldSync", MessageType.Info);
|
||||
|
||||
OldDialogueTrees.Clear();
|
||||
OldDialogueTrees.AddRange(GetUnityObjects<CharacterDialogueTree>());
|
||||
|
||||
if (!QSBCore.IsHost)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
DebugLog.DebugWrite($"DIALOGUE CONDITIONS :");
|
||||
DialogueConditions = (Dictionary<string, bool>)DialogueConditionManager.SharedInstance._dictConditions;
|
||||
foreach (var item in DialogueConditions)
|
||||
{
|
||||
DebugLog.DebugWrite($"- {item.Key}, {item.Value}");
|
||||
}
|
||||
|
||||
DebugLog.DebugWrite($"PERSISTENT CONDITIONS :");
|
||||
var dictConditions = PlayerData._currentGameSave.dictConditions;
|
||||
var syncedConditions = dictConditions.Where(x => ConversationPatches.PersistentConditionsToSync.Contains(x.Key));
|
||||
PersistentConditions = syncedConditions.ToDictionary(x => x.Key, x => x.Value);
|
||||
foreach (var item in PersistentConditions)
|
||||
{
|
||||
DebugLog.DebugWrite($"- {item.Key}, {item.Value}");
|
||||
}
|
||||
}
|
||||
|
||||
public static void Reset()
|
||||
{
|
||||
DebugLog.DebugWrite($"Reset QSBWorldSync", MessageType.Info);
|
||||
|
||||
OldDialogueTrees.Clear();
|
||||
DialogueConditions.Clear();
|
||||
PersistentConditions.Clear();
|
||||
ShipLogFacts.Clear();
|
||||
}
|
||||
|
||||
public static IEnumerable<IWorldObject> GetWorldObjects() => WorldObjects;
|
||||
|
||||
public static IEnumerable<TWorldObject> GetWorldObjects<TWorldObject>()
|
||||
@ -122,11 +164,33 @@ namespace QSB.WorldSync
|
||||
{
|
||||
//DebugLog.DebugWrite($"{typeof(TWorldObject).Name} init : {listToInitFrom.Count()} instances.", MessageType.Info);
|
||||
foreach (var item in listToInitFrom)
|
||||
{
|
||||
var obj = new TWorldObject
|
||||
{
|
||||
AttachedObject = item,
|
||||
ObjectId = WorldObjects.Count
|
||||
};
|
||||
|
||||
obj.Init();
|
||||
WorldObjects.Add(obj);
|
||||
WorldObjectsToUnityObjects.Add(item, obj);
|
||||
}
|
||||
}
|
||||
|
||||
public static void Init<TWorldObject, TUnityObject>(Func<TUnityObject, OWTriggerVolume> triggerSelector)
|
||||
where TWorldObject : QSBTrigger<TUnityObject>, new()
|
||||
where TUnityObject : MonoBehaviour
|
||||
{
|
||||
var list = GetUnityObjects<TUnityObject>()
|
||||
.Select(x => (triggerSelector(x), x))
|
||||
.Where(x => x.Item1);
|
||||
foreach (var (item, owner) in list)
|
||||
{
|
||||
var obj = new TWorldObject
|
||||
{
|
||||
AttachedObject = item,
|
||||
ObjectId = WorldObjects.Count,
|
||||
TriggerOwner = owner
|
||||
};
|
||||
|
||||
obj.Init();
|
||||
@ -139,13 +203,24 @@ namespace QSB.WorldSync
|
||||
{
|
||||
if (!QSBCore.IsHost)
|
||||
{
|
||||
DebugLog.ToConsole("Warning - Cannot write to condition dict when not server!", MessageType.Warning);
|
||||
DebugLog.ToConsole("Warning - Cannot write to dialogue condition dict when not server!", MessageType.Warning);
|
||||
return;
|
||||
}
|
||||
|
||||
DialogueConditions[name] = state;
|
||||
}
|
||||
|
||||
public static void SetPersistentCondition(string name, bool state)
|
||||
{
|
||||
if (!QSBCore.IsHost)
|
||||
{
|
||||
DebugLog.ToConsole("Warning - Cannot write to persistent condition dict when not server!", MessageType.Warning);
|
||||
return;
|
||||
}
|
||||
|
||||
PersistentConditions[name] = state;
|
||||
}
|
||||
|
||||
public static void AddFactReveal(string id, bool saveGame)
|
||||
{
|
||||
if (!QSBCore.IsHost)
|
||||
|
@ -9,13 +9,14 @@ namespace QSB.WorldSync
|
||||
public int ObjectId { get; init; }
|
||||
public T AttachedObject { get; init; }
|
||||
public string Name => AttachedObject == null ? "<NullObject!>" : AttachedObject.name;
|
||||
public string LogName => $"{QSBPlayerManager.LocalPlayerId}.{ObjectId}:{GetType().Name}";
|
||||
public string LogName => $"{QSBPlayerManager.LocalPlayerId}.{ObjectId}:{GetType().Name} ({Name})";
|
||||
|
||||
public virtual void Init() { }
|
||||
public virtual void OnRemoval() { }
|
||||
public MonoBehaviour ReturnObject() => AttachedObject;
|
||||
public virtual bool ShouldDisplayLabel() => true;
|
||||
public virtual bool ShouldDisplayDebug() => AttachedObject != null && AttachedObject.gameObject.activeInHierarchy;
|
||||
public virtual string ReturnLabel() => LogName;
|
||||
public virtual void DisplayLines() { }
|
||||
|
||||
/// indicates that this won't become ready immediately
|
||||
protected void StartDelayedReady() => WorldObjectManager._numObjectsReadying++;
|
||||
|
@ -1,5 +1,6 @@
|
||||
using OWML.Common;
|
||||
using QSB.Player;
|
||||
using QSB.Player.TransformSync;
|
||||
using QSB.Utility;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
@ -66,10 +67,10 @@ namespace QSB.WorldSync
|
||||
return;
|
||||
}
|
||||
|
||||
if (QSBPlayerManager.LocalPlayerId == uint.MaxValue)
|
||||
if (PlayerTransformSync.LocalInstance == null)
|
||||
{
|
||||
DebugLog.ToConsole($"Warning - Tried to rebuild WorldObjects when LocalPlayer is not ready! Building when ready...", MessageType.Warning);
|
||||
QSBCore.UnityEvents.RunWhen(() => QSBPlayerManager.LocalPlayerId != uint.MaxValue, () => Rebuild(scene));
|
||||
QSBCore.UnityEvents.RunWhen(() => PlayerTransformSync.LocalInstance, () => Rebuild(scene));
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -8,6 +8,6 @@
|
||||
},
|
||||
"uniqueName": "Raicuparta.QuantumSpaceBuddies",
|
||||
"version": "0.15.0",
|
||||
"owmlVersion": "2.2.0",
|
||||
"owmlVersion": "2.3.1",
|
||||
"dependencies": [ "_nebula.MenuFramework" ]
|
||||
}
|
||||
|
@ -2,6 +2,7 @@
|
||||
using Mono.Cecil;
|
||||
using Mono.Cecil.Cil;
|
||||
using Mono.Cecil.Rocks;
|
||||
using MonoMod.Cil;
|
||||
using QSB.Messaging;
|
||||
using QSB.Utility;
|
||||
using System;
|
||||
@ -34,7 +35,7 @@ namespace QSBTests
|
||||
|
||||
foreach (var field in fields)
|
||||
{
|
||||
if (!field.Eq(fromField) && !field.Eq(toField) && !field.Eq(objectIdField))
|
||||
if (!field.GenericEq(fromField) && !field.GenericEq(toField) && !field.GenericEq(objectIdField))
|
||||
{
|
||||
constructor.CheckUses(field, Util.UseType.Store);
|
||||
}
|
||||
@ -46,60 +47,45 @@ namespace QSBTests
|
||||
}
|
||||
}
|
||||
|
||||
internal static class Util
|
||||
public static partial class Util
|
||||
{
|
||||
public const BindingFlags Flags = BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic;
|
||||
|
||||
public static bool Eq(this MemberReference a, MemberReference b) =>
|
||||
/// <summary>
|
||||
/// ignores open vs closed generic type
|
||||
/// </summary>
|
||||
public static bool GenericEq(this MemberReference a, MemberReference b) =>
|
||||
a.DeclaringType.Namespace == b.DeclaringType.Namespace &&
|
||||
a.DeclaringType.Name == b.DeclaringType.Name &&
|
||||
a.Name == b.Name;
|
||||
|
||||
public static bool IsOp<T>(this Instruction instruction, OpCode opCode, out T operand)
|
||||
{
|
||||
if (instruction.OpCode == opCode)
|
||||
{
|
||||
operand = (T)instruction.Operand;
|
||||
return true;
|
||||
}
|
||||
|
||||
operand = default;
|
||||
return false;
|
||||
}
|
||||
|
||||
public enum UseType { Store, Load };
|
||||
public enum UseType { Store, Load }
|
||||
|
||||
public static void CheckUses(this MethodDefinition method, FieldReference field, UseType useType)
|
||||
{
|
||||
var opCode = useType switch
|
||||
Func<Instruction, bool> matches = useType switch
|
||||
{
|
||||
UseType.Store => OpCodes.Stfld,
|
||||
UseType.Load => OpCodes.Ldfld,
|
||||
UseType.Store => x => x.MatchStfld(out var f) && f.GenericEq(field),
|
||||
UseType.Load => x => x.MatchLdfld(out var f) && f.GenericEq(field),
|
||||
_ => throw new ArgumentOutOfRangeException(nameof(useType), useType, null)
|
||||
};
|
||||
|
||||
while (true)
|
||||
{
|
||||
var il = method.Body.Instructions;
|
||||
var uses = il.Any(x =>
|
||||
x.IsOp(opCode, out FieldReference f) &&
|
||||
f.Eq(field)
|
||||
);
|
||||
var uses = il.Any(matches);
|
||||
if (uses)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var baseMethod = method.GetBaseMethod();
|
||||
if (baseMethod.Eq(method))
|
||||
if (baseMethod == method)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
var callsBase = il.Any(x =>
|
||||
x.IsOp(OpCodes.Call, out MethodReference m) &&
|
||||
m.Eq(baseMethod)
|
||||
);
|
||||
var callsBase = il.Any(x => x.MatchCall(out var m) && m.GenericEq(baseMethod));
|
||||
if (!callsBase)
|
||||
{
|
||||
break;
|
||||
|
@ -19,12 +19,12 @@
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VSToolsPath)\TeamTest\Microsoft.TestTools.targets" Condition="Exists('$(VSToolsPath)\TeamTest\Microsoft.TestTools.targets')" />
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.0.1" />
|
||||
<PackageReference Include="MSTest.TestAdapter" Version="1.4.0" />
|
||||
<PackageReference Include="MSTest.TestFramework" Version="1.4.0" />
|
||||
<PackageReference Include="OuterWildsGameLibs" Version="*" />
|
||||
<PackageReference Include="OWML" Version="2.*" />
|
||||
<PackageReference Include="HarmonyX" Version="2.*" />
|
||||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.0.0" />
|
||||
<PackageReference Include="MSTest.TestAdapter" Version="2.2.8" />
|
||||
<PackageReference Include="MSTest.TestFramework" Version="2.2.8" />
|
||||
<PackageReference Include="OuterWildsGameLibs" Version="1.1.12.125" />
|
||||
<PackageReference Include="OWML" Version="2.3.1" />
|
||||
<PackageReference Include="HarmonyX" Version="2.8.0" />
|
||||
<ProjectReference Include="..\QSB\QSB.csproj" />
|
||||
</ItemGroup>
|
||||
</Project>
|
@ -153,10 +153,6 @@ namespace QuantumUNET
|
||||
do
|
||||
{
|
||||
networkEventType = NetworkTransport.ReceiveFromHost(serverHostId, out var connectionId, out var channelId, messageBuffer, messageBuffer.Length, out var receivedSize, out var b);
|
||||
if (networkEventType != NetworkEventType.Nothing)
|
||||
{
|
||||
Debug.Log($"Server event: host={serverHostId} event={networkEventType} error={b}");
|
||||
}
|
||||
|
||||
switch (networkEventType)
|
||||
{
|
||||
|
@ -13,7 +13,7 @@
|
||||
<DebugType>pdbonly</DebugType>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<PackageReference Include="OuterWildsGameLibs" Version="*" IncludeAssets="compile" />
|
||||
<PackageReference Include="OuterWildsGameLibs" Version="1.1.12.125" IncludeAssets="compile" />
|
||||
<Reference Include="System.Data.DataSetExtensions" />
|
||||
</ItemGroup>
|
||||
</Project>
|
Loading…
x
Reference in New Issue
Block a user