155 lines
5.1 KiB
C#
155 lines
5.1 KiB
C#
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using EscapeRoomEngine.Engine.Runtime.Modules;
|
|
using EscapeRoomEngine.Engine.Runtime.Modules.State;
|
|
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 Station46.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 = EscapeRoomEngine.Engine.Runtime.Engine.Theme.puzzleColor.hdr;
|
|
symbols.ForEach(symbol => symbol.Enable());
|
|
break;
|
|
case PuzzleEventType.Solved:
|
|
_ball.Active = false;
|
|
terminalLight.color = EscapeRoomEngine.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;
|
|
}
|
|
} |