MiniGames/Assets/Scripts/ClawGrab/ClawGameModeManager.cs

619 lines
24 KiB
C#
Raw Normal View History

2025-09-06 23:30:06 +05:00
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; // <20>highlighted<65> 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();
2025-09-22 17:26:19 +05:00
int typeCount = System.Enum.GetValues(typeof(ClawBubbleType)).Length;
precisionTargetType = (ClawBubbleType)Random.Range(0, typeCount);
targetWolfType = (ClawBubbleType)Random.Range(0, typeCount);
Debug.Log("Precision Target is: " + precisionTargetType.ToString());
2025-09-06 23:30:06 +05:00
switch (mode)
{
case ClawGameMode.Frenzy:
if (modeLabel) modeLabel.text = "Mode: Frenzy";
if (platform) platform.StartFrenzy();
if (subLabel) subLabel.text = "";
break;
2025-09-22 17:26:19 +05:00
2025-09-06 23:30:06 +05:00
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);
2025-09-22 17:26:19 +05:00
// Guarantee at least one target bubble is present right away
spawner?.EnsureTypePresent(_precisionCurrentType);
// right after EnsureTypePresent:
spawner?.QueueType(_precisionCurrentType, 2); // e.g., next two spawns are also target
2025-09-06 23:30:06 +05:00
break;
2025-09-22 17:26:19 +05:00
//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;
2025-09-06 23:30:06 +05:00
case ClawGameMode.TargetChallenge:
if (modeLabel) modeLabel.text = "Mode: Target Challenge";
_targetCollected = 0;
UpdateSub($"Collect {_targetCollected}/{targetRequiredCount} {targetWolfType}");
HighlightType(targetWolfType, targetHighlightColor, true);
2025-09-22 17:26:19 +05:00
spawner?.EnsureTypePresent(targetWolfType);
// right after EnsureTypePresent:
spawner?.QueueType(targetWolfType, 2);
2025-09-06 23:30:06 +05:00
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;
}
}
// <20><><EFBFBD> helpers <20><><EFBFBD>
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)
{
// <20>Missing reduces score<72>
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;
}
}
}
}
2025-09-22 17:26:19 +05:00
//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; // <20>highlighted<65> 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();
// int typeCount = System.Enum.GetValues(typeof(ClawBubbleType)).Length;
// precisionTargetType = (ClawBubbleType)Random.Range(0, typeCount);
// Debug.Log("Precision Target is: " + precisionTargetType.ToString());
// 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);
// // Guarantee at least one target bubble is present right away
// spawner?.EnsureTypePresent(_precisionCurrentType);
// // right after EnsureTypePresent:
// spawner?.QueueType(_precisionCurrentType, 2); // e.g., next two spawns are also target
// 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;
// }
// }
// // <20><><EFBFBD> helpers <20><><EFBFBD>
// 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)
// {
// // <20>Missing reduces score<72>
// 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;
// }
// }
// }
//}