Merge branch 'dev' into eote-dreamworld-entry-exit

This commit is contained in:
Mister_Nebula 2022-03-28 18:03:00 +01:00
commit c96052911a
18 changed files with 313 additions and 65 deletions

View File

@ -150,50 +150,121 @@ public class DeathPatches : QSBPatch
[HarmonyPrefix]
[HarmonyPatch(typeof(DeathManager), nameof(DeathManager.KillPlayer))]
public static bool DeathManager_KillPlayer_Prefix(DeathType deathType)
private static bool DeathManager_KillPlayer(DeathManager __instance, DeathType deathType)
{
if (RespawnOnDeath.Instance == null)
{
return true;
}
if (RespawnOnDeath.Instance.AllowedDeathTypes.Contains(deathType))
{
return true;
}
if (QSBPlayerManager.LocalPlayer.IsDead)
{
return false;
}
var deadPlayersCount = QSBPlayerManager.PlayerList.Count(x => x.IsDead);
if (deadPlayersCount == QSBPlayerManager.PlayerList.Count - 1)
{
new EndLoopMessage().Send();
return true;
}
RespawnOnDeath.Instance.ResetPlayer();
Original(__instance, deathType);
return false;
}
[HarmonyPostfix]
[HarmonyPatch(typeof(DeathManager), nameof(DeathManager.KillPlayer))]
public static void DeathManager_KillPlayer_Postfix(DeathType deathType)
{
if (QSBPlayerManager.LocalPlayer.IsDead)
static void Original(DeathManager @this, DeathType deathType)
{
return;
@this._fakeMeditationDeath = false;
if (deathType == DeathType.Meditation && @this.CheckShouldWakeInDreamWorld())
{
@this._fakeMeditationDeath = true;
OWInput.ChangeInputMode(InputMode.None);
ReticleController.Hide();
Locator.GetPromptManager().SetPromptsVisible(false);
GlobalMessenger.FireEvent("FakePlayerMeditationDeath");
return;
}
if (deathType == DeathType.DreamExplosion)
{
Achievements.Earn(Achievements.Type.EARLY_ADOPTER);
}
if (PlayerState.InDreamWorld() && deathType != DeathType.Dream && deathType != DeathType.DreamExplosion && deathType != DeathType.Supernova && deathType != DeathType.TimeLoop && deathType != DeathType.Meditation)
{
Locator.GetDreamWorldController().ExitDreamWorld(deathType);
return;
}
if (!@this._isDying)
{
if (@this._invincible && deathType != DeathType.Supernova && deathType != DeathType.BigBang && deathType != DeathType.Meditation && deathType != DeathType.TimeLoop && deathType != DeathType.BlackHole)
{
return;
}
if (!Custom(deathType))
{
return;
}
if (!TimeLoopCoreController.ParadoxExists())
{
var component = Locator.GetPlayerBody().GetComponent<PlayerResources>();
if ((deathType == DeathType.TimeLoop || deathType == DeathType.Supernova) && component.GetTotalDamageThisLoop() > 1000f)
{
Achievements.Earn(Achievements.Type.DIEHARD);
PlayerData.SetPersistentCondition("THERE_IS_BUT_VOID", true);
}
if ((TimeLoop.GetLoopCount() != 1 && TimeLoop.GetSecondsElapsed() < 60f || TimeLoop.GetLoopCount() == 1 && Time.timeSinceLevelLoad < 60f && !TimeLoop.IsTimeFlowing()) && deathType != DeathType.Meditation && LoadManager.GetCurrentScene() == OWScene.SolarSystem)
{
Achievements.Earn(Achievements.Type.GONE_IN_60_SECONDS);
}
if (TimeLoop.GetLoopCount() > 1)
{
Achievements.SetHeroStat(Achievements.HeroStat.TIMELOOP_COUNT, (uint)(TimeLoop.GetLoopCount() - 1));
if (deathType == DeathType.TimeLoop || deathType == DeathType.BigBang || deathType == DeathType.Supernova)
{
PlayerData.CompletedFullTimeLoop();
}
}
if (deathType == DeathType.Supernova && !PlayerData.GetPersistentCondition("KILLED_BY_SUPERNOVA_AND_KNOWS_IT") && PlayerData.GetFullTimeLoopsCompleted() > 2U && PlayerData.GetPersistentCondition("HAS_SEEN_SUN_EXPLODE"))
{
PlayerData.SetPersistentCondition("KILLED_BY_SUPERNOVA_AND_KNOWS_IT", true);
MonoBehaviour.print("KILLED_BY_SUPERNOVA_AND_KNOWS_IT");
}
}
@this._isDying = true;
@this._deathType = deathType;
MonoBehaviour.print("Player was killed by " + deathType);
Locator.GetPauseCommandListener().AddPauseCommandLock();
PlayerData.SetLastDeathType(deathType);
GlobalMessenger<DeathType>.FireEvent("PlayerDeath", deathType);
}
}
QSBPlayerManager.LocalPlayer.IsDead = true;
new PlayerDeathMessage(deathType).Send();
if (PlayerAttachWatcher.Current)
static bool Custom(DeathType deathType)
{
PlayerAttachWatcher.Current.DetachPlayer();
if (RespawnOnDeath.Instance == null)
{
return true;
}
if (RespawnOnDeath.Instance.AllowedDeathTypes.Contains(deathType))
{
return true;
}
if (QSBPlayerManager.LocalPlayer.IsDead)
{
return false;
}
var deadPlayersCount = QSBPlayerManager.PlayerList.Count(x => x.IsDead);
if (deadPlayersCount == QSBPlayerManager.PlayerList.Count - 1)
{
new EndLoopMessage().Send();
return true;
}
RespawnOnDeath.Instance.ResetPlayer();
QSBPlayerManager.LocalPlayer.IsDead = true;
new PlayerDeathMessage(deathType).Send();
if (PlayerAttachWatcher.Current)
{
PlayerAttachWatcher.Current.DetachPlayer();
}
return false;
}
}

View File

@ -0,0 +1,21 @@
using Cysharp.Threading.Tasks;
using QSB.EchoesOfTheEye.DreamRafts.WorldObjects;
using QSB.WorldSync;
using System.Threading;
namespace QSB.EchoesOfTheEye.DreamRafts;
public class DreamRaftManager : WorldObjectManager
{
public override WorldObjectScene WorldObjectScene => WorldObjectScene.SolarSystem;
public override bool DlcOnly => true;
public override async UniTask BuildWorldObjects(OWScene scene, CancellationToken ct)
{
QSBWorldSync.Init<QSBDreamRaft, DreamRaftController>();
QSBWorldSync.Init<QSBSealRaft, SealRaftController>();
QSBWorldSync.Init<QSBDreamRaftProjector, DreamRaftProjector>();
QSBWorldSync.Init<QSBDreamRaftProjection, DreamRaftProjection>();
}
}

View File

@ -0,0 +1,11 @@
using QSB.EchoesOfTheEye.DreamRafts.WorldObjects;
using QSB.Messaging;
using QSB.Patches;
namespace QSB.EchoesOfTheEye.DreamRafts.Messages;
public class ExtinguishMessage : QSBWorldObjectMessage<QSBDreamRaftProjection>
{
public override void OnReceiveRemote() =>
QSBPatch.RemoteCall(() => WorldObject.AttachedObject.SetVisible(false));
}

View File

@ -0,0 +1,11 @@
using QSB.EchoesOfTheEye.DreamRafts.WorldObjects;
using QSB.Messaging;
using QSB.Patches;
namespace QSB.EchoesOfTheEye.DreamRafts.Messages;
public class SpawnRaftMessage : QSBWorldObjectMessage<QSBDreamRaftProjector>
{
public override void OnReceiveRemote() =>
QSBPatch.RemoteCall(WorldObject.AttachedObject.RespawnRaft);
}

View File

@ -0,0 +1,56 @@
using HarmonyLib;
using QSB.EchoesOfTheEye.DreamRafts.Messages;
using QSB.EchoesOfTheEye.DreamRafts.WorldObjects;
using QSB.Messaging;
using QSB.Patches;
using QSB.WorldSync;
using System.Linq;
namespace QSB.EchoesOfTheEye.DreamRafts.Patches;
public class DreamRaftPatches : QSBPatch
{
public override QSBPatchTypes Type => QSBPatchTypes.OnClientConnect;
[HarmonyPrefix]
[HarmonyPatch(typeof(DreamRaftProjector), nameof(DreamRaftProjector.SpawnRaft))]
private static void SpawnRaft(DreamRaftProjector __instance)
{
if (Remote)
{
return;
}
if (!QSBWorldSync.AllObjectsReady)
{
return;
}
__instance.GetWorldObject<QSBDreamRaftProjector>()
.SendMessage(new SpawnRaftMessage());
}
[HarmonyPrefix]
[HarmonyPatch(typeof(DreamRaftProjection), nameof(DreamRaftProjection.OnCandleLitStateChanged))]
private static bool OnCandleLitStateChanged(DreamRaftProjection __instance)
{
if (!__instance._visible)
{
return false;
}
if (__instance._candles.Any(x => x.IsLit()))
{
return false;
}
__instance.SetVisible(false);
if (!Remote && QSBWorldSync.AllObjectsReady)
{
__instance.GetWorldObject<QSBDreamRaftProjection>()
.SendMessage(new ExtinguishMessage());
}
return false;
}
}

View File

@ -0,0 +1,13 @@
using QSB.EchoesOfTheEye.RaftSync.TransformSync;
using QSB.Utility.LinkedWorldObject;
using UnityEngine;
namespace QSB.EchoesOfTheEye.DreamRafts.WorldObjects;
public class QSBDreamRaft : LinkedWorldObject<DreamRaftController, RaftTransformSync>
{
public override void SendInitialState(uint to) { }
protected override GameObject NetworkObjectPrefab => QSBNetworkManager.singleton.RaftPrefab;
protected override bool SpawnWithServerAuthority => false;
}

View File

@ -0,0 +1,8 @@
using QSB.WorldSync;
namespace QSB.EchoesOfTheEye.DreamRafts.WorldObjects;
public class QSBDreamRaftProjection : WorldObject<DreamRaftProjection>
{
public override void SendInitialState(uint to) { }
}

View File

@ -0,0 +1,16 @@
using QSB.EchoesOfTheEye.DreamRafts.Messages;
using QSB.Messaging;
using QSB.WorldSync;
namespace QSB.EchoesOfTheEye.DreamRafts.WorldObjects;
public class QSBDreamRaftProjector : WorldObject<DreamRaftProjector>
{
public override void SendInitialState(uint to)
{
if (AttachedObject._lit)
{
this.SendMessage(new SpawnRaftMessage());
}
}
}

View File

@ -0,0 +1,13 @@
using QSB.EchoesOfTheEye.RaftSync.TransformSync;
using QSB.Utility.LinkedWorldObject;
using UnityEngine;
namespace QSB.EchoesOfTheEye.DreamRafts.WorldObjects;
public class QSBSealRaft : LinkedWorldObject<SealRaftController, RaftTransformSync>
{
public override void SendInitialState(uint to) { }
protected override GameObject NetworkObjectPrefab => QSBNetworkManager.singleton.RaftPrefab;
protected override bool SpawnWithServerAuthority => false;
}

View File

@ -28,6 +28,8 @@ internal class EnterDreamWorldMessage : QSBWorldObjectMessage<QSBDreamLanternIte
});
}
public override void OnReceiveLocal() => OnReceiveRemote();
public override void OnReceiveRemote()
{
var player = QSBPlayerManager.GetPlayer(From);

View File

@ -22,6 +22,8 @@ internal class ExitDreamWorldMessage : QSBMessage
});
}
public override void OnReceiveLocal() => OnReceiveRemote();
public override void OnReceiveRemote()
{
var player = QSBPlayerManager.GetPlayer(From);

View File

@ -1,9 +1,9 @@
using QSB.AuthoritySync;
using QSB.EchoesOfTheEye.RaftSync.WorldObjects;
using QSB.Syncs.Unsectored.Rigidbodies;
using QSB.Utility;
using QSB.Utility.LinkedWorldObject;
using QSB.WorldSync;
using System;
namespace QSB.EchoesOfTheEye.RaftSync.TransformSync;
@ -11,10 +11,17 @@ public class RaftTransformSync : UnsectoredRigidbodySync, ILinkedNetworkBehaviou
{
protected override bool UseInterpolation => false;
private QSBRaft _qsbRaft;
public void SetWorldObject(IWorldObject worldObject) => _qsbRaft = (QSBRaft)worldObject;
private IWorldObject _worldObject;
public void SetWorldObject(IWorldObject worldObject) => _worldObject = worldObject;
protected override OWRigidbody InitAttachedRigidbody() => _qsbRaft.AttachedObject._raftBody;
protected override OWRigidbody InitAttachedRigidbody() =>
_worldObject.AttachedObject switch
{
RaftController x => x._raftBody,
DreamRaftController x => x._raftBody,
SealRaftController x => x._raftBody,
_ => throw new ArgumentOutOfRangeException(nameof(_worldObject.AttachedObject), _worldObject.AttachedObject, null)
};
public override void OnStartClient()
{

View File

@ -1,9 +1,4 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using UnityEngine;
using UnityEngine;
namespace QSB.Player;

View File

@ -1,9 +1,4 @@
using QSB.ItemSync.WorldObjects.Items;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace QSB.Player;

View File

@ -11,7 +11,7 @@ public partial class PlayerInfo
{
if (!IsLocalPlayer)
{
DebugLog.ToConsole($"Warning - Tried to access local-only property LocalProbeLauncher in PlayerInfo for non local player!", MessageType.Warning);
DebugLog.ToConsole("Warning - Tried to access local-only property LocalProbeLauncher in PlayerInfo for non local player!", MessageType.Warning);
return null;
}
@ -25,7 +25,7 @@ public partial class PlayerInfo
{
if (!IsLocalPlayer)
{
DebugLog.ToConsole($"Warning - Tried to access local-only property LocalFlashlight in PlayerInfo for non local player!", MessageType.Warning);
DebugLog.ToConsole("Warning - Tried to access local-only property LocalFlashlight in PlayerInfo for non local player!", MessageType.Warning);
return null;
}
@ -39,7 +39,7 @@ public partial class PlayerInfo
{
if (!IsLocalPlayer)
{
DebugLog.ToConsole($"Warning - Tried to access local-only property LocalSignalscope in PlayerInfo for non local player!", MessageType.Warning);
DebugLog.ToConsole("Warning - Tried to access local-only property LocalSignalscope in PlayerInfo for non local player!", MessageType.Warning);
return null;
}
@ -53,7 +53,7 @@ public partial class PlayerInfo
{
if (!IsLocalPlayer)
{
DebugLog.ToConsole($"Warning - Tried to access local-only property LocalTranslator in PlayerInfo for non local player!", MessageType.Warning);
DebugLog.ToConsole("Warning - Tried to access local-only property LocalTranslator in PlayerInfo for non local player!", MessageType.Warning);
return null;
}

View File

@ -11,8 +11,8 @@ public class ShipCustomAttach : MonoBehaviour
private void Awake()
{
Locator.GetPromptManager().AddScreenPrompt(_attachPrompt, PromptPosition.UpperRight);
Locator.GetPromptManager().AddScreenPrompt(_detachPrompt, PromptPosition.UpperRight);
Locator.GetPromptManager().AddScreenPrompt(_attachPrompt, PromptPosition.Center);
Locator.GetPromptManager().AddScreenPrompt(_detachPrompt, PromptPosition.Center);
_playerAttachPoint = gameObject.AddComponent<PlayerAttachPoint>();
_playerAttachPoint._lockPlayerTurning = false;
@ -24,8 +24,8 @@ public class ShipCustomAttach : MonoBehaviour
{
if (Locator.GetPromptManager())
{
Locator.GetPromptManager().RemoveScreenPrompt(_attachPrompt, PromptPosition.UpperRight);
Locator.GetPromptManager().RemoveScreenPrompt(_detachPrompt, PromptPosition.UpperRight);
Locator.GetPromptManager().RemoveScreenPrompt(_attachPrompt, PromptPosition.Center);
Locator.GetPromptManager().RemoveScreenPrompt(_detachPrompt, PromptPosition.Center);
}
}

View File

@ -1,8 +1,10 @@
using QSB.Messaging;
using QSB.ItemSync.WorldObjects.Items;
using QSB.Messaging;
using QSB.Player;
using QSB.RespawnSync;
using QSB.ShipSync;
using QSB.Utility.Messages;
using QSB.WorldSync;
using System.Linq;
using UnityEngine;
using UnityEngine.InputSystem;
@ -45,7 +47,7 @@ public class DebugActions : MonoBehaviour, IAddComponentOnStart
/*
* 1 - Warp to first non local player
* 2 - Set time flowing
* 2 - Enter dream world
* 3 - Destroy probe
* 4 - Damage ship electricals
* 5 - Trigger supernova
@ -66,7 +68,32 @@ public class DebugActions : MonoBehaviour, IAddComponentOnStart
if (Keyboard.current[Key.Numpad2].wasPressedThisFrame)
{
TimeLoop._isTimeFlowing = true;
if (!QSBPlayerManager.LocalPlayer.InDreamWorld)
{
var relativeLocation = new RelativeLocationData(Vector3.up * 2 + Vector3.forward * 2, Quaternion.identity, Vector3.zero);
const DreamArrivalPoint.Location location = DreamArrivalPoint.Location.Zone3;
var arrivalPoint = Locator.GetDreamArrivalPoint(location);
var dreamCampfire = Locator.GetDreamCampfire(location);
if (Locator.GetToolModeSwapper().GetItemCarryTool().GetHeldItemType() != ItemType.DreamLantern)
{
var dreamLanternItem = QSBWorldSync.GetWorldObjects<QSBDreamLanternItem>().First(x =>
x.AttachedObject._lanternType == DreamLanternType.Functioning &&
QSBPlayerManager.PlayerList.All(y => y.HeldItem != x)
).AttachedObject;
Locator.GetToolModeSwapper().GetItemCarryTool().PickUpItemInstantly(dreamLanternItem);
}
Locator.GetDreamWorldController().EnterDreamWorld(dreamCampfire, arrivalPoint, relativeLocation);
}
else
{
if (Locator.GetToolModeSwapper().GetItemCarryTool().GetHeldItemType() != ItemType.DreamLantern)
{
var dreamLanternItem = QSBPlayerManager.LocalPlayer.AssignedSimulationLantern.AttachedObject;
Locator.GetToolModeSwapper().GetItemCarryTool().PickUpItemInstantly(dreamLanternItem);
}
}
}
if (Keyboard.current[Key.Numpad3].wasPressedThisFrame)
@ -122,4 +149,4 @@ public class DebugActions : MonoBehaviour, IAddComponentOnStart
RespawnManager.Instance.RespawnSomePlayer();
}
}
}
}

View File

@ -93,7 +93,7 @@ Long answer : Pay me enough money, and maybe I'll consider it.
Boring boring physics stuff. The velocity of the ship is synced, as well as the angular velocity. However, this velocity is not also applied to the player. (Or it is sometimes. I don't 100% know.) This means the ship will accelerate, leaving the player "behind". Which makes you fly into the walls alot.
**Update**: you can attach/detach yourself to/from the ship using the prompt in the upper right corner of the screen.
**Update**: you can attach/detach yourself to/from the ship using the prompt in the center of the screen.
### What's the difference between QSB and Outer Wilds Online?