small fixes
This commit is contained in:
39
Assets/Station46/Runtime/Puzzle A/Ball.cs
Normal file
39
Assets/Station46/Runtime/Puzzle A/Ball.cs
Normal file
@@ -0,0 +1,39 @@
|
||||
using EscapeRoomEngine.Engine.Runtime.Modules;
|
||||
using NaughtyAttributes;
|
||||
|
||||
namespace EscapeRoomEngine.Desert.Runtime.Puzzle_A
|
||||
{
|
||||
/// <summary>
|
||||
/// The main component for the symbol ball module.
|
||||
/// </summary>
|
||||
public class Ball : ModuleState
|
||||
{
|
||||
[BoxGroup("Internal")] [Required]
|
||||
public Emission statusLight;
|
||||
[BoxGroup("Internal")] [Required]
|
||||
public Ring ring;
|
||||
|
||||
public bool StatusLight
|
||||
{
|
||||
set => statusLight.active = value;
|
||||
}
|
||||
|
||||
public bool Active
|
||||
{
|
||||
set
|
||||
{
|
||||
statusLight.color = value ?
|
||||
Engine.Runtime.Engine.Theme.puzzleColor.hdr
|
||||
: Engine.Runtime.Engine.Theme.solvedColor.hdr;
|
||||
ring.rotating = value;
|
||||
if (!value)
|
||||
{
|
||||
ring.crystal.Active = false;
|
||||
ring.symbols.ForEach(symbol => symbol.Active = false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public override void SetModule(Module module) {}
|
||||
}
|
||||
}
|
||||
3
Assets/Station46/Runtime/Puzzle A/Ball.cs.meta
Normal file
3
Assets/Station46/Runtime/Puzzle A/Ball.cs.meta
Normal file
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: b9b2d31478f94735a2e19e7c07a27f05
|
||||
timeCreated: 1668705636
|
||||
65
Assets/Station46/Runtime/Puzzle A/Ring.cs
Normal file
65
Assets/Station46/Runtime/Puzzle A/Ring.cs
Normal file
@@ -0,0 +1,65 @@
|
||||
using System.Collections.Generic;
|
||||
using EscapeRoomEngine.Engine.Runtime.Utilities;
|
||||
using JetBrains.Annotations;
|
||||
using NaughtyAttributes;
|
||||
using UnityEngine;
|
||||
|
||||
namespace EscapeRoomEngine.Desert.Runtime.Puzzle_A
|
||||
{
|
||||
/// <summary>
|
||||
/// The rotating ring in the symbol ball module.
|
||||
/// </summary>
|
||||
public class Ring : MonoBehaviour
|
||||
{
|
||||
[Tooltip("Whether the ring is rotating.")]
|
||||
public bool rotating = true;
|
||||
[Tooltip("The current angle of the rotation.")]
|
||||
public float rotationAngle;
|
||||
[Tooltip("The range in degrees from the front of the module where a symbol should be lit up.")]
|
||||
[MinMaxSlider(-180, 180)]
|
||||
public Vector2 activeRange;
|
||||
[BoxGroup("Internal")] [Required]
|
||||
public Crystal crystal;
|
||||
[BoxGroup("Internal")]
|
||||
[ValidateInput("SymbolCount", "Must have same amount of symbols and slots.")]
|
||||
public List<Symbol> symbols;
|
||||
[BoxGroup("Internal")]
|
||||
public List<Transform> symbolSlots;
|
||||
|
||||
private void Awake()
|
||||
{
|
||||
var angleDistance = 360f / symbols.Count;
|
||||
List<Symbol> symbolInstances = new(symbols.Count);
|
||||
|
||||
for (var i = 0; i < symbols.Count; i++)
|
||||
{
|
||||
var symbol = Instantiate(symbols.RandomElement(), symbolSlots[i], false);
|
||||
symbol.symbolPosition = i;
|
||||
symbol.anglePosition = i * angleDistance;
|
||||
symbolInstances.Add(symbol);
|
||||
}
|
||||
|
||||
symbols = symbolInstances;
|
||||
}
|
||||
|
||||
private void Update()
|
||||
{
|
||||
if(rotating)
|
||||
{
|
||||
transform.localRotation = Quaternion.AngleAxis(rotationAngle, Vector3.forward);
|
||||
|
||||
var activeSymbol = false;
|
||||
symbols.ForEach(symbol =>
|
||||
{
|
||||
var angle = (rotationAngle - symbol.anglePosition) % 360;
|
||||
var active = angle > activeRange.x && angle < activeRange.y || angle > 360 + activeRange.x;
|
||||
symbol.Active = active;
|
||||
activeSymbol |= active;
|
||||
});
|
||||
crystal.Active = activeSymbol;
|
||||
}
|
||||
}
|
||||
|
||||
[UsedImplicitly] private bool SymbolCount(List<Symbol> list) => list.Count == symbolSlots.Count;
|
||||
}
|
||||
}
|
||||
11
Assets/Station46/Runtime/Puzzle A/Ring.cs.meta
Normal file
11
Assets/Station46/Runtime/Puzzle A/Ring.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 7902f6a7fa0fd844f8ed93e3debd7778
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
86
Assets/Station46/Runtime/Puzzle A/Symbol.cs
Normal file
86
Assets/Station46/Runtime/Puzzle A/Symbol.cs
Normal file
@@ -0,0 +1,86 @@
|
||||
using System;
|
||||
using NaughtyAttributes;
|
||||
using UnityEngine;
|
||||
using Logger = EscapeRoomEngine.Engine.Runtime.Utilities.Logger;
|
||||
using LogType = EscapeRoomEngine.Engine.Runtime.Utilities.LogType;
|
||||
|
||||
namespace EscapeRoomEngine.Desert.Runtime.Puzzle_A
|
||||
{
|
||||
public enum SymbolEventType
|
||||
{
|
||||
Activated, Deactivated
|
||||
}
|
||||
|
||||
public static class SymbolEventExtensions
|
||||
{
|
||||
public static string Description(this SymbolEventType type, Symbol symbol)
|
||||
{
|
||||
var action = type switch
|
||||
{
|
||||
SymbolEventType.Activated => "activated",
|
||||
SymbolEventType.Deactivated => "deactivated",
|
||||
_ => throw new ArgumentOutOfRangeException(nameof(type), type, null)
|
||||
};
|
||||
|
||||
return $"{symbol} was {action}";
|
||||
}
|
||||
}
|
||||
|
||||
public delegate void SymbolEventHandler(SymbolEventType e);
|
||||
|
||||
/// <summary>
|
||||
/// The main component for the symbols on the symbol ring module.
|
||||
/// </summary>
|
||||
[RequireComponent(typeof(Emission))]
|
||||
public class Symbol : MonoBehaviour
|
||||
{
|
||||
[Tooltip("The number of the symbol in the puzzle solution.")]
|
||||
public int symbolNumber;
|
||||
[BoxGroup("Internal")]
|
||||
public int symbolPosition;
|
||||
[BoxGroup("Internal")]
|
||||
public float anglePosition;
|
||||
public event SymbolEventHandler SymbolEvent;
|
||||
|
||||
/// <summary>
|
||||
/// Whether the symbol is lit up. This is controlled by the <see cref="Ring"/>.
|
||||
/// </summary>
|
||||
public bool Active
|
||||
{
|
||||
set
|
||||
{
|
||||
var previous = _emission.active;
|
||||
_emission.active = value;
|
||||
|
||||
if (previous != value)
|
||||
{
|
||||
OnSymbolEvent(value ? SymbolEventType.Activated : SymbolEventType.Deactivated);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private Emission _emission;
|
||||
|
||||
private void Awake()
|
||||
{
|
||||
_emission = GetComponent<Emission>();
|
||||
}
|
||||
|
||||
private void Start()
|
||||
{
|
||||
Active = false;
|
||||
}
|
||||
|
||||
private void OnSymbolEvent(SymbolEventType type)
|
||||
{
|
||||
Logger.Log(type.Description(this), LogType.PuzzleDetail);
|
||||
|
||||
SymbolEvent?.Invoke(type);
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return name;
|
||||
}
|
||||
}
|
||||
}
|
||||
11
Assets/Station46/Runtime/Puzzle A/Symbol.cs.meta
Normal file
11
Assets/Station46/Runtime/Puzzle A/Symbol.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 1e099fd852792c34188dcf102aa895e4
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
13
Assets/Station46/Runtime/Puzzle A/SymbolButton.cs
Normal file
13
Assets/Station46/Runtime/Puzzle A/SymbolButton.cs
Normal file
@@ -0,0 +1,13 @@
|
||||
using UnityEngine;
|
||||
|
||||
namespace EscapeRoomEngine.Desert.Runtime.Puzzle_A
|
||||
{
|
||||
/// <summary>
|
||||
/// A <see cref="HoloButton"/> that includes the number of its assigned symbol.
|
||||
/// </summary>
|
||||
public class SymbolButton : HoloButton
|
||||
{
|
||||
[Tooltip("The number of the symbol assigned to this button.")]
|
||||
public int symbolNumber;
|
||||
}
|
||||
}
|
||||
11
Assets/Station46/Runtime/Puzzle A/SymbolButton.cs.meta
Normal file
11
Assets/Station46/Runtime/Puzzle A/SymbolButton.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 3d6620bee0f14224b11a19808d537cbd
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
154
Assets/Station46/Runtime/Puzzle A/Terminal.cs
Normal file
154
Assets/Station46/Runtime/Puzzle A/Terminal.cs
Normal file
@@ -0,0 +1,154 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using EscapeRoomEngine.Engine.Runtime.Modules;
|
||||
using EscapeRoomEngine.Engine.Runtime.Utilities;
|
||||
using JetBrains.Annotations;
|
||||
using NaughtyAttributes;
|
||||
using UnityEngine;
|
||||
using Logger = EscapeRoomEngine.Engine.Runtime.Utilities.Logger;
|
||||
using LogType = EscapeRoomEngine.Engine.Runtime.Utilities.LogType;
|
||||
|
||||
namespace EscapeRoomEngine.Desert.Runtime.Puzzle_A
|
||||
{
|
||||
/// <summary>
|
||||
/// The main component for the terminal module.
|
||||
/// </summary>
|
||||
[RequireComponent(typeof(Animator))]
|
||||
public class Terminal : CyclicStepPuzzle
|
||||
{
|
||||
private static readonly int LightFlash = Animator.StringToHash("Light Flash");
|
||||
|
||||
[BoxGroup("Internal")] [Required]
|
||||
public Emission terminalLight;
|
||||
[BoxGroup("Internal")]
|
||||
[ValidateInput("SymbolCount", "Must have same amount of symbols and slots.")]
|
||||
public List<SymbolButton> symbols;
|
||||
[BoxGroup("Internal")]
|
||||
public List<Transform> symbolSlots;
|
||||
|
||||
private IOption<Symbol> _activeSymbol;
|
||||
private Animator _animator;
|
||||
private Ball _ball;
|
||||
|
||||
private void Awake()
|
||||
{
|
||||
_animator = GetComponent<Animator>();
|
||||
|
||||
List<SymbolButton> symbolInstances = new(symbols.Count);
|
||||
symbolInstances.AddRange(symbols.Select((t, i) => Instantiate(t, symbolSlots[i], false)));
|
||||
symbols = symbolInstances;
|
||||
}
|
||||
|
||||
protected override void Start()
|
||||
{
|
||||
base.Start();
|
||||
|
||||
PuzzleEvent += (_, type) =>
|
||||
{
|
||||
// ReSharper disable once SwitchStatementHandlesSomeKnownEnumValuesWithDefault
|
||||
switch (type)
|
||||
{
|
||||
case PuzzleEventType.Restarted:
|
||||
_ball.Active = true;
|
||||
terminalLight.color = Engine.Runtime.Engine.Theme.puzzleColor.hdr;
|
||||
symbols.ForEach(symbol => symbol.Enable());
|
||||
break;
|
||||
case PuzzleEventType.Solved:
|
||||
_ball.Active = false;
|
||||
terminalLight.color = Engine.Runtime.Engine.Theme.solvedColor.hdr;
|
||||
symbols.ForEach(symbol => symbol.Disable());
|
||||
break;
|
||||
case PuzzleEventType.WrongInput:
|
||||
_animator.SetTrigger(LightFlash);
|
||||
break;
|
||||
}
|
||||
};
|
||||
|
||||
symbols.ForEach(symbol =>
|
||||
{
|
||||
symbol.ButtonEvent += (_, type) =>
|
||||
{
|
||||
if (type == ButtonEventType.Pressed)
|
||||
{
|
||||
PressedSymbol(symbol.symbolNumber);
|
||||
}
|
||||
};
|
||||
});
|
||||
|
||||
_ball.ring.symbols.ForEach(symbol =>
|
||||
{
|
||||
symbol.SymbolEvent += type =>
|
||||
_activeSymbol = type == SymbolEventType.Activated ? Some<Symbol>.Of(symbol) : None<Symbol>.New();
|
||||
});
|
||||
}
|
||||
|
||||
public override void SetModule(Module module)
|
||||
{
|
||||
base.SetModule(module);
|
||||
|
||||
// The terminal requires a related symbol ball module
|
||||
var firstRelatedModule = Module.relatedModules[0];
|
||||
if (firstRelatedModule.State is Ball ball)
|
||||
{
|
||||
_ball = ball;
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new EngineException("Terminal was not assigned a related Ball.");
|
||||
}
|
||||
|
||||
TurnOnLights();
|
||||
}
|
||||
|
||||
[UsedImplicitly] // required in animation
|
||||
internal void TurnOnLights()
|
||||
{
|
||||
terminalLight.active = true;
|
||||
_ball.StatusLight = true;
|
||||
}
|
||||
|
||||
[UsedImplicitly] // required in animation
|
||||
internal void TurnOffLights()
|
||||
{
|
||||
terminalLight.active = false;
|
||||
_ball.StatusLight = false;
|
||||
}
|
||||
|
||||
private void PressedSymbol(int number)
|
||||
{
|
||||
if (!Solved)
|
||||
{
|
||||
Logger.Log($"Pressed symbol {number} on {this}", LogType.PuzzleDetail);
|
||||
|
||||
_activeSymbol.Match(some: symbol =>
|
||||
{
|
||||
if (number == symbol.symbolNumber)
|
||||
{
|
||||
CheckStep(symbol.symbolPosition);
|
||||
}
|
||||
else
|
||||
{
|
||||
WrongInput();
|
||||
}
|
||||
}, none: WrongInput);
|
||||
}
|
||||
}
|
||||
|
||||
#region Debug Buttons
|
||||
|
||||
[UsedImplicitly]
|
||||
[Button(enabledMode: EButtonEnableMode.Playmode)]
|
||||
public void PressSymbol0() => PressedSymbol(0);
|
||||
[UsedImplicitly]
|
||||
[Button(enabledMode: EButtonEnableMode.Playmode)]
|
||||
public void PressSymbol1() => PressedSymbol(1);
|
||||
[UsedImplicitly]
|
||||
[Button(enabledMode: EButtonEnableMode.Playmode)]
|
||||
public void PressSymbol2() => PressedSymbol(2);
|
||||
|
||||
#endregion
|
||||
|
||||
[UsedImplicitly] // used for field validation
|
||||
private bool SymbolCount(List<SymbolButton> list) => list.Count == symbolSlots.Count;
|
||||
}
|
||||
}
|
||||
3
Assets/Station46/Runtime/Puzzle A/Terminal.cs.meta
Normal file
3
Assets/Station46/Runtime/Puzzle A/Terminal.cs.meta
Normal file
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 7c5df397607f423a8cde06954f22a2bd
|
||||
timeCreated: 1668762976
|
||||
Reference in New Issue
Block a user