mirror of
https://github.com/misternebula/quantum-space-buddies.git
synced 2025-03-12 22:14:37 +00:00
Merge pull request #437 from misternebula/disconnect-at-end-of-game
Disconnect at end of game, stop players from progressing past Galaxy Map without all players preset
This commit is contained in:
commit
c5788a6d53
Binary file not shown.
@ -1,12 +1,12 @@
|
||||
ManifestFileVersion: 0
|
||||
CRC: 1208921857
|
||||
CRC: 3225525052
|
||||
Hashes:
|
||||
AssetFileHash:
|
||||
serializedVersion: 2
|
||||
Hash: e6fb281706df372893c7d91213b2598a
|
||||
Hash: 87f7c3f8f1dad1f9a7b628009679b8a9
|
||||
TypeTreeHash:
|
||||
serializedVersion: 2
|
||||
Hash: 91770441465e7cb2442c311d5ad605d6
|
||||
Hash: aea5b327f5eb025bf5354f2e56c088be
|
||||
HashAppended: 0
|
||||
ClassTypes:
|
||||
- Class: 1
|
||||
|
BIN
QSB/AssetBundles/textassets
Normal file
BIN
QSB/AssetBundles/textassets
Normal file
Binary file not shown.
17
QSB/AssetBundles/textassets.manifest
Normal file
17
QSB/AssetBundles/textassets.manifest
Normal file
@ -0,0 +1,17 @@
|
||||
ManifestFileVersion: 0
|
||||
CRC: 3102539871
|
||||
Hashes:
|
||||
AssetFileHash:
|
||||
serializedVersion: 2
|
||||
Hash: 520c501e95916cc8415cccee47d482d5
|
||||
TypeTreeHash:
|
||||
serializedVersion: 2
|
||||
Hash: 5ad585dd02dfb5016c0dad519eab8f49
|
||||
HashAppended: 0
|
||||
ClassTypes:
|
||||
- Class: 49
|
||||
Script: {instanceID: 0}
|
||||
SerializeReferenceClassIdentifiers: []
|
||||
Assets:
|
||||
- Assets/TextAssets/GalaxyMap.txt
|
||||
Dependencies: []
|
@ -34,7 +34,10 @@ namespace QSB.DeathSync.Events
|
||||
var player = QSBPlayerManager.GetPlayer(message.AboutId);
|
||||
var playerName = player.Name;
|
||||
var deathMessage = Necronomicon.GetPhrase(message.EnumValue, message.NecronomiconIndex);
|
||||
DebugLog.ToAll(string.Format(deathMessage, playerName));
|
||||
if (deathMessage != string.Empty)
|
||||
{
|
||||
DebugLog.ToAll(string.Format(deathMessage, playerName));
|
||||
}
|
||||
|
||||
RespawnManager.Instance.OnPlayerDeath(player);
|
||||
}
|
||||
|
@ -80,16 +80,6 @@ namespace QSB.DeathSync
|
||||
"{0} died due to digestion"
|
||||
}
|
||||
},
|
||||
{
|
||||
DeathType.BigBang,
|
||||
new[] // End of the game
|
||||
{
|
||||
// TODO : maybe don't show these?
|
||||
"{0} sacrificed themself for the universe",
|
||||
"{0} knows the true meaning of sacrifice",
|
||||
"{0} won at the cost of their life"
|
||||
}
|
||||
},
|
||||
{
|
||||
DeathType.Crushed,
|
||||
new[] // Crushed in sand
|
||||
@ -104,15 +94,6 @@ namespace QSB.DeathSync
|
||||
"{0} died due to being crushed"
|
||||
}
|
||||
},
|
||||
{
|
||||
DeathType.TimeLoop,
|
||||
new[] // Escaping the supernova
|
||||
{
|
||||
"{0} ran out of time",
|
||||
"{0} lost track of time",
|
||||
"{0} watched the sun go kaboom"
|
||||
}
|
||||
},
|
||||
{
|
||||
DeathType.Lava,
|
||||
new[] // Lava
|
||||
@ -164,7 +145,7 @@ namespace QSB.DeathSync
|
||||
|
||||
public static string GetPhrase(DeathType deathType, int index)
|
||||
=> !Darkhold.ContainsKey(deathType)
|
||||
? Darkhold[DeathType.Default][index]
|
||||
? string.Empty
|
||||
: Darkhold[deathType][index];
|
||||
|
||||
public static int GetRandomIndex(DeathType deathType)
|
||||
|
@ -23,6 +23,7 @@
|
||||
public const string ExitFlightConsole = nameof(ExitFlightConsole);
|
||||
public const string EnterShip = nameof(EnterShip);
|
||||
public const string ExitShip = nameof(ExitShip);
|
||||
public const string EyeStateChanged = nameof(EyeStateChanged);
|
||||
|
||||
// Custom event names -- change if you want! These can be anything, as long as both
|
||||
// sides of the GlobalMessenger (fireevent and addlistener) reference the same thing.
|
||||
@ -107,5 +108,6 @@
|
||||
public const string QSBGameDetails = nameof(QSBGameDetails);
|
||||
public const string QSBEnterRemoteDialogue = nameof(QSBEnterRemoteDialogue);
|
||||
public const string QSBGatherInstrument = nameof(QSBGatherInstrument);
|
||||
public const string QSBZoomOut = nameof(QSBZoomOut);
|
||||
}
|
||||
}
|
||||
|
33
QSB/EyeOfTheUniverse/EyeStateSync/Events/EyeStateEvent.cs
Normal file
33
QSB/EyeOfTheUniverse/EyeStateSync/Events/EyeStateEvent.cs
Normal file
@ -0,0 +1,33 @@
|
||||
using QSB.Events;
|
||||
using QSB.Messaging;
|
||||
using QSB.Player;
|
||||
|
||||
namespace QSB.EyeOfTheUniverse.EyeStateSync.Events
|
||||
{
|
||||
internal class EyeStateEvent : QSBEvent<EnumMessage<EyeState>>
|
||||
{
|
||||
public override bool RequireWorldObjectsReady => true;
|
||||
|
||||
public override void SetupListener() => GlobalMessenger<EyeState>.AddListener(EventNames.EyeStateChanged, Handler);
|
||||
public override void CloseListener() => GlobalMessenger<EyeState>.RemoveListener(EventNames.EyeStateChanged, Handler);
|
||||
|
||||
private void Handler(EyeState state) => SendEvent(CreateMessage(state));
|
||||
|
||||
private EnumMessage<EyeState> CreateMessage(EyeState state) => new()
|
||||
{
|
||||
AboutId = LocalPlayerId,
|
||||
EnumValue = state
|
||||
};
|
||||
|
||||
public override void OnReceiveLocal(bool isHost, EnumMessage<EyeState> message)
|
||||
{
|
||||
QSBPlayerManager.LocalPlayer.EyeState = message.EnumValue;
|
||||
}
|
||||
|
||||
public override void OnReceiveRemote(bool isHost, EnumMessage<EyeState> message)
|
||||
{
|
||||
var player = QSBPlayerManager.GetPlayer(message.AboutId);
|
||||
player.EyeState = message.EnumValue;
|
||||
}
|
||||
}
|
||||
}
|
38
QSB/EyeOfTheUniverse/GalaxyMap/Events/ZoomOutEvent.cs
Normal file
38
QSB/EyeOfTheUniverse/GalaxyMap/Events/ZoomOutEvent.cs
Normal file
@ -0,0 +1,38 @@
|
||||
using QSB.Events;
|
||||
using QSB.Messaging;
|
||||
using QSB.WorldSync;
|
||||
using System.Linq;
|
||||
|
||||
namespace QSB.EyeOfTheUniverse.GalaxyMap.Events
|
||||
{
|
||||
internal class ZoomOutEvent : QSBEvent<PlayerMessage>
|
||||
{
|
||||
public override bool RequireWorldObjectsReady => true;
|
||||
|
||||
public override void SetupListener() => GlobalMessenger.AddListener(EventNames.QSBZoomOut, Handler);
|
||||
public override void CloseListener() => GlobalMessenger.RemoveListener(EventNames.QSBZoomOut, Handler);
|
||||
|
||||
private void Handler() => SendEvent(CreateMessage());
|
||||
|
||||
private PlayerMessage CreateMessage() => new()
|
||||
{
|
||||
AboutId = LocalPlayerId
|
||||
};
|
||||
|
||||
public override void OnReceiveRemote(bool isHost, PlayerMessage message)
|
||||
{
|
||||
var controller = QSBWorldSync.GetUnityObjects<GalaxyMapController>().First();
|
||||
controller.enabled = true;
|
||||
Locator.GetPlayerController().SetColliderActivation(false);
|
||||
controller._endlessObservatoryVolume.SetActivation(false);
|
||||
controller._forestOfGalaxiesVolume.SetTriggerActivation(false);
|
||||
ReticleController.Hide();
|
||||
controller._zoomSpeed = 50f;
|
||||
Locator.GetPlayerBody().AddVelocityChange(-Locator.GetPlayerCamera().transform.forward * controller._zoomSpeed);
|
||||
controller._origEyePos = controller._eyeTransform.localPosition;
|
||||
controller._audioSource.Play();
|
||||
RumbleManager.PlayGalaxyZoom();
|
||||
Locator.GetEyeStateManager().SetState(EyeState.ZoomOut);
|
||||
}
|
||||
}
|
||||
}
|
39
QSB/EyeOfTheUniverse/GalaxyMap/GalaxyMapManager.cs
Normal file
39
QSB/EyeOfTheUniverse/GalaxyMap/GalaxyMapManager.cs
Normal file
@ -0,0 +1,39 @@
|
||||
using QSB.WorldSync;
|
||||
using System.Linq;
|
||||
using UnityEngine;
|
||||
|
||||
namespace QSB.EyeOfTheUniverse.GalaxyMap
|
||||
{
|
||||
internal class GalaxyMapManager : MonoBehaviour
|
||||
{
|
||||
public static GalaxyMapManager Instance { get; private set; }
|
||||
|
||||
public QSBCharacterDialogueTree Tree { get; private set; }
|
||||
|
||||
private void Awake()
|
||||
{
|
||||
Instance = this;
|
||||
QSBSceneManager.OnSceneLoaded += OnSceneLoaded;
|
||||
}
|
||||
|
||||
private void OnSceneLoaded(OWScene oldScene, OWScene newScene, bool inUniverse)
|
||||
{
|
||||
if (newScene != OWScene.EyeOfTheUniverse)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var mapController = QSBWorldSync.GetUnityObjects<GalaxyMapController>().First();
|
||||
var map = mapController._interactVolume.gameObject;
|
||||
|
||||
map.SetActive(false);
|
||||
Tree = map.AddComponent<QSBCharacterDialogueTree>();
|
||||
Tree._xmlCharacterDialogueAsset = QSBCore.TextAssetsBundle.LoadAsset<TextAsset>("Assets/TextAssets/GalaxyMap.txt");
|
||||
Tree._attentionPoint = map.transform;
|
||||
Tree._attentionPointOffset = new Vector3(0, 1, 0);
|
||||
Tree._turnOffFlashlight = true;
|
||||
Tree._turnOnFlashlight = true;
|
||||
map.SetActive(true);
|
||||
}
|
||||
}
|
||||
}
|
37
QSB/EyeOfTheUniverse/GalaxyMap/Patches/GalaxyMapPatches.cs
Normal file
37
QSB/EyeOfTheUniverse/GalaxyMap/Patches/GalaxyMapPatches.cs
Normal file
@ -0,0 +1,37 @@
|
||||
using HarmonyLib;
|
||||
using QSB.Events;
|
||||
using QSB.Patches;
|
||||
using QSB.Player;
|
||||
using System.Linq;
|
||||
|
||||
namespace QSB.EyeOfTheUniverse.GalaxyMap.Patches
|
||||
{
|
||||
internal class GalaxyMapPatches : QSBPatch
|
||||
{
|
||||
public override QSBPatchTypes Type => QSBPatchTypes.OnClientConnect;
|
||||
|
||||
[HarmonyPrefix]
|
||||
[HarmonyPatch(typeof(GalaxyMapController), nameof(GalaxyMapController.OnPressInteract))]
|
||||
public static bool OnPressInteractPrefix()
|
||||
{
|
||||
var allInObservatory = QSBPlayerManager.PlayerList.All(x => x.EyeState == EyeState.Observatory);
|
||||
|
||||
if (!allInObservatory)
|
||||
{
|
||||
GalaxyMapManager.Instance.Tree.StartConversation();
|
||||
}
|
||||
|
||||
return allInObservatory;
|
||||
}
|
||||
|
||||
[HarmonyPostfix]
|
||||
[HarmonyPatch(typeof(GalaxyMapController), nameof(GalaxyMapController.OnPressInteract))]
|
||||
public static void OnPressInteractPostfix()
|
||||
{
|
||||
if (QSBPlayerManager.PlayerList.All(x => x.EyeState == EyeState.Observatory))
|
||||
{
|
||||
QSBEventManager.FireEvent(EventNames.QSBZoomOut);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
534
QSB/EyeOfTheUniverse/GalaxyMap/QSBCharacterDialogueTree.cs
Normal file
534
QSB/EyeOfTheUniverse/GalaxyMap/QSBCharacterDialogueTree.cs
Normal file
@ -0,0 +1,534 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Xml.Linq;
|
||||
using UnityEngine;
|
||||
|
||||
namespace QSB.EyeOfTheUniverse.GalaxyMap
|
||||
{
|
||||
internal class QSBCharacterDialogueTree : MonoBehaviour
|
||||
{
|
||||
public TextAsset _xmlCharacterDialogueAsset;
|
||||
public Transform _attentionPoint;
|
||||
public Vector3 _attentionPointOffset = Vector3.zero;
|
||||
public bool _turnOffFlashlight = true;
|
||||
public bool _turnOnFlashlight = true;
|
||||
|
||||
private SingleInteractionVolume _interactVolume;
|
||||
private string _characterName;
|
||||
private bool _initialized;
|
||||
private IDictionary<string, QSBDialogueNode> _mapDialogueNodes;
|
||||
private List<DialogueOption> _listOptionNodes;
|
||||
private QSBDialogueNode _currentNode;
|
||||
private DialogueBoxVer2 _currentDialogueBox;
|
||||
private bool _wasFlashlightOn;
|
||||
private bool _timeFrozen;
|
||||
private bool _isRecording;
|
||||
|
||||
private const string SIGN_NAME = "SIGN";
|
||||
private const string RECORDING_NAME = "RECORDING";
|
||||
private const float MINIMUM_TIME_TEXT_VISIBLE = 0.1f;
|
||||
|
||||
private void Awake()
|
||||
{
|
||||
_attentionPoint ??= transform;
|
||||
_initialized = false;
|
||||
_interactVolume = this.GetRequiredComponent<SingleInteractionVolume>();
|
||||
GlobalMessenger.AddListener("DialogueConditionsReset", new Callback(OnDialogueConditionsReset));
|
||||
GlobalMessenger<DeathType>.AddListener("PlayerDeath", new Callback<DeathType>(OnPlayerDeath));
|
||||
enabled = false;
|
||||
}
|
||||
|
||||
private void OnDestroy()
|
||||
{
|
||||
GlobalMessenger.RemoveListener("DialogueConditionsReset", new Callback(OnDialogueConditionsReset));
|
||||
GlobalMessenger<DeathType>.RemoveListener("PlayerDeath", new Callback<DeathType>(OnPlayerDeath));
|
||||
}
|
||||
|
||||
public void LateInitialize()
|
||||
{
|
||||
_mapDialogueNodes = new Dictionary<string, QSBDialogueNode>(ComparerLibrary.stringEqComparer);
|
||||
_listOptionNodes = new List<DialogueOption>();
|
||||
_initialized = LoadXml();
|
||||
}
|
||||
|
||||
public void VerifyInitialized()
|
||||
{
|
||||
if (!_initialized)
|
||||
{
|
||||
LateInitialize();
|
||||
}
|
||||
}
|
||||
|
||||
public void SetTextXml(TextAsset textAsset)
|
||||
{
|
||||
_xmlCharacterDialogueAsset = textAsset;
|
||||
if (_initialized)
|
||||
{
|
||||
LoadXml();
|
||||
}
|
||||
}
|
||||
|
||||
public bool InConversation()
|
||||
{
|
||||
return enabled;
|
||||
}
|
||||
|
||||
public InteractVolume GetInteractVolume()
|
||||
{
|
||||
return _interactVolume;
|
||||
}
|
||||
|
||||
private void Update()
|
||||
{
|
||||
if (_currentDialogueBox != null && OWInput.GetInputMode() == InputMode.Dialogue)
|
||||
{
|
||||
if (OWInput.IsNewlyPressed(InputLibrary.interact, InputMode.All) || OWInput.IsNewlyPressed(InputLibrary.cancel, InputMode.All) || OWInput.IsNewlyPressed(InputLibrary.enter, InputMode.All) || OWInput.IsNewlyPressed(InputLibrary.enter2, InputMode.All))
|
||||
{
|
||||
if (!_currentDialogueBox.AreTextEffectsComplete())
|
||||
{
|
||||
_currentDialogueBox.FinishAllTextEffects();
|
||||
return;
|
||||
}
|
||||
|
||||
if (_currentDialogueBox.TimeCompletelyRevealed() < 0.1f)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var selectedOption = _currentDialogueBox.GetSelectedOption();
|
||||
if (!InputDialogueOption(selectedOption))
|
||||
{
|
||||
EndConversation();
|
||||
return;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (OWInput.IsNewlyPressed(InputLibrary.down, InputMode.All) || OWInput.IsNewlyPressed(InputLibrary.down2, InputMode.All))
|
||||
{
|
||||
_currentDialogueBox.OnDownPressed();
|
||||
return;
|
||||
}
|
||||
|
||||
if (OWInput.IsNewlyPressed(InputLibrary.up, InputMode.All) || OWInput.IsNewlyPressed(InputLibrary.up2, InputMode.All))
|
||||
{
|
||||
_currentDialogueBox.OnUpPressed();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void SetEntryNode()
|
||||
{
|
||||
var list = new List<QSBDialogueNode>();
|
||||
list.AddRange(_mapDialogueNodes.Values);
|
||||
for (var i = list.Count - 1; i >= 0; i--)
|
||||
{
|
||||
if (list[i].EntryConditionsSatisfied())
|
||||
{
|
||||
_currentNode = list[i];
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
Debug.LogWarning("CharacterDialogueTree " + _characterName + " no EntryConditions satisfied. Did you forget to add <EntryCondition>DEFAULT</EntryCondition> to a node?");
|
||||
}
|
||||
|
||||
private bool LoadXml()
|
||||
{
|
||||
try
|
||||
{
|
||||
_mapDialogueNodes.Clear();
|
||||
_listOptionNodes.Clear();
|
||||
var sharedInstance = DialogueConditionManager.SharedInstance;
|
||||
var xelement = XDocument.Parse(OWUtilities.RemoveByteOrderMark(_xmlCharacterDialogueAsset)).Element("DialogueTree");
|
||||
var xelement2 = xelement.Element("NameField");
|
||||
if (xelement2 == null)
|
||||
{
|
||||
_characterName = "";
|
||||
}
|
||||
else
|
||||
{
|
||||
_characterName = xelement2.Value;
|
||||
}
|
||||
|
||||
foreach (var xelement3 in xelement.Elements("DialogueNode"))
|
||||
{
|
||||
var dialogueNode = new QSBDialogueNode();
|
||||
if (xelement3.Element("Name") != null)
|
||||
{
|
||||
dialogueNode.Name = xelement3.Element("Name").Value;
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.LogWarning("Missing name on a Node");
|
||||
}
|
||||
|
||||
var randomize = xelement3.Element("Randomize") != null;
|
||||
dialogueNode.DisplayTextData = new DialogueText(xelement3.Elements("Dialogue"), randomize);
|
||||
var xelement4 = xelement3.Element("DialogueTarget");
|
||||
if (xelement4 != null)
|
||||
{
|
||||
dialogueNode.TargetName = xelement4.Value;
|
||||
}
|
||||
|
||||
var enumerable = xelement3.Elements("EntryCondition");
|
||||
if (enumerable != null)
|
||||
{
|
||||
foreach (var xelement5 in enumerable)
|
||||
{
|
||||
dialogueNode.ListEntryCondition.Add(xelement5.Value);
|
||||
if (!sharedInstance.ConditionExists(xelement5.Value))
|
||||
{
|
||||
sharedInstance.AddCondition(xelement5.Value, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var enumerable2 = xelement3.Elements("DialogueTargetShipLogCondition");
|
||||
if (enumerable2 != null)
|
||||
{
|
||||
foreach (var xelement6 in enumerable2)
|
||||
{
|
||||
dialogueNode.ListTargetCondition.Add(xelement6.Value);
|
||||
}
|
||||
}
|
||||
|
||||
foreach (var xelement7 in xelement3.Elements("SetCondition"))
|
||||
{
|
||||
dialogueNode.ConditionsToSet.Add(xelement7.Value);
|
||||
}
|
||||
|
||||
var xelement8 = xelement3.Element("SetPersistentCondition");
|
||||
if (xelement8 != null)
|
||||
{
|
||||
dialogueNode.PersistentConditionToSet = xelement8.Value;
|
||||
}
|
||||
|
||||
var xelement9 = xelement3.Element("DisablePersistentCondition");
|
||||
if (xelement9 != null)
|
||||
{
|
||||
dialogueNode.PersistentConditionToDisable = xelement9.Value;
|
||||
}
|
||||
|
||||
var xelement10 = xelement3.Element("RevealFacts");
|
||||
if (xelement10 != null)
|
||||
{
|
||||
var enumerable3 = xelement10.Elements("FactID");
|
||||
if (enumerable3 != null)
|
||||
{
|
||||
var list = new List<string>();
|
||||
foreach (var xelement11 in enumerable3)
|
||||
{
|
||||
list.Add(xelement11.Value);
|
||||
}
|
||||
|
||||
dialogueNode.DBEntriesToSet = new string[list.Count];
|
||||
for (var i = 0; i < list.Count; i++)
|
||||
{
|
||||
dialogueNode.DBEntriesToSet[i] = list[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var list2 = new List<DialogueOption>();
|
||||
var xelement12 = xelement3.Element("DialogueOptionsList");
|
||||
if (xelement12 != null)
|
||||
{
|
||||
var enumerable4 = xelement12.Elements("DialogueOption");
|
||||
if (enumerable4 != null)
|
||||
{
|
||||
foreach (var xelement13 in enumerable4)
|
||||
{
|
||||
var dialogueOption = new DialogueOption
|
||||
{
|
||||
Text = OWUtilities.CleanupXmlText(xelement13.Element("Text").Value, false)
|
||||
};
|
||||
dialogueOption.SetNodeId(dialogueNode.Name, _characterName);
|
||||
var xelement14 = xelement13.Element("DialogueTarget");
|
||||
if (xelement14 != null)
|
||||
{
|
||||
dialogueOption.TargetName = xelement14.Value;
|
||||
}
|
||||
|
||||
if (xelement13.Element("RequiredCondition") != null)
|
||||
{
|
||||
dialogueOption.ConditionRequirement = xelement13.Element("RequiredCondition").Value;
|
||||
if (!sharedInstance.ConditionExists(dialogueOption.ConditionRequirement))
|
||||
{
|
||||
sharedInstance.AddCondition(dialogueOption.ConditionRequirement, false);
|
||||
}
|
||||
}
|
||||
|
||||
foreach (var xelement15 in xelement13.Elements("RequiredPersistentCondition"))
|
||||
{
|
||||
dialogueOption.PersistentCondition.Add(xelement15.Value);
|
||||
}
|
||||
|
||||
if (xelement13.Element("CancelledCondition") != null)
|
||||
{
|
||||
dialogueOption.CancelledRequirement = xelement13.Element("CancelledCondition").Value;
|
||||
if (!sharedInstance.ConditionExists(dialogueOption.CancelledRequirement))
|
||||
{
|
||||
sharedInstance.AddCondition(dialogueOption.CancelledRequirement, false);
|
||||
}
|
||||
}
|
||||
|
||||
foreach (var xelement16 in xelement13.Elements("CancelledPersistentCondition"))
|
||||
{
|
||||
dialogueOption.CancelledPersistentRequirement.Add(xelement16.Value);
|
||||
}
|
||||
|
||||
foreach (var xelement17 in xelement13.Elements("RequiredLogCondition"))
|
||||
{
|
||||
dialogueOption.LogConditionRequirement.Add(xelement17.Value);
|
||||
}
|
||||
|
||||
if (xelement13.Element("ConditionToSet") != null)
|
||||
{
|
||||
dialogueOption.ConditionToSet = xelement13.Element("ConditionToSet").Value;
|
||||
if (!sharedInstance.ConditionExists(dialogueOption.ConditionToSet))
|
||||
{
|
||||
sharedInstance.AddCondition(dialogueOption.ConditionToSet, false);
|
||||
}
|
||||
}
|
||||
|
||||
if (xelement13.Element("ConditionToCancel") != null)
|
||||
{
|
||||
dialogueOption.ConditionToCancel = xelement13.Element("ConditionToCancel").Value;
|
||||
if (!sharedInstance.ConditionExists(dialogueOption.ConditionToCancel))
|
||||
{
|
||||
sharedInstance.AddCondition(dialogueOption.ConditionToCancel, false);
|
||||
}
|
||||
}
|
||||
|
||||
list2.Add(dialogueOption);
|
||||
_listOptionNodes.Add(dialogueOption);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
dialogueNode.ListDialogueOptions = list2;
|
||||
_mapDialogueNodes.Add(dialogueNode.Name, dialogueNode);
|
||||
}
|
||||
|
||||
var list3 = new List<QSBDialogueNode>();
|
||||
list3.AddRange(_mapDialogueNodes.Values);
|
||||
for (var j = 0; j < list3.Count; j++)
|
||||
{
|
||||
var dialogueNode2 = list3[j];
|
||||
var targetName = dialogueNode2.TargetName;
|
||||
if (targetName != "")
|
||||
{
|
||||
if (_mapDialogueNodes.ContainsKey(targetName))
|
||||
{
|
||||
dialogueNode2.Target = _mapDialogueNodes[targetName];
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.LogError("Target Node: " + targetName + " does not exist", this);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
dialogueNode2.Target = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Debug.LogError("XML Error in CharacterDialogueTree!\n" + ex.Message, this);
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public void StartConversation()
|
||||
{
|
||||
VerifyInitialized();
|
||||
enabled = true;
|
||||
if (!_timeFrozen && PlayerData.GetFreezeTimeWhileReadingConversations() && !Locator.GetGlobalMusicController().IsEndTimesPlaying())
|
||||
{
|
||||
_timeFrozen = true;
|
||||
OWTime.Pause(OWTime.PauseType.Reading);
|
||||
}
|
||||
|
||||
Locator.GetToolModeSwapper().UnequipTool();
|
||||
GlobalMessenger.FireEvent("EnterConversation");
|
||||
Locator.GetPlayerAudioController().PlayDialogueEnter(_isRecording);
|
||||
_wasFlashlightOn = Locator.GetFlashlight().IsFlashlightOn();
|
||||
if (_wasFlashlightOn && _turnOffFlashlight)
|
||||
{
|
||||
Locator.GetFlashlight().TurnOff(false);
|
||||
}
|
||||
|
||||
DialogueConditionManager.SharedInstance.ReadPlayerData();
|
||||
SetEntryNode();
|
||||
_currentDialogueBox = DisplayDialogueBox2();
|
||||
if (_attentionPoint != null && !PlayerState.InZeroG())
|
||||
{
|
||||
Locator.GetPlayerTransform().GetRequiredComponent<PlayerLockOnTargeting>().LockOn(_attentionPoint, _attentionPointOffset, 2f, false, 1f);
|
||||
}
|
||||
|
||||
if (PlayerState.InZeroG() && !_timeFrozen)
|
||||
{
|
||||
Locator.GetPlayerBody().GetComponent<Autopilot>().StartMatchVelocity(this.GetAttachedOWRigidbody(false).GetReferenceFrame(), false);
|
||||
}
|
||||
}
|
||||
|
||||
public void EndConversation()
|
||||
{
|
||||
if (!enabled)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
enabled = false;
|
||||
if (_timeFrozen)
|
||||
{
|
||||
_timeFrozen = false;
|
||||
OWTime.Unpause(OWTime.PauseType.Reading);
|
||||
}
|
||||
|
||||
_interactVolume.ResetInteraction();
|
||||
Locator.GetPlayerTransform().GetRequiredComponent<PlayerLockOnTargeting>().BreakLock();
|
||||
GlobalMessenger.FireEvent("ExitConversation");
|
||||
Locator.GetPlayerAudioController().PlayDialogueExit(_isRecording);
|
||||
if (_wasFlashlightOn && _turnOffFlashlight && _turnOnFlashlight)
|
||||
{
|
||||
Locator.GetFlashlight().TurnOn(false);
|
||||
}
|
||||
|
||||
GameObject.FindWithTag("DialogueGui").GetRequiredComponent<DialogueBoxVer2>().OnEndDialogue();
|
||||
if (_currentNode != null)
|
||||
{
|
||||
_currentNode.SetNodeCompleted();
|
||||
}
|
||||
|
||||
if (PlayerState.InZeroG())
|
||||
{
|
||||
var component = Locator.GetPlayerBody().GetComponent<Autopilot>();
|
||||
if (component.enabled)
|
||||
{
|
||||
component.Abort();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private bool InputDialogueOption(int optionIndex)
|
||||
{
|
||||
var result = true;
|
||||
var flag = true;
|
||||
if (optionIndex >= 0)
|
||||
{
|
||||
var selectedOption = _currentDialogueBox.OptionFromUIIndex(optionIndex);
|
||||
ContinueToNextNode(selectedOption);
|
||||
}
|
||||
else if (!_currentNode.HasNext())
|
||||
{
|
||||
ContinueToNextNode();
|
||||
}
|
||||
|
||||
if (_currentNode == null)
|
||||
{
|
||||
_currentDialogueBox = null;
|
||||
flag = false;
|
||||
result = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
_currentDialogueBox = DisplayDialogueBox2();
|
||||
}
|
||||
|
||||
if (flag)
|
||||
{
|
||||
Locator.GetPlayerAudioController().PlayDialogueAdvance();
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
private DialogueBoxVer2 DisplayDialogueBox2()
|
||||
{
|
||||
var richText = "";
|
||||
var listOptions = new List<DialogueOption>();
|
||||
_currentNode.RefreshConditionsData();
|
||||
if (_currentNode.HasNext())
|
||||
{
|
||||
_currentNode.GetNextPage(out richText, ref listOptions);
|
||||
}
|
||||
|
||||
var requiredComponent = GameObject.FindWithTag("DialogueGui").GetRequiredComponent<DialogueBoxVer2>();
|
||||
requiredComponent.SetVisible(true);
|
||||
requiredComponent.SetDialogueText(richText, listOptions);
|
||||
if (_characterName == "")
|
||||
{
|
||||
requiredComponent.SetNameFieldVisible(false);
|
||||
}
|
||||
else
|
||||
{
|
||||
requiredComponent.SetNameFieldVisible(true);
|
||||
requiredComponent.SetNameField(TextTranslation.Translate(_characterName));
|
||||
}
|
||||
|
||||
return requiredComponent;
|
||||
}
|
||||
|
||||
private void ContinueToNextNode()
|
||||
{
|
||||
_currentNode.SetNodeCompleted();
|
||||
if (_currentNode.ListTargetCondition.Count > 0 && !_currentNode.TargetNodeConditionsSatisfied())
|
||||
{
|
||||
_currentNode = null;
|
||||
return;
|
||||
}
|
||||
|
||||
_currentNode = _currentNode.Target;
|
||||
}
|
||||
|
||||
private void ContinueToNextNode(DialogueOption selectedOption)
|
||||
{
|
||||
_currentNode.SetNodeCompleted();
|
||||
if (selectedOption.ConditionToSet != string.Empty)
|
||||
{
|
||||
DialogueConditionManager.SharedInstance.SetConditionState(selectedOption.ConditionToSet, true);
|
||||
}
|
||||
|
||||
if (selectedOption.ConditionToCancel != string.Empty)
|
||||
{
|
||||
DialogueConditionManager.SharedInstance.SetConditionState(selectedOption.ConditionToCancel, false);
|
||||
}
|
||||
|
||||
if (selectedOption.TargetName == string.Empty)
|
||||
{
|
||||
_currentNode = null;
|
||||
return;
|
||||
}
|
||||
|
||||
if (!_mapDialogueNodes.ContainsKey(selectedOption.TargetName))
|
||||
{
|
||||
Debug.LogError("Cannot find target node " + selectedOption.TargetName);
|
||||
Debug.Break();
|
||||
}
|
||||
|
||||
_currentNode = _mapDialogueNodes[selectedOption.TargetName];
|
||||
}
|
||||
|
||||
private void OnDialogueConditionsReset()
|
||||
{
|
||||
if (_initialized)
|
||||
{
|
||||
LoadXml();
|
||||
}
|
||||
}
|
||||
|
||||
private void OnPlayerDeath(DeathType deathType)
|
||||
{
|
||||
if (enabled)
|
||||
{
|
||||
EndConversation();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
161
QSB/EyeOfTheUniverse/GalaxyMap/QSBDialogueNode.cs
Normal file
161
QSB/EyeOfTheUniverse/GalaxyMap/QSBDialogueNode.cs
Normal file
@ -0,0 +1,161 @@
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace QSB.EyeOfTheUniverse.GalaxyMap
|
||||
{
|
||||
internal class QSBDialogueNode
|
||||
{
|
||||
private List<string> _listPagesToDisplay;
|
||||
|
||||
public string Name { get; set; }
|
||||
public List<DialogueOption> ListDialogueOptions { get; set; }
|
||||
public List<string> ListEntryCondition { get; set; }
|
||||
public List<string> ConditionsToSet { get; set; }
|
||||
public string PersistentConditionToSet { get; set; }
|
||||
public string PersistentConditionToDisable { get; set; }
|
||||
public string[] DBEntriesToSet { get; set; }
|
||||
public DialogueText DisplayTextData { get; set; }
|
||||
public string TargetName { get; set; }
|
||||
public List<string> ListTargetCondition { get; set; }
|
||||
public QSBDialogueNode Target { get; set; }
|
||||
public int CurrentPage { get; private set; }
|
||||
|
||||
public QSBDialogueNode()
|
||||
{
|
||||
Name = "";
|
||||
CurrentPage = -1;
|
||||
TargetName = "";
|
||||
Target = null;
|
||||
ListEntryCondition = new List<string>();
|
||||
_listPagesToDisplay = new List<string>();
|
||||
ListTargetCondition = new List<string>();
|
||||
ListDialogueOptions = new List<DialogueOption>();
|
||||
ConditionsToSet = new List<string>();
|
||||
PersistentConditionToSet = string.Empty;
|
||||
PersistentConditionToDisable = string.Empty;
|
||||
DBEntriesToSet = new string[0];
|
||||
}
|
||||
|
||||
public void RefreshConditionsData()
|
||||
{
|
||||
_listPagesToDisplay = DisplayTextData.GetDisplayStringList();
|
||||
}
|
||||
|
||||
public void GetNextPage(out string mainText, ref List<DialogueOption> options)
|
||||
{
|
||||
if (HasNext())
|
||||
{
|
||||
CurrentPage++;
|
||||
}
|
||||
|
||||
mainText = _listPagesToDisplay[CurrentPage].Trim();
|
||||
if (!HasNext())
|
||||
{
|
||||
for (var i = 0; i < ListDialogueOptions.Count; i++)
|
||||
{
|
||||
options.Add(ListDialogueOptions[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public bool HasNext()
|
||||
{
|
||||
return CurrentPage + 1 < _listPagesToDisplay.Count;
|
||||
}
|
||||
|
||||
public string GetOptionsText(out int count)
|
||||
{
|
||||
var text = "";
|
||||
count = 0;
|
||||
for (var i = 0; i < ListDialogueOptions.Count; i++)
|
||||
{
|
||||
text += ListDialogueOptions[i].Text;
|
||||
text += "\n";
|
||||
count++;
|
||||
}
|
||||
|
||||
return text;
|
||||
}
|
||||
|
||||
public bool EntryConditionsSatisfied()
|
||||
{
|
||||
var result = true;
|
||||
if (ListEntryCondition.Count == 0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
var sharedInstance = DialogueConditionManager.SharedInstance;
|
||||
for (var i = 0; i < ListEntryCondition.Count; i++)
|
||||
{
|
||||
var text = ListEntryCondition[i];
|
||||
if (sharedInstance.ConditionExists(text))
|
||||
{
|
||||
if (!sharedInstance.GetConditionState(text))
|
||||
{
|
||||
result = false;
|
||||
}
|
||||
}
|
||||
else if (!PlayerData.PersistentConditionExists(text))
|
||||
{
|
||||
if (!PlayerData.GetPersistentCondition(text))
|
||||
{
|
||||
result = false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
result = false;
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public bool TargetNodeConditionsSatisfied()
|
||||
{
|
||||
var result = true;
|
||||
if (ListTargetCondition.Count == 0)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
for (var i = 0; i < ListTargetCondition.Count; i++)
|
||||
{
|
||||
var id = ListTargetCondition[i];
|
||||
if (!Locator.GetShipLogManager().IsFactRevealed(id))
|
||||
{
|
||||
result = false;
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public void SetNodeCompleted()
|
||||
{
|
||||
CurrentPage = -1;
|
||||
var sharedInstance = DialogueConditionManager.SharedInstance;
|
||||
for (var i = 0; i < ConditionsToSet.Count; i++)
|
||||
{
|
||||
sharedInstance.SetConditionState(ConditionsToSet[i], true);
|
||||
}
|
||||
|
||||
if (PersistentConditionToSet != string.Empty)
|
||||
{
|
||||
PlayerData.SetPersistentCondition(PersistentConditionToSet, true);
|
||||
sharedInstance.SetConditionState(PersistentConditionToSet, true);
|
||||
}
|
||||
|
||||
if (PersistentConditionToDisable != string.Empty)
|
||||
{
|
||||
PlayerData.SetPersistentCondition(PersistentConditionToDisable, false);
|
||||
sharedInstance.SetConditionState(PersistentConditionToDisable, false);
|
||||
}
|
||||
|
||||
for (var j = 0; j < DBEntriesToSet.Length; j++)
|
||||
{
|
||||
Locator.GetShipLogManager().RevealFact(DBEntriesToSet[j], true, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -120,6 +120,7 @@ namespace QSB.Player
|
||||
public JetpackAccelerationSync JetpackAcceleration { get; set; }
|
||||
|
||||
// Misc
|
||||
// CLEANUP : this file is very messy. especially this bit
|
||||
public bool IsReady { get; set; }
|
||||
public bool IsInMoon;
|
||||
public bool IsInShrine;
|
||||
@ -133,6 +134,7 @@ namespace QSB.Player
|
||||
public bool TranslatorEquipped { get; set; }
|
||||
public bool ProbeActive { get; set; }
|
||||
public QSBPlayerAudioController AudioController { get; set; }
|
||||
public EyeState EyeState { get; set; }
|
||||
|
||||
// Local only
|
||||
public PlayerProbeLauncher LocalProbeLauncher
|
||||
|
@ -1,6 +1,7 @@
|
||||
using OWML.Common;
|
||||
using OWML.ModHelper;
|
||||
using OWML.ModHelper.Input;
|
||||
using QSB.EyeOfTheUniverse.GalaxyMap;
|
||||
using QSB.Inputs;
|
||||
using QSB.Menus;
|
||||
using QSB.Patches;
|
||||
@ -53,6 +54,7 @@ namespace QSB
|
||||
public static AssetBundle InstrumentAssetBundle { get; private set; }
|
||||
public static AssetBundle ConversationAssetBundle { get; private set; }
|
||||
public static AssetBundle DebugAssetBundle { get; private set; }
|
||||
public static AssetBundle TextAssetsBundle { get; private set; }
|
||||
public static bool IsHost => QNetworkServer.active;
|
||||
public static bool IsInMultiplayer => QNetworkManager.singleton.isNetworkActive;
|
||||
public static string QSBVersion => Helper.Manifest.Version;
|
||||
@ -83,6 +85,7 @@ namespace QSB
|
||||
InstrumentAssetBundle = Helper.Assets.LoadBundle("AssetBundles/instruments");
|
||||
ConversationAssetBundle = Helper.Assets.LoadBundle("AssetBundles/conversation");
|
||||
DebugAssetBundle = Helper.Assets.LoadBundle("AssetBundles/debug");
|
||||
TextAssetsBundle = Helper.Assets.LoadBundle("AssetBundles/textassets");
|
||||
|
||||
DebugSettings = ModHelper.Storage.Load<DebugSettings>("debugsettings.json");
|
||||
|
||||
@ -103,6 +106,7 @@ namespace QSB
|
||||
gameObject.AddComponent<RespawnManager>();
|
||||
gameObject.AddComponent<SatelliteProjectorManager>();
|
||||
gameObject.AddComponent<StatueManager>();
|
||||
gameObject.AddComponent<GalaxyMapManager>();
|
||||
|
||||
// WorldObject managers
|
||||
foreach (var type in typeof(WorldObjectManager).GetDerivedTypes())
|
||||
|
@ -35,6 +35,11 @@ namespace QSB
|
||||
{
|
||||
OnUniverseSceneLoaded?.SafeInvoke(oldScene, newScene);
|
||||
}
|
||||
|
||||
if (newScene == OWScene.TitleScreen && QSBCore.IsInMultiplayer)
|
||||
{
|
||||
QSBNetworkManager.Instance.StopHost();
|
||||
}
|
||||
}
|
||||
|
||||
private static bool InUniverse(OWScene scene) =>
|
||||
|
@ -133,6 +133,7 @@ namespace QSB.Utility
|
||||
|
||||
WriteLine(2, $"{player.PlayerId}.{player.Name}");
|
||||
WriteLine(2, $"State : {player.State}");
|
||||
WriteLine(2, $"Eye State : {player.EyeState}");
|
||||
WriteLine(2, $"Dead : {player.IsDead}");
|
||||
WriteLine(2, $"Visible : {player.Visible}");
|
||||
WriteLine(2, $"Ready : {player.IsReady}");
|
||||
@ -158,7 +159,15 @@ namespace QSB.Utility
|
||||
var instance = ShipTransformSync.LocalInstance;
|
||||
if (QSBCore.IsHost)
|
||||
{
|
||||
WriteLine(3, $"Current Owner : {instance.NetIdentity.ClientAuthorityOwner.GetPlayerId()}");
|
||||
var currentOwner = instance.NetIdentity.ClientAuthorityOwner;
|
||||
if (currentOwner == null)
|
||||
{
|
||||
WriteLine(3, $"Current Owner : NULL");
|
||||
}
|
||||
else
|
||||
{
|
||||
WriteLine(3, $"Current Owner : {currentOwner.GetPlayerId()}");
|
||||
}
|
||||
}
|
||||
|
||||
var sector = instance.ReferenceSector;
|
||||
|
@ -45,7 +45,7 @@ namespace QSB.Utility
|
||||
{
|
||||
if (connection == null)
|
||||
{
|
||||
DebugLog.ToConsole($"Error - Trying to get player id of null QNetworkConnection.", MessageType.Error);
|
||||
DebugLog.ToConsole($"Error - Trying to get player id of null QNetworkConnection.\r\n{Environment.StackTrace}", MessageType.Error);
|
||||
return uint.MaxValue;
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user