MiniGames/Assets/Scripts/ClawGrab/ClawGameModeManager.cs
2025-09-06 23:30:06 +05:00

289 lines
11 KiB
C#

using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using TMPro;
public enum ClawGameMode { None, Frenzy, Precision, TargetChallenge, RandomMayhem }
public class ClawGameModeManager : MonoBehaviour
{
public static ClawGameModeManager Instance { get; private set; }
[Header("Scene References")]
public ClawController claw;
public PlatformSpinController platform;
public RoundTimer timer;
public ClawBubbleSpawner spawner;
public ClawScoreManager score;
[Header("UI (optional)")]
public TextMeshProUGUI modeLabel;
public TextMeshProUGUI subLabel;
[Header("Precision Mode")]
public int precisionMaxAttempts = 10;
public ClawBubbleType precisionTargetType = ClawBubbleType.Wolf; // “highlighted” type
public int precisionWrongPenalty = 50;
public bool precisionChangeTargetEveryHit = true;
public Color precisionHighlightColor = new Color(1f, 0.95f, 0f, 1f); // yellow
[Header("Target Challenge")]
public ClawBubbleType targetWolfType = ClawBubbleType.Wolf; // or GoldenWolf
public int targetRequiredCount = 5;
public int targetSetBonus = 500;
public int targetWrongPenalty = 50;
public Color targetHighlightColor = new Color(0.4f, 1f, 1f, 1f); // cyan
[Header("Random Mayhem")]
public Vector2 mayhemIntervalRange = new Vector2(2f, 4f);
public Vector2 mayhemEffectDurationRange = new Vector2(1.5f, 4f);
public float mayhemTurboScalarSeconds = 4f;
public float mayhemSlowScalarSeconds = 4f;
public float mayhemFreezeSeconds = 2f;
public float mayhemJamSeconds = 2f;
public float mayhemDisableSeconds = 2f;
public ClawGameMode CurrentMode { get; private set; } = ClawGameMode.None;
// state
int _precisionAttemptsLeft;
ClawBubbleType _precisionCurrentType;
int _targetCollected;
Coroutine _mayhemCo;
void Awake()
{
Instance = this;
// keep the room idle until a mode is picked
if (spawner) spawner.enabled = false;
}
void OnEnable()
{
if (!score) score = ClawScoreManager.Instance;
if (score) score.OnScoreAdded += HandleAnyScoreDelta; // just to keep a pulse; real logic is per-mode below
}
void OnDisable()
{
if (score) score.OnScoreAdded -= HandleAnyScoreDelta;
if (Instance == this) Instance = null;
}
// -------- UI hooks (wire these to your 4 buttons) --------
public void StartFrenzyMode() => StartMode(ClawGameMode.Frenzy);
public void StartPrecisionMode() => StartMode(ClawGameMode.Precision);
public void StartTargetChallengeMode() => StartMode(ClawGameMode.TargetChallenge);
public void StartRandomMayhemMode() => StartMode(ClawGameMode.RandomMayhem);
public void StartMode(ClawGameMode mode)
{
StopAllModeEffects();
CurrentMode = mode;
if (spawner && !spawner.enabled) spawner.enabled = true;
// Ensure claw is enabled at start of any mode
claw?.ForceClearJam();
claw?.ForceEnableControl();
switch (mode)
{
case ClawGameMode.Frenzy:
if (modeLabel) modeLabel.text = "Mode: Frenzy";
if (platform) platform.StartFrenzy();
if (subLabel) subLabel.text = "";
break;
case ClawGameMode.Precision:
if (modeLabel) modeLabel.text = "Mode: Precision";
_precisionAttemptsLeft = Mathf.Max(1, precisionMaxAttempts);
_precisionCurrentType = precisionTargetType;
UpdateSub($"Attempts: {_precisionAttemptsLeft} | Target: {_precisionCurrentType}");
HighlightType(_precisionCurrentType, precisionHighlightColor, true);
break;
case ClawGameMode.TargetChallenge:
if (modeLabel) modeLabel.text = "Mode: Target Challenge";
_targetCollected = 0;
UpdateSub($"Collect {_targetCollected}/{targetRequiredCount} {targetWolfType}");
HighlightType(targetWolfType, targetHighlightColor, true);
break;
case ClawGameMode.RandomMayhem:
if (modeLabel) modeLabel.text = "Mode: Random Mayhem";
_mayhemCo = StartCoroutine(MayhemLoop());
UpdateSub("");
break;
default:
if (modeLabel) modeLabel.text = "Mode: None";
UpdateSub("");
break;
}
// fresh timer start if you want it to restart when you pick a mode
if (timer && timer.autoStart) { timer.StopTimer(); timer.StartTimer(); }
}
// ===== ClawScoreManager -> hook points =====
// Called *before* ScoreManager adds points. Return the points you want applied (can be negative for penalties).
public int ModifyPointsBeforeApply(ClawBubbleType type, int currentPoints)
{
switch (CurrentMode)
{
case ClawGameMode.Precision:
if (type != _precisionCurrentType) return -Mathf.Abs(precisionWrongPenalty);
break;
case ClawGameMode.TargetChallenge:
if (type != targetWolfType) return -Mathf.Abs(targetWrongPenalty);
break;
}
return currentPoints;
}
// Called right after ScoreManager applies the delta, so we can update per-mode state.
public void NotifyBubbleResolved(ClawBubbleType type, int awarded)
{
switch (CurrentMode)
{
//case ClawGameMode.Precision:
// _precisionAttemptsLeft = Mathf.Max(0, _precisionAttemptsLeft - 1);
// if (awarded > 0 && precisionChangeTargetEveryHit)
// {
// _precisionCurrentType = NextTargetType(_precisionCurrentType);
// HighlightType(_precisionCurrentType, precisionHighlightColor, true);
// }
// UpdateSub($"Attempts: {_precisionAttemptsLeft} | Target: {_precisionCurrentType}");
// if (_precisionAttemptsLeft <= 0) EndPrecisionRound();
// break;
case ClawGameMode.Precision:
if (awarded > 0 && precisionChangeTargetEveryHit)
{
_precisionCurrentType = NextTargetType(_precisionCurrentType);
HighlightType(_precisionCurrentType, precisionHighlightColor, true);
}
UpdateSub($"Attempts: {_precisionAttemptsLeft} | Target: {_precisionCurrentType}");
break;
case ClawGameMode.TargetChallenge:
if (type == targetWolfType && awarded > 0)
{
_targetCollected++;
UpdateSub($"Collect {_targetCollected}/{targetRequiredCount} {targetWolfType}");
if (_targetCollected >= targetRequiredCount)
{
// give set bonus
if (score) score.ApplyExternalDelta?.Invoke(targetSetBonus);
HighlightType(targetWolfType, targetHighlightColor, false);
CurrentMode = ClawGameMode.None;
UpdateSub("Set completed!");
}
}
break;
}
}
// ——— helpers ———
void EndPrecisionRound()
{
if (claw) claw.ApplyDisable(9999f); // lock input
if (platform) platform.ApplySlow(2f);
UpdateSub("Out of attempts!");
// (you can also StopTimer or pop a panel here if you like)
}
void StopAllModeEffects()
{
HighlightType(_precisionCurrentType, precisionHighlightColor, false);
HighlightType(targetWolfType, targetHighlightColor, false);
platform?.StopFrenzy();
if (_mayhemCo != null) StopCoroutine(_mayhemCo);
_mayhemCo = null;
claw?.ForceClearJam();
claw?.ForceEnableControl();
}
//void StopAllModeEffects()
//{
// HighlightType(_precisionCurrentType, precisionHighlightColor, false);
// HighlightType(targetWolfType, targetHighlightColor, false);
// if (platform) platform.StopFrenzy();
// if (_mayhemCo != null) StopCoroutine(_mayhemCo);
// _mayhemCo = null;
// if (claw) claw.ApplyDisable(0f); // ensure re-enabled
//}
void UpdateSub(string s) { if (subLabel) subLabel.text = s; }
void HandleAnyScoreDelta(int _) { /* placeholder; not used now */ }
public void NotifyDropAttempt()
{
if (CurrentMode == ClawGameMode.Precision)
{
_precisionAttemptsLeft = Mathf.Max(0, _precisionAttemptsLeft - 1);
UpdateSub($"Attempts: {_precisionAttemptsLeft} | Target: {_precisionCurrentType}");
if (_precisionAttemptsLeft <= 0) EndPrecisionRound();
}
}
public void NotifyMiss()
{
if (CurrentMode == ClawGameMode.Precision)
{
// “Missing reduces score”
score?.ApplyExternalDelta?.Invoke(-Mathf.Abs(precisionWrongPenalty));
}
}
public void NotifyGrabbed(ClawBubbleType type)
{
// Optional hook if you ever want immediate feedback on the grab itself.
// (We still keep your scoring logic in ModifyPointsBeforeApply/NotifyBubbleResolved)
}
ClawBubbleType NextTargetType(ClawBubbleType t)
{
switch (t)
{
case ClawBubbleType.Wolf: return ClawBubbleType.Star;
case ClawBubbleType.Star: return ClawBubbleType.Crystal;
case ClawBubbleType.Crystal: return ClawBubbleType.Wolf;
default: return ClawBubbleType.Wolf;
}
}
void HighlightType(ClawBubbleType type, Color color, bool on)
{
var all = FindObjectsOfType<ClawBubble>(false);
foreach (var b in all)
{
if (!b || b.type != type) continue;
var rend = b.bottomMeshRenderer ? b.bottomMeshRenderer : b.GetComponentInChildren<MeshRenderer>();
if (!rend) continue;
var mpb = new MaterialPropertyBlock();
rend.GetPropertyBlock(mpb);
mpb.SetColor("_EmissionColor", on ? color : Color.black);
rend.SetPropertyBlock(mpb);
}
}
IEnumerator MayhemLoop()
{
while (true)
{
yield return new WaitForSeconds(Random.Range(mayhemIntervalRange.x, mayhemIntervalRange.y));
float dur = Random.Range(mayhemEffectDurationRange.x, mayhemEffectDurationRange.y);
switch (Random.Range(0, 6))
{
case 0: if (platform) platform.ApplyReverse(dur); break;
case 1: if (platform) platform.ApplyTurbo(mayhemTurboScalarSeconds); break;
case 2: if (platform) platform.ApplySlow(mayhemSlowScalarSeconds); break;
case 3: if (platform) platform.ApplyFreeze(mayhemFreezeSeconds); break;
case 4: if (claw) claw.ApplyJam(mayhemJamSeconds); break;
case 5: if (claw) claw.ApplyDisable(mayhemDisableSeconds); break;
}
}
}
}