289 lines
11 KiB
C#
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;
|
|
}
|
|
}
|
|
}
|
|
}
|