mirror of
https://github.com/NotAKidoS/NAK_CVR_Mods.git
synced 2025-09-02 06:19:22 +00:00
Added World Restriction Checks
This commit is contained in:
parent
5f6a85984d
commit
71d780248f
2 changed files with 344 additions and 313 deletions
|
@ -1,124 +1,151 @@
|
||||||
using ABI_RC.Core.IO;
|
using ABI_RC.Core.IO;
|
||||||
using ABI_RC.Core.Networking.IO.Instancing;
|
using ABI_RC.Core.Networking.IO.Instancing;
|
||||||
using ABI_RC.Core.UI;
|
using ABI_RC.Core.UI;
|
||||||
using ABI_RC.Systems.GameEventSystem;
|
using ABI_RC.Systems.GameEventSystem;
|
||||||
using NAK.Stickers.Networking;
|
using JetBrains.Annotations;
|
||||||
using NAK.Stickers.Utilities;
|
using NAK.Stickers.Networking;
|
||||||
|
using NAK.Stickers.Utilities;
|
||||||
namespace NAK.Stickers;
|
using System.EnterpriseServices;
|
||||||
|
using UnityEngine;
|
||||||
public partial class StickerSystem
|
using MelonLoader;
|
||||||
{
|
using UnityEngine.ProBuilder.MeshOperations;
|
||||||
#region Singleton
|
using NAK.Stickers.Integrations;
|
||||||
|
|
||||||
public static StickerSystem Instance { get; private set; }
|
namespace NAK.Stickers;
|
||||||
|
|
||||||
public static void Initialize()
|
public partial class StickerSystem
|
||||||
{
|
{
|
||||||
if (Instance != null)
|
#region Singleton
|
||||||
return;
|
|
||||||
|
public static bool RestrictedInstance = false;
|
||||||
Instance = new StickerSystem();
|
|
||||||
|
public static StickerSystem Instance { get; private set; }
|
||||||
// configure decalery
|
|
||||||
DecalManager.SetPreferredMode(DecalUtils.Mode.GPU, false, 0);
|
public static void Initialize()
|
||||||
|
{
|
||||||
// ensure cache folder exists
|
if (Instance != null)
|
||||||
EnsureStickersFolderExists();
|
return;
|
||||||
|
|
||||||
// listen for game events
|
Instance = new StickerSystem();
|
||||||
CVRGameEventSystem.Initialization.OnPlayerSetupStart.AddListener(Instance.OnPlayerSetupStart);
|
|
||||||
}
|
// configure decalery
|
||||||
|
DecalManager.SetPreferredMode(DecalUtils.Mode.GPU, false, 0);
|
||||||
#endregion Singleton
|
|
||||||
|
// ensure cache folder exists
|
||||||
#region Callback Registration
|
EnsureStickersFolderExists();
|
||||||
|
|
||||||
private void OnPlayerSetupStart()
|
// listen for game events
|
||||||
{
|
CVRGameEventSystem.Initialization.OnPlayerSetupStart.AddListener(Instance.OnPlayerSetupStart);
|
||||||
CVRGameEventSystem.World.OnUnload.AddListener(_ => OnWorldUnload());
|
|
||||||
CVRGameEventSystem.Instance.OnConnected.AddListener((_) => { if (!Instances.IsReconnecting) OnInitialConnection(); });
|
}
|
||||||
|
|
||||||
CVRGameEventSystem.Player.OnJoinEntity.AddListener(Instance.OnPlayerJoined);
|
#endregion Singleton
|
||||||
CVRGameEventSystem.Player.OnLeaveEntity.AddListener(Instance.OnPlayerLeft);
|
|
||||||
SchedulerSystem.AddJob(Instance.OnUpdate, 10f, -1);
|
#region Callback Registration
|
||||||
LoadAllImagesAtStartup();
|
|
||||||
}
|
private void OnPlayerSetupStart()
|
||||||
|
{
|
||||||
#endregion Callback Registration
|
CVRGameEventSystem.World.OnUnload.AddListener(_ => OnWorldUnload());
|
||||||
|
CVRGameEventSystem.World.OnLoad.AddListener(_ => OnWorldLoad());
|
||||||
#region Game Events
|
CVRGameEventSystem.Instance.OnConnected.AddListener((_) => { if (!Instances.IsReconnecting) OnInitialConnection(); });
|
||||||
|
|
||||||
private void OnInitialConnection()
|
CVRGameEventSystem.Player.OnJoinEntity.AddListener(Instance.OnPlayerJoined);
|
||||||
{
|
CVRGameEventSystem.Player.OnLeaveEntity.AddListener(Instance.OnPlayerLeft);
|
||||||
ClearStickersSelf(); // clear stickers on remotes just in case we rejoined
|
SchedulerSystem.AddJob(Instance.OnUpdate, 10f, -1);
|
||||||
ModNetwork.Reset(); // reset network buffers and metadata
|
LoadAllImagesAtStartup();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void OnWorldUnload()
|
#endregion Callback Registration
|
||||||
{
|
|
||||||
CleanupAllButSelf(); // release all stickers except for self
|
#region Game Events
|
||||||
}
|
|
||||||
|
private void OnInitialConnection()
|
||||||
#endregion Game Events
|
{
|
||||||
|
OnWorldLoad(); //Checks the world again in case the bundle updated.
|
||||||
#region Data
|
ClearStickersSelf(); // clear stickers on remotes just in case we rejoined
|
||||||
|
ModNetwork.Reset(); // reset network buffers and metadata
|
||||||
// private bool _isEnabled = true;
|
}
|
||||||
//
|
|
||||||
// public bool IsEnabled
|
private void OnWorldLoad()
|
||||||
// {
|
{
|
||||||
// get => _isEnabled;
|
GameObject StickerWorldRestriction = GameObject.Find("[DisableStickers]");
|
||||||
// set
|
if (StickerWorldRestriction != null)
|
||||||
// {
|
{
|
||||||
// if (_isEnabled == value)
|
RestrictedInstance = true;
|
||||||
// return;
|
MelonLogger.Msg("This is a Restricted Instance");
|
||||||
//
|
}
|
||||||
// _isEnabled = value;
|
else
|
||||||
// if (!_isEnabled) ClearAllStickers();
|
{
|
||||||
// ModNetwork.IsEnabled = _isEnabled;
|
MelonLogger.Msg("This is NOT a Restricted Instance");
|
||||||
// }
|
}
|
||||||
// }
|
BTKUIAddon.UpdateStickerMenu();
|
||||||
|
}
|
||||||
private string SelectedStickerName => ModSettings.Hidden_SelectedStickerNames.Value[_selectedStickerSlot];
|
|
||||||
|
private void OnWorldUnload()
|
||||||
private const float StickerKillTime = 30f;
|
{
|
||||||
private const float StickerCooldown = 0.2f;
|
RestrictedInstance = false;
|
||||||
private readonly Dictionary<string, StickerData> _playerStickers = new();
|
CleanupAllButSelf(); // release all stickers except for self
|
||||||
internal const string PlayerLocalId = "_PLAYERLOCAL";
|
}
|
||||||
|
|
||||||
private int _selectedStickerSlot;
|
#endregion Game Events
|
||||||
public int SelectedStickerSlot
|
|
||||||
{
|
#region Data
|
||||||
get => _selectedStickerSlot;
|
|
||||||
set
|
// private bool _isEnabled = true;
|
||||||
{
|
//
|
||||||
_selectedStickerSlot = value < 0 ? ModSettings.MaxStickerSlots - 1 : value % ModSettings.MaxStickerSlots;
|
// public bool IsEnabled
|
||||||
IsInStickerMode = IsInStickerMode; // refresh sticker mode
|
// {
|
||||||
}
|
// get => _isEnabled;
|
||||||
}
|
// set
|
||||||
|
// {
|
||||||
private bool _isInStickerMode;
|
// if (_isEnabled == value)
|
||||||
public bool IsInStickerMode
|
// return;
|
||||||
{
|
//
|
||||||
get => _isInStickerMode;
|
// _isEnabled = value;
|
||||||
set
|
// if (!_isEnabled) ClearAllStickers();
|
||||||
{
|
// ModNetwork.IsEnabled = _isEnabled;
|
||||||
_isInStickerMode = value;
|
// }
|
||||||
if (_isInStickerMode)
|
// }
|
||||||
{
|
|
||||||
CohtmlHud.Instance.SelectPropToSpawn(
|
private string SelectedStickerName => ModSettings.Hidden_SelectedStickerNames.Value[_selectedStickerSlot];
|
||||||
StickerCache.GetCohtmlResourcesPath(SelectedStickerName),
|
|
||||||
Path.GetFileNameWithoutExtension(SelectedStickerName),
|
private const float StickerKillTime = 30f;
|
||||||
"Sticker selected for stickering:");
|
private const float StickerCooldown = 0.2f;
|
||||||
}
|
private readonly Dictionary<string, StickerData> _playerStickers = new();
|
||||||
else
|
internal const string PlayerLocalId = "_PLAYERLOCAL";
|
||||||
{
|
|
||||||
CohtmlHud.Instance.ClearPropToSpawn();
|
private int _selectedStickerSlot;
|
||||||
ClearStickerPreview();
|
public int SelectedStickerSlot
|
||||||
}
|
{
|
||||||
}
|
get => _selectedStickerSlot;
|
||||||
}
|
set
|
||||||
|
{
|
||||||
#endregion Data
|
_selectedStickerSlot = value < 0 ? ModSettings.MaxStickerSlots - 1 : value % ModSettings.MaxStickerSlots;
|
||||||
|
IsInStickerMode = IsInStickerMode; // refresh sticker mode
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private bool _isInStickerMode;
|
||||||
|
public bool IsInStickerMode
|
||||||
|
{
|
||||||
|
get => _isInStickerMode;
|
||||||
|
set
|
||||||
|
{
|
||||||
|
_isInStickerMode = value;
|
||||||
|
if (_isInStickerMode)
|
||||||
|
{
|
||||||
|
CohtmlHud.Instance.SelectPropToSpawn(
|
||||||
|
StickerCache.GetCohtmlResourcesPath(SelectedStickerName),
|
||||||
|
Path.GetFileNameWithoutExtension(SelectedStickerName),
|
||||||
|
"Sticker selected for stickering:");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
CohtmlHud.Instance.ClearPropToSpawn();
|
||||||
|
ClearStickerPreview();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion Data
|
||||||
}
|
}
|
|
@ -1,190 +1,194 @@
|
||||||
using ABI_RC.Core;
|
using ABI_RC.Core;
|
||||||
using ABI_RC.Core.Player;
|
using ABI_RC.Core.Player;
|
||||||
using ABI_RC.Systems.InputManagement;
|
using ABI_RC.Systems.InputManagement;
|
||||||
using NAK.Stickers.Networking;
|
using NAK.Stickers.Networking;
|
||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
|
|
||||||
namespace NAK.Stickers;
|
namespace NAK.Stickers;
|
||||||
|
|
||||||
public partial class StickerSystem
|
public partial class StickerSystem
|
||||||
{
|
{
|
||||||
#region Sticker Lifecycle
|
#region Sticker Lifecycle
|
||||||
|
|
||||||
private StickerData GetOrCreateStickerData(string playerId)
|
private StickerData GetOrCreateStickerData(string playerId)
|
||||||
{
|
{
|
||||||
if (_playerStickers.TryGetValue(playerId, out StickerData stickerData))
|
if (_playerStickers.TryGetValue(playerId, out StickerData stickerData))
|
||||||
return stickerData;
|
return stickerData;
|
||||||
|
|
||||||
stickerData = new StickerData(playerId, ModSettings.MaxStickerSlots);
|
stickerData = new StickerData(playerId, ModSettings.MaxStickerSlots);
|
||||||
_playerStickers[playerId] = stickerData;
|
_playerStickers[playerId] = stickerData;
|
||||||
return stickerData;
|
return stickerData;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void PlaceStickerFromControllerRay(Transform transform, CVRHand hand = CVRHand.Left, bool isPreview = false)
|
public void PlaceStickerFromControllerRay(Transform transform, CVRHand hand = CVRHand.Left, bool isPreview = false)
|
||||||
{
|
{
|
||||||
Vector3 controllerForward = transform.forward;
|
Vector3 controllerForward = transform.forward;
|
||||||
Vector3 controllerUp = transform.up;
|
Vector3 controllerUp = transform.up;
|
||||||
Vector3 playerUp = PlayerSetup.Instance.transform.up;
|
Vector3 playerUp = PlayerSetup.Instance.transform.up;
|
||||||
|
|
||||||
// extracting angle of controller ray on forward axis
|
// extracting angle of controller ray on forward axis
|
||||||
Vector3 projectedControllerUp = Vector3.ProjectOnPlane(controllerUp, controllerForward).normalized;
|
Vector3 projectedControllerUp = Vector3.ProjectOnPlane(controllerUp, controllerForward).normalized;
|
||||||
Vector3 projectedPlayerUp = Vector3.ProjectOnPlane(playerUp, controllerForward).normalized;
|
Vector3 projectedPlayerUp = Vector3.ProjectOnPlane(playerUp, controllerForward).normalized;
|
||||||
float angle = Vector3.Angle(projectedControllerUp, projectedPlayerUp);
|
float angle = Vector3.Angle(projectedControllerUp, projectedPlayerUp);
|
||||||
|
|
||||||
float angleThreshold = ModSettings.Entry_PlayerUpAlignmentThreshold.Value;
|
float angleThreshold = ModSettings.Entry_PlayerUpAlignmentThreshold.Value;
|
||||||
Vector3 targetUp = (angleThreshold != 0f && angle <= angleThreshold)
|
Vector3 targetUp = (angleThreshold != 0f && angle <= angleThreshold)
|
||||||
// leave 0.01% of the controller up vector to prevent issues with alignment on floor & ceiling in Desktop
|
// leave 0.01% of the controller up vector to prevent issues with alignment on floor & ceiling in Desktop
|
||||||
? Vector3.Slerp(controllerUp, playerUp, 0.99f)
|
? Vector3.Slerp(controllerUp, playerUp, 0.99f)
|
||||||
: controllerUp;
|
: controllerUp;
|
||||||
|
|
||||||
if (isPreview)
|
if (isPreview)
|
||||||
{
|
{
|
||||||
PlaceStickerPreview(transform.position, controllerForward, targetUp);
|
PlaceStickerPreview(transform.position, controllerForward, targetUp);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!PlaceStickerSelf(transform.position, transform.forward, targetUp))
|
if (!PlaceStickerSelf(transform.position, transform.forward, targetUp))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
CVRInputManager.Instance.Vibrate(0f, 0.1f, 10f, 0.1f, hand);
|
CVRInputManager.Instance.Vibrate(0f, 0.1f, 10f, 0.1f, hand);
|
||||||
}
|
}
|
||||||
|
|
||||||
private bool PlaceStickerSelf(Vector3 position, Vector3 forward, Vector3 up, bool alignWithNormal = true)
|
private bool PlaceStickerSelf(Vector3 position, Vector3 forward, Vector3 up, bool alignWithNormal = true)
|
||||||
{
|
{
|
||||||
if (!AttemptPlaceSticker(PlayerLocalId, position, forward, up, alignWithNormal, SelectedStickerSlot))
|
if (!AttemptPlaceSticker(PlayerLocalId, position, forward, up, alignWithNormal, SelectedStickerSlot, RestrictedInstance))
|
||||||
return false; // failed
|
return false; // failed
|
||||||
|
|
||||||
// placed, now network
|
// placed, now network
|
||||||
ModNetwork.SendPlaceSticker(SelectedStickerSlot, position, forward, up);
|
ModNetwork.SendPlaceSticker(SelectedStickerSlot, position, forward, up);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
private bool AttemptPlaceSticker(string playerId, Vector3 position, Vector3 forward, Vector3 up, bool alignWithNormal = true, int stickerSlot = 0, bool isPreview = false)
|
private bool AttemptPlaceSticker(string playerId, Vector3 position, Vector3 forward, Vector3 up, bool alignWithNormal = true, int stickerSlot = 0, bool RestrictedInstance = false, bool isPreview = false)
|
||||||
{
|
{
|
||||||
StickerData stickerData = GetOrCreateStickerData(playerId);
|
StickerData stickerData = GetOrCreateStickerData(playerId);
|
||||||
if (Time.time - stickerData.LastPlacedTime < StickerCooldown)
|
if (Time.time - stickerData.LastPlacedTime < StickerCooldown)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
// Every layer other than IgnoreRaycast, PlayerLocal, PlayerClone, PlayerNetwork, and UI Internal
|
// Every layer other than IgnoreRaycast, PlayerLocal, PlayerClone, PlayerNetwork, and UI Internal
|
||||||
const int LayerMask = ~((1 << 2) | (1 << 8) | (1 << 9) | (1 << 10) | (1 << 15));
|
const int LayerMask = ~((1 << 2) | (1 << 8) | (1 << 9) | (1 << 10) | (1 << 15));
|
||||||
if (!Physics.Raycast(position, forward, out RaycastHit hit,
|
if (!Physics.Raycast(position, forward, out RaycastHit hit,
|
||||||
10f, LayerMask, QueryTriggerInteraction.Ignore))
|
10f, LayerMask, QueryTriggerInteraction.Ignore))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
// if gameobject name starts with [NoSticker] then don't place sticker
|
// if gameobject name starts with [NoSticker] then don't place sticker
|
||||||
if (hit.transform.gameObject.name.StartsWith("[NoSticker]"))
|
if (hit.transform.gameObject.name.StartsWith("[NoSticker]"))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (isPreview)
|
// if the world contained a gameobject with the [DisableStickers] name and restricted the instance disable stickers!
|
||||||
{
|
if (RestrictedInstance == true)
|
||||||
stickerData.PlacePreview(hit, alignWithNormal ? -hit.normal : forward, up, stickerSlot);
|
return false;
|
||||||
return true;
|
|
||||||
}
|
if (isPreview)
|
||||||
|
{
|
||||||
stickerData.Place(hit, alignWithNormal ? -hit.normal : forward, up, stickerSlot);
|
stickerData.PlacePreview(hit, alignWithNormal ? -hit.normal : forward, up, stickerSlot);
|
||||||
stickerData.PlayAudio();
|
return true;
|
||||||
return true;
|
}
|
||||||
}
|
|
||||||
|
stickerData.Place(hit, alignWithNormal ? -hit.normal : forward, up, stickerSlot);
|
||||||
public void ClearStickersSelf()
|
stickerData.PlayAudio();
|
||||||
{
|
return true;
|
||||||
ClearStickersForPlayer(PlayerLocalId);
|
}
|
||||||
ModNetwork.SendClearAllStickers();
|
|
||||||
}
|
public void ClearStickersSelf()
|
||||||
|
{
|
||||||
public void ClearStickerSelf(int stickerSlot)
|
ClearStickersForPlayer(PlayerLocalId);
|
||||||
{
|
ModNetwork.SendClearAllStickers();
|
||||||
ClearStickersForPlayer(PlayerLocalId, stickerSlot);
|
}
|
||||||
ModNetwork.SendClearSticker(stickerSlot);
|
|
||||||
}
|
public void ClearStickerSelf(int stickerSlot)
|
||||||
|
{
|
||||||
private void ClearStickersForPlayer(string playerId)
|
ClearStickersForPlayer(PlayerLocalId, stickerSlot);
|
||||||
{
|
ModNetwork.SendClearSticker(stickerSlot);
|
||||||
if (!_playerStickers.TryGetValue(playerId, out StickerData stickerData))
|
}
|
||||||
return;
|
|
||||||
|
private void ClearStickersForPlayer(string playerId)
|
||||||
stickerData.Clear();
|
{
|
||||||
}
|
if (!_playerStickers.TryGetValue(playerId, out StickerData stickerData))
|
||||||
|
return;
|
||||||
private void ClearStickersForPlayer(string playerId, int stickerSlot)
|
|
||||||
{
|
stickerData.Clear();
|
||||||
if (!_playerStickers.TryGetValue(playerId, out StickerData stickerData))
|
}
|
||||||
return;
|
|
||||||
|
private void ClearStickersForPlayer(string playerId, int stickerSlot)
|
||||||
stickerData.Clear(stickerSlot);
|
{
|
||||||
}
|
if (!_playerStickers.TryGetValue(playerId, out StickerData stickerData))
|
||||||
|
return;
|
||||||
private void SetTextureSelf(byte[] imageBytes, int stickerSlot = 0)
|
|
||||||
{
|
stickerData.Clear(stickerSlot);
|
||||||
Texture2D texture = new(1, 1); // placeholder
|
}
|
||||||
texture.LoadImage(imageBytes);
|
|
||||||
texture.Compress(true); // noachi said to do
|
private void SetTextureSelf(byte[] imageBytes, int stickerSlot = 0)
|
||||||
|
{
|
||||||
ClearStickerSelf(stickerSlot); // clear placed stickers in-scene so we can't replace an entire wall at once
|
Texture2D texture = new(1, 1); // placeholder
|
||||||
OnPlayerStickerTextureReceived(PlayerLocalId, Guid.Empty, texture, stickerSlot);
|
texture.LoadImage(imageBytes);
|
||||||
ModNetwork.SetTexture(stickerSlot, imageBytes);
|
texture.Compress(true); // noachi said to do
|
||||||
}
|
|
||||||
|
ClearStickerSelf(stickerSlot); // clear placed stickers in-scene so we can't replace an entire wall at once
|
||||||
public void ClearAllStickers()
|
OnPlayerStickerTextureReceived(PlayerLocalId, Guid.Empty, texture, stickerSlot);
|
||||||
{
|
ModNetwork.SetTexture(stickerSlot, imageBytes);
|
||||||
foreach (StickerData stickerData in _playerStickers.Values)
|
}
|
||||||
stickerData.Clear();
|
|
||||||
|
public void ClearAllStickers()
|
||||||
ModNetwork.SendClearAllStickers();
|
{
|
||||||
}
|
foreach (StickerData stickerData in _playerStickers.Values)
|
||||||
|
stickerData.Clear();
|
||||||
public void OnPlayerStickerTextureReceived(string playerId, Guid textureHash, Texture2D texture, int stickerSlot = 0)
|
|
||||||
{
|
ModNetwork.SendClearAllStickers();
|
||||||
StickerData stickerData = GetOrCreateStickerData(playerId);
|
}
|
||||||
stickerData.SetTexture(textureHash, texture, stickerSlot);
|
|
||||||
}
|
public void OnPlayerStickerTextureReceived(string playerId, Guid textureHash, Texture2D texture, int stickerSlot = 0)
|
||||||
|
{
|
||||||
public bool HasTextureHash(string playerId, Guid textureHash)
|
StickerData stickerData = GetOrCreateStickerData(playerId);
|
||||||
{
|
stickerData.SetTexture(textureHash, texture, stickerSlot);
|
||||||
StickerData stickerData = GetOrCreateStickerData(playerId);
|
}
|
||||||
return stickerData.CheckHasTextureHash(textureHash);
|
|
||||||
}
|
public bool HasTextureHash(string playerId, Guid textureHash)
|
||||||
|
{
|
||||||
public void CleanupAll()
|
StickerData stickerData = GetOrCreateStickerData(playerId);
|
||||||
{
|
return stickerData.CheckHasTextureHash(textureHash);
|
||||||
foreach ((_, StickerData data) in _playerStickers)
|
}
|
||||||
data.Cleanup();
|
|
||||||
|
public void CleanupAll()
|
||||||
_playerStickers.Clear();
|
{
|
||||||
}
|
foreach ((_, StickerData data) in _playerStickers)
|
||||||
|
data.Cleanup();
|
||||||
public void CleanupAllButSelf()
|
|
||||||
{
|
_playerStickers.Clear();
|
||||||
StickerData localStickerData = GetOrCreateStickerData(PlayerLocalId);
|
}
|
||||||
|
|
||||||
foreach ((_, StickerData data) in _playerStickers)
|
public void CleanupAllButSelf()
|
||||||
{
|
{
|
||||||
if (data == localStickerData) data.Clear();
|
StickerData localStickerData = GetOrCreateStickerData(PlayerLocalId);
|
||||||
else data.Cleanup();
|
|
||||||
}
|
foreach ((_, StickerData data) in _playerStickers)
|
||||||
|
{
|
||||||
_playerStickers.Clear();
|
if (data == localStickerData) data.Clear();
|
||||||
_playerStickers[PlayerLocalId] = localStickerData;
|
else data.Cleanup();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void PlaceStickerPreview(Vector3 position, Vector3 forward, Vector3 up)
|
_playerStickers.Clear();
|
||||||
{
|
_playerStickers[PlayerLocalId] = localStickerData;
|
||||||
AttemptPlaceSticker(PlayerLocalId, position, forward, up, true, SelectedStickerSlot, true);
|
}
|
||||||
}
|
|
||||||
|
public void PlaceStickerPreview(Vector3 position, Vector3 forward, Vector3 up)
|
||||||
public void UpdateStickerPreview()
|
{
|
||||||
{
|
AttemptPlaceSticker(PlayerLocalId, position, forward, up, true, SelectedStickerSlot, true);
|
||||||
if (!IsInStickerMode) return;
|
}
|
||||||
|
|
||||||
StickerData localStickerData = GetOrCreateStickerData(PlayerLocalId);
|
public void UpdateStickerPreview()
|
||||||
localStickerData.UpdatePreview(SelectedStickerSlot);
|
{
|
||||||
}
|
if (!IsInStickerMode) return;
|
||||||
|
|
||||||
public void ClearStickerPreview()
|
StickerData localStickerData = GetOrCreateStickerData(PlayerLocalId);
|
||||||
{
|
localStickerData.UpdatePreview(SelectedStickerSlot);
|
||||||
StickerData localStickerData = GetOrCreateStickerData(PlayerLocalId);
|
}
|
||||||
localStickerData.ClearPreview();
|
|
||||||
}
|
public void ClearStickerPreview()
|
||||||
|
{
|
||||||
#endregion Sticker Lifecycle
|
StickerData localStickerData = GetOrCreateStickerData(PlayerLocalId);
|
||||||
}
|
localStickerData.ClearPreview();
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion Sticker Lifecycle
|
||||||
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue