mirror of
https://github.com/misternebula/quantum-space-buddies.git
synced 2025-02-06 00:39:55 +00:00
Merge branch 'dev' into update-changelog-popup
This commit is contained in:
commit
d425a0d712
@ -17,5 +17,6 @@ internal class CharacterAnimManager : WorldObjectManager
|
||||
QSBWorldSync.Init<QSBSolanumAnimController, SolanumAnimController>();
|
||||
QSBWorldSync.Init<QSBHearthianRecorderEffects, HearthianRecorderEffects>();
|
||||
QSBWorldSync.Init<QSBTravelerEyeController, TravelerEyeController>();
|
||||
QSBWorldSync.Init<PrisonerDialogue, PrisonerDirector>();
|
||||
}
|
||||
}
|
12
QSB/Animation/NPC/WorldObjects/PrisonerDialogue.cs
Normal file
12
QSB/Animation/NPC/WorldObjects/PrisonerDialogue.cs
Normal file
@ -0,0 +1,12 @@
|
||||
namespace QSB.Animation.NPC.WorldObjects;
|
||||
|
||||
internal class PrisonerDialogue : NpcAnimController<PrisonerDirector>
|
||||
{
|
||||
public override void SendInitialState(uint to)
|
||||
{
|
||||
// todo : implement
|
||||
}
|
||||
|
||||
public override CharacterDialogueTree GetDialogueTree()
|
||||
=> AttachedObject._characterDialogueTree;
|
||||
}
|
1171
QSB/Assets/cellevator.pdn
Normal file
1171
QSB/Assets/cellevator.pdn
Normal file
File diff suppressed because one or more lines are too long
1376
QSB/Assets/cellevator1.pdn
Normal file
1376
QSB/Assets/cellevator1.pdn
Normal file
File diff suppressed because one or more lines are too long
BIN
QSB/Assets/cellevator1.png
Normal file
BIN
QSB/Assets/cellevator1.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 488 KiB |
1376
QSB/Assets/cellevator2.pdn
Normal file
1376
QSB/Assets/cellevator2.pdn
Normal file
File diff suppressed because one or more lines are too long
BIN
QSB/Assets/cellevator2.png
Normal file
BIN
QSB/Assets/cellevator2.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 483 KiB |
1376
QSB/Assets/cellevator3.pdn
Normal file
1376
QSB/Assets/cellevator3.pdn
Normal file
File diff suppressed because one or more lines are too long
BIN
QSB/Assets/cellevator3.png
Normal file
BIN
QSB/Assets/cellevator3.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 504 KiB |
1376
QSB/Assets/cellevatorBASE.pdn
Normal file
1376
QSB/Assets/cellevatorBASE.pdn
Normal file
File diff suppressed because one or more lines are too long
@ -1,4 +1,5 @@
|
||||
using GhostEnums;
|
||||
using QSB.Player;
|
||||
using QSB.Utility;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
@ -11,8 +12,8 @@ namespace QSB.EchoesOfTheEye.Ghosts.Actions;
|
||||
internal class QSBGrabAction : QSBGhostAction
|
||||
{
|
||||
private bool _playerIsGrabbed;
|
||||
|
||||
private bool _grabAnimComplete;
|
||||
private PlayerInfo _grabbedPlayer;
|
||||
|
||||
public override GhostAction.Name GetName()
|
||||
{
|
||||
@ -26,7 +27,7 @@ internal class QSBGrabAction : QSBGhostAction
|
||||
return -100f;
|
||||
}
|
||||
|
||||
if (PlayerState.IsAttached() || !_data.interestedPlayer.sensor.inContactWithPlayer)
|
||||
if (_playerIsGrabbed || !_data.interestedPlayer.sensor.inContactWithPlayer)
|
||||
{
|
||||
return -100f;
|
||||
}
|
||||
@ -58,10 +59,16 @@ internal class QSBGrabAction : QSBGhostAction
|
||||
_playerIsGrabbed = false;
|
||||
_grabAnimComplete = false;
|
||||
_effects.AttachedObject.OnGrabComplete -= OnGrabComplete;
|
||||
_grabbedPlayer = null;
|
||||
}
|
||||
|
||||
public override bool Update_Action()
|
||||
{
|
||||
if (_grabbedPlayer != null && !_grabbedPlayer.InDreamWorld)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (_playerIsGrabbed)
|
||||
{
|
||||
return true;
|
||||
@ -75,24 +82,20 @@ internal class QSBGrabAction : QSBGhostAction
|
||||
_controller.FaceLocalPosition(_data.interestedPlayer.playerLocation.localPosition, TurnSpeed.FASTEST);
|
||||
if (_sensors.CanGrabPlayer(_data.interestedPlayer))
|
||||
{
|
||||
DebugLog.DebugWrite($"Grab player {_data.interestedPlayer.player.PlayerId}!");
|
||||
GrabPlayer();
|
||||
}
|
||||
else
|
||||
{
|
||||
DebugLog.DebugWrite($"can't grab player {_data.interestedPlayer.player.PlayerId}");
|
||||
GrabPlayer(_data.interestedPlayer);
|
||||
}
|
||||
|
||||
return !_grabAnimComplete;
|
||||
}
|
||||
|
||||
private void GrabPlayer()
|
||||
private void GrabPlayer(GhostPlayer player)
|
||||
{
|
||||
_grabbedPlayer = player.player;
|
||||
_playerIsGrabbed = true;
|
||||
_controller.StopMovingInstantly();
|
||||
_controller.StopFacing();
|
||||
_controller.SetLanternConcealed(true, false);
|
||||
_controller.AttachedObject.GetGrabController().GrabPlayer(1f);
|
||||
_controller.GetGrabController().GrabPlayer(1f, player);
|
||||
}
|
||||
|
||||
private void OnGrabComplete()
|
||||
|
@ -27,11 +27,13 @@ internal class GhostManager : WorldObjectManager
|
||||
QSBWorldSync.Init<QSBPrisonerEffects, GhostEffects>(QSBWorldSync.GetUnityObjects<PrisonerEffects>());
|
||||
QSBWorldSync.Init<QSBGhostSensors, GhostSensors>();
|
||||
QSBWorldSync.Init<QSBGhostNodeMap, GhostNodeMap>();
|
||||
// to avoid disabled ghosts (TheCollector)
|
||||
QSBWorldSync.Init<QSBGhostBrain, GhostBrain>(QSBWorldSync.GetUnityObjects<GhostBrain>().Where(x => x.gameObject.activeSelf).SortDeterministic());
|
||||
QSBWorldSync.Init<QSBGhostGrabController, GhostGrabController>();
|
||||
|
||||
_hotelDirector = QSBWorldSync.GetUnityObjects<GhostHotelDirector>().First();
|
||||
_partyPathDirector = QSBWorldSync.GetUnityObjects<GhostPartyPathDirector>().First();
|
||||
_zone2Director = QSBWorldSync.GetUnityObjects<GhostZone2Director>().First();
|
||||
_hotelDirector = QSBWorldSync.GetUnityObject<GhostHotelDirector>();
|
||||
_partyPathDirector = QSBWorldSync.GetUnityObject<GhostPartyPathDirector>();
|
||||
_zone2Director = QSBWorldSync.GetUnityObject<GhostZone2Director>();
|
||||
|
||||
for (int i = 0; i < _hotelDirector._hotelDepthsGhosts.Length; i++)
|
||||
{
|
||||
|
20
QSB/EchoesOfTheEye/Ghosts/Messages/ContactTriggerMessage.cs
Normal file
20
QSB/EchoesOfTheEye/Ghosts/Messages/ContactTriggerMessage.cs
Normal file
@ -0,0 +1,20 @@
|
||||
using QSB.EchoesOfTheEye.Ghosts.WorldObjects;
|
||||
using QSB.Messaging;
|
||||
using QSB.Player;
|
||||
|
||||
namespace QSB.EchoesOfTheEye.Ghosts.Messages;
|
||||
|
||||
internal class ContactTriggerMessage : QSBWorldObjectMessage<QSBGhostSensors, bool>
|
||||
{
|
||||
public ContactTriggerMessage(bool inContact) : base(inContact) { }
|
||||
|
||||
public override void OnReceiveRemote()
|
||||
{
|
||||
var player = QSBPlayerManager.GetPlayer(From);
|
||||
|
||||
if (WorldObject._data.players[player] != null && WorldObject._data.players[player].sensor != null)
|
||||
{
|
||||
WorldObject._data.players[player].sensor.inContactWithPlayer = Data;
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,23 @@
|
||||
using QSB.EchoesOfTheEye.Ghosts.WorldObjects;
|
||||
using QSB.Messaging;
|
||||
using QSB.Player;
|
||||
using QSB.WorldSync;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace QSB.EchoesOfTheEye.Ghosts.Messages;
|
||||
|
||||
internal class GrabRemotePlayerMessage : QSBWorldObjectMessage<QSBGhostGrabController, (float speed, uint playerId)>
|
||||
{
|
||||
public GrabRemotePlayerMessage(float speed, uint playerId) : base((speed, playerId)) { }
|
||||
|
||||
public override void OnReceiveRemote()
|
||||
{
|
||||
var allGhosts = QSBWorldSync.GetWorldObjects<QSBGhostBrain>();
|
||||
var owningGhost = allGhosts.First(x => x.AttachedObject._controller == WorldObject.AttachedObject._effects._controller);
|
||||
WorldObject.GrabPlayer(Data.speed, owningGhost._data.players[QSBPlayerManager.GetPlayer(Data.playerId)], true);
|
||||
}
|
||||
}
|
@ -66,7 +66,7 @@ internal class GhostSensorsPatches : QSBPatch
|
||||
return true;
|
||||
}
|
||||
|
||||
__instance.GetWorldObject<QSBGhostSensors>().OnEnterContactTrigger(hitObj);
|
||||
DebugLog.ToConsole($"Error - {MethodBase.GetCurrentMethod().Name} not supported!", OWML.Common.MessageType.Error);
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -79,7 +79,7 @@ internal class GhostSensorsPatches : QSBPatch
|
||||
return true;
|
||||
}
|
||||
|
||||
__instance.GetWorldObject<QSBGhostSensors>().OnExitContactTrigger(hitObj);
|
||||
DebugLog.ToConsole($"Error - {MethodBase.GetCurrentMethod().Name} not supported!", OWML.Common.MessageType.Error);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
@ -157,12 +157,19 @@ public class QSBGhostBrain : WorldObject<GhostBrain>, IGhostObject
|
||||
return false;
|
||||
}
|
||||
|
||||
if (fearAudioAlreadyPlaying)
|
||||
if (_data.interestedPlayer == null)
|
||||
{
|
||||
return _currentAction.GetName() is GhostAction.Name.Chase or GhostAction.Name.Grab;
|
||||
return false;
|
||||
}
|
||||
|
||||
return _currentAction.GetName() == GhostAction.Name.Chase;
|
||||
if (_data.interestedPlayer.player != QSBPlayerManager.LocalPlayer)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return fearAudioAlreadyPlaying
|
||||
? _currentAction.GetName() is GhostAction.Name.Chase or GhostAction.Name.Grab
|
||||
: _currentAction.GetName() == GhostAction.Name.Chase;
|
||||
}
|
||||
|
||||
public void Awake()
|
||||
@ -181,7 +188,7 @@ public class QSBGhostBrain : WorldObject<GhostBrain>, IGhostObject
|
||||
AttachedObject.enabled = false;
|
||||
AttachedObject._controller.GetDreamLanternController().enabled = false;
|
||||
AttachedObject._controller.GetWorldObject<QSBGhostController>().Initialize(AttachedObject._nodeLayer, AttachedObject._effects.GetWorldObject<QSBGhostEffects>());
|
||||
AttachedObject._sensors.GetWorldObject<QSBGhostSensors>().Initialize(_data, AttachedObject._guardVolume);
|
||||
AttachedObject._sensors.GetWorldObject<QSBGhostSensors>().Initialize(_data);
|
||||
AttachedObject._effects.GetWorldObject<QSBGhostEffects>().Initialize(AttachedObject._controller.GetNodeRoot(), AttachedObject._controller.GetWorldObject<QSBGhostController>(), _data);
|
||||
AttachedObject._effects.OnCallForHelp += AttachedObject.OnCallForHelp;
|
||||
_data.reducedFrights_allowChase = AttachedObject._reducedFrights_allowChase;
|
||||
@ -190,11 +197,8 @@ public class QSBGhostBrain : WorldObject<GhostBrain>, IGhostObject
|
||||
AttachedObject._intruderConfirmPending = false;
|
||||
AttachedObject._intruderConfirmTime = 0f;
|
||||
|
||||
DebugLog.DebugWrite($"{AttachedObject._name} setting up actions :");
|
||||
|
||||
for (var i = 0; i < AttachedObject._actions.Length; i++)
|
||||
{
|
||||
DebugLog.DebugWrite($"- {AttachedObject._actions[i]}");
|
||||
var ghostAction = QSBGhostAction.CreateAction(AttachedObject._actions[i]);
|
||||
ghostAction.Initialize(this);
|
||||
_actionLibrary.Add(ghostAction);
|
||||
@ -269,10 +273,7 @@ public class QSBGhostBrain : WorldObject<GhostBrain>, IGhostObject
|
||||
}
|
||||
|
||||
public void WakeUp()
|
||||
{
|
||||
DebugLog.DebugWrite($"Wake up!");
|
||||
_data.hasWokenUp = true;
|
||||
}
|
||||
=> _data.hasWokenUp = true;
|
||||
|
||||
public bool HearGhostCall(Vector3 playerLocalPosition, float reactDelay, bool playResponseAudio = false)
|
||||
{
|
||||
@ -300,8 +301,6 @@ public class QSBGhostBrain : WorldObject<GhostBrain>, IGhostObject
|
||||
return false;
|
||||
}
|
||||
|
||||
DebugLog.DebugWrite($"{AttachedObject._name} Hear call for help!");
|
||||
|
||||
if (_data.threatAwareness < GhostData.ThreatAwareness.IntruderConfirmed)
|
||||
{
|
||||
_data.threatAwareness = GhostData.ThreatAwareness.IntruderConfirmed;
|
||||
@ -408,7 +407,6 @@ public class QSBGhostBrain : WorldObject<GhostBrain>, IGhostObject
|
||||
&& (_data.threatAwareness > GhostData.ThreatAwareness.EverythingIsNormal || _data.players.Values.Any(x => x.playerLocation.distance < 20f) || _data.players.Values.Any(x => x.sensor.isPlayerIlluminatedByUs))
|
||||
&& (_data.players.Values.Any(x => x.sensor.isPlayerVisible) || _data.players.Values.Any(x => x.sensor.inContactWithPlayer)))
|
||||
{
|
||||
DebugLog.DebugWrite($"INTRUDER CONFIRMED BY SELF");
|
||||
AttachedObject._intruderConfirmedBySelf = true;
|
||||
AttachedObject._intruderConfirmPending = true;
|
||||
var closestPlayer = _data.players.Values.MinBy(x => x.playerLocation.distance);
|
||||
@ -558,8 +556,6 @@ public class QSBGhostBrain : WorldObject<GhostBrain>, IGhostObject
|
||||
|
||||
public void OnCallForHelp()
|
||||
{
|
||||
DebugLog.DebugWrite($"{AttachedObject._name} - iterating through helper list for callforhelp");
|
||||
|
||||
if (AttachedObject._helperGhosts != null)
|
||||
{
|
||||
for (var i = 0; i < AttachedObject._helperGhosts.Length; i++)
|
||||
|
@ -39,6 +39,9 @@ public class QSBGhostController : WorldObject<GhostController>, IGhostObject
|
||||
AttachedObject._playerCollider = Locator.GetPlayerBody().GetComponent<CapsuleCollider>();
|
||||
}
|
||||
|
||||
public QSBGhostGrabController GetGrabController()
|
||||
=> AttachedObject.GetGrabController().GetWorldObject<QSBGhostGrabController>();
|
||||
|
||||
public void SetLanternConcealed(bool concealed, bool playAudio = true)
|
||||
{
|
||||
if (playAudio && AttachedObject._lantern.IsConcealed() != concealed)
|
||||
|
@ -0,0 +1,67 @@
|
||||
using QSB.EchoesOfTheEye.Ghosts.Messages;
|
||||
using QSB.Messaging;
|
||||
using QSB.Player;
|
||||
using QSB.Utility;
|
||||
using QSB.WorldSync;
|
||||
using UnityEngine;
|
||||
|
||||
namespace QSB.EchoesOfTheEye.Ghosts.WorldObjects;
|
||||
|
||||
public class QSBGhostGrabController : WorldObject<GhostGrabController>
|
||||
{
|
||||
public override void SendInitialState(uint to)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public void GrabPlayer(float speed, GhostPlayer player, bool remote = false)
|
||||
{
|
||||
if (!remote)
|
||||
{
|
||||
this.SendMessage(new GrabRemotePlayerMessage(speed, player.player.PlayerId));
|
||||
}
|
||||
|
||||
var isLocalPlayer = player.player.IsLocalPlayer;
|
||||
|
||||
if (isLocalPlayer)
|
||||
{
|
||||
AttachedObject.enabled = true;
|
||||
AttachedObject._snappingNeck = !player.player.AssignedSimulationLantern.AttachedObject.GetLanternController().IsHeldByPlayer();
|
||||
AttachedObject._holdingInPlace = true;
|
||||
AttachedObject._grabMoveComplete = false;
|
||||
AttachedObject._extinguishStarted = false;
|
||||
AttachedObject._attachPoint.transform.parent = AttachedObject._origParent;
|
||||
AttachedObject._attachPoint.transform.position = Locator.GetPlayerTransform().position;
|
||||
AttachedObject._attachPoint.transform.rotation = Locator.GetPlayerTransform().rotation;
|
||||
AttachedObject._startLocalPos = AttachedObject._attachPoint.transform.localPosition;
|
||||
AttachedObject._startLocalRot = AttachedObject._attachPoint.transform.localRotation;
|
||||
AttachedObject._playerAttached = true;
|
||||
AttachedObject._attachPoint.AttachPlayer();
|
||||
GlobalMessenger.FireEvent("PlayerGrabbedByGhost");
|
||||
OWInput.ChangeInputMode(InputMode.None);
|
||||
ReticleController.Hide();
|
||||
Locator.GetDreamWorldController().SetActiveGhostGrabController(AttachedObject);
|
||||
AttachedObject._grabStartTime = Time.time;
|
||||
AttachedObject._grabMoveDuration = Mathf.Min(Vector3.Distance(AttachedObject._startLocalPos, AttachedObject._holdPoint.localPosition) / speed, 2f);
|
||||
RumbleManager.PlayGhostGrab();
|
||||
Achievement_Ghost.GotCaughtByGhost();
|
||||
}
|
||||
|
||||
var effects = AttachedObject._effects.GetWorldObject<QSBGhostEffects>();
|
||||
|
||||
if (QSBCore.IsHost)
|
||||
{
|
||||
if (AttachedObject._snappingNeck)
|
||||
{
|
||||
effects.PlaySnapNeckAnimation();
|
||||
}
|
||||
else
|
||||
{
|
||||
// todo : make this track grab counts, so we can use the fast animation
|
||||
effects.PlayBlowOutLanternAnimation();
|
||||
}
|
||||
}
|
||||
|
||||
effects.AttachedObject.PlayGrabAudio(AudioType.Ghost_Grab_Contact);
|
||||
}
|
||||
}
|
@ -22,11 +22,14 @@ public class QSBGhostSensors : WorldObject<GhostSensors>, IGhostObject
|
||||
|
||||
public QSBGhostData _data;
|
||||
|
||||
public void Initialize(QSBGhostData data, OWTriggerVolume guardVolume = null)
|
||||
public void Initialize(QSBGhostData data)
|
||||
{
|
||||
_data = data;
|
||||
AttachedObject._contactTrigger.OnEntry -= AttachedObject.OnEnterContactTrigger;
|
||||
AttachedObject._contactTrigger.OnEntry += OnEnterContactTrigger;
|
||||
AttachedObject._contactTrigger.OnExit -= AttachedObject.OnExitContactTrigger;
|
||||
AttachedObject._contactTrigger.OnExit += OnExitContactTrigger;
|
||||
AttachedObject._origEdgeCatcherSize = AttachedObject._contactEdgeCatcherShape.size;
|
||||
AttachedObject._guardVolume = guardVolume;
|
||||
}
|
||||
|
||||
public bool CanGrabPlayer(GhostPlayer player)
|
||||
@ -107,7 +110,6 @@ public class QSBGhostSensors : WorldObject<GhostSensors>, IGhostObject
|
||||
|
||||
if (_data.interestedPlayer != closest)
|
||||
{
|
||||
DebugLog.DebugWrite($"CHANGE INTERESTED PLAYER!");
|
||||
_data.interestedPlayer = closest;
|
||||
this.SendMessage(new ChangeInterestedPlayerMessage(closest.player.PlayerId));
|
||||
}
|
||||
@ -118,6 +120,11 @@ public class QSBGhostSensors : WorldObject<GhostSensors>, IGhostObject
|
||||
if (hitObj.CompareTag("PlayerDetector") && _data.localPlayer != null && _data.localPlayer.sensor != null)
|
||||
{
|
||||
_data.localPlayer.sensor.inContactWithPlayer = true;
|
||||
|
||||
if (!QSBCore.IsHost)
|
||||
{
|
||||
this.SendMessage(new ContactTriggerMessage(true));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -126,6 +133,11 @@ public class QSBGhostSensors : WorldObject<GhostSensors>, IGhostObject
|
||||
if (hitObj.CompareTag("PlayerDetector") && _data.localPlayer != null && _data.localPlayer.sensor != null)
|
||||
{
|
||||
_data.localPlayer.sensor.inContactWithPlayer = false;
|
||||
|
||||
if (!QSBCore.IsHost)
|
||||
{
|
||||
this.SendMessage(new ContactTriggerMessage(false));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
187
QSB/EchoesOfTheEye/Prisoner/CustomAutoSlideProjector.cs
Normal file
187
QSB/EchoesOfTheEye/Prisoner/CustomAutoSlideProjector.cs
Normal file
@ -0,0 +1,187 @@
|
||||
using QSB.Utility;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using UnityEngine;
|
||||
|
||||
namespace QSB.EchoesOfTheEye.Prisoner;
|
||||
|
||||
internal class CustomAutoSlideProjector : MonoBehaviour
|
||||
{
|
||||
public float _defaultSlideDuration;
|
||||
public float _endPauseDuration;
|
||||
|
||||
[SerializeField]
|
||||
public CustomSlideCollectionContainer _slideCollectionItem;
|
||||
|
||||
public OWLight2 _light;
|
||||
|
||||
[SerializeField]
|
||||
[Space]
|
||||
private OWAudioSource _oneShotAudio;
|
||||
|
||||
private float _lastSlidePlayTime;
|
||||
private float _startPausingEndTime;
|
||||
private bool _isPlaying;
|
||||
private bool _isPausingEnd;
|
||||
|
||||
protected void Awake()
|
||||
{
|
||||
if (this._slideCollectionItem != null)
|
||||
{
|
||||
this._slideCollectionItem.onSlideTextureUpdated += this.OnSlideTextureUpdated;
|
||||
this._slideCollectionItem.Initialize();
|
||||
this._slideCollectionItem.enabled = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
DebugLog.DebugWrite($"COLLECTION ITEM NULL IN AWAKE", OWML.Common.MessageType.Error);
|
||||
}
|
||||
base.enabled = false;
|
||||
}
|
||||
|
||||
protected void OnDestroy()
|
||||
{
|
||||
if (this._slideCollectionItem != null)
|
||||
{
|
||||
this._slideCollectionItem.onSlideTextureUpdated -= this.OnSlideTextureUpdated;
|
||||
}
|
||||
}
|
||||
|
||||
public bool IsPlaying()
|
||||
{
|
||||
return this._isPlaying;
|
||||
}
|
||||
|
||||
public void Play(bool reset)
|
||||
{
|
||||
if (this._isPlaying)
|
||||
{
|
||||
return;
|
||||
}
|
||||
this._light.SetActivation(true);
|
||||
if (reset)
|
||||
{
|
||||
this._slideCollectionItem.ResetSlideIndex();
|
||||
}
|
||||
this.UpdateSlideTexture();
|
||||
this._lastSlidePlayTime = Time.time;
|
||||
this._isPlaying = true;
|
||||
base.enabled = true;
|
||||
}
|
||||
|
||||
public void Stop()
|
||||
{
|
||||
if (!this._isPlaying)
|
||||
{
|
||||
return;
|
||||
}
|
||||
this._isPlaying = false;
|
||||
base.enabled = false;
|
||||
this._slideCollectionItem.enabled = false;
|
||||
}
|
||||
|
||||
public void TurnOff()
|
||||
{
|
||||
this.Stop();
|
||||
this._oneShotAudio.PlayOneShot(global::AudioType.Lantern_Remove, 1f);
|
||||
this._light.SetActivation(false);
|
||||
}
|
||||
|
||||
public void SetSlideCollection(CustomSlideCollectionContainer collection)
|
||||
{
|
||||
if (this._slideCollectionItem != null)
|
||||
{
|
||||
if (this._isPlaying)
|
||||
{
|
||||
this._slideCollectionItem.enabled = false;
|
||||
}
|
||||
this._slideCollectionItem.onSlideTextureUpdated -= this.OnSlideTextureUpdated;
|
||||
}
|
||||
this._slideCollectionItem = collection;
|
||||
this._slideCollectionItem.onSlideTextureUpdated += this.OnSlideTextureUpdated;
|
||||
this._slideCollectionItem.Initialize();
|
||||
if (this._isPlaying)
|
||||
{
|
||||
this.UpdateSlideTexture();
|
||||
}
|
||||
}
|
||||
|
||||
protected virtual void Update()
|
||||
{
|
||||
if (this._isPlaying)
|
||||
{
|
||||
if (this._isPausingEnd)
|
||||
{
|
||||
if (Time.time >= this._endPauseDuration + this._startPausingEndTime)
|
||||
{
|
||||
this._isPausingEnd = false;
|
||||
this.FirstSlide();
|
||||
}
|
||||
return;
|
||||
}
|
||||
if (Time.time >= this.GetCurrentSlidePlayDuration() + this._lastSlidePlayTime)
|
||||
{
|
||||
if (!this._slideCollectionItem.isEndOfSlide)
|
||||
{
|
||||
this.NextSlide();
|
||||
return;
|
||||
}
|
||||
if (this._endPauseDuration > 0f)
|
||||
{
|
||||
this._isPausingEnd = true;
|
||||
this._startPausingEndTime = Time.time;
|
||||
return;
|
||||
}
|
||||
this.FirstSlide();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void OnSlideTextureUpdated()
|
||||
{
|
||||
this.UpdateSlideTexture();
|
||||
}
|
||||
|
||||
private void UpdateSlideTexture()
|
||||
{
|
||||
if (_light == null)
|
||||
{
|
||||
DebugLog.DebugWrite($"- Light is null!");
|
||||
}
|
||||
|
||||
if (_slideCollectionItem == null)
|
||||
{
|
||||
DebugLog.DebugWrite($"- slide collection item is null!");
|
||||
}
|
||||
|
||||
this._light.GetLight().cookie = this._slideCollectionItem.GetCurrentSlideTexture();
|
||||
}
|
||||
|
||||
private void FirstSlide()
|
||||
{
|
||||
this._slideCollectionItem.ResetSlideIndex();
|
||||
this._lastSlidePlayTime = Time.time;
|
||||
if (this._oneShotAudio != null)
|
||||
{
|
||||
this._oneShotAudio.PlayOneShot(global::AudioType.Projector_Next, 1f);
|
||||
}
|
||||
}
|
||||
|
||||
private void NextSlide()
|
||||
{
|
||||
this._slideCollectionItem.IncreaseSlideIndex();
|
||||
this._lastSlidePlayTime = Time.time;
|
||||
if (this._oneShotAudio != null)
|
||||
{
|
||||
this._oneShotAudio.PlayOneShot(global::AudioType.Projector_Next, 1f);
|
||||
}
|
||||
}
|
||||
|
||||
private float GetCurrentSlidePlayDuration()
|
||||
{
|
||||
return this._defaultSlideDuration;
|
||||
}
|
||||
}
|
105
QSB/EchoesOfTheEye/Prisoner/CustomSlide.cs
Normal file
105
QSB/EchoesOfTheEye/Prisoner/CustomSlide.cs
Normal file
@ -0,0 +1,105 @@
|
||||
using QSB.Utility;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using UnityEngine;
|
||||
|
||||
namespace QSB.EchoesOfTheEye.Prisoner;
|
||||
|
||||
[Serializable]
|
||||
public class CustomSlide
|
||||
{
|
||||
public Texture2D _image;
|
||||
private Texture2D _textureOverride;
|
||||
private CustomSlideCollectionContainer _owningItem;
|
||||
public bool expanded;
|
||||
|
||||
public Texture2D textureOverride
|
||||
{
|
||||
get
|
||||
{
|
||||
return this._textureOverride;
|
||||
}
|
||||
set
|
||||
{
|
||||
if (this._textureOverride == value)
|
||||
{
|
||||
return;
|
||||
}
|
||||
this._textureOverride = value;
|
||||
this.InvokeTextureUpdate();
|
||||
}
|
||||
}
|
||||
|
||||
public CustomSlide()
|
||||
{
|
||||
this._image = null;
|
||||
this.expanded = false;
|
||||
}
|
||||
|
||||
public CustomSlide(CustomSlide other)
|
||||
{
|
||||
this._image = other._image;
|
||||
this.expanded = false;
|
||||
}
|
||||
|
||||
public Texture GetTexture()
|
||||
{
|
||||
if (this._textureOverride != null)
|
||||
{
|
||||
return this._textureOverride;
|
||||
}
|
||||
|
||||
if (_image == null)
|
||||
{
|
||||
DebugLog.DebugWrite($"IMAGE IS NULL!", OWML.Common.MessageType.Error);
|
||||
}
|
||||
|
||||
return this._image;
|
||||
}
|
||||
|
||||
public void Display(CustomSlideCollectionContainer owner, bool forward)
|
||||
{
|
||||
|
||||
if (owner == null)
|
||||
{
|
||||
DebugLog.DebugWrite($"OWNER IS NULL IN DISPLAY", OWML.Common.MessageType.Error);
|
||||
}
|
||||
|
||||
this._owningItem = owner;
|
||||
this.InvokeTextureUpdate();
|
||||
}
|
||||
|
||||
public void InvokeTextureUpdate()
|
||||
{
|
||||
if (this._owningItem != null)
|
||||
{
|
||||
this._owningItem.onSlideTextureUpdated.Invoke();
|
||||
}
|
||||
else
|
||||
{
|
||||
DebugLog.DebugWrite($"OWNING ITEM IS NULL!", OWML.Common.MessageType.Error);
|
||||
}
|
||||
}
|
||||
|
||||
public void SetChangeSlidesAllowed(bool allowed)
|
||||
{
|
||||
this._owningItem.SetChangeSlidesAllowed(allowed);
|
||||
}
|
||||
|
||||
public void SetOwner(CustomSlideCollectionContainer owner)
|
||||
{
|
||||
this._owningItem = owner;
|
||||
}
|
||||
|
||||
public static CustomSlide CreateSlide(Texture2D texture)
|
||||
{
|
||||
CustomSlide slide = new CustomSlide
|
||||
{
|
||||
_image = texture
|
||||
};
|
||||
return slide;
|
||||
}
|
||||
}
|
27
QSB/EchoesOfTheEye/Prisoner/CustomSlideCollection.cs
Normal file
27
QSB/EchoesOfTheEye/Prisoner/CustomSlideCollection.cs
Normal file
@ -0,0 +1,27 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using UnityEngine;
|
||||
|
||||
namespace QSB.EchoesOfTheEye.Prisoner;
|
||||
|
||||
public class CustomSlideCollection
|
||||
{
|
||||
[SerializeField]
|
||||
public CustomSlide[] slides;
|
||||
|
||||
public CustomSlideCollection(int startArrSize)
|
||||
{
|
||||
this.slides = new CustomSlide[startArrSize];
|
||||
}
|
||||
|
||||
public CustomSlide this[int i]
|
||||
{
|
||||
get
|
||||
{
|
||||
return this.slides[i];
|
||||
}
|
||||
}
|
||||
}
|
143
QSB/EchoesOfTheEye/Prisoner/CustomSlideCollectionContainer.cs
Normal file
143
QSB/EchoesOfTheEye/Prisoner/CustomSlideCollectionContainer.cs
Normal file
@ -0,0 +1,143 @@
|
||||
using QSB.Utility;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using UnityEngine;
|
||||
|
||||
namespace QSB.EchoesOfTheEye.Prisoner;
|
||||
|
||||
public class CustomSlideCollectionContainer : MonoBehaviour
|
||||
{
|
||||
[SerializeField]
|
||||
public CustomSlideCollection _slideCollection = new CustomSlideCollection(0);
|
||||
|
||||
private bool _changeSlidesAllowed;
|
||||
private int _currentSlideIndex;
|
||||
private bool _initialized;
|
||||
|
||||
public int slideCount
|
||||
{
|
||||
get
|
||||
{
|
||||
if (this._slideCollection.slides == null)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
return this._slideCollection.slides.Length;
|
||||
}
|
||||
}
|
||||
|
||||
public bool isEndOfSlide
|
||||
{
|
||||
get
|
||||
{
|
||||
return this._currentSlideIndex >= this.slideCount - 1;
|
||||
}
|
||||
}
|
||||
|
||||
public int slideIndex
|
||||
{
|
||||
get
|
||||
{
|
||||
return this._currentSlideIndex;
|
||||
}
|
||||
set
|
||||
{
|
||||
if (!this._changeSlidesAllowed)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (this._currentSlideIndex == value)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
bool forward = this._currentSlideIndex < value;
|
||||
this._currentSlideIndex = value;
|
||||
if (this._currentSlideIndex > this._slideCollection.slides.Length - 1)
|
||||
{
|
||||
this._currentSlideIndex = 0;
|
||||
}
|
||||
|
||||
if (this._currentSlideIndex < 0)
|
||||
{
|
||||
this._currentSlideIndex = this._slideCollection.slides.Length - 1;
|
||||
}
|
||||
|
||||
this.GetCurrentSlide().Display(this, forward);
|
||||
}
|
||||
}
|
||||
|
||||
public OWEvent onSlideTextureUpdated = new OWEvent(1);
|
||||
public OWEvent onEndOfSlides = new OWEvent(1);
|
||||
|
||||
public void Initialize()
|
||||
{
|
||||
if (this._initialized)
|
||||
{
|
||||
return;
|
||||
}
|
||||
this._changeSlidesAllowed = true;
|
||||
this._initialized = true;
|
||||
}
|
||||
|
||||
public CustomSlide GetCurrentSlide()
|
||||
{
|
||||
if (this._slideCollection.slides.Length == 0)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
return this._slideCollection.slides[this._currentSlideIndex];
|
||||
}
|
||||
|
||||
public Texture GetCurrentSlideTexture()
|
||||
{
|
||||
if (this._slideCollection.slides.Length == 0)
|
||||
{
|
||||
DebugLog.DebugWrite($"NO SLIDES!", OWML.Common.MessageType.Error);
|
||||
return null;
|
||||
}
|
||||
return this.GetCurrentSlide().GetTexture();
|
||||
}
|
||||
|
||||
public void ResetSlideIndex()
|
||||
{
|
||||
this.slideIndex = 0;
|
||||
this.GetCurrentSlide().SetOwner(this);
|
||||
}
|
||||
|
||||
public bool IncreaseSlideIndex()
|
||||
{
|
||||
if (!this._changeSlidesAllowed)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
int slideIndex = this.slideIndex;
|
||||
this.slideIndex = slideIndex + 1;
|
||||
if (this.slideIndex == 0)
|
||||
{
|
||||
this.onEndOfSlides.Invoke();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public bool DecreaseSlideIndex()
|
||||
{
|
||||
if (!this._changeSlidesAllowed)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
int slideIndex = this.slideIndex;
|
||||
this.slideIndex = slideIndex - 1;
|
||||
return true;
|
||||
}
|
||||
|
||||
public void SetChangeSlidesAllowed(bool allowed)
|
||||
{
|
||||
this._changeSlidesAllowed = allowed;
|
||||
}
|
||||
}
|
@ -0,0 +1,14 @@
|
||||
using QSB.EchoesOfTheEye.Prisoner.WorldObjects;
|
||||
using QSB.Messaging;
|
||||
|
||||
namespace QSB.EchoesOfTheEye.Prisoner.Messages;
|
||||
|
||||
internal class CellevatorCallMessage : QSBWorldObjectMessage<QSBPrisonCellElevator, int>
|
||||
{
|
||||
public CellevatorCallMessage(int index) : base(index) { }
|
||||
|
||||
public override void OnReceiveRemote()
|
||||
{
|
||||
WorldObject.CallToFloorIndex(Data, true);
|
||||
}
|
||||
}
|
19
QSB/EchoesOfTheEye/Prisoner/Messages/EmergeTriggerMessage.cs
Normal file
19
QSB/EchoesOfTheEye/Prisoner/Messages/EmergeTriggerMessage.cs
Normal file
@ -0,0 +1,19 @@
|
||||
using QSB.Messaging;
|
||||
using QSB.WorldSync;
|
||||
using System.Linq;
|
||||
|
||||
namespace QSB.EchoesOfTheEye.Prisoner.Messages;
|
||||
|
||||
internal class EmergeTriggerMessage : QSBMessage
|
||||
{
|
||||
public override void OnReceiveRemote()
|
||||
{
|
||||
// hewwo
|
||||
var director = QSBWorldSync.GetUnityObject<PrisonerDirector>();
|
||||
director._darknessAwoken = true;
|
||||
director._cellevator.OnPrisonerReveal();
|
||||
director._musicSource.SetLocalVolume(Locator.GetAudioManager().GetAudioEntry(director._musicSource.audioLibraryClip).volume);
|
||||
director._musicSource.Play();
|
||||
director._prisonerBrain.BeginBehavior(PrisonerBehavior.Emerge);
|
||||
}
|
||||
}
|
@ -0,0 +1,17 @@
|
||||
using QSB.Messaging;
|
||||
using QSB.WorldSync;
|
||||
using System.Linq;
|
||||
|
||||
namespace QSB.EchoesOfTheEye.Prisoner.Messages;
|
||||
|
||||
internal class EnterLightsOutMessage : QSBMessage
|
||||
{
|
||||
public override void OnReceiveRemote()
|
||||
{
|
||||
var director = QSBWorldSync.GetUnityObject<PrisonerDirector>();
|
||||
director._lightsOutTrigger.OnEntry -= director.OnEnterLightsOutTrigger;
|
||||
director._prisonLighting.FadeTo(0, 1);
|
||||
director._hangingLampSource.PlayOneShot(AudioType.Candle_Extinguish, 1f);
|
||||
director._lightsOnAudioVolume.SetVolumeActivation(false);
|
||||
}
|
||||
}
|
@ -0,0 +1,14 @@
|
||||
using QSB.Messaging;
|
||||
using QSB.WorldSync;
|
||||
using System.Linq;
|
||||
|
||||
namespace QSB.EchoesOfTheEye.Prisoner.Messages;
|
||||
|
||||
internal class MindProjectionCompleteMessage : QSBMessage
|
||||
{
|
||||
public override void OnReceiveRemote()
|
||||
{
|
||||
var director = QSBWorldSync.GetUnityObject<PrisonerDirector>();
|
||||
director.OnMindProjectionComplete();
|
||||
}
|
||||
}
|
14
QSB/EchoesOfTheEye/Prisoner/Messages/ProjectMessage.cs
Normal file
14
QSB/EchoesOfTheEye/Prisoner/Messages/ProjectMessage.cs
Normal file
@ -0,0 +1,14 @@
|
||||
using QSB.Messaging;
|
||||
using QSB.WorldSync;
|
||||
using System.Linq;
|
||||
|
||||
namespace QSB.EchoesOfTheEye.Prisoner.Messages;
|
||||
|
||||
internal class ProjectMessage : QSBMessage
|
||||
{
|
||||
public override void OnReceiveRemote()
|
||||
{
|
||||
var director = QSBWorldSync.GetUnityObject<PrisonerDirector>();
|
||||
director._prisonerBrain.BeginBehavior(PrisonerBehavior.ExperienceVision, 0f);
|
||||
}
|
||||
}
|
28
QSB/EchoesOfTheEye/Prisoner/Messages/StopProjectMessage.cs
Normal file
28
QSB/EchoesOfTheEye/Prisoner/Messages/StopProjectMessage.cs
Normal file
@ -0,0 +1,28 @@
|
||||
using QSB.Messaging;
|
||||
using QSB.WorldSync;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace QSB.EchoesOfTheEye.Prisoner.Messages;
|
||||
|
||||
internal class StopProjectMessage : QSBMessage<bool>
|
||||
{
|
||||
public StopProjectMessage(bool done) : base(done) { }
|
||||
|
||||
public override void OnReceiveRemote()
|
||||
{
|
||||
var director = QSBWorldSync.GetUnityObject<PrisonerDirector>();
|
||||
|
||||
if (!Data)
|
||||
{
|
||||
director._prisonerBrain.BeginBehavior(PrisonerBehavior.WaitForProjection, 0.5f);
|
||||
return;
|
||||
}
|
||||
|
||||
director._prisonerDetector.SetActivation(false);
|
||||
director._prisonerBrain.BeginBehavior(PrisonerBehavior.ExperienceEmotionalCatharsis, 0.5f);
|
||||
}
|
||||
}
|
28
QSB/EchoesOfTheEye/Prisoner/Patches/CellevatorPatches.cs
Normal file
28
QSB/EchoesOfTheEye/Prisoner/Patches/CellevatorPatches.cs
Normal file
@ -0,0 +1,28 @@
|
||||
using HarmonyLib;
|
||||
using QSB.EchoesOfTheEye.Prisoner.WorldObjects;
|
||||
using QSB.Patches;
|
||||
using QSB.WorldSync;
|
||||
|
||||
namespace QSB.EchoesOfTheEye.Prisoner.Patches;
|
||||
|
||||
[HarmonyPatch(typeof(PrisonCellElevator))]
|
||||
public class CellevatorPatches : QSBPatch
|
||||
{
|
||||
public override QSBPatchTypes Type => QSBPatchTypes.OnClientConnect;
|
||||
|
||||
[HarmonyPrefix]
|
||||
[HarmonyPatch(nameof(PrisonCellElevator.CallToTopFloor))]
|
||||
public static bool CallToTopFloor(PrisonCellElevator __instance)
|
||||
{
|
||||
__instance.GetWorldObject<QSBPrisonCellElevator>().CallToFloorIndex(1);
|
||||
return false;
|
||||
}
|
||||
|
||||
[HarmonyPrefix]
|
||||
[HarmonyPatch(nameof(PrisonCellElevator.CallToBottomFloor))]
|
||||
public static bool CallToBottomFloor(PrisonCellElevator __instance)
|
||||
{
|
||||
__instance.GetWorldObject<QSBPrisonCellElevator>().CallToFloorIndex(0);
|
||||
return false;
|
||||
}
|
||||
}
|
@ -3,13 +3,9 @@ using QSB.EchoesOfTheEye.Prisoner.Messages;
|
||||
using QSB.EchoesOfTheEye.Prisoner.WorldObjects;
|
||||
using QSB.Messaging;
|
||||
using QSB.Patches;
|
||||
using QSB.Player;
|
||||
using QSB.Utility;
|
||||
using QSB.WorldSync;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using UnityEngine;
|
||||
|
||||
namespace QSB.EchoesOfTheEye.Prisoner.Patches;
|
||||
@ -87,4 +83,17 @@ internal class PrisonerBrainPatches : QSBPatch
|
||||
__instance.GetWorldObject<QSBPrisonerBrain>().FixedUpdate();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
[HarmonyPrefix]
|
||||
[HarmonyPatch(nameof(PrisonerBrain.OnFinishEmergeAnimation))]
|
||||
public static bool OnFinishEmergeAnimation(PrisonerBrain __instance)
|
||||
{
|
||||
if (__instance._currentBehavior is PrisonerBehavior.Emerge or PrisonerBehavior.WaitForConversation)
|
||||
{
|
||||
__instance._effects.OnRevealAnimationComplete -= __instance.OnFinishEmergeAnimation;
|
||||
__instance.OnFinishEmergeBehavior.Invoke();
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
@ -0,0 +1,78 @@
|
||||
using HarmonyLib;
|
||||
using QSB.EchoesOfTheEye.Prisoner.Messages;
|
||||
using QSB.Messaging;
|
||||
using QSB.Patches;
|
||||
using UnityEngine;
|
||||
|
||||
namespace QSB.EchoesOfTheEye.Prisoner.Patches;
|
||||
|
||||
[HarmonyPatch(typeof(PrisonerDirector))]
|
||||
public class PrisonerDirectorPatches : QSBPatch
|
||||
{
|
||||
public override QSBPatchTypes Type => QSBPatchTypes.OnClientConnect;
|
||||
|
||||
[HarmonyPrefix]
|
||||
[HarmonyPatch(nameof(PrisonerDirector.OnEnterEmergeTrigger))]
|
||||
public static bool OnEnterEmergeTrigger(PrisonerDirector __instance, GameObject hitObj)
|
||||
{
|
||||
if (__instance._darknessAwoken)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (hitObj.CompareTag("PlayerDetector"))
|
||||
{
|
||||
__instance._darknessAwoken = true;
|
||||
__instance._prisonerBrain.BeginBehavior(PrisonerBehavior.Emerge, 0f);
|
||||
__instance._cellevator.OnPrisonerReveal();
|
||||
__instance._musicSource.SetLocalVolume(Locator.GetAudioManager().GetAudioEntry(__instance._musicSource.audioLibraryClip).volume);
|
||||
__instance._musicSource.Play();
|
||||
new EmergeTriggerMessage().Send();
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
[HarmonyPrefix]
|
||||
[HarmonyPatch(nameof(PrisonerDirector.OnMindProjectionComplete))]
|
||||
public static bool OnMindProjectionComplete(PrisonerDirector __instance)
|
||||
{
|
||||
if (__instance._projectingVision)
|
||||
{
|
||||
__instance._visionTorchItem.mindProjectorTrigger.SetProjectorActive(false);
|
||||
__instance._projectingVision = false;
|
||||
__instance._prisonerBrain.BeginBehavior(PrisonerBehavior.OfferTorch, 3f);
|
||||
|
||||
new MindProjectionCompleteMessage().Send();
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
[HarmonyPostfix]
|
||||
[HarmonyPatch(nameof(PrisonerDirector.OnStartProjectingOnPrisoner))]
|
||||
public static void OnStartProjectingOnPrisoner()
|
||||
=> new ProjectMessage().Send();
|
||||
|
||||
[HarmonyPostfix]
|
||||
[HarmonyPatch(nameof(PrisonerDirector.OnStopProjectingOnPrisoner))]
|
||||
public static void OnStopProjectingOnPrisoner(PrisonerDirector __instance)
|
||||
=> new StopProjectMessage(__instance._visionTorchItem.mindSlideProjector.mindSlideCollection.slideCollectionContainer.isEndOfSlide).Send();
|
||||
|
||||
[HarmonyPrefix]
|
||||
[HarmonyPatch(nameof(PrisonerDirector.OnEnterLightsOutTrigger))]
|
||||
public static bool OnEnterLightsOutTrigger(PrisonerDirector __instance, GameObject hitObj)
|
||||
{
|
||||
if (hitObj.CompareTag("PlayerDetector"))
|
||||
{
|
||||
__instance._lightsOutTrigger.OnEntry -= __instance.OnEnterLightsOutTrigger;
|
||||
__instance._prisonLighting.FadeTo(0f, 1f);
|
||||
__instance._hangingLampSource.PlayOneShot(AudioType.Candle_Extinguish, 1f);
|
||||
__instance._lightsOnAudioVolume.SetVolumeActivation(false);
|
||||
|
||||
new EnterLightsOutMessage().Send();
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
@ -18,7 +18,7 @@ internal class PrisonerManager : WorldObjectManager
|
||||
|
||||
public override async UniTask BuildWorldObjects(OWScene scene, CancellationToken ct)
|
||||
{
|
||||
var director = QSBWorldSync.GetUnityObjects<PrisonerDirector>().First();
|
||||
var director = QSBWorldSync.GetUnityObject<PrisonerDirector>();
|
||||
|
||||
var markers = new List<Transform>()
|
||||
{
|
||||
@ -37,5 +37,6 @@ internal class PrisonerManager : WorldObjectManager
|
||||
|
||||
QSBWorldSync.Init<QSBPrisonerMarker, PrisonerBehaviourCueMarker>();
|
||||
QSBWorldSync.Init<QSBPrisonerBrain, PrisonerBrain>();
|
||||
QSBWorldSync.Init<QSBPrisonCellElevator, PrisonCellElevator>();
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,93 @@
|
||||
using Cysharp.Threading.Tasks;
|
||||
using QSB.Audio;
|
||||
using QSB.EchoesOfTheEye.Ghosts.WorldObjects;
|
||||
using QSB.EchoesOfTheEye.Prisoner.Messages;
|
||||
using QSB.ItemSync.WorldObjects;
|
||||
using QSB.Messaging;
|
||||
using QSB.Player;
|
||||
using QSB.Utility;
|
||||
using QSB.WorldSync;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using UnityEngine;
|
||||
|
||||
namespace QSB.EchoesOfTheEye.Prisoner.WorldObjects;
|
||||
|
||||
internal class QSBPrisonCellElevator : WorldObject<PrisonCellElevator>, IQSBDropTarget, IGhostObject
|
||||
{
|
||||
public override void SendInitialState(uint to)
|
||||
{
|
||||
// todo : implement this
|
||||
}
|
||||
|
||||
IItemDropTarget IQSBDropTarget.AttachedObject => AttachedObject;
|
||||
|
||||
/*public override async UniTask Init(CancellationToken ct)
|
||||
{
|
||||
DebugLog.DebugWrite($"INIT {AttachedObject.name}");
|
||||
|
||||
var Interactibles_PrisonCell = AttachedObject.GetAttachedOWRigidbody().GetOrigParent().parent;
|
||||
DebugLog.DebugWrite(Interactibles_PrisonCell.name);
|
||||
|
||||
var AUTO_SLIDE_PROJECTOR = new GameObject("AUTO SLIDE PROJECTOR");
|
||||
AUTO_SLIDE_PROJECTOR.transform.parent = Interactibles_PrisonCell;
|
||||
AUTO_SLIDE_PROJECTOR.transform.localPosition = new Vector3(-1.8f, 6.4f, 11.33f);
|
||||
AUTO_SLIDE_PROJECTOR.transform.localRotation = Quaternion.identity;
|
||||
AUTO_SLIDE_PROJECTOR.transform.localScale = Vector3.one;
|
||||
|
||||
AUTO_SLIDE_PROJECTOR.SetActive(false);
|
||||
|
||||
var Light = new GameObject("Light");
|
||||
Light.transform.parent = AUTO_SLIDE_PROJECTOR.transform;
|
||||
Light.transform.localPosition = Vector3.zero;
|
||||
Light.transform.localRotation = Quaternion.Euler(32f, 90f, 0f);
|
||||
var lightComponent = Light.AddComponent<Light>();
|
||||
lightComponent.type = LightType.Spot;
|
||||
lightComponent.range = 10;
|
||||
lightComponent.intensity = 2;
|
||||
lightComponent.spotAngle = 50;
|
||||
lightComponent.shadows = LightShadows.Soft;
|
||||
lightComponent.shadowStrength = 1f;
|
||||
lightComponent.shadowResolution = UnityEngine.Rendering.LightShadowResolution.Low;
|
||||
lightComponent.shadowBias = 0.05f;
|
||||
lightComponent.shadowNormalBias = 0.4f;
|
||||
lightComponent.shadowNearPlane = 0.2f;
|
||||
Light.AddComponent<OWLight2>();
|
||||
|
||||
var projectorComponent = AUTO_SLIDE_PROJECTOR.AddComponent<CustomAutoSlideProjector>();
|
||||
projectorComponent._light = Light.GetComponent<OWLight2>();
|
||||
|
||||
var cellevator1 = TextureHelper.LoadTexture("Assets/cellevator1.png", TextureWrapMode.Clamp, true);
|
||||
var cellevator2 = TextureHelper.LoadTexture("Assets/cellevator2.png", TextureWrapMode.Clamp, true);
|
||||
var cellevator3 = TextureHelper.LoadTexture("Assets/cellevator3.png", TextureWrapMode.Clamp, true);
|
||||
|
||||
var slideCollection = new CustomSlideCollection(3);
|
||||
slideCollection.slides[0] = new CustomSlide() { _image = cellevator1 };
|
||||
slideCollection.slides[1] = new CustomSlide() { _image = cellevator2 };
|
||||
slideCollection.slides[2] = new CustomSlide() { _image = cellevator3 };
|
||||
|
||||
var slideContainer = AUTO_SLIDE_PROJECTOR.AddComponent<CustomSlideCollectionContainer>();
|
||||
slideContainer._slideCollection = slideCollection;
|
||||
|
||||
projectorComponent.SetSlideCollection(slideContainer);
|
||||
projectorComponent._defaultSlideDuration = 1f;
|
||||
|
||||
AUTO_SLIDE_PROJECTOR.SetActive(true);
|
||||
|
||||
projectorComponent.Play(false);
|
||||
}*/
|
||||
|
||||
public void CallToFloorIndex(int index, bool remote = false)
|
||||
{
|
||||
if (!remote)
|
||||
{
|
||||
this.SendMessage(new CellevatorCallMessage(index));
|
||||
}
|
||||
|
||||
AttachedObject.CallElevatorToFloor(index);
|
||||
}
|
||||
}
|
@ -10,7 +10,7 @@ using UnityEngine;
|
||||
|
||||
namespace QSB.EchoesOfTheEye.Prisoner.WorldObjects;
|
||||
|
||||
internal class QSBPrisonerBrain : WorldObject<PrisonerBrain>
|
||||
internal class QSBPrisonerBrain : WorldObject<PrisonerBrain>, IGhostObject
|
||||
{
|
||||
public override void SendInitialState(uint to)
|
||||
{
|
||||
@ -27,13 +27,57 @@ internal class QSBPrisonerBrain : WorldObject<PrisonerBrain>
|
||||
public QSBGhostSensors Sensors => AttachedObject._sensors.GetWorldObject<QSBGhostSensors>();
|
||||
public QSBGhostData Data;
|
||||
|
||||
public override void DisplayLines()
|
||||
{
|
||||
ControllerLines(Controller);
|
||||
DataLines(Data, Controller);
|
||||
}
|
||||
|
||||
private void ControllerLines(QSBGhostController controller)
|
||||
{
|
||||
Popcron.Gizmos.Sphere(controller.AttachedObject.transform.position, 2f, Color.white);
|
||||
|
||||
if (controller.AttachedObject._followNodePath)
|
||||
{
|
||||
for (var i = controller.AttachedObject._nodePath.Count - 1; i >= 0; i--)
|
||||
{
|
||||
Popcron.Gizmos.Sphere(controller.AttachedObject.LocalToWorldPosition(controller.AttachedObject._nodePath[i].localPosition), 0.25f, Color.cyan, 3);
|
||||
|
||||
var hasVisited = controller.AttachedObject._pathIndex < i;
|
||||
var color = hasVisited ? Color.white : Color.cyan;
|
||||
|
||||
if (i != 0)
|
||||
{
|
||||
Popcron.Gizmos.Line(controller.AttachedObject.LocalToWorldPosition(controller.AttachedObject._nodePath[i].localPosition), controller.AttachedObject.LocalToWorldPosition(controller.AttachedObject._nodePath[i - 1].localPosition), color);
|
||||
}
|
||||
}
|
||||
|
||||
if (controller.AttachedObject._hasFinalPathPosition)
|
||||
{
|
||||
Popcron.Gizmos.Sphere(controller.AttachedObject.LocalToWorldPosition(controller.AttachedObject._finalPathPosition), 0.3f, Color.red, 8);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void DataLines(QSBGhostData data, QSBGhostController controller)
|
||||
{
|
||||
foreach (var player in data.players.Values)
|
||||
{
|
||||
if (player.timeSincePlayerLocationKnown != float.PositiveInfinity)
|
||||
{
|
||||
Popcron.Gizmos.Line(controller.AttachedObject.transform.position, controller.AttachedObject.LocalToWorldPosition(player.lastKnownPlayerLocation.localPosition), Color.magenta);
|
||||
Popcron.Gizmos.Sphere(controller.AttachedObject.LocalToWorldPosition(player.lastKnownPlayerLocation.localPosition), 1f, Color.magenta);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void Start()
|
||||
{
|
||||
AttachedObject.enabled = false;
|
||||
AttachedObject._controller.GetDreamLanternController().enabled = false;
|
||||
Controller.Initialize(AttachedObject._nodeLayer, Effects);
|
||||
Data = new QSBGhostData();
|
||||
Sensors.Initialize(Data, null);
|
||||
Sensors.Initialize(Data);
|
||||
Effects.Initialize(AttachedObject._controller.GetNodeRoot(), Controller, Data);
|
||||
}
|
||||
|
||||
|
@ -12,7 +12,7 @@ internal class EyeCloneSeenMessage : QSBMessage
|
||||
|
||||
public override void OnReceiveRemote()
|
||||
{
|
||||
var controller = QSBWorldSync.GetUnityObjects<PlayerCloneController>().First();
|
||||
var controller = QSBWorldSync.GetUnityObject<PlayerCloneController>();
|
||||
|
||||
controller._warpFlickerActivated = true;
|
||||
controller._warpTime = Time.time + 0.5f;
|
||||
|
@ -29,7 +29,7 @@ internal class KillGalaxiesMessage : QSBMessage
|
||||
|
||||
public override void OnReceiveRemote()
|
||||
{
|
||||
var galaxyController = QSBWorldSync.GetUnityObjects<MiniGalaxyController>().First();
|
||||
var galaxyController = QSBWorldSync.GetUnityObject<MiniGalaxyController>();
|
||||
|
||||
galaxyController._killTrigger.OnEntry -= galaxyController.OnEnterKillTrigger;
|
||||
|
||||
|
@ -24,7 +24,7 @@ internal class GalaxyMapManager : MonoBehaviour, IAddComponentOnStart
|
||||
return;
|
||||
}
|
||||
|
||||
var mapController = QSBWorldSync.GetUnityObjects<GalaxyMapController>().First();
|
||||
var mapController = QSBWorldSync.GetUnityObject<GalaxyMapController>();
|
||||
var map = mapController._interactVolume.gameObject;
|
||||
|
||||
map.SetActive(false);
|
||||
|
@ -10,7 +10,7 @@ internal class ZoomOutMessage : QSBMessage
|
||||
|
||||
public override void OnReceiveRemote()
|
||||
{
|
||||
var controller = QSBWorldSync.GetUnityObjects<GalaxyMapController>().First();
|
||||
var controller = QSBWorldSync.GetUnityObject<GalaxyMapController>();
|
||||
controller.enabled = true;
|
||||
Locator.GetPlayerController().SetColliderActivation(false);
|
||||
controller._endlessObservatoryVolume.SetActivation(false);
|
||||
|
@ -13,10 +13,10 @@ internal class QSBQuantumInstrument : WorldObject<QuantumInstrument>
|
||||
|
||||
public void Gather()
|
||||
{
|
||||
var maskZoneController = QSBWorldSync.GetUnityObjects<MaskZoneController>().First();
|
||||
var maskZoneController = QSBWorldSync.GetUnityObject<MaskZoneController>();
|
||||
if (maskZoneController._maskInstrument == AttachedObject)
|
||||
{
|
||||
var shuttleController = QSBWorldSync.GetUnityObjects<EyeShuttleController>().First();
|
||||
var shuttleController = QSBWorldSync.GetUnityObject<EyeShuttleController>();
|
||||
|
||||
foreach (var player in MaskManager.WentOnSolanumsWildRide)
|
||||
{
|
||||
|
@ -39,8 +39,7 @@ internal class MaskManager : MonoBehaviour, IAddComponentOnStart
|
||||
{
|
||||
if (_flickering && Time.time > _flickerOutTime)
|
||||
{
|
||||
// TODO : Optimize this out.
|
||||
var controller = QSBWorldSync.GetUnityObjects<EyeShuttleController>().First();
|
||||
var controller = QSBWorldSync.GetUnityObject<EyeShuttleController>();
|
||||
controller._shuttleObject.SetActive(false);
|
||||
_flickering = false;
|
||||
_flickerOutTime = 0f;
|
||||
|
@ -35,7 +35,7 @@ internal class ItemManager : WorldObjectManager
|
||||
|
||||
// other drop targets that don't already have world objects
|
||||
var listToInitFrom = QSBWorldSync.GetUnityObjects<MonoBehaviour>()
|
||||
.Where(x => x is IItemDropTarget and not (RaftDock or RaftController))
|
||||
.Where(x => x is IItemDropTarget and not (RaftDock or RaftController or PrisonCellElevator))
|
||||
.SortDeterministic();
|
||||
QSBWorldSync.Init<QSBOtherDropTarget, MonoBehaviour>(listToInitFrom);
|
||||
}
|
||||
|
@ -17,7 +17,7 @@ public class MeteorManager : WorldObjectManager
|
||||
// wait for all late initializers (which includes meteor launchers) to finish
|
||||
await UniTask.WaitUntil(() => LateInitializerManager.isDoneInitializing, cancellationToken: ct);
|
||||
|
||||
WhiteHoleVolume = QSBWorldSync.GetUnityObjects<WhiteHoleVolume>().First();
|
||||
WhiteHoleVolume = QSBWorldSync.GetUnityObject<WhiteHoleVolume>();
|
||||
QSBWorldSync.Init<QSBFragment, FragmentIntegrity>();
|
||||
QSBWorldSync.Init<QSBMeteorLauncher, MeteorLauncher>();
|
||||
QSBWorldSync.Init<QSBMeteor, MeteorController>();
|
||||
|
@ -40,7 +40,7 @@ public static class LocalPlayerCreation
|
||||
PlayerToolsManager.InitLocal();
|
||||
|
||||
// stick
|
||||
var pivot = QSBWorldSync.GetUnityObjects<RoastingStickController>().First().transform.Find("Stick_Root/Stick_Pivot");
|
||||
var pivot = QSBWorldSync.GetUnityObject<RoastingStickController>().transform.Find("Stick_Root/Stick_Pivot");
|
||||
player.RoastingStick = pivot.parent.gameObject;
|
||||
visibleRoastingSystem = pivot.parent.parent;
|
||||
visibleStickPivot = pivot;
|
||||
|
@ -73,6 +73,10 @@
|
||||
<None Include="storage.json">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</None>
|
||||
<None Include="Assets\*">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</None>
|
||||
<None Remove="Assets\*.pdn" />
|
||||
<None Include="AssetBundles\*">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</None>
|
||||
@ -89,7 +93,7 @@
|
||||
<ProjectReference Include="..\EpicOnlineTransport\EpicOnlineTransport.csproj" />
|
||||
<ProjectReference Include="..\EpicRerouter\EpicRerouter.csproj" />
|
||||
<ProjectReference Include="..\MirrorWeaver\MirrorWeaver.csproj" ReferenceOutputAssembly="false" />
|
||||
<PackageReference Include="HarmonyX" Version="2.9.0" IncludeAssets="compile" />
|
||||
<PackageReference Include="OWML" Version="2.3.2" IncludeAssets="compile" />
|
||||
<PackageReference Include="HarmonyX" Version="2.10.0" IncludeAssets="compile" />
|
||||
<PackageReference Include="OWML" Version="2.3.3" IncludeAssets="compile" />
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
|
@ -217,4 +217,6 @@ public class QSBCore : ModBehaviour
|
||||
* Daft Punk
|
||||
* Natalie Holt
|
||||
* WMD
|
||||
* Woody Jackson
|
||||
* Brian David Gilbert
|
||||
*/
|
||||
|
@ -34,7 +34,7 @@ internal class QuantumManager : WorldObjectManager
|
||||
QSBWorldSync.Init<QSBQuantumSkeletonTower, QuantumSkeletonTower>();
|
||||
if (scene == OWScene.SolarSystem)
|
||||
{
|
||||
Shrine = QSBWorldSync.GetUnityObjects<QuantumShrine>().First();
|
||||
Shrine = QSBWorldSync.GetUnityObject<QuantumShrine>();
|
||||
}
|
||||
|
||||
UpdateFromDebugSetting();
|
||||
|
@ -51,7 +51,7 @@ internal class MarshmallowEventMessage : QSBMessage<MarshmallowMessageType>
|
||||
var stick = player.RoastingStick;
|
||||
var stickTip = stick.transform.GetChild(0);
|
||||
|
||||
var mallowPrefab = QSBWorldSync.GetUnityObjects<RoastingStickController>().First()._mallowBodyPrefab;
|
||||
var mallowPrefab = QSBWorldSync.GetUnityObject<RoastingStickController>()._mallowBodyPrefab;
|
||||
|
||||
var tossedMallow = Object.Instantiate(mallowPrefab, stickTip.position, stickTip.rotation);
|
||||
var rigidbody = tossedMallow.GetComponent<OWRigidbody>();
|
||||
|
@ -52,7 +52,7 @@ internal class SatelliteProjectorManager : MonoBehaviour, IAddComponentOnStart
|
||||
{
|
||||
if (newScene == OWScene.SolarSystem)
|
||||
{
|
||||
Projector = QSBWorldSync.GetUnityObjects<SatelliteSnapshotController>().First();
|
||||
Projector = QSBWorldSync.GetUnityObject<SatelliteSnapshotController>();
|
||||
Projector._loopingSource.spatialBlend = 1f;
|
||||
Projector._oneShotSource.spatialBlend = 1f;
|
||||
|
||||
|
@ -18,6 +18,7 @@ internal class GameStateMessage : QSBMessage
|
||||
private int LoopCount;
|
||||
private bool[] KnownFrequencies;
|
||||
private Dictionary<int, bool> KnownSignals;
|
||||
private bool ReducedFrights;
|
||||
|
||||
public GameStateMessage(uint toId)
|
||||
{
|
||||
@ -29,6 +30,7 @@ internal class GameStateMessage : QSBMessage
|
||||
LoopCount = gameSave.loopCount;
|
||||
KnownFrequencies = gameSave.knownFrequencies;
|
||||
KnownSignals = gameSave.knownSignals;
|
||||
ReducedFrights = PlayerData.GetReducedFrights();
|
||||
}
|
||||
|
||||
|
||||
@ -48,6 +50,8 @@ internal class GameStateMessage : QSBMessage
|
||||
writer.Write(name);
|
||||
writer.Write(discovered);
|
||||
}
|
||||
|
||||
writer.Write(ReducedFrights);
|
||||
}
|
||||
|
||||
public override void Deserialize(NetworkReader reader)
|
||||
@ -68,6 +72,8 @@ internal class GameStateMessage : QSBMessage
|
||||
var value = reader.Read<bool>();
|
||||
KnownSignals.Add(key, value);
|
||||
}
|
||||
|
||||
ReducedFrights = reader.Read<bool>();
|
||||
}
|
||||
|
||||
public override void OnReceiveRemote()
|
||||
@ -88,6 +94,7 @@ internal class GameStateMessage : QSBMessage
|
||||
gameSave.secondsRemainingOnWarp = SecondsRemainingOnWarp;
|
||||
|
||||
PlayerData.SetPersistentCondition("LAUNCH_CODES_GIVEN", LaunchCodesGiven);
|
||||
PlayerData._settingsSave.reducedFrights = ReducedFrights;
|
||||
|
||||
PlayerData.SaveCurrentGame();
|
||||
|
||||
|
@ -62,8 +62,7 @@ public class QSBSector : WorldObject<Sector>
|
||||
}
|
||||
else if (QSBSceneManager.CurrentScene == OWScene.EyeOfTheUniverse)
|
||||
{
|
||||
// TODO : Optimize this out.
|
||||
var shuttleController = QSBWorldSync.GetUnityObjects<EyeShuttleController>().First();
|
||||
var shuttleController = QSBWorldSync.GetUnityObject<EyeShuttleController>();
|
||||
if (shuttleController == null)
|
||||
{
|
||||
DebugLog.ToConsole($"Warning - Expected to find a EyeShuttleController for {AttachedObject.name}!", MessageType.Warning);
|
||||
|
@ -63,9 +63,9 @@ internal class ShipManager : WorldObjectManager
|
||||
}
|
||||
|
||||
HatchInteractZone = HatchController.GetComponent<InteractZone>();
|
||||
ShipTractorBeam = QSBWorldSync.GetUnityObjects<ShipTractorBeamSwitch>().First();
|
||||
CockpitController = QSBWorldSync.GetUnityObjects<ShipCockpitController>().First();
|
||||
ShipElectricalComponent = QSBWorldSync.GetUnityObjects<ShipElectricalComponent>().First();
|
||||
ShipTractorBeam = QSBWorldSync.GetUnityObject<ShipTractorBeamSwitch>();
|
||||
CockpitController = QSBWorldSync.GetUnityObject<ShipCockpitController>();
|
||||
ShipElectricalComponent = QSBWorldSync.GetUnityObject<ShipElectricalComponent>();
|
||||
|
||||
var sphereShape = HatchController.GetComponent<SphereShape>();
|
||||
sphereShape.radius = 2.5f;
|
||||
|
@ -31,7 +31,7 @@ internal class TimeSyncUI : MonoBehaviour, IAddComponentOnStart
|
||||
private void OnUniverseSceneLoad(OWScene oldScene, OWScene newScene)
|
||||
{
|
||||
_isSetUp = true;
|
||||
var obj = QSBWorldSync.GetUnityObjects<SleepTimerUI>().First();
|
||||
var obj = QSBWorldSync.GetUnityObject<SleepTimerUI>();
|
||||
_canvas = obj._canvas;
|
||||
_text = obj._text;
|
||||
_canvas.enabled = false;
|
||||
|
@ -99,7 +99,15 @@ public class DebugActions : MonoBehaviour, IAddComponentOnStart
|
||||
|
||||
if (Keyboard.current[Key.Numpad3].wasPressedThisFrame)
|
||||
{
|
||||
Destroy(Locator.GetProbe().gameObject);
|
||||
var sarcoController = QSBWorldSync.GetUnityObject<SarcophagusController>();
|
||||
|
||||
sarcoController.firstSealProjector.SetLit(false);
|
||||
sarcoController.secondSealProjector.SetLit(false);
|
||||
sarcoController.thirdSealProjector.SetLit(false);
|
||||
|
||||
sarcoController._attemptOpenAfterDelay = true;
|
||||
sarcoController._openAttemptTime = Time.time + 0.5f;
|
||||
sarcoController.enabled = true;
|
||||
}
|
||||
|
||||
if (Keyboard.current[Key.Numpad4].wasPressedThisFrame)
|
||||
|
@ -234,7 +234,7 @@ internal class DebugGUI : MonoBehaviour, IAddComponentOnStart
|
||||
|
||||
if (QSBWorldSync.AllObjectsReady)
|
||||
{
|
||||
var ghost = QSBWorldSync.GetWorldObjects<QSBGhostBrain>().First(x => x.AttachedObject._name == "Kamaji");
|
||||
var ghost = QSBWorldSync.GetWorldObjects<QSBGhostBrain>().First(x => x.AttachedObject._name == "Yubaba");
|
||||
WriteLine(4, ghost.AttachedObject._name);
|
||||
WriteLine(4, $"Action:{ghost.GetCurrentActionName()}");
|
||||
WriteLine(4, $"Threat Awareness:{ghost.GetThreatAwareness()}");
|
||||
@ -255,15 +255,24 @@ internal class DebugGUI : MonoBehaviour, IAddComponentOnStart
|
||||
WriteLine(4, $"- IsHeldByPlayer:{lantern.AttachedObject.GetLanternController().IsHeldByPlayer()}");
|
||||
WriteLine(4, $"- Concealed:{lantern.AttachedObject.GetLanternController().IsConcealed()}");
|
||||
}
|
||||
|
||||
var position = player.player.Camera.transform.position;
|
||||
WriteLine(4, $"- Camera in vision cone:{ghost.AttachedObject._sensors.CheckPointInVisionCone(position)}");
|
||||
WriteLine(4, $"- CheckLineOccluded:{ghost.AttachedObject._sensors.CheckLineOccluded(ghost.AttachedObject._sensors._sightOrigin.position, position)}");
|
||||
}
|
||||
else
|
||||
{
|
||||
WriteLine(4, $"- LANTERN NULL", Color.red);
|
||||
}
|
||||
|
||||
WriteLine(4, $"First check:{!ghost.AttachedObject._intruderConfirmPending}");
|
||||
WriteLine(4, $"Second check:{ghost._data.threatAwareness > GhostData.ThreatAwareness.EverythingIsNormal || ghost._data.players.Values.Any(x => x.playerLocation.distance < 20f) || ghost._data.players.Values.Any(x => x.sensor.isPlayerIlluminatedByUs)}");
|
||||
WriteLine(4, $"Third check:{ghost._data.players.Values.Any(x => x.sensor.isPlayerVisible) || ghost._data.players.Values.Any(x => x.sensor.inContactWithPlayer)}");
|
||||
var playerCamera = player.player.Camera;
|
||||
|
||||
if (playerCamera != null)
|
||||
{
|
||||
var position = playerCamera.transform.position;
|
||||
WriteLine(4, $"- Camera in vision cone:{ghost.AttachedObject._sensors.CheckPointInVisionCone(position)}");
|
||||
WriteLine(4, $"- CheckLineOccluded:{ghost.AttachedObject._sensors.CheckLineOccluded(ghost.AttachedObject._sensors._sightOrigin.position, position)}");
|
||||
}
|
||||
else
|
||||
{
|
||||
WriteLine(4, $"- CAMERA NULL", Color.red);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
|
30
QSB/Utility/TextureHelper.cs
Normal file
30
QSB/Utility/TextureHelper.cs
Normal file
@ -0,0 +1,30 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using UnityEngine;
|
||||
|
||||
namespace QSB.Utility;
|
||||
|
||||
public static class TextureHelper
|
||||
{
|
||||
public static Texture2D LoadTexture(string relativePath, TextureWrapMode wrapMode, bool forceMaxResolution)
|
||||
{
|
||||
var path = QSBCore.Helper.Manifest.ModFolderPath + relativePath;
|
||||
|
||||
if (!File.Exists(path))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
var data = File.ReadAllBytes(path);
|
||||
var tex = forceMaxResolution
|
||||
? new Texture2D(1, 1, TextureFormat.RGB24, false)
|
||||
: new Texture2D(1, 1);
|
||||
tex.LoadImage(data);
|
||||
tex.wrapMode = wrapMode;
|
||||
return tex;
|
||||
}
|
||||
}
|
@ -178,6 +178,7 @@ public static class QSBWorldSync
|
||||
|
||||
private static readonly List<IWorldObject> WorldObjects = new();
|
||||
private static readonly Dictionary<MonoBehaviour, IWorldObject> UnityObjectsToWorldObjects = new();
|
||||
private static readonly Dictionary<Type, MonoBehaviour> CachedUnityObjects = new();
|
||||
|
||||
static QSBWorldSync() =>
|
||||
RequestInitialStatesMessage.SendInitialState += to =>
|
||||
@ -216,6 +217,7 @@ public static class QSBWorldSync
|
||||
DialogueConditions.Clear();
|
||||
PersistentConditions.Clear();
|
||||
ShipLogFacts.Clear();
|
||||
CachedUnityObjects.Clear();
|
||||
}
|
||||
|
||||
public static IEnumerable<IWorldObject> GetWorldObjects() => WorldObjects;
|
||||
@ -260,6 +262,30 @@ public static class QSBWorldSync
|
||||
return (TWorldObject)worldObject;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// not deterministic across platforms
|
||||
/// </summary>
|
||||
public static TUnityObject GetUnityObject<TUnityObject>()
|
||||
where TUnityObject : MonoBehaviour
|
||||
{
|
||||
if (CachedUnityObjects.ContainsKey(typeof(TUnityObject)))
|
||||
{
|
||||
return CachedUnityObjects[typeof(TUnityObject)] as TUnityObject;
|
||||
}
|
||||
|
||||
var unityObjects = GetUnityObjects<TUnityObject>();
|
||||
|
||||
if (unityObjects.Count() != 1)
|
||||
{
|
||||
DebugLog.ToConsole($"Warning - Tried to cache a unity object that there are multiple of. ({typeof(TUnityObject).Name})" +
|
||||
$"\r\nCaching the first one - this probably is going to end badly!", MessageType.Warning);
|
||||
}
|
||||
|
||||
var unityObject = unityObjects.First();
|
||||
CachedUnityObjects.Add(typeof(TUnityObject), unityObject);
|
||||
return unityObject;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// not deterministic across platforms
|
||||
/// </summary>
|
||||
|
@ -7,8 +7,8 @@
|
||||
"body": "- Disable *all* other mods. (Can heavily affect performance)\n- Make sure you are not running any other network-intensive applications."
|
||||
},
|
||||
"uniqueName": "Raicuparta.QuantumSpaceBuddies",
|
||||
"version": "0.18.0",
|
||||
"owmlVersion": "2.3.2",
|
||||
"version": "0.19.0",
|
||||
"owmlVersion": "2.3.3",
|
||||
"dependencies": [ "_nebula.MenuFramework" ],
|
||||
"pathsToPreserve": [ "debugsettings.json" ]
|
||||
}
|
||||
|
19
README.md
19
README.md
@ -75,10 +75,7 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
### How complete is this mod? How far through the game can I play?
|
||||
|
||||
| Area of the game | Working |
|
||||
|-------------------|--------------------|
|
||||
| Base game | :heavy_check_mark: |
|
||||
| Echoes of the Eye | :x: |
|
||||
The base game is around 95% done, whereas EotE is around 80% done.
|
||||
|
||||
### Compatibility with other mods
|
||||
TL;DR - Don't use any mods with QSB that aren't marked as QSB compatible.
|
||||
@ -87,9 +84,7 @@ QSB relies on object hierarchy to sync objects, so any mod that changes that ris
|
||||
|
||||
### Will you make this compatible with NomaiVR?
|
||||
|
||||
Short answer : No.
|
||||
|
||||
Long answer : Pay me enough money, and maybe I'll consider it.
|
||||
Maybe.
|
||||
|
||||
### Why do I keep getting thrown around the ship?
|
||||
|
||||
@ -136,11 +131,11 @@ Some debugging options exist to make things easier. These come in the form of ac
|
||||
Hold Q and press :
|
||||
|
||||
- Numpad 1 - Teleport to nearest player.
|
||||
- Numpad 2 - Warp to the Dreamworld.
|
||||
- Numpad 3 - Destroy the probe.
|
||||
- Numpad 2 - If holding LeftShift, warp to the dreamworld Vault fire. If not, warp to the Endless Canyon.
|
||||
- Numpad 3 - Unlock the Sealed Vault.
|
||||
- Numpad 4 - Damage the ship's electrical system.
|
||||
- Numpad 5 - Trigger the supernova.
|
||||
- Numpad 6 - Set the flags for meeting Solanum and the Prisoner.
|
||||
- Numpad 6 - Set the flags for having met Solanum and the Prisoner.
|
||||
- Numpad 7 - Warp to the Vessel.
|
||||
- Numpad 8 - Insert the Advanced Warp Core into the Vessel.
|
||||
- Numpad 9 - If holding LeftShift, load the SolarSystem scene. If not, load the EyeOfTheUniverse scene.
|
||||
@ -164,7 +159,8 @@ The template for this file is this :
|
||||
"drawLabels": false,
|
||||
"drawQuantumVisibilityObjects": false,
|
||||
"skipTitleScreen": false,
|
||||
"greySkybox": false
|
||||
"greySkybox": false,
|
||||
"drawGhostAI": false
|
||||
}
|
||||
```
|
||||
|
||||
@ -180,6 +176,7 @@ The template for this file is this :
|
||||
- drawQuantumVisibilityObjects - Indicates visibility objects with an orange shape.
|
||||
- skipTitleScreen - Auto-skips the splash screen.
|
||||
- greySkybox - Turns the skybox grey. Useful in the Eye, where it's pretty dark.
|
||||
- drawGhostAI - Draws debug lines and labels just for the ghosts.
|
||||
|
||||
**Warning : Mod development can lead to unexpected errors in your computer system.**
|
||||
- **When editing the networking code, mistakes can lead to QSB overwhelming your network connection with excess packets**.
|
||||
|
Loading…
x
Reference in New Issue
Block a user