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(false); foreach (var b in all) { if (!b || b.type != type) continue; var rend = b.bottomMeshRenderer ? b.bottomMeshRenderer : b.GetComponentInChildren(); 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; } } } }