using System; using System.Collections.Generic; using DG.Tweening; using Monetization.Runtime.Ads; using MoreMountains.NiceVibrations; using UnityEngine; using UnityEngine.UI; public class GameManager : Singleton { public PhysicsMaterial2D lineDrawPhysics2dMat; public EnvironmentClass[] environmentSkinsList; public static Action OnGameStarts; public static Action OnStoreClosed; public static Action OnLevelComplete; public static Action OnNewEnemyUnlocked; public static Action OnGameComplete; public static Action OnLevelFailed; public static Action OnNoInternetAvailable; public static Action OnLineDrawingStarts; public static Action OnLineDrawingComplete; public static Action OnEnemyHit; public static Action OnPointDraw; public static Action OnHintShowCalled; public static Action OnHintHideCalled; public static Action OnCoinGrant; public static List EnemyList = new List(); public static List FriendList = new List(); public static Action OnMusicToggle; public static Action OnSoundAudioToggle; public static Action OnLevelReload; public static Action OnShopItemSelection; public static Action OnEnvironmentChange; public Image flashScreenPanel; public Image bloodFadeOverlay; private bool isInit; public Button[] gameplayUiBtns; public Button skinBtn; public GameObject lineParentTr; [Header("UI Slide Out Animation")] public RectTransform[] leftSideUI; public RectTransform[] rightSideUI; public RectTransform levelNumBar; public GameObject happyEmojis; public GameObject sadEmojis; public Button hintBtn; public GameObject hintRewardedIcon; public GameObject noOfHintsObj; public Text noOfHintsText; public CanvasGroup hintGlowCanvasGroup; public ParticleSystem hintSparkleParticles; [Header("Splash Canvas (shown before interstitial ad)")] public GameObject splashCanvas; [Header("Confetti Win GO (Is_PanelTest == 3)")] public GameObject confettiOnWin; public static bool isGamePlayedOnce = false; public static bool anyFriendDied = false; private bool isEmojiSpawned; public GameObject storePanelObj; private bool rewardedHintVideoClicked; private Color _hintGlowBaseColor; private bool _hintGlowColorCached; private bool isLevelFailed; private bool isLevelCompleted; private bool isShowingPopUp; private static int lastFailedLevelNum_PanelTest4 = -1; private static int _failAttemptLevel = -1; private static int _failAttemptCount = 0; public bool IsGameEnded => isLevelFailed || isLevelCompleted; public static int FreeHintsUsed { get { if (PlayerPrefs.GetInt("FirstHintFree", 0) == 1 && PlayerPrefs.GetInt("FreeHintsMigrated", 0) == 0) { PlayerPrefs.SetInt("FreeHintsUsed", Mathf.Max(PlayerPrefs.GetInt("FreeHintsUsed", 0), 1)); PlayerPrefs.SetInt("FreeHintsMigrated", 1); PlayerPrefs.Save(); } return PlayerPrefs.GetInt("FreeHintsUsed", 0); } } public static bool FreeHintsRemaining => FreeHintsUsed < AdConstants.free_hints_count + BonusFreeHints; public static int BonusFreeHints { get { return PlayerPrefs.GetInt("BonusFreeHints", 0); } set { PlayerPrefs.SetInt("BonusFreeHints", value); PlayerPrefs.Save(); } } private void Start() { if (!AdConstants.AdsRemoved && (AdConstants.Is_PanelTest == 2 || AdConstants.Is_PanelTest == 3 || AdConstants.Is_PanelTest == 4)) { AdsManager.HideMRec(); if (UiManager.Instance != null) { UiManager.Instance.BannerPati.SetActive(true); } } InitGame(); } private void InitGame() { if (isInit) { return; } print("Game Started"); AppConstants.IsDialogueOpened = false; if (PlayerPrefs.GetInt("CurrentZoneLevel" + AppConstants.currentCharacterIndex) == 0) { PlayerPrefs.SetInt("CurrentZoneLevel" + AppConstants.currentCharacterIndex, 1); } anyFriendDied = false; isLevelFailed = false; isLevelCompleted = false; if (hintBtn != null && PlayerPrefs.GetInt("HintBtnUnlocked", 0) == 0) { hintBtn.gameObject.SetActive(false); } RefreshHintCounterDisplay(); Invoke("StartGame", 0.1f); if (isGamePlayedOnce) { if (PlayerPrefs.GetInt("IsRated") == 0 && !AppConstants.isRetryingLevel && Array.IndexOf(AppConstants.RatePanelLevels, PersistableData.Instance.itemsData.currentLevelNumProgressive) >= 0) { UiManager.Instance.ShowRatePopUp(); } if (PersistableData.Instance.itemsData.currentLevelNumProgressive % AppConstants.ShowNewSkinAtLevel != 0 && LevelManager.currentLevel == 6 && PlayerPrefs.GetInt("CurrentLevelNum") == 5 && PlayerPrefs.GetInt("ShopIndicationShown") == 0) { PlayerPrefs.SetInt("ShopIndicationShown", 1); Invoke("OpenShopStoreWithTutorialPanel", 0.5f); } } isInit = true; } private void OpenShopStoreWithTutorialPanel() { SoundManager soundManager = SoundManager.instance; if (soundManager != null && soundManager.gameSoundSFX != null) { soundManager.PlaySFX_UI(soundManager.gameSoundSFX.TutorialScreenAppear, 1f); } storePanelObj.gameObject.SetActive(true); } private void OnEnable() { OnLineDrawingStarts += OnHideGameUi; OnEnemyHit += OnEnemyHitEffect; OnGameComplete += OnGameCompletion; OnLineDrawingComplete += CheckFriendOnlyLevel; } private void OnDisable() { OnLineDrawingStarts -= OnHideGameUi; OnGameComplete -= OnGameCompletion; OnEnemyHit -= OnEnemyHitEffect; OnLineDrawingComplete -= CheckFriendOnlyLevel; } public void SpawnEmoji(GameObject emojiPrefab) { if (!isEmojiSpawned) { Instantiate(emojiPrefab); isEmojiSpawned = true; } } private void CheckFriendOnlyLevel() { if (LevelScript.Instance == null) { return; } if (!LevelScript.Instance.isFriendLevel) { return; } if (EnemyList.Count != 0) { return; } if (FriendList.Count < 1) { return; } Invoke("TryCompleteFriendOnlyLevel", LevelScript.Instance.friendOnlyCompleteDelay); } private void TryCompleteFriendOnlyLevel() { if (!isLevelFailed && !isLevelCompleted && !anyFriendDied) { CheckLevelComplete(); } } private void OnEnemyHitEffect() { } private void StartGame() { OnGameStarts?.Invoke(); } public void IsObjectDropCompleted() { AppConstants.Haptic(HapticTypes.LightImpact); Invoke("changeAction", 1.5f); } private void changeAction() { if (CharacterAction.EnemyAction != null) { CharacterAction.EnemyAction(3); } } public void ShowHint() { if (rewardedHintVideoClicked) { return; } UiManager.Instance.SettingPanelAnim.SetBool("SettingIn", false); UiManager.Instance.SettingPanelAnim.SetBool("SettingOut", true); UiManager.Instance.isSettingsOpen = false; if (FreeHintsRemaining) { int num = FreeHintsUsed + 1; PlayerPrefs.SetInt("FreeHintsUsed", num); PlayerPrefs.Save(); LevelAnalytics.Send("Hint_Free_" + num); HintGranted(); return; } LevelAnalytics.Send("Hint_Watch"); HintGranted(); } private void HintGranted() { if (isLevelCompleted) { return; } AppConstants.Haptic(HapticTypes.Selection); SoundManager soundManager = SoundManager.instance; if (soundManager != null && soundManager.gameSoundSFX != null) { soundManager.PlaySFX_UI(soundManager.gameSoundSFX.hintShownSound, 1f); } OnHintShowCalled?.Invoke(); hintBtn.transform.DOKill(false); hintBtn.transform.localScale = Vector3.one; StopHintGlowAnim(); hintBtn.gameObject.SetActive(false); if (LevelManager.instance.hintTutorialObj != null) { LevelManager.instance.hintTutorialObj.SetActive(false); } if (hintRewardedIcon != null) { hintRewardedIcon.SetActive(true); } PlayerPrefs.SetInt("HintWatched_" + LevelManager.instance.currentLevelNumberToShow, 1); PlayerPrefs.Save(); rewardedHintVideoClicked = false; } private void ResetShowHintBtnClickAgain() { rewardedHintVideoClicked = false; } public void ShowHintButton(bool playBreath = false) { hintBtn.gameObject.SetActive(true); hintBtn.transform.DOKill(false); hintBtn.transform.localScale = Vector3.one; bool freeHintsRemaining = FreeHintsRemaining; if (hintRewardedIcon != null) { hintRewardedIcon.SetActive(!freeHintsRemaining); } if (noOfHintsObj != null) { noOfHintsObj.SetActive(freeHintsRemaining); } if (noOfHintsText != null && freeHintsRemaining) { noOfHintsText.text = (BonusFreeHints + AdConstants.free_hints_count - FreeHintsUsed).ToString(); } if (!freeHintsRemaining && playBreath) { StartHintBreathAnim(); } else { StopHintGlowAnim(); } } public void RefreshHintCounterDisplay() { if (hintBtn == null) { return; } bool freeHintsRemaining = FreeHintsRemaining; if (hintRewardedIcon != null) { hintRewardedIcon.SetActive(!freeHintsRemaining); } if (noOfHintsObj != null) { noOfHintsObj.SetActive(freeHintsRemaining); } if (noOfHintsText != null && freeHintsRemaining) { noOfHintsText.text = (BonusFreeHints + AdConstants.free_hints_count - FreeHintsUsed).ToString(); } } private void StartHintBreathAnim() { if (hintGlowCanvasGroup == null) { return; } hintGlowCanvasGroup.DOKill(false); hintGlowCanvasGroup.alpha = 1f; int step = 0; hintGlowCanvasGroup.DOFade(0f, 1f).SetLoops(-1, LoopType.Yoyo).SetEase(Ease.InOutSine) .OnStepComplete(delegate { step++; if (step % 2 == 0 && hintSparkleParticles != null) { hintSparkleParticles.Play(); } }); Image image = hintGlowCanvasGroup.GetComponent(); if (image != null) { if (!_hintGlowColorCached) { _hintGlowBaseColor = image.color; _hintGlowColorCached = true; } image.DOKill(false); image.DOColor(new Color(Mathf.Min(_hintGlowBaseColor.r * 1.15f, 1f), Mathf.Min(_hintGlowBaseColor.g * 1.05f, 1f), Mathf.Min(_hintGlowBaseColor.b * 1.4f, 1f), _hintGlowBaseColor.a), 1f).SetLoops(-1, LoopType.Yoyo) .SetEase(Ease.InOutSine); } } private void StopHintGlowAnim() { if (hintGlowCanvasGroup == null) { return; } hintGlowCanvasGroup.DOKill(false); hintGlowCanvasGroup.alpha = 1f; Image image = hintGlowCanvasGroup.GetComponent(); if (image != null) { image.DOKill(false); if (_hintGlowColorCached) { image.color = _hintGlowBaseColor; } } if (hintSparkleParticles != null) { hintSparkleParticles.Stop(); } } public void ShowHintThroughCode() { OnHintShowCalled?.Invoke(); hintBtn.transform.DOKill(false); hintBtn.transform.localScale = Vector3.one; StopHintGlowAnim(); hintBtn.gameObject.SetActive(false); } private void OnGameCompletion() { skinBtn.interactable = false; isLevelCompleted = true; } private void OnHideGameUi() { for (int i = 0; i < leftSideUI.Length; i++) { RectTransform rt = leftSideUI[i]; if (!(rt == null)) { rt.DOAnchorPosX(rt.anchoredPosition.x + -500f, 0.5f).SetEase(Ease.InBack).OnComplete(delegate { rt.gameObject.SetActive(false); }); } } for (int j = 0; j < rightSideUI.Length; j++) { RectTransform rt2 = rightSideUI[j]; if (!(rt2 == null)) { rt2.DOAnchorPosX(rt2.anchoredPosition.x + 500f, 0.5f).SetEase(Ease.InBack).OnComplete(delegate { rt2.gameObject.SetActive(false); }); } } if (levelNumBar != null) { levelNumBar.DOAnchorPosY(levelNumBar.anchoredPosition.y + 500f, 0.5f).SetEase(Ease.InBack).OnComplete(delegate { levelNumBar.gameObject.SetActive(false); }); } } public void CheckLevelFailed() { if (isLevelFailed || isLevelCompleted) { return; } if (EnemyList.Count < 1) { return; } AppConstants.isLevelFailedOnce = true; isLevelFailed = true; ShowLevelFailed(); } public void CheckLevelFailedFreind() { if (isLevelFailed) { return; } anyFriendDied = true; isLevelFailed = true; isLevelCompleted = true; CancelInvoke("ShowLevelCompleteScreen"); CancelInvoke("ShowLevelComplete"); Invoke("ShowLevelFailed", 0.5f); } private void ShowLevelFailed() { OnLevelFailed?.Invoke(); AppConstants.Haptic(HapticTypes.HeavyImpact); ShowLevelFailedScreen(); if (SoundManager.instance != null) { SoundManager.instance.StopMusic(); } } private void ConfettiSound() { SoundManager soundManager = SoundManager.instance; if (soundManager != null && soundManager.gameSoundSFX != null) { soundManager.PlaySFX_UI(soundManager.gameSoundSFX.confettiSound, 1f); } Invoke("BGMUsic", 2f); } private void BGMUsic() { SoundManager soundManager = SoundManager.instance; if (soundManager != null) { soundManager.ChangeMusicWithTransition(soundManager.mainMenuMusicClip); } } public void CheckLevelComplete() { if (isLevelFailed || isLevelCompleted) { return; } if (anyFriendDied) { return; } if (EnemyList.Count > 0) { return; } isLevelCompleted = true; OnLevelComplete?.Invoke(); CancelInvoke("CheckLevelFailed"); CancelInvoke("ShowLevelFailed"); ShowLevelCompleteScreen(); } private void ShowLevelCompleteScreen() { if (isLevelFailed || anyFriendDied) { return; } isGamePlayedOnce = true; OnGameComplete?.Invoke(); CancelInvoke("CheckLevelFailed"); CancelInvoke("ShowLevelFailed"); SoundManager soundManager = SoundManager.instance; if (soundManager != null && soundManager.gameSoundSFX != null) { soundManager.PlaySFX_UI(soundManager.gameSoundSFX.winSfx, 1f); } ConfettiSound(); ShowLevelComplete(); } private void ShowLevelComplete() { AppConstants.levelsSinceLastInterstitial++; LevelAnalytics.Send("Level_Comp_PT" + AdConstants.Is_PanelTest); AppConstants.Haptic(HapticTypes.HeavyImpact); if (LevelScript.Instance.levelType != LevelType.Pendulum && BeadDrawer.instance != null) { BeadDrawer.instance.SetLineStatic(); } SoundManager.instance.StopMusic(); if (AdConstants.Is_PanelTest == 3 || AdConstants.Is_PanelTest == 4) { if (confettiOnWin != null) { confettiOnWin.SetActive(true); } if (LevelManager.instance != null) { LevelManager.instance.SetupCompScreenConfettiTest(); } return; } UiManager.Instance.LevelCompletePanel.gameObject.SetActive(true); if (!AdConstants.AdsRemoved && (AdConstants.Is_PanelTest == 2 || AdConstants.Is_PanelTest == 3) && AdConstants.ShowMrecOnPanels) { AdsManager.HideBanner(); if (UiManager.Instance != null) { UiManager.Instance.BannerPati.SetActive(false); } AdsManager.RepositionMRec(MRecPosition.Bottom); AdsManager.ShowMRec(); } if (AdConstants.Is_PanelTest != 1) { LevelManager.instance.SetupCompScreenNoPanelTest(); } } private void ShowLevelFailedScreen() { LevelManager levelManager = LevelManager.instance; int currentLevelNumberToShow = levelManager.currentLevelNumberToShow; if (_failAttemptLevel != currentLevelNumberToShow) { _failAttemptLevel = currentLevelNumberToShow; _failAttemptCount = 0; } _failAttemptCount++; LevelAnalytics.Send("Level_Fail_PT" + AdConstants.Is_PanelTest, "Attempt_" + _failAttemptCount); if (AdConstants.Is_PanelTest == 4) { if (lastFailedLevelNum_PanelTest4 == LevelManager.instance.currentLevelNumberToShow) { SoundManager soundManager = SoundManager.instance; if (soundManager != null && soundManager.gameSoundSFX != null) { soundManager.PlaySFX_UI(soundManager.gameSoundSFX.looseSfx, 1f); } if (bloodFadeOverlay != null) { bloodFadeOverlay.gameObject.SetActive(true); Color color = bloodFadeOverlay.color; color.a = 0f; bloodFadeOverlay.color = color; bloodFadeOverlay.DOKill(false); bloodFadeOverlay.DOFade(0.8823529f, 1.5f).OnComplete(delegate { LevelManager.instance.ReloadLevelSilently(); }); } else { LevelManager.instance.ReloadLevelSilently(); } return; } lastFailedLevelNum_PanelTest4 = LevelManager.instance.currentLevelNumberToShow; } if (LevelScript.Instance.levelType != LevelType.Pendulum && BeadDrawer.instance != null) { BeadDrawer.instance.SetLineStatic(); } UiManager.Instance.LevelFailedPanel.gameObject.SetActive(true); if (!AdConstants.AdsRemoved && (AdConstants.Is_PanelTest == 2 || AdConstants.Is_PanelTest == 3 || AdConstants.Is_PanelTest == 4) && AdConstants.ShowMrecOnPanels) { AdsManager.HideBanner(); if (UiManager.Instance != null) { UiManager.Instance.BannerPati.SetActive(false); } AdsManager.RepositionMRec(MRecPosition.Bottom); AdsManager.ShowMRec(); } if (UiManager.Instance.reloadBtnRect != null) { UiManager.Instance.reloadBtnRect.gameObject.SetActive(false); } SoundManager soundManager2 = SoundManager.instance; if (soundManager2 != null && soundManager2.gameSoundSFX != null) { soundManager2.PlaySFX_UI(soundManager2.gameSoundSFX.looseSfx, 1f); } PlayerPrefs.SetInt("EverFailed", 1); PlayerPrefs.Save(); bool flag = LevelScript.Instance != null && LevelScript.Instance.isAutoHintLevel; UiManager.Instance.ShowFailButtons(flag); if (!flag) { PlayerPrefs.SetInt("HintBtnUnlocked", 1); PlayerPrefs.Save(); if (PlayerPrefs.GetInt("HintWatched_" + LevelManager.instance.currentLevelNumberToShow, 0) != 1) { ShowHintButton(true); } } if (AdConstants.Is_PanelTest != 1) { LevelManager.instance.SetupFailScreenNoPanelTest(); } Invoke("BGMUsic", 3f); } public void WatchAdForHintsPanel() { LevelAnalytics.Send("HintsPanel_WatchAd"); OnHintsPanelRewardGranted(); } private void OnHintsPanelRewardGranted() { BonusFreeHints = BonusFreeHints + 3; LevelAnalytics.Send("HintsPanel_Rewarded"); ShowHintButton(false); UiManager.Instance.CloseHintsPanel(); } public void ShowInterstitialTimer(string eventName, Action rewardCallBack = null) { if (PlayerPrefs.GetInt("FirstAdShown", 0) == 0) { PlayerPrefs.SetInt("FirstAdShown", 1); PlayerPrefs.Save(); if (UiManager.Instance != null) { UiManager.Instance.ShowRemoveAdsBtn(); } } else if (AdConstants.Int_Level_Gap >= 1 && AppConstants.levelsSinceLastInterstitial < AdConstants.Int_Level_Gap) { return; } if (splashCanvas != null) { splashCanvas.SetActive(true); } AdsTimerAndCallBack.Instance.SetInterstitialFirstAdsWatchedStatus(GameType.DrawToCrash); if (LevelManager.instance != null) { AppConstants.lastIntAdShownLevel = LevelManager.instance.currentLevelNumberToShow; } LevelAnalytics.IntAdBefore(eventName); AppConstants.levelsSinceLastInterstitial = 0; LevelAnalytics.IntAdAfter(); if (rewardCallBack != null) { rewardCallBack(); } } public bool ShouldShowAd() { if (AdConstants.AdsRemoved) { return false; } if (PlayerPrefs.GetInt("FirstAdShown", 0) != 0) { return AdsTimerAndCallBack.Instance.ShouldShowAd(AdsTimerAndCallBack.Instance.gametype); } if (LevelManager.instance != null) { return LevelManager.instance.currentLevelNumberToShow >= AdConstants.first_interstitial_level; } return false; } }