2025-05-03 20:36:17 +08:00

407 lines
11 KiB
C#

using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using Godot;
using Godot.Bridge;
using Godot.NativeInterop;
[ScriptPath("res://Scripts/Puzzles/MemoryGame.cs")]
public class MemoryGame : Node2D
{
[Signal]
public delegate void EndGameSignalEventHandler();
public new class MethodName : Node2D.MethodName
{
public new static readonly StringName _Ready = "_Ready";
}
public new class PropertyName : Node2D.PropertyName
{
public static readonly StringName winDiag = "winDiag";
public static readonly StringName loseDiag = "loseDiag";
public static readonly StringName music = "music";
public static readonly StringName defaultLives = "defaultLives";
public static readonly StringName last = "last";
public static readonly StringName running = "running";
public static readonly StringName lives = "lives";
}
public new class SignalName : Node2D.SignalName
{
public static readonly StringName EndGameSignal = "EndGameSignal";
}
[Export(PropertyHint.None, "")]
public string winDiag;
[Export(PropertyHint.None, "")]
public string loseDiag;
[Export(PropertyHint.None, "")]
private AudioStream music;
[Export(PropertyHint.None, "")]
public int defaultLives = 5;
private List<MemGameCards> cards = new List<MemGameCards>();
public List<int> flipped = new List<int>();
public MemGameCards last;
public bool running;
public int lives;
public const int max = 18;
private static readonly int[] order = new int[18]
{
1, 1, 2, 2, 3, 3, 4, 4, 5, 5,
6, 6, 7, 7, 8, 8, 9, 9
};
public static bool result;
private EndGameSignalEventHandler backing_EndGameSignal;
public event EndGameSignalEventHandler EndGameSignal
{
add
{
backing_EndGameSignal = (EndGameSignalEventHandler)Delegate.Combine(backing_EndGameSignal, value);
}
remove
{
backing_EndGameSignal = (EndGameSignalEventHandler)Delegate.Remove(backing_EndGameSignal, value);
}
}
public override void _Ready()
{
foreach (Node child in GetChildren())
{
cards.Add(child.GetChild<MemGameCards>(0));
}
base.Modulate = Main.colorClear;
}
public IEnumerator StartGame()
{
int[] array = order;
if (Main.RandomRange(0, 31) == 0)
{
int num = Main.RandomRange(0, 8);
array[num * 2] = 10;
array[num * 2 + 1] = 10;
}
array = order.OrderBy((int x) => Guid.NewGuid()).ToArray();
for (int num2 = 0; num2 < cards.Count; num2++)
{
cards[num2].id = array[num2];
cards[num2].sprite.Frame = 0;
cards[num2].flipped = false;
}
Audio.PlaySound("snd_shadowpendant_ch1.wav");
Audio.ChangeMusic(music);
float a = 0f;
for (float b = 30f; a <= b + 1f; a += Main.deltaTime)
{
base.Modulate = Main.colorClear.Lerp(Main.colorWhite, Mathf.Min(a / b, 1f));
yield return null;
}
Coroutine s = Coroutine.Start(CameraController.PanToObj(this, 2f));
while (!s.done)
{
yield return null;
}
Audio.PlaySound("snd_wing_ch1.wav", 1.2f);
for (int num3 = 0; num3 < cards.Count; num3++)
{
Coroutine.Start(cards[num3].FlipAnim(cards[num3].id, noSound: true));
}
for (float b = 0f; b < 300f; b += Main.deltaTime)
{
if (Input.IsActionJustPressed(Main.keys[4]))
{
break;
}
if (Input.IsActionJustPressed(Main.keys[5]))
{
break;
}
yield return null;
}
Audio.PlaySound("snd_wing_ch1.wav", 1.2f);
for (int num4 = 0; num4 < cards.Count; num4++)
{
Coroutine.Start(cards[num4].FlipAnim(0, noSound: true));
}
for (float b = 0f; b < 30f; b += Main.deltaTime)
{
yield return null;
}
s = Coroutine.Start(CameraController.PanToObj(Player.instance, 2f));
while (!s.done)
{
yield return null;
}
flipped.Clear();
lives = defaultLives;
running = true;
}
public IEnumerator EndGame(bool won)
{
running = false;
result = won;
if (won)
{
Audio.PlaySound("snd_won.wav");
TextSystem.GetText(winDiag);
}
else
{
TextSystem.GetText(loseDiag);
}
while (TextSystem.instance.Visible)
{
yield return null;
}
Room.current.DoMusic();
float a = 0f;
for (float b = 30f; a <= b + 1f; a += Main.deltaTime)
{
base.Modulate = Main.colorWhite.Lerp(Main.colorClear, Mathf.Min(a / b, 1f));
yield return null;
}
EmitSignal(SignalName.EndGameSignal);
}
[EditorBrowsable(EditorBrowsableState.Never)]
internal static List<MethodInfo> GetGodotMethodList()
{
return new List<MethodInfo>(1)
{
new MethodInfo(MethodName._Ready, new PropertyInfo(Variant.Type.Nil, "", PropertyHint.None, "", PropertyUsageFlags.Default, exported: false), MethodFlags.Normal, null, null)
};
}
[EditorBrowsable(EditorBrowsableState.Never)]
protected override bool InvokeGodotClassMethod(in godot_string_name method, NativeVariantPtrArgs args, out godot_variant ret)
{
if (method == MethodName._Ready && args.Count == 0)
{
_Ready();
ret = default(godot_variant);
return true;
}
return base.InvokeGodotClassMethod(in method, args, out ret);
}
[EditorBrowsable(EditorBrowsableState.Never)]
protected override bool HasGodotClassMethod(in godot_string_name method)
{
if (method == MethodName._Ready)
{
return true;
}
return base.HasGodotClassMethod(in method);
}
[EditorBrowsable(EditorBrowsableState.Never)]
protected override bool SetGodotClassPropertyValue(in godot_string_name name, in godot_variant value)
{
if (name == PropertyName.winDiag)
{
winDiag = VariantUtils.ConvertTo<string>(in value);
return true;
}
if (name == PropertyName.loseDiag)
{
loseDiag = VariantUtils.ConvertTo<string>(in value);
return true;
}
if (name == PropertyName.music)
{
music = VariantUtils.ConvertTo<AudioStream>(in value);
return true;
}
if (name == PropertyName.defaultLives)
{
defaultLives = VariantUtils.ConvertTo<int>(in value);
return true;
}
if (name == PropertyName.last)
{
last = VariantUtils.ConvertTo<MemGameCards>(in value);
return true;
}
if (name == PropertyName.running)
{
running = VariantUtils.ConvertTo<bool>(in value);
return true;
}
if (name == PropertyName.lives)
{
lives = VariantUtils.ConvertTo<int>(in value);
return true;
}
return base.SetGodotClassPropertyValue(in name, in value);
}
[EditorBrowsable(EditorBrowsableState.Never)]
protected override bool GetGodotClassPropertyValue(in godot_string_name name, out godot_variant value)
{
if (name == PropertyName.winDiag)
{
value = VariantUtils.CreateFrom(in winDiag);
return true;
}
if (name == PropertyName.loseDiag)
{
value = VariantUtils.CreateFrom(in loseDiag);
return true;
}
if (name == PropertyName.music)
{
value = VariantUtils.CreateFrom(in music);
return true;
}
if (name == PropertyName.defaultLives)
{
value = VariantUtils.CreateFrom(in defaultLives);
return true;
}
if (name == PropertyName.last)
{
value = VariantUtils.CreateFrom(in last);
return true;
}
if (name == PropertyName.running)
{
value = VariantUtils.CreateFrom(in running);
return true;
}
if (name == PropertyName.lives)
{
value = VariantUtils.CreateFrom(in lives);
return true;
}
return base.GetGodotClassPropertyValue(in name, out value);
}
[EditorBrowsable(EditorBrowsableState.Never)]
internal static List<PropertyInfo> GetGodotPropertyList()
{
return new List<PropertyInfo>
{
new PropertyInfo(Variant.Type.String, PropertyName.winDiag, PropertyHint.None, "", PropertyUsageFlags.Default | PropertyUsageFlags.ScriptVariable, exported: true),
new PropertyInfo(Variant.Type.String, PropertyName.loseDiag, PropertyHint.None, "", PropertyUsageFlags.Default | PropertyUsageFlags.ScriptVariable, exported: true),
new PropertyInfo(Variant.Type.Object, PropertyName.music, PropertyHint.ResourceType, "AudioStream", PropertyUsageFlags.Default | PropertyUsageFlags.ScriptVariable, exported: true),
new PropertyInfo(Variant.Type.Int, PropertyName.defaultLives, PropertyHint.None, "", PropertyUsageFlags.Default | PropertyUsageFlags.ScriptVariable, exported: true),
new PropertyInfo(Variant.Type.Object, PropertyName.last, PropertyHint.None, "", PropertyUsageFlags.ScriptVariable, exported: false),
new PropertyInfo(Variant.Type.Bool, PropertyName.running, PropertyHint.None, "", PropertyUsageFlags.ScriptVariable, exported: false),
new PropertyInfo(Variant.Type.Int, PropertyName.lives, PropertyHint.None, "", PropertyUsageFlags.ScriptVariable, exported: false)
};
}
[EditorBrowsable(EditorBrowsableState.Never)]
protected override void SaveGodotObjectData(GodotSerializationInfo info)
{
base.SaveGodotObjectData(info);
info.AddProperty(PropertyName.winDiag, Variant.From(in winDiag));
info.AddProperty(PropertyName.loseDiag, Variant.From(in loseDiag));
info.AddProperty(PropertyName.music, Variant.From(in music));
info.AddProperty(PropertyName.defaultLives, Variant.From(in defaultLives));
info.AddProperty(PropertyName.last, Variant.From(in last));
info.AddProperty(PropertyName.running, Variant.From(in running));
info.AddProperty(PropertyName.lives, Variant.From(in lives));
info.AddSignalEventDelegate(SignalName.EndGameSignal, backing_EndGameSignal);
}
[EditorBrowsable(EditorBrowsableState.Never)]
protected override void RestoreGodotObjectData(GodotSerializationInfo info)
{
base.RestoreGodotObjectData(info);
if (info.TryGetProperty(PropertyName.winDiag, out var value))
{
winDiag = value.As<string>();
}
if (info.TryGetProperty(PropertyName.loseDiag, out var value2))
{
loseDiag = value2.As<string>();
}
if (info.TryGetProperty(PropertyName.music, out var value3))
{
music = value3.As<AudioStream>();
}
if (info.TryGetProperty(PropertyName.defaultLives, out var value4))
{
defaultLives = value4.As<int>();
}
if (info.TryGetProperty(PropertyName.last, out var value5))
{
last = value5.As<MemGameCards>();
}
if (info.TryGetProperty(PropertyName.running, out var value6))
{
running = value6.As<bool>();
}
if (info.TryGetProperty(PropertyName.lives, out var value7))
{
lives = value7.As<int>();
}
if (info.TryGetSignalEventDelegate<EndGameSignalEventHandler>(SignalName.EndGameSignal, out var value8))
{
backing_EndGameSignal = value8;
}
}
[EditorBrowsable(EditorBrowsableState.Never)]
internal static List<MethodInfo> GetGodotSignalList()
{
return new List<MethodInfo>(1)
{
new MethodInfo(SignalName.EndGameSignal, new PropertyInfo(Variant.Type.Nil, "", PropertyHint.None, "", PropertyUsageFlags.Default, exported: false), MethodFlags.Normal, null, null)
};
}
protected void EmitSignalEndGameSignal()
{
EmitSignal(SignalName.EndGameSignal);
}
[EditorBrowsable(EditorBrowsableState.Never)]
protected override void RaiseGodotClassSignalCallbacks(in godot_string_name signal, NativeVariantPtrArgs args)
{
if (signal == SignalName.EndGameSignal && args.Count == 0)
{
backing_EndGameSignal?.Invoke();
}
else
{
base.RaiseGodotClassSignalCallbacks(in signal, args);
}
}
[EditorBrowsable(EditorBrowsableState.Never)]
protected override bool HasGodotClassSignal(in godot_string_name signal)
{
if (signal == SignalName.EndGameSignal)
{
return true;
}
return base.HasGodotClassSignal(in signal);
}
}