First MVP of sorting minigame (#60)

Co-authored-by: Michal Pikulski <michal.a.pikulski@gmail.com>
Co-authored-by: Michal Pikulski <michal@foolhardyhorizons.com>
Reviewed-on: #60
This commit is contained in:
2025-11-19 13:56:10 +00:00
parent f878521dab
commit fee5515bbd
91 changed files with 9205 additions and 178 deletions

View File

@@ -170,6 +170,7 @@ namespace Core
var interactionSettings = SettingsProvider.Instance.LoadSettingsSynchronous<InteractionSettings>();
var minigameSettings = SettingsProvider.Instance.LoadSettingsSynchronous<DivingMinigameSettings>();
var cardSystemSettings = SettingsProvider.Instance.LoadSettingsSynchronous<CardSystemSettings>();
var sortingGameSettings = SettingsProvider.Instance.LoadSettingsSynchronous<CardSortingSettings>();
// Register settings with service locator
if (playerSettings != null)
@@ -211,6 +212,16 @@ namespace Core
{
Debug.LogError("Failed to load CardSystemSettings");
}
if (sortingGameSettings != null)
{
ServiceLocator.Register<ICardSortingSettings>(sortingGameSettings);
Logging.Debug("CardSortingSettings registered successfully");
}
else
{
Debug.LogError("Failed to load CardSystemSettings");
}
// Log success
_settingsLoaded = playerSettings != null && interactionSettings != null && minigameSettings != null && cardSystemSettings != null;

View File

@@ -0,0 +1,92 @@
using AppleHills.Core.Settings;
using Minigames.CardSorting.Data;
using UnityEngine;
namespace Core.Settings
{
/// <summary>
/// Settings for Card Sorting minigame.
/// Follows DivingMinigameSettings pattern.
/// </summary>
[CreateAssetMenu(fileName = "CardSortingSettings", menuName = "AppleHills/Settings/CardSorting", order = 4)]
public class CardSortingSettings : BaseSettings, ICardSortingSettings
{
[Header("Timing")]
[Tooltip("Total game duration in seconds")]
[SerializeField] private float gameDuration = 120f;
[Tooltip("Distance between item spawns (units)")]
[SerializeField] private float spawnDistance = 50f;
[Header("Conveyor Speed")]
[Tooltip("Initial belt movement speed")]
[SerializeField] private float initialBeltSpeed = 1f;
[Tooltip("Maximum belt movement speed")]
[SerializeField] private float maxBeltSpeed = 3f;
[Tooltip("Curve for difficulty progression (X=time%, Y=speed multiplier)")]
[SerializeField] private AnimationCurve speedCurve = AnimationCurve.EaseInOut(0f, 0f, 1f, 1f);
[Header("Item Pools")]
[Tooltip("Garbage items that can spawn (banana peels, cans, receipts, etc.)")]
[SerializeField] private GarbageItemDefinition[] garbageItems = new GarbageItemDefinition[0];
[Header("Spawn Weights")]
[Tooltip("Weight for spawning normal rarity cards")]
[Range(0, 100)] [SerializeField] private float normalCardWeight = 40f;
[Tooltip("Weight for spawning rare rarity cards")]
[Range(0, 100)] [SerializeField] private float rareCardWeight = 30f;
[Tooltip("Weight for spawning legendary rarity cards")]
[Range(0, 100)] [SerializeField] private float legendCardWeight = 20f;
[Tooltip("Weight for spawning garbage items")]
[Range(0, 100)] [SerializeField] private float garbageWeight = 10f;
[Header("Scoring")]
[Tooltip("Points awarded for correct sort")]
[SerializeField] private int correctSortPoints = 10;
[Tooltip("Points deducted for incorrect sort")]
[SerializeField] private int incorrectSortPenalty = -5;
[Tooltip("Points deducted when item falls off belt")]
[SerializeField] private int missedItemPenalty = -3;
[Header("Rewards")]
[Tooltip("Booster packs awarded per correct sort")]
[SerializeField] private int boosterPacksPerCorrectItem = 1;
// Interface implementation
public float GameDuration => gameDuration;
public float SpawnDistance => spawnDistance;
public float InitialBeltSpeed => initialBeltSpeed;
public float MaxBeltSpeed => maxBeltSpeed;
public AnimationCurve SpeedCurve => speedCurve;
public GarbageItemDefinition[] GarbageItems => garbageItems;
public float NormalCardWeight => normalCardWeight;
public float RareCardWeight => rareCardWeight;
public float LegendCardWeight => legendCardWeight;
public float GarbageWeight => garbageWeight;
public int CorrectSortPoints => correctSortPoints;
public int IncorrectSortPenalty => incorrectSortPenalty;
public int MissedItemPenalty => missedItemPenalty;
public int BoosterPacksPerCorrectItem => boosterPacksPerCorrectItem;
public override void OnValidate()
{
base.OnValidate();
gameDuration = Mathf.Max(1f, gameDuration);
initialBeltSpeed = Mathf.Max(0.1f, initialBeltSpeed);
maxBeltSpeed = Mathf.Max(initialBeltSpeed, maxBeltSpeed);
correctSortPoints = Mathf.Max(0, correctSortPoints);
boosterPacksPerCorrectItem = Mathf.Max(0, boosterPacksPerCorrectItem);
}
}
}

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: a0fd5f8ab5d74b12968501dd4e3cc416
timeCreated: 1763461789

View File

@@ -0,0 +1,39 @@
using Minigames.CardSorting.Data;
using UnityEngine;
namespace Core.Settings
{
/// <summary>
/// Settings interface for Card Sorting minigame.
/// Accessed via GameManager.GetSettingsObject&lt;ICardSortingSettings&gt;()
/// </summary>
public interface ICardSortingSettings
{
// Timing
float GameDuration { get; }
float SpawnDistance { get; }
// Conveyor Speed
float InitialBeltSpeed { get; }
float MaxBeltSpeed { get; }
AnimationCurve SpeedCurve { get; }
// Item Pools
GarbageItemDefinition[] GarbageItems { get; }
// Spawn Weights
float NormalCardWeight { get; }
float RareCardWeight { get; }
float LegendCardWeight { get; }
float GarbageWeight { get; }
// Scoring
int CorrectSortPoints { get; }
int IncorrectSortPenalty { get; }
int MissedItemPenalty { get; }
// Rewards
int BoosterPacksPerCorrectItem { get; }
}
}

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 646b90dfa92640e59430f871037affea
timeCreated: 1763461774