Initial commit: Unity WordConnect project
This commit is contained in:
@ -0,0 +1,78 @@
|
||||
// // ©2015 - 2025 Candy Smith
|
||||
// // All rights reserved
|
||||
// // Redistribution of this software is strictly not allowed.
|
||||
// // Copy of this software can be obtained from unity asset store only.
|
||||
// // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// // FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// // THE SOFTWARE.
|
||||
|
||||
using UnityEngine;
|
||||
using UnityEngine.Audio;
|
||||
using UnityEngine.UI;
|
||||
using WordsToolkit.Scripts.Audio;
|
||||
|
||||
namespace WordsToolkit.Scripts.Popups
|
||||
{
|
||||
public class AudioSettingsUI : MonoBehaviour
|
||||
{
|
||||
[SerializeField]
|
||||
private Slider musicButton;
|
||||
|
||||
[SerializeField]
|
||||
private Slider soundButton;
|
||||
|
||||
[SerializeField]
|
||||
private AudioMixer mixer;
|
||||
|
||||
[SerializeField]
|
||||
private string musicParameter = "musicVolume";
|
||||
|
||||
[SerializeField]
|
||||
private string soundParameter = "soundVolume";
|
||||
|
||||
private void Start()
|
||||
{
|
||||
musicButton.onValueChanged.AddListener(ToggleMusic);
|
||||
soundButton.onValueChanged.AddListener(ToggleSound);
|
||||
OnEnable();
|
||||
}
|
||||
|
||||
private void OnEnable()
|
||||
{
|
||||
UpdateButtonState("Music", musicParameter);
|
||||
UpdateButtonState("Sound", soundParameter);
|
||||
}
|
||||
|
||||
private void UpdateButtonState(string playerPrefKey, string volumeParameter)
|
||||
{
|
||||
var enabledState = PlayerPrefs.GetInt(playerPrefKey, 1) != 0f;
|
||||
float volumeValue = enabledState ? 0 : -80;
|
||||
|
||||
mixer.SetFloat(volumeParameter, volumeValue);
|
||||
if (playerPrefKey == "Sound")
|
||||
{
|
||||
soundButton.value = enabledState ? 1 : 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
musicButton.value = enabledState ? 1 : 0;
|
||||
}
|
||||
}
|
||||
|
||||
private void ToggleMusic(float arg0)
|
||||
{
|
||||
PlayerPrefs.SetInt("Music", (int)arg0);
|
||||
OnEnable();
|
||||
}
|
||||
|
||||
private void ToggleSound(float arg0)
|
||||
{
|
||||
PlayerPrefs.SetInt("Sound", (int)arg0);
|
||||
OnEnable();
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 4884d074b935462cab770ad5d3b1e12d
|
||||
timeCreated: 1725698039
|
||||
32
Assets/WordConnectGameToolkit/Scripts/Popups/Banner.cs
Normal file
32
Assets/WordConnectGameToolkit/Scripts/Popups/Banner.cs
Normal file
@ -0,0 +1,32 @@
|
||||
// // ©2015 - 2025 Candy Smith
|
||||
// // All rights reserved
|
||||
// // Redistribution of this software is strictly not allowed.
|
||||
// // Copy of this software can be obtained from unity asset store only.
|
||||
// // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// // FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// // THE SOFTWARE.
|
||||
|
||||
using System.Collections;
|
||||
using UnityEngine;
|
||||
|
||||
namespace WordsToolkit.Scripts.Popups
|
||||
{
|
||||
public class Banner : Popup
|
||||
{
|
||||
public override void AfterShowAnimation()
|
||||
{
|
||||
base.AfterShowAnimation();
|
||||
StartCoroutine(Wait());
|
||||
}
|
||||
|
||||
protected virtual IEnumerator Wait()
|
||||
{
|
||||
yield return new WaitForSeconds(1.8f);
|
||||
Close();
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 0842f95857d34b26adc08a0a1fd9f297
|
||||
timeCreated: 1729076105
|
||||
98
Assets/WordConnectGameToolkit/Scripts/Popups/CoinsShop.cs
Normal file
98
Assets/WordConnectGameToolkit/Scripts/Popups/CoinsShop.cs
Normal file
@ -0,0 +1,98 @@
|
||||
// // ©2015 - 2025 Candy Smith
|
||||
// // All rights reserved
|
||||
// // Redistribution of this software is strictly not allowed.
|
||||
// // Copy of this software can be obtained from unity asset store only.
|
||||
// // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// // FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// // THE SOFTWARE.
|
||||
|
||||
using System.Linq;
|
||||
using UnityEngine;
|
||||
using UnityEngine.Serialization;
|
||||
using WordsToolkit.Scripts.Audio;
|
||||
using WordsToolkit.Scripts.Data;
|
||||
using WordsToolkit.Scripts.Enums;
|
||||
using WordsToolkit.Scripts.GUI;
|
||||
using WordsToolkit.Scripts.GUI.Labels;
|
||||
using WordsToolkit.Scripts.Services;
|
||||
using WordsToolkit.Scripts.Services.IAP;
|
||||
using WordsToolkit.Scripts.Settings;
|
||||
using WordsToolkit.Scripts.System;
|
||||
|
||||
namespace WordsToolkit.Scripts.Popups
|
||||
{
|
||||
public class CoinsShop : PopupWithCurrencyLabel
|
||||
{
|
||||
public ItemPurchase[] packs;
|
||||
private CoinsShopSettings shopSettings;
|
||||
public ProductID noAdsProduct;
|
||||
[SerializeField]
|
||||
private AudioClip coinsSound;
|
||||
|
||||
private void OnEnable()
|
||||
{
|
||||
shopSettings = Resources.Load<CoinsShopSettings>("Settings/CoinsShopSettings");
|
||||
foreach (var itemPurchase in packs)
|
||||
{
|
||||
if (shopSettings.coinsProducts.Count > 0)
|
||||
{
|
||||
var productID = itemPurchase.productID;
|
||||
if (shopSettings.coinsProducts.TryToGetPair(kvp => kvp.Key == productID, out var settingsShopItem))
|
||||
{
|
||||
itemPurchase.Init(settingsShopItem, iapManager);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
EventManager.GetEvent<string>(EGameEvent.PurchaseSucceeded).Subscribe(PurchaseSucceded);
|
||||
}
|
||||
|
||||
private void OnDisable()
|
||||
{
|
||||
EventManager.GetEvent<string>(EGameEvent.PurchaseSucceeded).Unsubscribe(PurchaseSucceded);
|
||||
}
|
||||
|
||||
private void PurchaseSucceded(string id)
|
||||
{
|
||||
var shopItem = packs.First(i => i.productID.ID == id);
|
||||
var count = shopItem.settingsShopItem.Value;
|
||||
shopItem.resource.AddAnimated(count, shopItem.BuyItemButton.transform.position, animationSourceObject: null, callback: () =>
|
||||
{
|
||||
GetComponentInParent<Popup>().CloseDelay();
|
||||
});
|
||||
|
||||
// If the item is non-consumable, mark it as purchased
|
||||
if (shopItem.productID.productType == ProductTypeWrapper.ProductType.NonConsumable)
|
||||
{
|
||||
PlayerPrefs.SetInt("Purchased_" + id, 1);
|
||||
PlayerPrefs.Save();
|
||||
|
||||
// Disable the button for this item
|
||||
var pack = shopItem;
|
||||
if (pack.BuyItemButton != null)
|
||||
{
|
||||
pack.BuyItemButton.interactable = false;
|
||||
}
|
||||
}
|
||||
if (id == noAdsProduct.ID)
|
||||
{
|
||||
adsManager.RemoveAds();
|
||||
Close();
|
||||
}
|
||||
}
|
||||
|
||||
public void BuyCoins(string id)
|
||||
{
|
||||
// StopInteration();
|
||||
#if UNITY_WEBGL
|
||||
gameManager.PurchaseSucceeded(id);
|
||||
#else
|
||||
iapManager.BuyProduct(id);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 0a33f6f1229248adabe29300449199f1
|
||||
timeCreated: 1725686485
|
||||
43
Assets/WordConnectGameToolkit/Scripts/Popups/ComingSoon.cs
Normal file
43
Assets/WordConnectGameToolkit/Scripts/Popups/ComingSoon.cs
Normal file
@ -0,0 +1,43 @@
|
||||
// // ©2015 - 2025 Candy Smith
|
||||
// // All rights reserved
|
||||
// // Redistribution of this software is strictly not allowed.
|
||||
// // Copy of this software can be obtained from unity asset store only.
|
||||
// // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// // FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// // THE SOFTWARE.
|
||||
|
||||
using WordsToolkit.Scripts.GUI.Buttons;
|
||||
|
||||
namespace WordsToolkit.Scripts.Popups
|
||||
{
|
||||
public class ComingSoon : Popup
|
||||
{
|
||||
public CustomButton mainMenuButton;
|
||||
|
||||
protected override void Awake()
|
||||
{
|
||||
base.Awake();
|
||||
if (mainMenuButton != null)
|
||||
{
|
||||
mainMenuButton.onClick.AddListener(() =>
|
||||
{
|
||||
gameManager.MainMenu();
|
||||
Close();
|
||||
});
|
||||
}
|
||||
|
||||
if (closeButton != null)
|
||||
{
|
||||
closeButton.onClick.AddListener(() =>
|
||||
{
|
||||
gameManager.MainMenu();
|
||||
Close();
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 7d297a58e25c40c59b0c113a9cdc59e7
|
||||
timeCreated: 1753958487
|
||||
44
Assets/WordConnectGameToolkit/Scripts/Popups/Confirmation.cs
Normal file
44
Assets/WordConnectGameToolkit/Scripts/Popups/Confirmation.cs
Normal file
@ -0,0 +1,44 @@
|
||||
// // ©2015 - 2025 Candy Smith
|
||||
// // All rights reserved
|
||||
// // Redistribution of this software is strictly not allowed.
|
||||
// // Copy of this software can be obtained from unity asset store only.
|
||||
// // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// // FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// // THE SOFTWARE.
|
||||
|
||||
using WordsToolkit.Scripts.GUI;
|
||||
using WordsToolkit.Scripts.GUI.Buttons;
|
||||
|
||||
namespace WordsToolkit.Scripts.Popups
|
||||
{
|
||||
public class Confirmation : Popup
|
||||
{
|
||||
public CustomButton yesButton;
|
||||
|
||||
private void OnEnable()
|
||||
{
|
||||
yesButton.onClick.AddListener(Yes);
|
||||
closeButton.onClick.AddListener(No);
|
||||
}
|
||||
|
||||
private void No()
|
||||
{
|
||||
StopInteration();
|
||||
|
||||
result = EPopupResult.No;
|
||||
Close();
|
||||
}
|
||||
|
||||
private void Yes()
|
||||
{
|
||||
StopInteration();
|
||||
|
||||
result = EPopupResult.Yes;
|
||||
Close();
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 683c1c93877244efba6c4bddd411a3bb
|
||||
timeCreated: 1725698320
|
||||
8
Assets/WordConnectGameToolkit/Scripts/Popups/Daily.meta
Normal file
8
Assets/WordConnectGameToolkit/Scripts/Popups/Daily.meta
Normal file
@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 9a5d84ad0b57045aa840b42147a0e766
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
217
Assets/WordConnectGameToolkit/Scripts/Popups/Daily/DailyBonus.cs
Normal file
217
Assets/WordConnectGameToolkit/Scripts/Popups/Daily/DailyBonus.cs
Normal file
@ -0,0 +1,217 @@
|
||||
// // ©2015 - 2025 Candy Smith
|
||||
// // All rights reserved
|
||||
// // Redistribution of this software is strictly not allowed.
|
||||
// // Copy of this software can be obtained from unity asset store only.
|
||||
// // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// // FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// // THE SOFTWARE.
|
||||
|
||||
using System;
|
||||
using System.Linq;
|
||||
using UnityEngine;
|
||||
using WordsToolkit.Scripts.Settings;
|
||||
|
||||
namespace WordsToolkit.Scripts.Popups.Daily
|
||||
{
|
||||
public class DailyBonus : PopupWithCurrencyLabel
|
||||
{
|
||||
[SerializeField]
|
||||
public DayHandle[] dayHandles;
|
||||
|
||||
// Instance of the custom scriptable object that stores daily bonus settings
|
||||
private DailyBonusSettings settings;
|
||||
private int rewardStreak;
|
||||
|
||||
public DayHandle[] daysPrefabs;
|
||||
|
||||
public Transform dayHandlesParent;
|
||||
private int days;
|
||||
|
||||
// This method is automatically called when the script becomes enabled
|
||||
public void OnEnable()
|
||||
{
|
||||
// Load daily bonus settings
|
||||
settings = LoadSettings("Settings/DailyBonusSettings");
|
||||
|
||||
days = settings.rewards.Length;
|
||||
|
||||
// Update the reward streak count and store it
|
||||
rewardStreak = UpdateRewardStreak();
|
||||
|
||||
// Update each day handle based on the current reward streak
|
||||
UpdateDayHandles(rewardStreak);
|
||||
}
|
||||
|
||||
// Loads and returns daily bonus settings stored at the specified path
|
||||
public DailyBonusSettings LoadSettings(string path)
|
||||
{
|
||||
return Resources.Load<DailyBonusSettings>(path);
|
||||
}
|
||||
|
||||
// Checks the last reward date and the current date
|
||||
// to determine and update the reward streak
|
||||
public int UpdateRewardStreak()
|
||||
{
|
||||
var today = DateTime.Today;
|
||||
var lastRewardDate = DateTime.Parse(PlayerPrefs.GetString("DailyBonusDay", today.Subtract(TimeSpan.FromDays(1)).ToString()));
|
||||
|
||||
if (today > lastRewardDate)
|
||||
{
|
||||
var rewardStreak = GetRewardStreak() + 1;
|
||||
PlayerPrefs.SetString("DailyBonusDay", today.ToString());
|
||||
PlayerPrefs.SetInt("RewardStreak", rewardStreak = (int)Mathf.Repeat(rewardStreak, dayHandles.Length));
|
||||
return rewardStreak;
|
||||
}
|
||||
|
||||
return GetRewardStreak();
|
||||
}
|
||||
|
||||
// Updates the status of each day handle in the scene
|
||||
// according to the current reward streak
|
||||
public void UpdateDayHandles(int rewardStreak)
|
||||
{
|
||||
dayHandles = new DayHandle[days];
|
||||
for (var i = 0; i < days; i++)
|
||||
{
|
||||
var status = i < rewardStreak ? EDailyStatus.passed : i == rewardStreak ? EDailyStatus.current : EDailyStatus.locked;
|
||||
var dayHandle = Instantiate(daysPrefabs[(int)status], dayHandlesParent);
|
||||
dayHandles[i] = dayHandle;
|
||||
dayHandle.name = $"Day_{i + 1}";
|
||||
dayHandle.SetDay(i + 1, settings.rewards[i]);
|
||||
|
||||
// Set status after setting the day to ensure proper icon display
|
||||
dayHandle.SetStatus(status);
|
||||
}
|
||||
}
|
||||
|
||||
// Gets and returns the reward streak count from player preferences
|
||||
public int GetRewardStreak()
|
||||
{
|
||||
return PlayerPrefs.GetInt("RewardStreak", -1);
|
||||
}
|
||||
|
||||
public override void Close()
|
||||
{
|
||||
StopInteration();
|
||||
closeButton.interactable = false;
|
||||
var resource = dayHandles[rewardStreak].RewardData.resource;
|
||||
|
||||
var dayHandle = dayHandles.First(i => i.DailyStatus == EDailyStatus.current);
|
||||
resource.AddAnimated(dayHandles[rewardStreak].RewardData.count, dayHandle.transform.position, animationSourceObject: null, callback: () =>
|
||||
{
|
||||
base.Close();
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
#if UNITY_EDITOR
|
||||
[ContextMenu("Test - Reset Daily Bonus")]
|
||||
private void TestResetDailyBonus()
|
||||
{
|
||||
CleanupDayHandles();
|
||||
PlayerPrefs.DeleteKey("DailyBonusDay");
|
||||
PlayerPrefs.DeleteKey("RewardStreak");
|
||||
Debug.Log("Daily bonus data reset!");
|
||||
if (Application.isPlaying)
|
||||
{
|
||||
OnEnable();
|
||||
}
|
||||
}
|
||||
|
||||
[ContextMenu("Test - Set Day 1")]
|
||||
private void TestSetDay1()
|
||||
{
|
||||
SetTestDay(0);
|
||||
}
|
||||
|
||||
[ContextMenu("Test - Set Day 2")]
|
||||
private void TestSetDay2()
|
||||
{
|
||||
SetTestDay(1);
|
||||
}
|
||||
|
||||
[ContextMenu("Test - Set Day 3")]
|
||||
private void TestSetDay3()
|
||||
{
|
||||
SetTestDay(2);
|
||||
}
|
||||
|
||||
[ContextMenu("Test - Set Day 4")]
|
||||
private void TestSetDay4()
|
||||
{
|
||||
SetTestDay(3);
|
||||
}
|
||||
|
||||
[ContextMenu("Test - Set Day 5")]
|
||||
private void TestSetDay5()
|
||||
{
|
||||
SetTestDay(4);
|
||||
}
|
||||
|
||||
[ContextMenu("Test - Set Day 6")]
|
||||
private void TestSetDay6()
|
||||
{
|
||||
SetTestDay(5);
|
||||
}
|
||||
|
||||
[ContextMenu("Test - Set Day 7")]
|
||||
private void TestSetDay7()
|
||||
{
|
||||
SetTestDay(6);
|
||||
}
|
||||
|
||||
private void SetTestDay(int day)
|
||||
{
|
||||
if (settings == null)
|
||||
{
|
||||
settings = LoadSettings("Settings/DailyBonusSettings");
|
||||
}
|
||||
|
||||
if (settings != null && day < settings.rewards.Length)
|
||||
{
|
||||
// Clean up existing day handles before setting new ones
|
||||
CleanupDayHandles();
|
||||
|
||||
PlayerPrefs.SetInt("RewardStreak", day);
|
||||
PlayerPrefs.SetString("DailyBonusDay", DateTime.Today.ToString());
|
||||
Debug.Log($"Set daily bonus to day {day + 1}");
|
||||
|
||||
if (Application.isPlaying)
|
||||
{
|
||||
OnEnable();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.LogWarning($"Cannot set day {day + 1}. Settings not found or day out of range.");
|
||||
}
|
||||
}
|
||||
|
||||
private void CleanupDayHandles()
|
||||
{
|
||||
if (dayHandles != null)
|
||||
{
|
||||
for (int i = 0; i < dayHandles.Length; i++)
|
||||
{
|
||||
if (dayHandles[i] != null)
|
||||
{
|
||||
if (Application.isPlaying)
|
||||
{
|
||||
Destroy(dayHandles[i].gameObject);
|
||||
}
|
||||
else
|
||||
{
|
||||
DestroyImmediate(dayHandles[i].gameObject);
|
||||
}
|
||||
}
|
||||
}
|
||||
dayHandles = null;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: d11f98927948741d98f1a26c78ec810a
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@ -0,0 +1,65 @@
|
||||
// // ©2015 - 2025 Candy Smith
|
||||
// // All rights reserved
|
||||
// // Redistribution of this software is strictly not allowed.
|
||||
// // Copy of this software can be obtained from unity asset store only.
|
||||
// // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// // FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// // THE SOFTWARE.
|
||||
|
||||
using TMPro;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
using WordsToolkit.Scripts.Settings;
|
||||
|
||||
namespace WordsToolkit.Scripts.Popups.Daily
|
||||
{
|
||||
public class DayHandle : MonoBehaviour
|
||||
{
|
||||
[SerializeField]
|
||||
private TextMeshProUGUI dayText;
|
||||
|
||||
[SerializeField]
|
||||
private TextMeshProUGUI coinsCountText;
|
||||
|
||||
[SerializeField] private GameObject rewardIcon;
|
||||
|
||||
[SerializeField]
|
||||
private GameObject lights;
|
||||
|
||||
public EDailyStatus DailyStatus { get; private set; }
|
||||
|
||||
public RewardSetting RewardData { get; set; }
|
||||
|
||||
public void SetDay(int day, RewardSetting rewardSetting)
|
||||
{
|
||||
dayText.text = dayText.text + " " + day;
|
||||
coinsCountText.text = rewardSetting.count.ToString();
|
||||
RewardData = rewardSetting;
|
||||
var image = rewardIcon.GetComponent<Image>();
|
||||
image.sprite = rewardSetting.icon;
|
||||
image.SetNativeSize();
|
||||
lights.SetActive(rewardSetting.isLight);
|
||||
}
|
||||
|
||||
public void SetStatus(EDailyStatus eDailyStatus)
|
||||
{
|
||||
DailyStatus = eDailyStatus;
|
||||
|
||||
// Update the reward icon based on status
|
||||
if (eDailyStatus == EDailyStatus.locked && RewardData != null && RewardData.iconGreyed != null)
|
||||
{
|
||||
rewardIcon.GetComponent<Image>().sprite = RewardData.iconGreyed;
|
||||
}
|
||||
|
||||
var list = GetComponentsInChildren<DayToggle>();
|
||||
foreach (var dayToggle in list)
|
||||
{
|
||||
dayToggle.SetStatus(eDailyStatus);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 6e7ff1621e23d4d8ba89656620d4c7de
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@ -0,0 +1,42 @@
|
||||
// // ©2015 - 2025 Candy Smith
|
||||
// // All rights reserved
|
||||
// // Redistribution of this software is strictly not allowed.
|
||||
// // Copy of this software can be obtained from unity asset store only.
|
||||
// // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// // FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// // THE SOFTWARE.
|
||||
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
|
||||
namespace WordsToolkit.Scripts.Popups.Daily
|
||||
{
|
||||
public class DayToggle : MonoBehaviour
|
||||
{
|
||||
public Image panelImage;
|
||||
public Color colorCurrent;
|
||||
|
||||
[SerializeField]
|
||||
public GameObject current;
|
||||
|
||||
public void SetStatus(EDailyStatus eDailyStatus)
|
||||
{
|
||||
if (eDailyStatus == EDailyStatus.current)
|
||||
{
|
||||
current.SetActive(true);
|
||||
panelImage.color = colorCurrent;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public enum EDailyStatus
|
||||
{
|
||||
locked = 0,
|
||||
passed = 1,
|
||||
current = 2
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: d42cb9a76f3954136ac19f1d0c1f54e5
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
23
Assets/WordConnectGameToolkit/Scripts/Popups/EPopupResult.cs
Normal file
23
Assets/WordConnectGameToolkit/Scripts/Popups/EPopupResult.cs
Normal file
@ -0,0 +1,23 @@
|
||||
// // ©2015 - 2025 Candy Smith
|
||||
// // All rights reserved
|
||||
// // Redistribution of this software is strictly not allowed.
|
||||
// // Copy of this software can be obtained from unity asset store only.
|
||||
// // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// // FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// // THE SOFTWARE.
|
||||
|
||||
namespace WordsToolkit.Scripts.Popups
|
||||
{
|
||||
public enum EPopupResult
|
||||
{
|
||||
Yes,
|
||||
No,
|
||||
Continue,
|
||||
Cancel,
|
||||
Restart
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: b1521b5741b84f0b88aac61775304725
|
||||
timeCreated: 1725685884
|
||||
336
Assets/WordConnectGameToolkit/Scripts/Popups/ExtraWords.cs
Normal file
336
Assets/WordConnectGameToolkit/Scripts/Popups/ExtraWords.cs
Normal file
@ -0,0 +1,336 @@
|
||||
// // ©2015 - 2025 Candy Smith
|
||||
// // All rights reserved
|
||||
// // Redistribution of this software is strictly not allowed.
|
||||
// // Copy of this software can be obtained from unity asset store only.
|
||||
// // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// // FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// // THE SOFTWARE.
|
||||
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using TMPro;
|
||||
using UnityEngine;
|
||||
using UnityEngine.InputSystem;
|
||||
using WordsToolkit.Scripts.Data;
|
||||
using WordsToolkit.Scripts.Enums;
|
||||
using WordsToolkit.Scripts.GUI.Buttons;
|
||||
using WordsToolkit.Scripts.System;
|
||||
|
||||
namespace WordsToolkit.Scripts.Popups
|
||||
{
|
||||
public class ExtraWords : Popup
|
||||
{
|
||||
[Header("Word Display")]
|
||||
// Format for displaying each word in the list
|
||||
[Tooltip("Format for each word in the list. Use {0} for the word.")]
|
||||
public string wordFormat = "• {0}";
|
||||
|
||||
// Separator between words
|
||||
[Tooltip("String to separate words in the list")]
|
||||
public string separator = "\n";
|
||||
|
||||
[Header("Font Size")]
|
||||
[Tooltip("Fixed font size for all text")]
|
||||
[Range(8, 72)]
|
||||
public float fixedFontSize = 60f;
|
||||
|
||||
[Tooltip("Enable font size adjustment to fit container")]
|
||||
public bool autoFitContainer = true;
|
||||
|
||||
[Header("Columns")]
|
||||
[Tooltip("List of pre-existing TextMeshPro components to use as columns")]
|
||||
public TextMeshProUGUI[] columnTextObjects;
|
||||
|
||||
[Tooltip("Maximum lines per column (0 = unlimited)")]
|
||||
[Range(0, 30)]
|
||||
public int maxLinesPerColumn = 6;
|
||||
|
||||
[Tooltip("Line spacing multiplier")]
|
||||
[Range(0.5f, 2f)]
|
||||
public float lineSpacingMultiplier = 1f;
|
||||
|
||||
[Header("Rewards")]
|
||||
[Tooltip("Button to claim gems for found extra words")]
|
||||
public CustomButton claimButton;
|
||||
|
||||
[Tooltip("Text to show total gems to be claimed")]
|
||||
public TextMeshProUGUI rewardText;
|
||||
|
||||
[Tooltip("Reference to the Gems resource")]
|
||||
public ResourceObject gemsResource;
|
||||
|
||||
private bool hasClaimedRewards = false;
|
||||
[SerializeField]
|
||||
private Transform startAnimationTransform;
|
||||
|
||||
|
||||
protected void OnEnable()
|
||||
{
|
||||
// Configure text components on enable
|
||||
SetupTextComponents();
|
||||
UpdateExtraWordsDisplay();
|
||||
SetupClaimButton();
|
||||
}
|
||||
|
||||
private void SetupTextComponents()
|
||||
{
|
||||
// Apply settings to existing text components
|
||||
if (columnTextObjects == null || columnTextObjects.Length == 0)
|
||||
return;
|
||||
|
||||
foreach (var text in columnTextObjects)
|
||||
{
|
||||
if (text == null)
|
||||
continue;
|
||||
|
||||
// Configure text formatting
|
||||
text.enableWordWrapping = true;
|
||||
text.overflowMode = TextOverflowModes.Ellipsis;
|
||||
|
||||
// Set font size with auto-fitting options
|
||||
if (autoFitContainer)
|
||||
{
|
||||
text.enableAutoSizing = true;
|
||||
text.fontSizeMax = fixedFontSize;
|
||||
text.fontSizeMin = fixedFontSize * 0.5f;
|
||||
}
|
||||
else
|
||||
{
|
||||
text.fontSize = fixedFontSize;
|
||||
text.enableAutoSizing = false;
|
||||
}
|
||||
|
||||
// Clear any existing content
|
||||
text.text = string.Empty;
|
||||
|
||||
// Hide all initially
|
||||
text.gameObject.SetActive(false);
|
||||
}
|
||||
}
|
||||
|
||||
private void SetupClaimButton()
|
||||
{
|
||||
if (claimButton != null)
|
||||
{
|
||||
// Reset claim state
|
||||
hasClaimedRewards = false;
|
||||
|
||||
// Setup button click handler
|
||||
claimButton.onClick.RemoveAllListeners();
|
||||
claimButton.onClick.AddListener(ClaimExtraWordRewards);
|
||||
|
||||
// Get words list
|
||||
List<string> words = GetWordsList();
|
||||
|
||||
// Calculate total reward
|
||||
int totalGems = gameSettings.gemsForExtraWords;
|
||||
|
||||
// Show total reward or hide button if no rewards
|
||||
int targetExtraWords = GetTargetExtraWordsFromGroup();
|
||||
if (PlayerPrefs.GetInt("ExtraWordsCollected",0) >= targetExtraWords)
|
||||
{
|
||||
claimButton.gameObject.SetActive(true);
|
||||
|
||||
// Update reward text if available
|
||||
if (rewardText != null)
|
||||
{
|
||||
rewardText.text = totalGems.ToString();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
claimButton.gameObject.SetActive(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void ClaimExtraWordRewards()
|
||||
{
|
||||
if (hasClaimedRewards)
|
||||
return;
|
||||
|
||||
int totalGems = gameSettings.gemsForExtraWords;
|
||||
|
||||
if (totalGems <= 0)
|
||||
return;
|
||||
|
||||
// Mark as claimed
|
||||
hasClaimedRewards = true;
|
||||
PlayerPrefs.SetInt("ExtraWordsCollected", 0); // Reset count after claiming
|
||||
EventManager.GetEvent(EGameEvent.ExtraWordClaimed).Invoke();
|
||||
// Use manually assigned reference or fall back to ResourceManager if not assigned
|
||||
var gems = gemsResource != null ? gemsResource : resourceManager.GetResource("Gems");
|
||||
|
||||
// Add reward with animation
|
||||
if (gems != null && claimButton != null)
|
||||
{
|
||||
gems.AddAnimated( totalGems, startAnimationTransform.position, animationSourceObject: null, callback: () => {
|
||||
claimButton.gameObject.SetActive(false);
|
||||
Close();
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#if UNITY_EDITOR
|
||||
private void Update()
|
||||
{
|
||||
// F5 to add a test word
|
||||
if (Keyboard.current != null && Keyboard.current.f5Key.wasPressedThisFrame)
|
||||
{
|
||||
AddTestWord();
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
// Context menu item for testing reward claim in the Unity editor
|
||||
[ContextMenu("Test Reward Claim")]
|
||||
private void TestRewardClaim()
|
||||
{
|
||||
// Reset claim state to ensure we can claim again
|
||||
hasClaimedRewards = false;
|
||||
|
||||
// Make sure the claim button is visible
|
||||
if (claimButton != null)
|
||||
claimButton.gameObject.SetActive(true);
|
||||
|
||||
// Set up reward text if available
|
||||
if (rewardText != null)
|
||||
{
|
||||
int testAmount = gameSettings.gemsForExtraWords;
|
||||
rewardText.text = testAmount.ToString();
|
||||
}
|
||||
|
||||
// Call the claim method to test the full reward process
|
||||
ClaimExtraWordRewards();
|
||||
}
|
||||
|
||||
// Context menu item for adding a test word
|
||||
[ContextMenu("Add Test Word")]
|
||||
private void AddTestWord()
|
||||
{
|
||||
if (customWordRepository != null)
|
||||
{
|
||||
customWordRepository.AddExtraWord("blablabla " + Random.Range(1, 1000));
|
||||
UpdateExtraWordsDisplay();
|
||||
SetupClaimButton();
|
||||
}
|
||||
}
|
||||
|
||||
// Updates the text components with current extra words
|
||||
public void UpdateExtraWordsDisplay()
|
||||
{
|
||||
// Get word list from game
|
||||
List<string> words = GetWordsList();
|
||||
|
||||
// Early exit if no columns are assigned
|
||||
if (columnTextObjects == null || columnTextObjects.Length == 0)
|
||||
return;
|
||||
|
||||
// If no words found, display message in first column
|
||||
if (words.Count == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// Otherwise, distribute words among columns
|
||||
DistributeWordsToColumns(words);
|
||||
}
|
||||
|
||||
private void DistributeWordsToColumns(List<string> words)
|
||||
{
|
||||
// Count valid columns
|
||||
int validColumnCount = 0;
|
||||
foreach (var col in columnTextObjects)
|
||||
{
|
||||
if (col != null)
|
||||
validColumnCount++;
|
||||
}
|
||||
|
||||
if (validColumnCount == 0)
|
||||
return;
|
||||
|
||||
int currentColumn = 0;
|
||||
int wordIndex = 0;
|
||||
|
||||
// First, disable all columns
|
||||
foreach (var col in columnTextObjects)
|
||||
{
|
||||
if (col != null)
|
||||
col.gameObject.SetActive(false);
|
||||
}
|
||||
|
||||
while (wordIndex < words.Count && currentColumn < columnTextObjects.Length)
|
||||
{
|
||||
TextMeshProUGUI col = columnTextObjects[currentColumn];
|
||||
if (col == null)
|
||||
{
|
||||
currentColumn++;
|
||||
continue;
|
||||
}
|
||||
|
||||
// Show this column
|
||||
col.gameObject.SetActive(true);
|
||||
|
||||
// Build text for this column
|
||||
StringBuilder sb = new StringBuilder();
|
||||
int wordCount = 0;
|
||||
bool columnIsFull = false;
|
||||
|
||||
// Fill this column until max lines or out of words
|
||||
while (!columnIsFull && wordIndex < words.Count)
|
||||
{
|
||||
// Check if we've reached the max lines for this column
|
||||
if (maxLinesPerColumn > 0 && wordCount >= maxLinesPerColumn)
|
||||
{
|
||||
columnIsFull = true;
|
||||
break;
|
||||
}
|
||||
|
||||
if (wordCount > 0)
|
||||
sb.Append(separator);
|
||||
sb.Append(string.Format(wordFormat, words[wordIndex]));
|
||||
wordIndex++;
|
||||
wordCount++;
|
||||
}
|
||||
|
||||
// Set text content
|
||||
col.text = sb.ToString();
|
||||
|
||||
// Move to next column if we have more words or the current column is full
|
||||
if (wordIndex < words.Count || columnIsFull)
|
||||
{
|
||||
currentColumn++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Gets the list of extra words from the level manager
|
||||
private List<string> GetWordsList()
|
||||
{
|
||||
if (levelManager != null)
|
||||
{
|
||||
List<string> words = customWordRepository.GetExtraWords().Where(word => word != null).ToList();
|
||||
if (words.Count > 24)
|
||||
{
|
||||
words = words.Skip(Mathf.Max(0, words.Count - 24)).ToList();
|
||||
}
|
||||
return words ?? new List<string>();
|
||||
}
|
||||
|
||||
return new List<string>();
|
||||
}
|
||||
|
||||
// Helper method to get target extra words from the current level's group or fallback to game settings
|
||||
private int GetTargetExtraWordsFromGroup()
|
||||
{
|
||||
var currentLevelGroup = GameDataManager.GetLevel().GetGroup();
|
||||
return Mathf.Max(1, currentLevelGroup.targetExtraWords); // Ensure it's at least 1
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 14d648b82c79410bac1c9a4e6e811118
|
||||
timeCreated: 1742316222
|
||||
47
Assets/WordConnectGameToolkit/Scripts/Popups/Fader.cs
Normal file
47
Assets/WordConnectGameToolkit/Scripts/Popups/Fader.cs
Normal file
@ -0,0 +1,47 @@
|
||||
// // ©2015 - 2025 Candy Smith
|
||||
// // All rights reserved
|
||||
// // Redistribution of this software is strictly not allowed.
|
||||
// // Copy of this software can be obtained from unity asset store only.
|
||||
// // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// // FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// // THE SOFTWARE.
|
||||
|
||||
using System;
|
||||
using DG.Tweening;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
|
||||
namespace WordsToolkit.Scripts.Popups
|
||||
{
|
||||
public class Fader : MonoBehaviour
|
||||
{
|
||||
public Image fader;
|
||||
private readonly float fadeTime = .3f;
|
||||
private readonly float maxValue = .993f;
|
||||
|
||||
public bool IsFaded()
|
||||
{
|
||||
return fader.color.a >= 0;
|
||||
}
|
||||
|
||||
public void FadeIn(float fadeAlpha, Action action = null)
|
||||
{
|
||||
fader.gameObject.SetActive(true);
|
||||
fader.DOFade(fadeAlpha, fadeTime).OnComplete(() => action?.Invoke());
|
||||
}
|
||||
|
||||
public void FadeOut()
|
||||
{
|
||||
fader.DOFade(0, fadeTime).OnComplete(() => fader.gameObject.SetActive(false));
|
||||
}
|
||||
|
||||
public void FadeAfterLoadingScene()
|
||||
{
|
||||
FadeOut();
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: ef3c4932b35844e8985afcacda4c590d
|
||||
timeCreated: 1725685718
|
||||
37
Assets/WordConnectGameToolkit/Scripts/Popups/Failed.cs
Normal file
37
Assets/WordConnectGameToolkit/Scripts/Popups/Failed.cs
Normal file
@ -0,0 +1,37 @@
|
||||
// // ©2015 - 2025 Candy Smith
|
||||
// // All rights reserved
|
||||
// // Redistribution of this software is strictly not allowed.
|
||||
// // Copy of this software can be obtained from unity asset store only.
|
||||
// // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// // FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// // THE SOFTWARE.
|
||||
|
||||
using WordsToolkit.Scripts.GUI;
|
||||
using WordsToolkit.Scripts.GUI.Buttons;
|
||||
using WordsToolkit.Scripts.System;
|
||||
|
||||
namespace WordsToolkit.Scripts.Popups
|
||||
{
|
||||
public class Failed : Popup
|
||||
{
|
||||
public CustomButton retryButton;
|
||||
|
||||
protected virtual void OnEnable()
|
||||
{
|
||||
retryButton.onClick.AddListener(Retry);
|
||||
closeButton.onClick.AddListener(() => gameManager.MainMenu());
|
||||
}
|
||||
|
||||
private void Retry()
|
||||
{
|
||||
StopInteration();
|
||||
|
||||
gameManager.RestartLevel();
|
||||
Close();
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: b60a316fdb72486ea91097dbef9cbb9f
|
||||
timeCreated: 1729248308
|
||||
64
Assets/WordConnectGameToolkit/Scripts/Popups/Finish.cs
Normal file
64
Assets/WordConnectGameToolkit/Scripts/Popups/Finish.cs
Normal file
@ -0,0 +1,64 @@
|
||||
// // ©2015 - 2025 Candy Smith
|
||||
// // All rights reserved
|
||||
// // Redistribution of this software is strictly not allowed.
|
||||
// // Copy of this software can be obtained from unity asset store only.
|
||||
// // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// // FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// // THE SOFTWARE.
|
||||
|
||||
using TMPro;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
using WordsToolkit.Scripts.Levels;
|
||||
using WordsToolkit.Scripts.System;
|
||||
|
||||
namespace WordsToolkit.Scripts.Popups
|
||||
{
|
||||
public class Finish : Popup
|
||||
{
|
||||
public TextMeshProUGUI title;
|
||||
public TextMeshProUGUI description;
|
||||
private Level currentLevel;
|
||||
[SerializeField]
|
||||
private AudioClip swish;
|
||||
|
||||
[SerializeField]
|
||||
private AudioClip cheers;
|
||||
|
||||
[SerializeField]
|
||||
private Image background;
|
||||
|
||||
private void OnEnable()
|
||||
{
|
||||
currentLevel = levelManager.GetCurrentLevel();
|
||||
|
||||
SetFinishText(currentLevel.GetTitle(gameManager.language),
|
||||
currentLevel.GetText(gameManager.language));
|
||||
|
||||
background.sprite = levelManager.GetCurrentLevel().background;
|
||||
}
|
||||
|
||||
private void SetFinishText(string titleText, string descriptionText)
|
||||
{
|
||||
if (titleText != "")
|
||||
{
|
||||
title.text = titleText;
|
||||
}
|
||||
|
||||
if (descriptionText != "")
|
||||
{
|
||||
description.text = descriptionText;
|
||||
}
|
||||
}
|
||||
|
||||
public override void ShowAnimationSound()
|
||||
{
|
||||
base.ShowAnimationSound();
|
||||
audioService.PlaySound(cheers);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 80d870e7714d48b4a86792fac4b3052c
|
||||
timeCreated: 1747906864
|
||||
37
Assets/WordConnectGameToolkit/Scripts/Popups/GDPR.cs
Normal file
37
Assets/WordConnectGameToolkit/Scripts/Popups/GDPR.cs
Normal file
@ -0,0 +1,37 @@
|
||||
// // ©2015 - 2025 Candy Smith
|
||||
// // All rights reserved
|
||||
// // Redistribution of this software is strictly not allowed.
|
||||
// // Copy of this software can be obtained from unity asset store only.
|
||||
// // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// // FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// // THE SOFTWARE.
|
||||
|
||||
using UnityEngine;
|
||||
using WordsToolkit.Scripts.System;
|
||||
|
||||
namespace WordsToolkit.Scripts.Popups
|
||||
{
|
||||
public class GDPR : Popup
|
||||
{
|
||||
public void OnUserClickAccept()
|
||||
{
|
||||
PlayerPrefs.SetInt("npa", 0);
|
||||
Close();
|
||||
}
|
||||
|
||||
public void OnUserClickCancel()
|
||||
{
|
||||
PlayerPrefs.SetInt("npa", 1);
|
||||
Close();
|
||||
}
|
||||
|
||||
public void OnUserClickPrivacyPolicy()
|
||||
{
|
||||
Application.OpenURL(gameSettings.privacyPolicyUrl);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 6c02172637514729966e9f5cd6078d9e
|
||||
timeCreated: 1725685718
|
||||
@ -0,0 +1,27 @@
|
||||
// // ©2015 - 2025 Candy Smith
|
||||
// // All rights reserved
|
||||
// // Redistribution of this software is strictly not allowed.
|
||||
// // Copy of this software can be obtained from unity asset store only.
|
||||
// // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// // FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// // THE SOFTWARE.
|
||||
|
||||
using UnityEngine;
|
||||
using UnityEngine.Events;
|
||||
|
||||
namespace WordsToolkit.Scripts.Popups
|
||||
{
|
||||
public class GiftClaimTrigger : MonoBehaviour
|
||||
{
|
||||
public UnityEvent onOpened;
|
||||
|
||||
public void OnBoxOpened()
|
||||
{
|
||||
onOpened?.Invoke();
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 17df131c94bc437289b191d79b801cb5
|
||||
timeCreated: 1748338463
|
||||
181
Assets/WordConnectGameToolkit/Scripts/Popups/GiftPopup.cs
Normal file
181
Assets/WordConnectGameToolkit/Scripts/Popups/GiftPopup.cs
Normal file
@ -0,0 +1,181 @@
|
||||
// // ©2015 - 2025 Candy Smith
|
||||
// // All rights reserved
|
||||
// // Redistribution of this software is strictly not allowed.
|
||||
// // Copy of this software can be obtained from unity asset store only.
|
||||
// // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// // FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// // THE SOFTWARE.
|
||||
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using DG.Tweening;
|
||||
using UnityEngine;
|
||||
using VContainer;
|
||||
using WordsToolkit.Scripts.GUI;
|
||||
using WordsToolkit.Scripts.GUI.Buttons;
|
||||
using WordsToolkit.Scripts.Popups.RewardsGift;
|
||||
using WordsToolkit.Scripts.Settings;
|
||||
using WordsToolkit.Scripts.System;
|
||||
|
||||
namespace WordsToolkit.Scripts.Popups
|
||||
{
|
||||
public class GiftPopup : Popup
|
||||
{
|
||||
[SerializeField] private CustomButton claimButton;
|
||||
[SerializeField] private Animator boxAnimator;
|
||||
[Inject] private GiftsSettings giftsSettings;
|
||||
private List<Transform> giftsPositionsSelected;
|
||||
[SerializeField] private Transform startTransform;
|
||||
[SerializeField] private Transform targetPosition;
|
||||
private bool opened;
|
||||
private List<GiftDataObject> giftsToClaim;
|
||||
[SerializeField]
|
||||
private AudioClip openBoxSound;
|
||||
|
||||
[SerializeField]
|
||||
private Transform transformParent;
|
||||
|
||||
private void OnEnable()
|
||||
{
|
||||
claimButton.onClick.AddListener(OnClaimButtonClicked);
|
||||
}
|
||||
|
||||
private void OnDestroy()
|
||||
{
|
||||
claimButton.onClick.RemoveListener(OnClaimButtonClicked);
|
||||
}
|
||||
|
||||
private void OnClaimButtonClicked()
|
||||
{
|
||||
if (!opened)
|
||||
{
|
||||
audioService.PlayDelayed(openBoxSound, 1.0f);
|
||||
boxAnimator.Play($"OpenBox");
|
||||
}
|
||||
else
|
||||
StartCoroutine(ClaimGifts());
|
||||
}
|
||||
|
||||
private IEnumerator ClaimGifts()
|
||||
{
|
||||
for (var index = 0; index < giftsToClaim.Count; index++)
|
||||
{
|
||||
var giftData = giftsToClaim[index];
|
||||
giftData.giftInstance.Animate();
|
||||
var giftInstanceGameObject = giftData.giftData.resourceObject.name != "Coins" ? giftData.giftInstance.gameObject : null;
|
||||
giftData.giftData.resourceObject.AddAnimated(giftData.giftData.giftCount, giftData.giftInstance.transform.position, giftInstanceGameObject, () => { CloseDelay(); });
|
||||
if (index > 0 && index < giftsToClaim.Count - 1)
|
||||
{
|
||||
yield return new WaitForSeconds(Random.Range(0.1f, 0.3f));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void OnBoxOpened()
|
||||
{
|
||||
giftsToClaim = new List<GiftDataObject>();
|
||||
|
||||
foreach(var giftData in giftsSettings.gifts)
|
||||
{
|
||||
var firstOrDefault = gameSettings.boostLevels.FirstOrDefault(i=> i.tag == giftData.tagUIElement);
|
||||
if(firstOrDefault != null && firstOrDefault!.level > GameDataManager.GetLevelNum())
|
||||
{
|
||||
break;
|
||||
}
|
||||
if(Random.value < giftData.giftChance/100f)
|
||||
{
|
||||
giftsToClaim.Add(new GiftDataObject
|
||||
{
|
||||
giftData = giftData,
|
||||
giftInstance = null // Will be instantiated later
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// If no gifts were added, force add the first gift
|
||||
if(giftsToClaim.Count == 0 && giftsSettings.gifts.Length > 0)
|
||||
{
|
||||
giftsToClaim.Add( new GiftDataObject
|
||||
{
|
||||
giftData = giftsSettings.gifts[Random.Range(0, giftsSettings.gifts.Length)],
|
||||
giftInstance = null // Will be instantiated later
|
||||
});
|
||||
}
|
||||
|
||||
for (var i = 0; i < giftsToClaim.Count; i++)
|
||||
{
|
||||
var giftData = giftsToClaim[i].giftData;
|
||||
var giftPrefab = giftData.giftPrefab;
|
||||
var giftInstance = Instantiate(giftPrefab, transformParent);
|
||||
giftsToClaim[i].giftInstance = giftInstance;
|
||||
giftInstance.transform.position = startTransform.position;
|
||||
AnimateGift(giftInstance, i, giftsToClaim.Count, giftData);
|
||||
giftInstance.SetCount(giftData.giftCount);
|
||||
}
|
||||
}
|
||||
|
||||
private void AnimateGift(GiftBase giftInstance, int i, int giftsCount, GiftData giftData)
|
||||
{
|
||||
giftInstance.transform.DOMove(GetGiftPosition(i, giftsCount), 0.5f).OnComplete(()=>OnCompleteAnimation(giftData));
|
||||
}
|
||||
|
||||
private void OnCompleteAnimation(GiftData giftData)
|
||||
{
|
||||
opened = true;
|
||||
var list = ShowTags(new[] { giftData.tagUIElement });
|
||||
foreach (var tagObject in list)
|
||||
{
|
||||
var showable = tagObject.GetComponent<IFadeable>();
|
||||
showable?.InstantHide();
|
||||
showable?.Show();
|
||||
var customButton = tagObject.GetComponent<CustomButton>();
|
||||
if (customButton)
|
||||
{
|
||||
customButton.interactable = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private Vector3 GetGiftPosition(int index, int totalCount)
|
||||
{
|
||||
// check even or odd total count
|
||||
if(totalCount % 2 == 0)
|
||||
{
|
||||
float radius = Vector3.Distance(targetPosition.position, startTransform.position)/1.2f;
|
||||
float sign = (index == 1) ? 1f : -1f;
|
||||
float angleInRadians = sign * 30f * Mathf.Deg2Rad;
|
||||
float x = startTransform.position.x - (radius * Mathf.Sin(angleInRadians));
|
||||
float y = startTransform.position.y + (radius * Mathf.Cos(angleInRadians));
|
||||
return new Vector3(x, y, targetPosition.position.z);
|
||||
}
|
||||
|
||||
// odd count
|
||||
if (index == 0)
|
||||
{
|
||||
return targetPosition.position;
|
||||
}
|
||||
else if (index == 1 || index == 2)
|
||||
{
|
||||
float radius = Vector3.Distance(targetPosition.position, startTransform.position)/1.2f;
|
||||
float sign = (index == 1) ? 1f : -1f;
|
||||
float angleInRadians = sign * 50f * Mathf.Deg2Rad;
|
||||
float x = startTransform.position.x - (radius * Mathf.Sin(angleInRadians));
|
||||
float y = startTransform.position.y + (radius * Mathf.Cos(angleInRadians));
|
||||
return new Vector3(x, y, targetPosition.position.z);
|
||||
}
|
||||
return targetPosition.position; // fallback
|
||||
}
|
||||
}
|
||||
|
||||
class GiftDataObject
|
||||
{
|
||||
public GiftBase giftInstance;
|
||||
public GiftData giftData;
|
||||
}
|
||||
}
|
||||
|
||||
@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 5db756b0b4a24c0bbde69ee4a65ec234
|
||||
timeCreated: 1748331316
|
||||
@ -0,0 +1,12 @@
|
||||
using UnityEngine;
|
||||
using System;
|
||||
|
||||
namespace WordsToolkit.Scripts.Popups
|
||||
{
|
||||
public interface IPopupFactory
|
||||
{
|
||||
Popup CreatePopup(string pathWithType, Transform parent);
|
||||
T CreatePopup<T>(Transform parent) where T : Popup;
|
||||
Popup CreatePopup(Popup popupPrefab, Transform parent);
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 677dfb691e6c64ee4b8c84b1a9acb6de
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
17
Assets/WordConnectGameToolkit/Scripts/Popups/IPopupStack.cs
Normal file
17
Assets/WordConnectGameToolkit/Scripts/Popups/IPopupStack.cs
Normal file
@ -0,0 +1,17 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace WordsToolkit.Scripts.Popups
|
||||
{
|
||||
public interface IPopupStack
|
||||
{
|
||||
void Push(Popup popup);
|
||||
void Pop();
|
||||
Popup Peek();
|
||||
bool IsEmpty();
|
||||
void Clear();
|
||||
int Count { get; }
|
||||
event Action<Popup> OnPopupPushed;
|
||||
event Action<Popup> OnPopupPopped;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: a1ad40a22680a410287838c0abd94a0b
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
82
Assets/WordConnectGameToolkit/Scripts/Popups/ItemPurchase.cs
Normal file
82
Assets/WordConnectGameToolkit/Scripts/Popups/ItemPurchase.cs
Normal file
@ -0,0 +1,82 @@
|
||||
// // ©2015 - 2025 Candy Smith
|
||||
// // All rights reserved
|
||||
// // Redistribution of this software is strictly not allowed.
|
||||
// // Copy of this software can be obtained from unity asset store only.
|
||||
// // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// // FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// // THE SOFTWARE.
|
||||
|
||||
using System.Collections.Generic;
|
||||
using TMPro;
|
||||
using UnityEngine;
|
||||
using WordsToolkit.Scripts.Data;
|
||||
using WordsToolkit.Scripts.GUI;
|
||||
using WordsToolkit.Scripts.GUI.Buttons;
|
||||
using WordsToolkit.Scripts.Services.IAP;
|
||||
|
||||
namespace WordsToolkit.Scripts.Popups
|
||||
{
|
||||
public class ItemPurchase : MonoBehaviour
|
||||
{
|
||||
public CustomButton BuyItemButton;
|
||||
public TextMeshProUGUI price;
|
||||
public TextMeshProUGUI count;
|
||||
public TextMeshProUGUI discountPercent;
|
||||
|
||||
[HideInInspector]
|
||||
public KeyValuePair<ProductID, int> settingsShopItem;
|
||||
|
||||
public ProductID productID;
|
||||
|
||||
[SerializeField]
|
||||
public ResourceObject resource;
|
||||
|
||||
private IIAPManager iapManager;
|
||||
|
||||
public void Init(KeyValuePair<ProductID, int> settingsShopItem, IIAPManager iapManager)
|
||||
{
|
||||
this.settingsShopItem = settingsShopItem;
|
||||
productID = settingsShopItem.Key;
|
||||
|
||||
if (count != null)
|
||||
{
|
||||
count.text = settingsShopItem.Value.ToString();
|
||||
}
|
||||
|
||||
if (productID != null && price != null)
|
||||
{
|
||||
var priceValue = iapManager.GetProductLocalizedPrice(productID.ID);
|
||||
if (priceValue > 0.01m)
|
||||
{
|
||||
price.text = iapManager.GetProductLocalizedPriceString(productID.ID);
|
||||
}
|
||||
}
|
||||
|
||||
BuyItemButton?.onClick.AddListener(BuyCoins);
|
||||
|
||||
// Check if non-consumable item is already purchased
|
||||
if (productID != null && productID.productType == ProductTypeWrapper.ProductType.NonConsumable &&
|
||||
PlayerPrefs.GetInt("Purchased_" + productID.ID, 0) == 1)
|
||||
{
|
||||
gameObject.SetActive(false);
|
||||
}
|
||||
}
|
||||
|
||||
private void OnEnable()
|
||||
{
|
||||
// Removed old initialization code since it's now in Init
|
||||
}
|
||||
|
||||
private void BuyCoins()
|
||||
{
|
||||
if (productID != null)
|
||||
{
|
||||
GetComponentInParent<CoinsShop>().BuyCoins(productID.ID);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 3375876541784a8f854c2536ec5cd514
|
||||
timeCreated: 1725686495
|
||||
25
Assets/WordConnectGameToolkit/Scripts/Popups/Loading.cs
Normal file
25
Assets/WordConnectGameToolkit/Scripts/Popups/Loading.cs
Normal file
@ -0,0 +1,25 @@
|
||||
// // ©2015 - 2025 Candy Smith
|
||||
// // All rights reserved
|
||||
// // Redistribution of this software is strictly not allowed.
|
||||
// // Copy of this software can be obtained from unity asset store only.
|
||||
// // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// // FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// // THE SOFTWARE.
|
||||
|
||||
namespace WordsToolkit.Scripts.Popups
|
||||
{
|
||||
public class Loading : Popup
|
||||
{
|
||||
public override void CloseAnimationSound()
|
||||
{
|
||||
}
|
||||
|
||||
public override void Hide()
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 3463917881594f2688a0688426106d74
|
||||
timeCreated: 1725687066
|
||||
239
Assets/WordConnectGameToolkit/Scripts/Popups/LuckySpin.cs
Normal file
239
Assets/WordConnectGameToolkit/Scripts/Popups/LuckySpin.cs
Normal file
@ -0,0 +1,239 @@
|
||||
// // ©2015 - 2025 Candy Smith
|
||||
// // All rights reserved
|
||||
// // Redistribution of this software is strictly not allowed.
|
||||
// // Copy of this software can be obtained from unity asset store only.
|
||||
// // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// // FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// // THE SOFTWARE.
|
||||
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Runtime.InteropServices;
|
||||
using TMPro;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
using VContainer;
|
||||
using WordsToolkit.Scripts.Audio;
|
||||
using WordsToolkit.Scripts.Data;
|
||||
using WordsToolkit.Scripts.GUI;
|
||||
using WordsToolkit.Scripts.GUI.Buttons;
|
||||
using WordsToolkit.Scripts.GUI.Labels;
|
||||
using WordsToolkit.Scripts.Popups.Reward;
|
||||
using WordsToolkit.Scripts.Settings;
|
||||
using WordsToolkit.Scripts.System;
|
||||
using Random = UnityEngine.Random;
|
||||
|
||||
namespace WordsToolkit.Scripts.Popups
|
||||
{
|
||||
public class LuckySpin : PopupWithCurrencyLabel
|
||||
{
|
||||
public float velocity;
|
||||
public float stoptime;
|
||||
|
||||
[SerializeField]
|
||||
private GameObject spin;
|
||||
|
||||
[SerializeField]
|
||||
private List<Image> lights = new();
|
||||
|
||||
public CustomButton freeSpinButton;
|
||||
public CustomButton rewardedAdButton;
|
||||
public RewardSettingSpin[] spinRewards;
|
||||
public List<RewardVisual> rewards = new();
|
||||
private SpinSettings spinSettings;
|
||||
private Rigidbody2D rb;
|
||||
private bool isSpinning;
|
||||
private int previousRotationMarker;
|
||||
private const string LastFreeSpinTimeKey = "LastFreeSpinTime";
|
||||
|
||||
[SerializeField]
|
||||
private float minVelocityMultiplier = 0.5f;
|
||||
|
||||
[SerializeField]
|
||||
private float maxVelocityMultiplier = 2.5f;
|
||||
|
||||
[SerializeField]
|
||||
private float additionalRandomFactor = 0.2f;
|
||||
[Inject]
|
||||
private SpinSettings luckySpinSettings;
|
||||
|
||||
[SerializeField]
|
||||
private AudioClip luckySpin;
|
||||
|
||||
[SerializeField]
|
||||
private AudioClip applause;
|
||||
|
||||
private void OnEnable()
|
||||
{
|
||||
rb = spin.GetComponent<Rigidbody2D>();
|
||||
freeSpinButton.onClick.AddListener(FreeSpin);
|
||||
|
||||
UpdateButtonVisibility();
|
||||
|
||||
spinSettings = luckySpinSettings;
|
||||
DefineRewards(spinSettings.rewards);
|
||||
StartCoroutine(SwitchLightsAlpha());
|
||||
}
|
||||
|
||||
private void UpdateButtonVisibility()
|
||||
{
|
||||
var canFreeSpin = CanUseFreeSpinToday();
|
||||
freeSpinButton.gameObject.SetActive(canFreeSpin);
|
||||
rewardedAdButton.gameObject.SetActive(!canFreeSpin);
|
||||
}
|
||||
|
||||
private void SetButtonsVisibility(bool visible)
|
||||
{
|
||||
freeSpinButton.gameObject.SetActive(visible);
|
||||
rewardedAdButton.gameObject.SetActive(visible);
|
||||
}
|
||||
|
||||
private bool CanUseFreeSpinToday()
|
||||
{
|
||||
if (!PlayerPrefs.HasKey(LastFreeSpinTimeKey))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
var lastFreeSpinTimeStr = PlayerPrefs.GetString(LastFreeSpinTimeKey);
|
||||
var lastFreeSpinTime = DateTime.Parse(lastFreeSpinTimeStr);
|
||||
return DateTime.Now.Date > lastFreeSpinTime.Date;
|
||||
}
|
||||
|
||||
private void FreeSpin()
|
||||
{
|
||||
PlayerPrefs.SetString(LastFreeSpinTimeKey, DateTime.Now.ToString("o"));
|
||||
Spin();
|
||||
}
|
||||
|
||||
private IEnumerator SwitchLightsAlpha()
|
||||
{
|
||||
const float maxSpeed = 100;
|
||||
|
||||
while (true)
|
||||
{
|
||||
var speedRatio = Mathf.Abs(rb.angularVelocity) / maxSpeed; // Ratio of the current speed to the maximum speed
|
||||
speedRatio = Mathf.Min(speedRatio, .9f);
|
||||
var delay = 1f - speedRatio; // Higher speed -> smaller delay
|
||||
yield return new WaitForSeconds(delay);
|
||||
|
||||
foreach (var light in lights)
|
||||
{
|
||||
light.color = new Color(light.color.r, light.color.g, light.color.b, light.color.a == 0 ? 1 : 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void DefineRewards(RewardSettingSpin[] spinRewards)
|
||||
{
|
||||
this.spinRewards = spinRewards;
|
||||
foreach (var reward in spinRewards)
|
||||
{
|
||||
var obj = Instantiate(reward.rewardVisualPrefab, spin.transform);
|
||||
//rotate to 360/number of rewards
|
||||
obj.transform.localPosition += new Vector3(0, 20, 0);
|
||||
obj.transform.RotateAround(spin.transform.position, Vector3.forward, 360f / spinRewards.Length * obj.transform.GetSiblingIndex());
|
||||
obj.SetCount(reward.count);
|
||||
rewards.Add(obj);
|
||||
}
|
||||
}
|
||||
|
||||
public void Spin()
|
||||
{
|
||||
StartCoroutine(StartSpin());
|
||||
}
|
||||
|
||||
private IEnumerator StartSpin()
|
||||
{
|
||||
// buttons interaction
|
||||
closeButton.interactable = false;
|
||||
freeSpinButton.interactable = false;
|
||||
rewardedAdButton.interactable = false;
|
||||
//hide buttons
|
||||
SetButtonsVisibility(false);
|
||||
|
||||
var randomVelocity = CalculateRandomVelocity();
|
||||
|
||||
float timeElapsed = 0;
|
||||
isSpinning = true;
|
||||
previousRotationMarker = Mathf.FloorToInt(spin.transform.eulerAngles.z / 25);
|
||||
|
||||
while (timeElapsed < stoptime)
|
||||
{
|
||||
var appliedTorque = Mathf.Lerp(0, randomVelocity, timeElapsed / stoptime);
|
||||
rb.AddTorque(appliedTorque);
|
||||
timeElapsed += Time.deltaTime;
|
||||
yield return new WaitForFixedUpdate();
|
||||
}
|
||||
|
||||
rb.angularDrag *= 100;
|
||||
yield return new WaitWhile(() => rb.angularVelocity != 0);
|
||||
isSpinning = false;
|
||||
CheckReward(GetWinReward());
|
||||
}
|
||||
|
||||
private float CalculateRandomVelocity()
|
||||
{
|
||||
var baseMultiplier = Random.Range(minVelocityMultiplier, maxVelocityMultiplier);
|
||||
var additionalRandomness = Random.Range(-additionalRandomFactor, additionalRandomFactor);
|
||||
return velocity * (baseMultiplier + additionalRandomness);
|
||||
}
|
||||
|
||||
private void Update()
|
||||
{
|
||||
if (isSpinning)
|
||||
{
|
||||
CheckPlaySound();
|
||||
}
|
||||
}
|
||||
|
||||
private void CheckPlaySound()
|
||||
{
|
||||
var currentZRotation = spin.transform.eulerAngles.z;
|
||||
var currentTenDegreeMarker = Mathf.FloorToInt(currentZRotation / 25);
|
||||
|
||||
if (currentTenDegreeMarker != previousRotationMarker)
|
||||
{
|
||||
audioService.PlaySound(luckySpin);
|
||||
previousRotationMarker = currentTenDegreeMarker;
|
||||
}
|
||||
}
|
||||
|
||||
private int GetWinReward()
|
||||
{
|
||||
audioService.PlaySound( applause);
|
||||
var highestYIndex = 0; // Start with first item's index
|
||||
var highestY = rewards[0].transform.position.y; // and its 'y' position
|
||||
|
||||
for (var i = 1; i < rewards.Count; i++)
|
||||
{
|
||||
// If current item's 'y' position is higher
|
||||
if (rewards[i].transform.position.y > highestY)
|
||||
{
|
||||
highestY = rewards[i].transform.position.y;
|
||||
highestYIndex = i;
|
||||
}
|
||||
}
|
||||
|
||||
return highestYIndex;
|
||||
}
|
||||
|
||||
private void CheckReward(int rewardIndex)
|
||||
{
|
||||
var rewardSettingSpin = spinRewards[rewardIndex];
|
||||
var rewardVisual = rewards[rewardIndex];
|
||||
var _resource = rewardSettingSpin.resource;
|
||||
var iconPos = rewardVisual.transform;
|
||||
var _count = rewardSettingSpin.count;
|
||||
_resource.AddAnimated(_count, iconPos.position, animationSourceObject: null, callback: () =>
|
||||
{
|
||||
Close();
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 8722eb05d50246be8189fdbf4f9d9709
|
||||
timeCreated: 1691983492
|
||||
93
Assets/WordConnectGameToolkit/Scripts/Popups/MainMenu.cs
Normal file
93
Assets/WordConnectGameToolkit/Scripts/Popups/MainMenu.cs
Normal file
@ -0,0 +1,93 @@
|
||||
// // ©2015 - 2025 Candy Smith
|
||||
// // All rights reserved
|
||||
// // Redistribution of this software is strictly not allowed.
|
||||
// // Copy of this software can be obtained from unity asset store only.
|
||||
// // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// // FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// // THE SOFTWARE.
|
||||
|
||||
using System;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
using WordsToolkit.Scripts.GUI;
|
||||
using WordsToolkit.Scripts.Levels;
|
||||
using WordsToolkit.Scripts.System;
|
||||
using VContainer;
|
||||
using WordsToolkit.Scripts.GUI.Buttons;
|
||||
using WordsToolkit.Scripts.Settings;
|
||||
|
||||
namespace WordsToolkit.Scripts.Popups
|
||||
{
|
||||
public class MainMenu : Popup
|
||||
{
|
||||
public CustomButton settingsButton;
|
||||
public CustomButton luckySpin;
|
||||
|
||||
public Button playButton;
|
||||
|
||||
[SerializeField]
|
||||
private GameObject freeSpinMarker;
|
||||
|
||||
[SerializeField]
|
||||
private Image background;
|
||||
|
||||
public Action OnAnimationEnded;
|
||||
|
||||
private const string LastFreeSpinTimeKey = "LastFreeSpinTime";
|
||||
|
||||
private void Start()
|
||||
{
|
||||
settingsButton.onClick.AddListener(SettingsButtonClicked);
|
||||
luckySpin.onClick.AddListener(LuckySpinButtonClicked);
|
||||
UpdateFreeSpinMarker();
|
||||
var levelsCount = Resources.LoadAll<Level>("Levels").Length;
|
||||
luckySpin.gameObject.SetActive(gameSettings.enableLuckySpin);
|
||||
playButton.onClick.AddListener(PlayButtonClicked);
|
||||
}
|
||||
|
||||
private void PlayButtonClicked()
|
||||
{
|
||||
menuManager.ShowPopup<MenuPlay>();
|
||||
}
|
||||
|
||||
private bool CanUseFreeSpinToday()
|
||||
{
|
||||
if (!PlayerPrefs.HasKey(LastFreeSpinTimeKey))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
var lastFreeSpinTimeStr = PlayerPrefs.GetString(LastFreeSpinTimeKey);
|
||||
var lastFreeSpinTime = DateTime.Parse(lastFreeSpinTimeStr);
|
||||
return DateTime.Now.Date > lastFreeSpinTime.Date;
|
||||
}
|
||||
|
||||
private void UpdateFreeSpinMarker()
|
||||
{
|
||||
var isFreeSpinAvailable = CanUseFreeSpinToday();
|
||||
if (freeSpinMarker != null)
|
||||
{
|
||||
freeSpinMarker.SetActive(isFreeSpinAvailable);
|
||||
}
|
||||
}
|
||||
|
||||
private void SettingsButtonClicked()
|
||||
{
|
||||
menuManager.ShowPopup<Settings>();
|
||||
}
|
||||
|
||||
private void LuckySpinButtonClicked()
|
||||
{
|
||||
menuManager.ShowPopup<LuckySpin>(null, _ => UpdateFreeSpinMarker());
|
||||
}
|
||||
|
||||
public void OnAnimationEnd()
|
||||
{
|
||||
OnAnimationEnded?.Invoke();
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 99f1ec34f0834cd1a917d610fb019478
|
||||
timeCreated: 1725696566
|
||||
202
Assets/WordConnectGameToolkit/Scripts/Popups/MenuManager.cs
Normal file
202
Assets/WordConnectGameToolkit/Scripts/Popups/MenuManager.cs
Normal file
@ -0,0 +1,202 @@
|
||||
// // ©2015 - 2025 Candy Smith
|
||||
// // All rights reserved
|
||||
// // Redistribution of this software is strictly not allowed.
|
||||
// // Copy of this software can be obtained from unity asset store only.
|
||||
// // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// // FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// // THE SOFTWARE.
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using UnityEngine;
|
||||
using UnityEngine.InputSystem;
|
||||
using UnityEngine.SceneManagement;
|
||||
using WordsToolkit.Scripts.System;
|
||||
using VContainer;
|
||||
|
||||
namespace WordsToolkit.Scripts.Popups
|
||||
{
|
||||
public class MenuManager : MonoBehaviour
|
||||
{
|
||||
public Fader fader;
|
||||
private List<Popup> popupStack = new();
|
||||
|
||||
[SerializeField]
|
||||
private Canvas canvas;
|
||||
|
||||
[Inject]
|
||||
private IPopupFactory popupFactory;
|
||||
|
||||
private void Awake()
|
||||
{
|
||||
DontDestroyOnLoad(this);
|
||||
}
|
||||
|
||||
private void OnEnable()
|
||||
{
|
||||
Popup.OnClosePopup += ClosePopup;
|
||||
Popup.OnBeforeCloseAction += OnBeforeCloseAction;
|
||||
SceneManager.activeSceneChanged += OnSceneLoaded;
|
||||
}
|
||||
|
||||
private void OnBeforeCloseAction(Popup popup)
|
||||
{
|
||||
if (fader != null && popupStack.Count == 1)
|
||||
{
|
||||
fader.FadeOut();
|
||||
}
|
||||
}
|
||||
|
||||
private void OnSceneLoaded(Scene scene, Scene scene1)
|
||||
{
|
||||
if (canvas == null && this != null)
|
||||
{
|
||||
canvas = GetComponent<Canvas>();
|
||||
}
|
||||
|
||||
canvas.worldCamera = Camera.main;
|
||||
}
|
||||
|
||||
private void OnDisable()
|
||||
{
|
||||
Popup.OnClosePopup -= ClosePopup;
|
||||
SceneManager.activeSceneChanged -= OnSceneLoaded;
|
||||
Popup.OnBeforeCloseAction -= OnBeforeCloseAction;
|
||||
}
|
||||
|
||||
public T ShowPopup<T>(Action onShow = null, Action<EPopupResult> onClose = null) where T : Popup
|
||||
{
|
||||
if (popupStack.OfType<T>().Any())
|
||||
{
|
||||
return popupStack.OfType<T>().First();
|
||||
}
|
||||
|
||||
var popup = popupFactory.CreatePopup<T>(transform);
|
||||
return (T)ShowPopupInternal(popup, onShow, onClose);
|
||||
}
|
||||
|
||||
public Popup ShowPopup(string pathWithType, Action onShow = null, Action<EPopupResult> onClose = null)
|
||||
{
|
||||
if (popupStack.Any(p => p.GetType().Name == pathWithType.Split('/').Last()))
|
||||
{
|
||||
return popupStack.First(p => p.GetType().Name == pathWithType.Split('/').Last());
|
||||
}
|
||||
|
||||
var popup = popupFactory.CreatePopup(pathWithType, transform);
|
||||
return ShowPopupInternal(popup, onShow, onClose);
|
||||
}
|
||||
|
||||
public Popup ShowPopup(Popup popupPrefab, Action onShow = null, Action<EPopupResult> onClose = null)
|
||||
{
|
||||
if (popupStack.Any(p => p.GetType() == popupPrefab.GetType()))
|
||||
{
|
||||
return popupStack.First(p => p.GetType() == popupPrefab.GetType());
|
||||
}
|
||||
var popup = popupFactory.CreatePopup(popupPrefab, transform);
|
||||
return ShowPopupInternal(popup, onShow, onClose);
|
||||
}
|
||||
|
||||
private Popup ShowPopupInternal(Popup popup, Action onShow = null, Action<EPopupResult> onClose = null)
|
||||
{
|
||||
if (popupStack.Count > 0)
|
||||
{
|
||||
popupStack.Last().Hide();
|
||||
}
|
||||
|
||||
popupStack.Add(popup);
|
||||
popup.Show<Popup>(onShow, onClose);
|
||||
|
||||
if (fader != null && popupStack.Count > 0 && popup.fade)
|
||||
{
|
||||
fader.transform.SetSiblingIndex(popup.transform.GetSiblingIndex() - 1);
|
||||
fader.FadeIn(popup.fadeAlpha);
|
||||
}
|
||||
|
||||
return popup;
|
||||
}
|
||||
|
||||
private void ClosePopup(Popup popupClose)
|
||||
{
|
||||
if (popupStack.Count > 0)
|
||||
{
|
||||
popupStack.Remove(popupClose);
|
||||
if (popupStack.Count > 0)
|
||||
{
|
||||
var popup = popupStack.Last();
|
||||
var siblingIndex = popup.transform.GetSiblingIndex() - 1;
|
||||
siblingIndex = Mathf.Clamp(siblingIndex, 0, transform.childCount - 1);
|
||||
fader.transform.SetSiblingIndex(siblingIndex);
|
||||
popup.OnActivate();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void ShowPurchased(GameObject imagePrefab, string boostName)
|
||||
{
|
||||
var menu = ShowPopup<PurchasedMenu>();
|
||||
menu.GetComponent<PurchasedMenu>().SetIconSprite(imagePrefab, boostName);
|
||||
}
|
||||
|
||||
private void Update()
|
||||
{
|
||||
if (Application.platform != RuntimePlatform.IPhonePlayer)
|
||||
{
|
||||
if (Keyboard.current[Key.Escape].wasReleasedThisFrame)
|
||||
{
|
||||
if (popupStack is { Count: > 0 })
|
||||
{
|
||||
var closeButton = popupStack.Last().closeButton;
|
||||
if (closeButton != null)
|
||||
{
|
||||
closeButton.onClick?.Invoke();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public T GetPopupOpened<T>() where T : Popup
|
||||
{
|
||||
foreach (var popup in popupStack)
|
||||
{
|
||||
if (popup.GetType() == typeof(T))
|
||||
{
|
||||
return (T)popup;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public void CloseAllPopups()
|
||||
{
|
||||
for (var i = 0; i < popupStack.Count; i++)
|
||||
{
|
||||
var popup = popupStack[i];
|
||||
popup.Close();
|
||||
}
|
||||
|
||||
popupStack.Clear();
|
||||
}
|
||||
|
||||
public bool IsAnyPopupOpened()
|
||||
{
|
||||
return popupStack.Count > 0;
|
||||
}
|
||||
|
||||
public Popup GetLastPopup()
|
||||
{
|
||||
return popupStack.Last();
|
||||
}
|
||||
|
||||
public MainMenu GetMainMenu()
|
||||
{
|
||||
return FindObjectOfType<MainMenu>();
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 168b675c084949949d771ac92e62757a
|
||||
timeCreated: 1725686357
|
||||
197
Assets/WordConnectGameToolkit/Scripts/Popups/MenuPlay.cs
Normal file
197
Assets/WordConnectGameToolkit/Scripts/Popups/MenuPlay.cs
Normal file
@ -0,0 +1,197 @@
|
||||
// // ©2015 - 2025 Candy Smith
|
||||
// // All rights reserved
|
||||
// // Redistribution of this software is strictly not allowed.
|
||||
// // Copy of this software can be obtained from unity asset store only.
|
||||
// // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// // FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// // THE SOFTWARE.
|
||||
|
||||
using TMPro;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
using WordsToolkit.Scripts.Levels;
|
||||
using WordsToolkit.Scripts.System;
|
||||
using VContainer;
|
||||
using WordsToolkit.Scripts.Gameplay.Managers;
|
||||
using WordsToolkit.Scripts.GUI;
|
||||
|
||||
namespace WordsToolkit.Scripts.Popups
|
||||
{
|
||||
public class MenuPlay : Popup
|
||||
{
|
||||
public Image[] backgroundImages;
|
||||
public Slider scrollBar;
|
||||
public TextMeshProUGUI counter;
|
||||
public Button play;
|
||||
|
||||
private LevelGroup currentGroup;
|
||||
private Level currentLevel;
|
||||
|
||||
[Inject]
|
||||
private SceneLoader sceneLoader;
|
||||
[Inject]
|
||||
private BackgroundChanger backgroundChanger;
|
||||
[SerializeField]
|
||||
private GameObject hardLabel;
|
||||
|
||||
private void OnEnable()
|
||||
{
|
||||
stateManager.HideMain();
|
||||
|
||||
play.onClick.AddListener(Play);
|
||||
|
||||
// Get the current level from GameDataManager
|
||||
currentLevel = GameDataManager.GetLevel();
|
||||
// If current level is null, try to find previous level
|
||||
if (currentLevel == null)
|
||||
{
|
||||
TryLoadPreviousLevel();
|
||||
}
|
||||
|
||||
currentGroup = currentLevel?.GetGroup();
|
||||
// Try to find a background sprite following the hierarchy
|
||||
Sprite backgroundToUse = GetBackgroundFromHierarchy();
|
||||
|
||||
backgroundChanger.SetBackground(backgroundToUse);
|
||||
|
||||
if (backgroundToUse != null && backgroundImages.Length > 0)
|
||||
{
|
||||
// Set sprite for all background images
|
||||
foreach (var bg in backgroundImages)
|
||||
{
|
||||
bg.sprite = backgroundToUse;
|
||||
}
|
||||
}
|
||||
|
||||
// Update progress UI elements
|
||||
UpdateProgressUI();
|
||||
}
|
||||
|
||||
public override void AfterShowAnimation()
|
||||
{
|
||||
base.AfterShowAnimation();
|
||||
if (currentLevel.isHardLevel)
|
||||
{
|
||||
hardLabel.SetActive(true); hardLabel.GetComponent<Animator>().Play("HardLabel");
|
||||
}
|
||||
}
|
||||
|
||||
private void TryLoadPreviousLevel()
|
||||
{
|
||||
Debug.LogWarning("Current level is null, trying to load previous level");
|
||||
|
||||
// Get current level number
|
||||
int currentLevelNum = GameDataManager.GetLevelNum();
|
||||
|
||||
// Try to find a valid previous level
|
||||
int previousLevel = currentLevelNum - 1;
|
||||
while (previousLevel > 0)
|
||||
{
|
||||
GameDataManager.SetLevelNum(previousLevel);
|
||||
Level levelData = GameDataManager.GetLevel();
|
||||
if (levelData != null)
|
||||
{
|
||||
currentLevel = levelData;
|
||||
Debug.Log($"Loaded previous level: {previousLevel}");
|
||||
break;
|
||||
}
|
||||
previousLevel--;
|
||||
}
|
||||
|
||||
// If we still couldn't find a valid level, log an error
|
||||
if (currentLevel == null)
|
||||
{
|
||||
Debug.LogError("Could not find any valid level to load");
|
||||
}
|
||||
}
|
||||
|
||||
private void Play()
|
||||
{
|
||||
// Make sure we have a valid level to play
|
||||
if (currentLevel == null)
|
||||
{
|
||||
Debug.LogWarning("Attempting to play with null level, trying to load previous level");
|
||||
TryLoadPreviousLevel();
|
||||
|
||||
// If still null, we can't play
|
||||
if (currentLevel == null)
|
||||
{
|
||||
Debug.LogError("No valid level to play");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
GameDataManager.SetLevel(currentLevel);
|
||||
sceneLoader.StartGameScene();
|
||||
Close();
|
||||
}
|
||||
|
||||
private void UpdateProgressUI()
|
||||
{
|
||||
if (counter != null && currentLevel != null)
|
||||
{
|
||||
// Check if we have a valid group
|
||||
if (currentGroup == null || currentGroup.levels == null)
|
||||
{
|
||||
counter.text = "0/0";
|
||||
scrollBar.minValue = 0;
|
||||
scrollBar.maxValue = 1;
|
||||
scrollBar.value = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
// Get the total number of levels in the group
|
||||
int totalLevels = currentGroup.levels.Count;
|
||||
|
||||
// Find the index of current level in the group
|
||||
int currentIndex = currentGroup.levels.IndexOf(currentLevel);
|
||||
|
||||
// If level is not found in the group, set index to 0
|
||||
if (currentIndex < 0)
|
||||
{
|
||||
currentIndex = 0;
|
||||
}
|
||||
|
||||
// Update counter and scrollbar
|
||||
counter.text = $"{currentIndex}/{totalLevels}";
|
||||
scrollBar.minValue = 0;
|
||||
scrollBar.maxValue = totalLevels;
|
||||
scrollBar.value = currentIndex;
|
||||
}
|
||||
}
|
||||
|
||||
private Sprite GetBackgroundFromHierarchy()
|
||||
{
|
||||
if (currentGroup == null) return null;
|
||||
|
||||
// Start from the top-most parent
|
||||
LevelGroup current = currentGroup;
|
||||
while (current.parentGroup != null)
|
||||
{
|
||||
if (current.parentGroup.background != null)
|
||||
{
|
||||
return current.parentGroup.background;
|
||||
}
|
||||
current = current.parentGroup;
|
||||
}
|
||||
|
||||
// Then check current group
|
||||
if (currentGroup.background != null)
|
||||
{
|
||||
return currentGroup.background;
|
||||
}
|
||||
|
||||
// Finally check the level itself
|
||||
if (currentLevel != null && currentLevel.background != null)
|
||||
{
|
||||
return currentLevel.background;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 3ab97f16234641e39222de5d96eb8d74
|
||||
timeCreated: 1742810007
|
||||
53
Assets/WordConnectGameToolkit/Scripts/Popups/NoAds.cs
Normal file
53
Assets/WordConnectGameToolkit/Scripts/Popups/NoAds.cs
Normal file
@ -0,0 +1,53 @@
|
||||
// // ©2015 - 2025 Candy Smith
|
||||
// // All rights reserved
|
||||
// // Redistribution of this software is strictly not allowed.
|
||||
// // Copy of this software can be obtained from unity asset store only.
|
||||
// // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// // FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// // THE SOFTWARE.
|
||||
|
||||
using WordsToolkit.Scripts.Enums;
|
||||
using WordsToolkit.Scripts.GUI;
|
||||
using WordsToolkit.Scripts.GUI.Buttons;
|
||||
using WordsToolkit.Scripts.Services;
|
||||
using WordsToolkit.Scripts.Services.IAP;
|
||||
using WordsToolkit.Scripts.System;
|
||||
|
||||
namespace WordsToolkit.Scripts.Popups
|
||||
{
|
||||
public class NoAds : Popup
|
||||
{
|
||||
public CustomButton removeAdsButton;
|
||||
public ProductID productID;
|
||||
|
||||
private void OnEnable()
|
||||
{
|
||||
removeAdsButton.onClick.AddListener(RemoveAds);
|
||||
EventManager.GetEvent<string>(EGameEvent.PurchaseSucceeded).Subscribe(PurchaseSucceeded);
|
||||
}
|
||||
|
||||
protected override void OnDisable()
|
||||
{
|
||||
base.OnDisable();
|
||||
EventManager.GetEvent<string>(EGameEvent.PurchaseSucceeded).Unsubscribe(PurchaseSucceeded);
|
||||
}
|
||||
|
||||
private void PurchaseSucceeded(string obj)
|
||||
{
|
||||
if (obj == productID.ID)
|
||||
{
|
||||
adsManager.RemoveAds();
|
||||
Close();
|
||||
}
|
||||
}
|
||||
|
||||
private void RemoveAds()
|
||||
{
|
||||
iapManager.BuyProduct(productID.ID);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: aa1ef191b5a343e9937c2ee97a24b843
|
||||
timeCreated: 1726157597
|
||||
@ -0,0 +1,18 @@
|
||||
// // ©2015 - 2025 Candy Smith
|
||||
// // All rights reserved
|
||||
// // Redistribution of this software is strictly not allowed.
|
||||
// // Copy of this software can be obtained from unity asset store only.
|
||||
// // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// // FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// // THE SOFTWARE.
|
||||
|
||||
namespace WordsToolkit.Scripts.Popups
|
||||
{
|
||||
public class NoAdsItemPurchase : ItemPurchase
|
||||
{
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: ecf8678021564e0c8ccdb00b43162f58
|
||||
timeCreated: 1742453759
|
||||
258
Assets/WordConnectGameToolkit/Scripts/Popups/Popup.cs
Normal file
258
Assets/WordConnectGameToolkit/Scripts/Popups/Popup.cs
Normal file
@ -0,0 +1,258 @@
|
||||
// // ©2015 - 2025 Candy Smith
|
||||
// // All rights reserved
|
||||
// // Redistribution of this software is strictly not allowed.
|
||||
// // Copy of this software can be obtained from unity asset store only.
|
||||
// // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// // FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// // THE SOFTWARE.
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using DG.Tweening;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
using VContainer;
|
||||
using WordsToolkit.Scripts.Audio;
|
||||
using WordsToolkit.Scripts.Data;
|
||||
using WordsToolkit.Scripts.Gameplay.Managers;
|
||||
using WordsToolkit.Scripts.GUI;
|
||||
using WordsToolkit.Scripts.GUI.Buttons;
|
||||
using WordsToolkit.Scripts.Localization;
|
||||
using WordsToolkit.Scripts.NLP;
|
||||
using WordsToolkit.Scripts.Services;
|
||||
using WordsToolkit.Scripts.Services.IAP;
|
||||
using WordsToolkit.Scripts.Settings;
|
||||
using WordsToolkit.Scripts.System;
|
||||
using WordsToolkit.Scripts.Utils;
|
||||
|
||||
namespace WordsToolkit.Scripts.Popups
|
||||
{
|
||||
[RequireComponent(typeof(Animator), typeof(CanvasGroup))]
|
||||
public class Popup : MonoBehaviour
|
||||
{
|
||||
public bool fade = true;
|
||||
private Animator animator;
|
||||
public CustomButton closeButton;
|
||||
private CanvasGroup canvasGroup;
|
||||
public Action OnShowAction;
|
||||
public Action<EPopupResult> OnCloseAction;
|
||||
protected EPopupResult result;
|
||||
protected GameManager gameManager;
|
||||
protected MenuManager menuManager;
|
||||
protected LevelManager levelManager;
|
||||
protected StateManager stateManager;
|
||||
protected GameSettings gameSettings;
|
||||
protected IAdsManager adsManager;
|
||||
protected IIAPManager iapManager;
|
||||
protected IAudioService audioService;
|
||||
protected ResourceManager resourceManager;
|
||||
public delegate void PopupEvents(Popup popup);
|
||||
|
||||
public static event PopupEvents OnOpenPopup;
|
||||
public static event PopupEvents OnClosePopup;
|
||||
public static event PopupEvents OnBeforeCloseAction;
|
||||
protected IObjectResolver _container;
|
||||
|
||||
[TagFieldUI, SerializeField]
|
||||
public string[] tagsToShow;
|
||||
private Dictionary<Transform, Transform> _tagsToShowDic = new Dictionary<Transform, Transform>();
|
||||
[SerializeField]
|
||||
private bool isPopupAboveTags;
|
||||
|
||||
protected ILocalizationService localizationManager;
|
||||
protected FieldManager fieldManager;
|
||||
protected ICustomWordRepository customWordRepository;
|
||||
[SerializeField]
|
||||
public float fadeAlpha = 1;
|
||||
|
||||
[SerializeField]
|
||||
private AudioClip appearSound;
|
||||
|
||||
[SerializeField]
|
||||
private AudioClip disappearSound;
|
||||
|
||||
|
||||
[Inject]
|
||||
public void Construct(GameManager gameManager, MenuManager menuManager, LevelManager levelManager, StateManager stateManager, GameSettings gameSettings, IAdsManager adsManager, IIAPManager iapManager, IAudioService audioService, ResourceManager resourceManager, IObjectResolver container, ILocalizationService localizationManager, FieldManager fieldManager, ICustomWordRepository customWordRepository)
|
||||
{
|
||||
this.gameManager = gameManager;
|
||||
this.menuManager = menuManager;
|
||||
this.levelManager = levelManager;
|
||||
this.stateManager = stateManager;
|
||||
this.gameSettings = gameSettings;
|
||||
this.adsManager = adsManager;
|
||||
this.iapManager = iapManager;
|
||||
this.audioService = audioService;
|
||||
this.resourceManager = resourceManager;
|
||||
_container = container;
|
||||
this.localizationManager = localizationManager;
|
||||
this.fieldManager = fieldManager;
|
||||
this.customWordRepository = customWordRepository;
|
||||
}
|
||||
|
||||
protected virtual void Awake()
|
||||
{
|
||||
animator = GetComponent<Animator>();
|
||||
canvasGroup = GetComponent<CanvasGroup>();
|
||||
if (closeButton != null)
|
||||
{
|
||||
closeButton.onClick.AddListener(Close);
|
||||
}
|
||||
}
|
||||
|
||||
public void Show<T>(Action onShow = null, Action<EPopupResult> onClose = null)
|
||||
{
|
||||
if (onShow != null)
|
||||
{
|
||||
OnShowAction = onShow;
|
||||
}
|
||||
|
||||
if (onClose != null)
|
||||
{
|
||||
OnCloseAction = onClose;
|
||||
}
|
||||
|
||||
OnOpenPopup?.Invoke(this);
|
||||
PlayShowAnimation();
|
||||
OnActivate();
|
||||
}
|
||||
|
||||
public List<GameObject> ShowTags(string[] tutorialDataTagsToShow)
|
||||
{
|
||||
List<GameObject> lObjects = new List<GameObject>();
|
||||
tagsToShow = tutorialDataTagsToShow;
|
||||
foreach (var t in tutorialDataTagsToShow)
|
||||
{
|
||||
var tagObject = GameObject.FindGameObjectsWithTag(t).FirstOrDefault(i=>i.gameObject.activeSelf);
|
||||
if (tagObject)
|
||||
{
|
||||
lObjects.Add(tagObject);
|
||||
MakeObjectVisible(tagObject);
|
||||
}
|
||||
}
|
||||
|
||||
if (isPopupAboveTags)
|
||||
{
|
||||
var canvas = transform.AddComponentIfNotExists<Canvas>();
|
||||
canvas.overrideSorting = true;
|
||||
canvas.sortingLayerID = SortingLayer.NameToID("UI");
|
||||
canvas.sortingOrder = 5; // Ensure popup is above tags
|
||||
}
|
||||
|
||||
return lObjects;
|
||||
}
|
||||
|
||||
public void MakeObjectVisible(GameObject tagObject, int sortingOrder = 4)
|
||||
{
|
||||
_tagsToShowDic.TryAdd(tagObject.transform, tagObject.transform.parent);
|
||||
var canvas = tagObject.AddComponentIfNotExists<Canvas>();
|
||||
if (canvas != null && canvas.sortingLayerID == SortingLayer.NameToID("UI"))
|
||||
return;
|
||||
canvas.overrideSorting = true;
|
||||
canvas.sortingLayerID = SortingLayer.NameToID("UI");
|
||||
canvas.sortingOrder = sortingOrder;
|
||||
tagObject.AddComponentIfNotExists<GraphicRaycaster>();
|
||||
}
|
||||
|
||||
private void PlayShowAnimation()
|
||||
{
|
||||
if (animator != null)
|
||||
{
|
||||
animator.Play("popup_show");
|
||||
}
|
||||
}
|
||||
|
||||
public virtual void ShowAnimationSound()
|
||||
{
|
||||
audioService.PlaySound(appearSound);
|
||||
}
|
||||
|
||||
public virtual void AfterShowAnimation()
|
||||
{
|
||||
OnShowAction?.Invoke();
|
||||
}
|
||||
|
||||
public virtual void CloseAnimationSound()
|
||||
{
|
||||
audioService.PlaySound(disappearSound);
|
||||
}
|
||||
|
||||
public virtual void Close()
|
||||
{
|
||||
if (closeButton)
|
||||
{
|
||||
closeButton.interactable = false;
|
||||
}
|
||||
|
||||
if (canvasGroup != null)
|
||||
{
|
||||
canvasGroup.interactable = false;
|
||||
}
|
||||
|
||||
OnBeforeCloseAction?.Invoke(this);
|
||||
if (animator != null)
|
||||
{
|
||||
animator.Play("popup_hide");
|
||||
}
|
||||
HideTags();
|
||||
}
|
||||
|
||||
private void HideTags()
|
||||
{
|
||||
foreach (var t in _tagsToShowDic)
|
||||
{
|
||||
if (!t.Key || !t.Key.gameObject)
|
||||
continue;
|
||||
var customButton = t.Key?.gameObject?.GetComponent<CustomButton>();
|
||||
if (customButton)
|
||||
{
|
||||
customButton.interactable = true;
|
||||
}
|
||||
Destroy(t.Key.GetComponent<GraphicRaycaster>());
|
||||
Destroy(t.Key.GetComponent<Canvas>());
|
||||
}
|
||||
_tagsToShowDic.Clear();
|
||||
}
|
||||
|
||||
public virtual void AfterHideAnimation()
|
||||
{
|
||||
OnClosePopup?.Invoke(this);
|
||||
OnCloseAction?.Invoke(result);
|
||||
Destroy(gameObject, .5f);
|
||||
}
|
||||
|
||||
protected virtual void OnDisable()
|
||||
{
|
||||
DOTween.Kill(gameObject);
|
||||
}
|
||||
|
||||
public void OnActivate()
|
||||
{
|
||||
ShowTags(tagsToShow);
|
||||
canvasGroup.interactable = true;
|
||||
canvasGroup.DOFade(1, 0.1f);
|
||||
}
|
||||
|
||||
public virtual void Hide()
|
||||
{
|
||||
canvasGroup.interactable = false;
|
||||
canvasGroup.DOFade(0, 0.5f);
|
||||
}
|
||||
|
||||
public void CloseDelay()
|
||||
{
|
||||
Invoke(nameof(Close), 0.5f);
|
||||
}
|
||||
|
||||
protected void StopInteration()
|
||||
{
|
||||
canvasGroup.interactable = false;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: c25b7a112efc4b81997a0dac8488b2c9
|
||||
timeCreated: 1725685853
|
||||
@ -0,0 +1,38 @@
|
||||
// // ©2015 - 2025 Candy Smith
|
||||
// // All rights reserved
|
||||
// // Redistribution of this software is strictly not allowed.
|
||||
// // Copy of this software can be obtained from unity asset store only.
|
||||
// // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// // FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// // THE SOFTWARE.
|
||||
|
||||
using UnityEngine.SceneManagement;
|
||||
using WordsToolkit.Scripts.Audio;
|
||||
|
||||
namespace WordsToolkit.Scripts.Popups
|
||||
{
|
||||
public class PopupWithCurrencyLabel : Popup
|
||||
{
|
||||
private UIPanel _panel;
|
||||
|
||||
public override void AfterShowAnimation()
|
||||
{
|
||||
_panel = FindObjectOfType<UIPanel>(true);
|
||||
_panel?.gameObject.SetActive(true);
|
||||
base.AfterShowAnimation();
|
||||
}
|
||||
|
||||
public override void Close()
|
||||
{
|
||||
base.Close();
|
||||
if (SceneManager.GetActiveScene().name != "main")
|
||||
{
|
||||
_panel?.gameObject.SetActive(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: abb10cf834b04599b175e39f80b10ae3
|
||||
timeCreated: 1725685718
|
||||
89
Assets/WordConnectGameToolkit/Scripts/Popups/PreFailed.cs
Normal file
89
Assets/WordConnectGameToolkit/Scripts/Popups/PreFailed.cs
Normal file
@ -0,0 +1,89 @@
|
||||
// // ©2015 - 2025 Candy Smith
|
||||
// // All rights reserved
|
||||
// // Redistribution of this software is strictly not allowed.
|
||||
// // Copy of this software can be obtained from unity asset store only.
|
||||
// // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// // FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// // THE SOFTWARE.
|
||||
|
||||
using DG.Tweening;
|
||||
using TMPro;
|
||||
using UnityEngine;
|
||||
using WordsToolkit.Scripts.Audio;
|
||||
using WordsToolkit.Scripts.Data;
|
||||
using WordsToolkit.Scripts.Enums;
|
||||
using WordsToolkit.Scripts.GUI;
|
||||
using WordsToolkit.Scripts.GUI.Buttons;
|
||||
using WordsToolkit.Scripts.System;
|
||||
|
||||
namespace WordsToolkit.Scripts.Popups
|
||||
{
|
||||
public class PreFailed : PopupWithCurrencyLabel
|
||||
{
|
||||
public TextMeshProUGUI continuePrice;
|
||||
public TextMeshProUGUI timerText;
|
||||
|
||||
public CustomButton continueButton;
|
||||
public CustomButton rewardButton;
|
||||
public CustomButton againButton;
|
||||
private int price;
|
||||
[SerializeField]
|
||||
private AudioClip warningTime;
|
||||
|
||||
[SerializeField]
|
||||
private AudioClip failedSound;
|
||||
|
||||
private void OnEnable()
|
||||
{
|
||||
price = gameSettings.continuePrice;
|
||||
continuePrice.text = price.ToString();
|
||||
continueButton.onClick.AddListener(Continue);
|
||||
|
||||
closeButton.onClick.AddListener(Cancel);
|
||||
|
||||
timerText.text = "<color=#FFF76B> +" + gameSettings.continueTime + "</color> sec";
|
||||
audioService.PlaySound(warningTime);
|
||||
rewardButton.gameObject.SetActive(gameSettings.enableAds);
|
||||
againButton.onClick.AddListener(Again);
|
||||
}
|
||||
|
||||
private void Cancel()
|
||||
{
|
||||
result = EPopupResult.Cancel;
|
||||
audioService.PlaySound(failedSound);
|
||||
Close();
|
||||
}
|
||||
|
||||
public override void Close()
|
||||
{
|
||||
base.Close();
|
||||
}
|
||||
|
||||
private void Again()
|
||||
{
|
||||
gameManager.RestartLevel();
|
||||
Close();
|
||||
}
|
||||
|
||||
private void Continue()
|
||||
{
|
||||
var coinsResource = resourceManager.GetResource("Coins");
|
||||
if (resourceManager.ConsumeWithEffects(coinsResource, price))
|
||||
{
|
||||
StopInteration();
|
||||
DOVirtual.DelayedCall(0.5f, ContinueGame);
|
||||
}
|
||||
}
|
||||
|
||||
public void ContinueGame()
|
||||
{
|
||||
result = EPopupResult.Continue;
|
||||
EventManager.GameStatus = EGameState.Playing;
|
||||
Close();
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 00e91d4ae82247a8996b0a7167979103
|
||||
timeCreated: 1727773522
|
||||
18
Assets/WordConnectGameToolkit/Scripts/Popups/PrePlay.cs
Normal file
18
Assets/WordConnectGameToolkit/Scripts/Popups/PrePlay.cs
Normal file
@ -0,0 +1,18 @@
|
||||
// // ©2015 - 2025 Candy Smith
|
||||
// // All rights reserved
|
||||
// // Redistribution of this software is strictly not allowed.
|
||||
// // Copy of this software can be obtained from unity asset store only.
|
||||
// // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// // FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// // THE SOFTWARE.
|
||||
|
||||
namespace WordsToolkit.Scripts.Popups
|
||||
{
|
||||
public class PrePlay : Banner
|
||||
{
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: b94c41c20da245d087d7f6f49e086dc1
|
||||
timeCreated: 1729181797
|
||||
28
Assets/WordConnectGameToolkit/Scripts/Popups/PreWin.cs
Normal file
28
Assets/WordConnectGameToolkit/Scripts/Popups/PreWin.cs
Normal file
@ -0,0 +1,28 @@
|
||||
// // ©2015 - 2025 Candy Smith
|
||||
// // All rights reserved
|
||||
// // Redistribution of this software is strictly not allowed.
|
||||
// // Copy of this software can be obtained from unity asset store only.
|
||||
// // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// // FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// // THE SOFTWARE.
|
||||
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
namespace WordsToolkit.Scripts.Popups
|
||||
{
|
||||
public class PreWin : Banner
|
||||
{
|
||||
protected override IEnumerator Wait()
|
||||
{
|
||||
audioService.PlayWin();
|
||||
yield return new WaitForSeconds(.5f);
|
||||
Close();
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 164829b7963d44e38d8fa37253d80a5c
|
||||
timeCreated: 1729061890
|
||||
@ -0,0 +1,32 @@
|
||||
// // ©2015 - 2025 Candy Smith
|
||||
// // All rights reserved
|
||||
// // Redistribution of this software is strictly not allowed.
|
||||
// // Copy of this software can be obtained from unity asset store only.
|
||||
// // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// // FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// // THE SOFTWARE.
|
||||
|
||||
using TMPro;
|
||||
using UnityEngine;
|
||||
|
||||
namespace WordsToolkit.Scripts.Popups
|
||||
{
|
||||
public class PurchasedMenu : Popup
|
||||
{
|
||||
[SerializeField]
|
||||
private Transform icon;
|
||||
|
||||
[SerializeField]
|
||||
private TextMeshProUGUI text;
|
||||
|
||||
public void SetIconSprite(GameObject imagePrefab, string boostName)
|
||||
{
|
||||
Instantiate(imagePrefab, icon);
|
||||
text.text = "You got " + boostName + " boost";
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: b6d0cb9b75bd454297d110789b964b5e
|
||||
timeCreated: 1725686465
|
||||
28
Assets/WordConnectGameToolkit/Scripts/Popups/Quit.cs
Normal file
28
Assets/WordConnectGameToolkit/Scripts/Popups/Quit.cs
Normal file
@ -0,0 +1,28 @@
|
||||
// // ©2015 - 2025 Candy Smith
|
||||
// // All rights reserved
|
||||
// // Redistribution of this software is strictly not allowed.
|
||||
// // Copy of this software can be obtained from unity asset store only.
|
||||
// // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// // FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// // THE SOFTWARE.
|
||||
|
||||
using UnityEngine;
|
||||
using WordsToolkit.Scripts.GUI;
|
||||
using WordsToolkit.Scripts.GUI.Buttons;
|
||||
|
||||
namespace WordsToolkit.Scripts.Popups
|
||||
{
|
||||
public class Quit : PopupWithCurrencyLabel
|
||||
{
|
||||
public CustomButton yes;
|
||||
|
||||
private void OnEnable()
|
||||
{
|
||||
yes.onClick.AddListener(Application.Quit);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 1627a1f4ce114cc486cc853f8a946e12
|
||||
timeCreated: 1726165082
|
||||
3
Assets/WordConnectGameToolkit/Scripts/Popups/Reward.meta
Normal file
3
Assets/WordConnectGameToolkit/Scripts/Popups/Reward.meta
Normal file
@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 609aa55a9fc44ea4b313194a00028fbd
|
||||
timeCreated: 1726114462
|
||||
@ -0,0 +1,47 @@
|
||||
// // ©2015 - 2025 Candy Smith
|
||||
// // All rights reserved
|
||||
// // Redistribution of this software is strictly not allowed.
|
||||
// // Copy of this software can be obtained from unity asset store only.
|
||||
// // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// // FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// // THE SOFTWARE.
|
||||
|
||||
using TMPro;
|
||||
using UnityEngine;
|
||||
using WordsToolkit.Scripts.Data;
|
||||
using WordsToolkit.Scripts.GUI.Labels;
|
||||
using WordsToolkit.Scripts.Settings;
|
||||
|
||||
namespace WordsToolkit.Scripts.Popups.Reward
|
||||
{
|
||||
public class RewardPopup : PopupWithCurrencyLabel
|
||||
{
|
||||
public Transform iconPos;
|
||||
private int _count;
|
||||
private ResourceObject _resource;
|
||||
private RewardSettingSpin rewardVisual;
|
||||
|
||||
public TextMeshProUGUI countText;
|
||||
|
||||
public void SetReward(RewardSettingSpin rewardVisual)
|
||||
{
|
||||
this.rewardVisual = rewardVisual;
|
||||
_count = rewardVisual.count;
|
||||
countText.text = _count.ToString();
|
||||
_resource = rewardVisual.resource;
|
||||
}
|
||||
|
||||
public override void Close()
|
||||
{
|
||||
StopInteration();
|
||||
_resource.AddAnimated(_count, iconPos.position, animationSourceObject: null, callback: () =>
|
||||
{
|
||||
base.Close();
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: f9adedea92f702d4995617ce27d3831d
|
||||
timeCreated: 1458824059
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@ -0,0 +1,27 @@
|
||||
// // ©2015 - 2025 Candy Smith
|
||||
// // All rights reserved
|
||||
// // Redistribution of this software is strictly not allowed.
|
||||
// // Copy of this software can be obtained from unity asset store only.
|
||||
// // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// // FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// // THE SOFTWARE.
|
||||
|
||||
using TMPro;
|
||||
using UnityEngine;
|
||||
|
||||
namespace WordsToolkit.Scripts.Popups.Reward
|
||||
{
|
||||
public class RewardVisual : MonoBehaviour
|
||||
{
|
||||
public TextMeshProUGUI countText;
|
||||
|
||||
public void SetCount(int count)
|
||||
{
|
||||
countText.text = count.ToString();
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 119251b6ae834c88a639a83ccec882d7
|
||||
timeCreated: 1691995253
|
||||
@ -0,0 +1,21 @@
|
||||
// // ©2015 - 2025 Candy Smith
|
||||
// // All rights reserved
|
||||
// // Redistribution of this software is strictly not allowed.
|
||||
// // Copy of this software can be obtained from unity asset store only.
|
||||
// // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// // FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// // THE SOFTWARE.
|
||||
|
||||
using WordsToolkit.Scripts.GUI;
|
||||
using WordsToolkit.Scripts.GUI.Buttons;
|
||||
|
||||
namespace WordsToolkit.Scripts.Popups.Reward
|
||||
{
|
||||
public class RewardedButton : CustomButton
|
||||
{
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 9b56a70df4a6f465ea1e315972ed2f33
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@ -0,0 +1,58 @@
|
||||
// // ©2015 - 2025 Candy Smith
|
||||
// // All rights reserved
|
||||
// // Redistribution of this software is strictly not allowed.
|
||||
// // Copy of this software can be obtained from unity asset store only.
|
||||
// // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// // FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// // THE SOFTWARE.
|
||||
|
||||
using UnityEngine;
|
||||
using UnityEngine.Events;
|
||||
using VContainer;
|
||||
using WordsToolkit.Scripts.GUI;
|
||||
using WordsToolkit.Scripts.GUI.Buttons;
|
||||
using WordsToolkit.Scripts.Services;
|
||||
using WordsToolkit.Scripts.Services.Ads.AdUnits;
|
||||
|
||||
namespace WordsToolkit.Scripts.Popups.Reward
|
||||
{
|
||||
public class RewardedButtonHandler : MonoBehaviour
|
||||
{
|
||||
[SerializeField]
|
||||
private AdReference adReference;
|
||||
|
||||
[SerializeField]
|
||||
private CustomButton rewardedButton;
|
||||
|
||||
[SerializeField]
|
||||
private UnityEvent onRewardedAdComplete;
|
||||
|
||||
[SerializeField]
|
||||
private UnityEvent onRewardedShow;
|
||||
|
||||
[Inject]
|
||||
private IAdsManager adsManager;
|
||||
|
||||
private void Awake()
|
||||
{
|
||||
rewardedButton.onClick.AddListener(ShowRewardedAd);
|
||||
}
|
||||
|
||||
private void ShowRewardedAd()
|
||||
{
|
||||
if (adsManager.IsRewardedAvailable(adReference))
|
||||
{
|
||||
onRewardedShow?.Invoke();
|
||||
adsManager.ShowAdByType(adReference, _ => onRewardedAdComplete?.Invoke());
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.Log("Rewarded ad is not available");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: dece0aac2cf9463587dade7a67633f5d
|
||||
timeCreated: 1726040785
|
||||
@ -0,0 +1,48 @@
|
||||
// // ©2015 - 2025 Candy Smith
|
||||
// // All rights reserved
|
||||
// // Redistribution of this software is strictly not allowed.
|
||||
// // Copy of this software can be obtained from unity asset store only.
|
||||
// // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// // FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// // THE SOFTWARE.
|
||||
|
||||
using UnityEngine;
|
||||
using WordsToolkit.Scripts.Popups;
|
||||
using VContainer;
|
||||
using WordsToolkit.Scripts.GUI;
|
||||
using WordsToolkit.Scripts.GUI.Buttons;
|
||||
|
||||
namespace WordsToolkit.Scripts.Popups.Reward
|
||||
{
|
||||
public class SpinOpenButton : MonoBehaviour
|
||||
{
|
||||
[Inject]
|
||||
private MenuManager menuManager;
|
||||
|
||||
[SerializeField]
|
||||
private CustomButton spinButton;
|
||||
|
||||
[SerializeField]
|
||||
private GameObject freeSpinLabel;
|
||||
|
||||
private void OnEnable()
|
||||
{
|
||||
spinButton.onClick.AddListener(ShowLuckySpin);
|
||||
CheckFree();
|
||||
}
|
||||
|
||||
private void CheckFree()
|
||||
{
|
||||
// freeSpinLabel.SetActive(PlayerPrefs.GetInt("FreeSpin", 0) == 0);
|
||||
}
|
||||
|
||||
public void ShowLuckySpin()
|
||||
{
|
||||
menuManager.ShowPopup<LuckySpin>(null, x => CheckFree());
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: b2dffeea3b8d4ba384015d8920b5f08b
|
||||
timeCreated: 1692033837
|
||||
@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 7a4e60ed8f034a82937ff13c7ec87e83
|
||||
timeCreated: 1748331848
|
||||
@ -0,0 +1,24 @@
|
||||
// // ©2015 - 2025 Candy Smith
|
||||
// // All rights reserved
|
||||
// // Redistribution of this software is strictly not allowed.
|
||||
// // Copy of this software can be obtained from unity asset store only.
|
||||
// // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// // FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// // THE SOFTWARE.
|
||||
|
||||
using DG.Tweening;
|
||||
|
||||
namespace WordsToolkit.Scripts.Popups.RewardsGift
|
||||
{
|
||||
public class CoinsGift : GiftBase
|
||||
{
|
||||
public override void Animate()
|
||||
{
|
||||
gameObject.SetActive(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: a4da337610604b04aa326a740e821066
|
||||
timeCreated: 1748332650
|
||||
@ -0,0 +1,37 @@
|
||||
// // ©2015 - 2025 Candy Smith
|
||||
// // All rights reserved
|
||||
// // Redistribution of this software is strictly not allowed.
|
||||
// // Copy of this software can be obtained from unity asset store only.
|
||||
// // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// // FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// // THE SOFTWARE.
|
||||
|
||||
using TMPro;
|
||||
using UnityEngine;
|
||||
|
||||
namespace WordsToolkit.Scripts.Popups.RewardsGift
|
||||
{
|
||||
public class GiftBase : MonoBehaviour
|
||||
{
|
||||
public TextMeshProUGUI amountText;
|
||||
|
||||
public virtual void Animate()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public void SetCount(int giftDataGiftCount)
|
||||
{
|
||||
amountText.text = giftDataGiftCount.ToString();
|
||||
}
|
||||
|
||||
public void HideText()
|
||||
{
|
||||
amountText.gameObject.SetActive(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: fe09d988ff694223be60881b378313e8
|
||||
timeCreated: 1748331871
|
||||
@ -0,0 +1,22 @@
|
||||
// // ©2015 - 2025 Candy Smith
|
||||
// // All rights reserved
|
||||
// // Redistribution of this software is strictly not allowed.
|
||||
// // Copy of this software can be obtained from unity asset store only.
|
||||
// // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// // FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// // THE SOFTWARE.
|
||||
|
||||
namespace WordsToolkit.Scripts.Popups.RewardsGift
|
||||
{
|
||||
public class HammerGift : GiftBase
|
||||
{
|
||||
public override void Animate()
|
||||
{
|
||||
gameObject.SetActive(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 2e29de9241dd4db8b6feb91aa18d850c
|
||||
timeCreated: 1748523167
|
||||
@ -0,0 +1,22 @@
|
||||
// // ©2015 - 2025 Candy Smith
|
||||
// // All rights reserved
|
||||
// // Redistribution of this software is strictly not allowed.
|
||||
// // Copy of this software can be obtained from unity asset store only.
|
||||
// // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// // FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// // THE SOFTWARE.
|
||||
|
||||
namespace WordsToolkit.Scripts.Popups.RewardsGift
|
||||
{
|
||||
public class TipGift : GiftBase
|
||||
{
|
||||
public override void Animate()
|
||||
{
|
||||
gameObject.SetActive(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 3808146b8c4d49a3ac5297caf2ad1ecb
|
||||
timeCreated: 1748331948
|
||||
66
Assets/WordConnectGameToolkit/Scripts/Popups/SceneLoader.cs
Normal file
66
Assets/WordConnectGameToolkit/Scripts/Popups/SceneLoader.cs
Normal file
@ -0,0 +1,66 @@
|
||||
// // ©2015 - 2025 Candy Smith
|
||||
// // All rights reserved
|
||||
// // Redistribution of this software is strictly not allowed.
|
||||
// // Copy of this software can be obtained from unity asset store only.
|
||||
// // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// // FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// // THE SOFTWARE.
|
||||
|
||||
using System;
|
||||
using UnityEngine;
|
||||
using UnityEngine.SceneManagement;
|
||||
using WordsToolkit.Scripts.Gameplay.Managers;
|
||||
using WordsToolkit.Scripts.Levels;
|
||||
using WordsToolkit.Scripts.System;
|
||||
using VContainer;
|
||||
|
||||
namespace WordsToolkit.Scripts.Popups
|
||||
{
|
||||
public class SceneLoader : MonoBehaviour
|
||||
{
|
||||
public static Action<Scene> OnSceneLoadedCallback;
|
||||
public static event Action OnGameStart;
|
||||
private Loading loading;
|
||||
private Scene previouseScene;
|
||||
|
||||
[Inject]
|
||||
private StateManager stateManager;
|
||||
|
||||
private void Start()
|
||||
{
|
||||
CheckEvent(SceneManager.GetActiveScene());
|
||||
}
|
||||
|
||||
public void StartGameScene()
|
||||
{
|
||||
// Let GameDataManager.GetLevel() handle loading the appropriate level
|
||||
// This ensures consistent behavior with our level selection logic
|
||||
Level level = GameDataManager.GetLevel();
|
||||
if (level != null)
|
||||
{
|
||||
GameDataManager.SetLevel(level);
|
||||
}
|
||||
OnGameStart?.Invoke();
|
||||
stateManager.CurrentState = EScreenStates.Game;
|
||||
}
|
||||
|
||||
public void GoMain()
|
||||
{
|
||||
stateManager.CurrentState = EScreenStates.MainMenu;
|
||||
}
|
||||
|
||||
private void CheckEvent(Scene scene)
|
||||
{
|
||||
if (previouseScene != scene)
|
||||
{
|
||||
OnSceneLoadedCallback?.Invoke(scene);
|
||||
previouseScene = scene;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: b3d805f2764540d59695480d886c6756
|
||||
timeCreated: 1725686397
|
||||
105
Assets/WordConnectGameToolkit/Scripts/Popups/Settings.cs
Normal file
105
Assets/WordConnectGameToolkit/Scripts/Popups/Settings.cs
Normal file
@ -0,0 +1,105 @@
|
||||
// // ©2015 - 2025 Candy Smith
|
||||
// // All rights reserved
|
||||
// // Redistribution of this software is strictly not allowed.
|
||||
// // Copy of this software can be obtained from unity asset store only.
|
||||
// // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// // FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// // THE SOFTWARE.
|
||||
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
using WordsToolkit.Scripts.Enums;
|
||||
using WordsToolkit.Scripts.Gameplay.Managers;
|
||||
using WordsToolkit.Scripts.GUI;
|
||||
using WordsToolkit.Scripts.System;
|
||||
using VContainer;
|
||||
using WordsToolkit.Scripts.GUI.Buttons;
|
||||
|
||||
namespace WordsToolkit.Scripts.Popups
|
||||
{
|
||||
public class Settings : PopupWithCurrencyLabel
|
||||
{
|
||||
[SerializeField]
|
||||
private CustomButton privacypolicy;
|
||||
|
||||
[SerializeField]
|
||||
private Button restorePurchase;
|
||||
|
||||
[SerializeField]
|
||||
private Slider vibrationSlider;
|
||||
|
||||
private const string VibrationPrefKey = "VibrationLevel";
|
||||
|
||||
|
||||
protected virtual void OnEnable()
|
||||
{
|
||||
privacypolicy?.onClick.AddListener(PrivacyPolicy);
|
||||
LoadVibrationLevel();
|
||||
vibrationSlider.onValueChanged.AddListener(SaveVibrationLevel);
|
||||
closeButton.onClick.RemoveAllListeners();
|
||||
closeButton.onClick.AddListener(BackToGame);
|
||||
restorePurchase?.onClick.AddListener(RestorePurchase);
|
||||
restorePurchase?.gameObject.SetActive(gameSettings.enableInApps);
|
||||
}
|
||||
|
||||
private void RestorePurchase()
|
||||
{
|
||||
gameManager.RestorePurchases(((b, list) =>
|
||||
{
|
||||
if (b)
|
||||
Close();
|
||||
}));
|
||||
}
|
||||
|
||||
private void BackToGame()
|
||||
{
|
||||
DisablePause();
|
||||
Close();
|
||||
}
|
||||
|
||||
protected override void OnDisable()
|
||||
{
|
||||
base.OnDisable();
|
||||
vibrationSlider.onValueChanged.RemoveListener(SaveVibrationLevel);
|
||||
}
|
||||
|
||||
private void SaveVibrationLevel(float value)
|
||||
{
|
||||
PlayerPrefs.SetFloat(VibrationPrefKey, value);
|
||||
PlayerPrefs.Save();
|
||||
}
|
||||
|
||||
private void LoadVibrationLevel()
|
||||
{
|
||||
if (PlayerPrefs.HasKey(VibrationPrefKey))
|
||||
{
|
||||
vibrationSlider.value = PlayerPrefs.GetFloat(VibrationPrefKey);
|
||||
}
|
||||
else
|
||||
{
|
||||
vibrationSlider.value = 1.0f;
|
||||
SaveVibrationLevel(1.0f);
|
||||
}
|
||||
}
|
||||
|
||||
private void PrivacyPolicy()
|
||||
{
|
||||
StopInteration();
|
||||
DisablePause();
|
||||
menuManager.ShowPopup<GDPR>();
|
||||
Close();
|
||||
}
|
||||
|
||||
private void DisablePause()
|
||||
{
|
||||
if (stateManager.CurrentState == EScreenStates.Game)
|
||||
{
|
||||
EventManager.GameStatus = EGameState.Playing;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 03864e15af6e454d993b1385ee634955
|
||||
timeCreated: 1726163156
|
||||
43
Assets/WordConnectGameToolkit/Scripts/Popups/SettingsGame.cs
Normal file
43
Assets/WordConnectGameToolkit/Scripts/Popups/SettingsGame.cs
Normal file
@ -0,0 +1,43 @@
|
||||
// // ©2015 - 2025 Candy Smith
|
||||
// // All rights reserved
|
||||
// // Redistribution of this software is strictly not allowed.
|
||||
// // Copy of this software can be obtained from unity asset store only.
|
||||
// // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// // FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// // THE SOFTWARE.
|
||||
|
||||
using UnityEngine;
|
||||
using WordsToolkit.Scripts.GUI.Buttons;
|
||||
|
||||
namespace WordsToolkit.Scripts.Popups
|
||||
{
|
||||
public class SettingsGame : Settings
|
||||
{
|
||||
[SerializeField]
|
||||
private CustomButton homeButton;
|
||||
|
||||
protected override void OnEnable()
|
||||
{
|
||||
base.OnEnable();
|
||||
homeButton.onClick.AddListener(OnHomeButtonClicked);
|
||||
}
|
||||
protected override void OnDisable()
|
||||
{
|
||||
base.OnDisable();
|
||||
homeButton.onClick.RemoveListener(OnHomeButtonClicked);
|
||||
}
|
||||
|
||||
private void OnHomeButtonClicked()
|
||||
{
|
||||
if (gameManager != null)
|
||||
{
|
||||
gameManager.MainMenu();
|
||||
Close();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 997e0362973d404c9b4f90a01990a019
|
||||
timeCreated: 1749453629
|
||||
20
Assets/WordConnectGameToolkit/Scripts/Popups/UIPanel.cs
Normal file
20
Assets/WordConnectGameToolkit/Scripts/Popups/UIPanel.cs
Normal file
@ -0,0 +1,20 @@
|
||||
// // ©2015 - 2025 Candy Smith
|
||||
// // All rights reserved
|
||||
// // Redistribution of this software is strictly not allowed.
|
||||
// // Copy of this software can be obtained from unity asset store only.
|
||||
// // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// // FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// // THE SOFTWARE.
|
||||
|
||||
using UnityEngine;
|
||||
|
||||
namespace WordsToolkit.Scripts.Popups
|
||||
{
|
||||
public class UIPanel : MonoBehaviour
|
||||
{
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 34530b51ab774051937fc1860ba68b5f
|
||||
timeCreated: 1726331373
|
||||
43
Assets/WordConnectGameToolkit/Scripts/Popups/Win.cs
Normal file
43
Assets/WordConnectGameToolkit/Scripts/Popups/Win.cs
Normal file
@ -0,0 +1,43 @@
|
||||
// // ©2015 - 2025 Candy Smith
|
||||
// // All rights reserved
|
||||
// // Redistribution of this software is strictly not allowed.
|
||||
// // Copy of this software can be obtained from unity asset store only.
|
||||
// // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// // FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// // THE SOFTWARE.
|
||||
|
||||
using WordsToolkit.Scripts.GUI;
|
||||
using WordsToolkit.Scripts.GUI.Buttons;
|
||||
using WordsToolkit.Scripts.System;
|
||||
|
||||
namespace WordsToolkit.Scripts.Popups
|
||||
{
|
||||
public class Win : Popup
|
||||
{
|
||||
public CustomButton nextLevelButton;
|
||||
|
||||
protected override void Awake()
|
||||
{
|
||||
base.Awake();
|
||||
nextLevelButton.onClick.AddListener(() =>
|
||||
{
|
||||
StopInteration();
|
||||
|
||||
if (GameDataManager.HasMoreLevels())
|
||||
{
|
||||
gameManager.NextLevel();
|
||||
}
|
||||
else
|
||||
{
|
||||
gameManager.MainMenu();
|
||||
}
|
||||
Close();
|
||||
});
|
||||
closeButton.onClick.AddListener(() => gameManager.MainMenu());
|
||||
}
|
||||
}
|
||||
}
|
||||
3
Assets/WordConnectGameToolkit/Scripts/Popups/Win.cs.meta
Normal file
3
Assets/WordConnectGameToolkit/Scripts/Popups/Win.cs.meta
Normal file
@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 93f042b170a34f38b0db1e8dfad45492
|
||||
timeCreated: 1725794899
|
||||
Reference in New Issue
Block a user