using Photon.Pun; using System.Collections.Generic; using UnityEngine; using UnityEngine.Events; namespace Kryz.CharacterStats.Examples { public class PlayerCharacterStats : CharacterStats { [Header("Listeners:")] [SerializeField] private GameEventListener_Float experienceOnNPCDeath; [Header("Components:")] [SerializeField] Inventory inventory; [SerializeField] EquipmentPanel equipmentPanel; [SerializeField] StatPanel statPanel; [HideInInspector] public RiftPlayer player; public Level level; PhotonView photonView; Health health; Mana mana; [Header("Runtime Data:")] public List AllocatedStatPoints = new List(); public int AvailablePointsToAllocate; CharacterData characterData = new CharacterData(); string characterDataKey; protected override void Awake() { player = GetComponentInParent(); photonView = GetComponentInParent(); health = player.GetComponent(); mana = player.GetComponent(); characterDataKey = GameConstants.PlayerPrefsKeys.GetCharacterDataKey(photonView.Owner.NickName); level = new Level(); base.Awake(); if (!photonView.IsMine) return; if (GameStatePersistenceManager.Instance.HasDataForKey(characterDataKey)) { characterData = GameStatePersistenceManager.Instance.LoadData(characterDataKey); level = new Level(characterData.currentLevel, characterData.currentExperience); for (int i = 0; i < statsDictionary.Keys.Count; i++) { AllocatedStatPoints.Add(characterData.allocatedStatPoints[i]); } AvailablePointsToAllocate = characterData.availablePointsToAllocate; UpdateAllocatedStats(); UpdateStatsBasedOnLevel(); } else { for (int i = 0; i < statsDictionary.Keys.Count; i++) { AllocatedStatPoints.Add(0); } AvailablePointsToAllocate = 3; } if (statPanel == null) statPanel = FindObjectOfType(); statPanel.SetPlayerStats(this); statPanel.SetStats(Strength, Agility, Intelligence, Spirit, Vitality); statPanel.UpdateStatValues(); statPanel.SetCharacterInfo(photonView.Owner.NickName, level.currentLevel.ToString()); statPanel.ToggleAllocateButtonsInteractable(AvailablePointsToAllocate > 0); onUpdateStatValues.AddListener(statPanel.UpdateStatValues); onUpdateStatValues.Invoke(); if (inventory == null) inventory = FindObjectOfType(); inventory.OnItemRightClickedEvent.AddListener(EquipFromInventory); if (equipmentPanel == null) equipmentPanel = FindObjectOfType(); equipmentPanel.OnItemRightClickedEvent.AddListener(UnequipFromEquipPanel); level.OnLevelUpEvent.AddListener(OnLevelUp); level.OnExperienceChanged.AddListener(OnExperienceChanged); experienceOnNPCDeath.Response.AddListener(level.GainExperience); UpdateLevelOnOthers(); } private void OnExperienceChanged() { characterData.currentLevel = level.currentLevel; characterData.currentExperience = level.GetCurrentExperience(); GameStatePersistenceManager.Instance.SaveData(characterDataKey, characterData); } private void OnLevelUp() { UpdateLevelOnOthers(); statPanel.UpdateLevelInfo(level.currentLevel.ToString()); UpdateStatsBasedOnLevel(); AvailablePointsToAllocate += 3; characterData.availablePointsToAllocate = AvailablePointsToAllocate; statPanel.ToggleAllocateButtonsInteractable(AvailablePointsToAllocate > 0); health.ChangeValue(health.GetMaxValue() * 0.2f); mana.ChangeValue(mana.GetMaxValue() * 0.2f); } private void EquipFromInventory(Item item) { if (item is EquippableItem) { Equip((EquippableItem)item); } } private void UnequipFromEquipPanel(Item item) { if (item is EquippableItem) { Unequip((EquippableItem)item); } } public void Equip(EquippableItem item) { if (inventory.RemoveItem(item)) { ItemTooltip.Instance.HideTooltip(); EquippableItem previousItem; if (equipmentPanel.AddItem(item, out previousItem)) { if (previousItem != null) { inventory.AddItem(previousItem); previousItem.Unequip(this); statPanel.UpdateStatValues(); } item.Equip(this); statPanel.UpdateStatValues(); onUpdateStatValues.Invoke(); } else { inventory.AddItem(item); } } } public void Unequip(EquippableItem item) { if (!inventory.IsFull() && equipmentPanel.RemoveItem(item)) { item.Unequip(this); statPanel.UpdateStatValues(); inventory.AddItem(item); onUpdateStatValues.Invoke(); } } public void UpdateLevelOnOthers() { if (photonView.IsMine) photonView.RPC(nameof(RPC_OnLevelUp), RpcTarget.OthersBuffered, this.level.currentLevel); } [PunRPC] public void RPC_OnLevelUp(int level) { this.level.currentLevel = level; this.level.OnLevelUpEvent.Invoke(); } public void UpdateAllocatedStats() { Strength.RemoveAllModifiersFromSource(GameConstants.ObjectSources.AllocatedSource); Agility.RemoveAllModifiersFromSource(GameConstants.ObjectSources.AllocatedSource); Intelligence.RemoveAllModifiersFromSource(GameConstants.ObjectSources.AllocatedSource); Spirit.RemoveAllModifiersFromSource(GameConstants.ObjectSources.AllocatedSource); Vitality.RemoveAllModifiersFromSource(GameConstants.ObjectSources.AllocatedSource); Strength.AddModifier(new StatModifier(AllocatedStatPoints[0], StatModType.Flat, GameConstants.ObjectSources.AllocatedSource)); Agility.AddModifier(new StatModifier(AllocatedStatPoints[1], StatModType.Flat, GameConstants.ObjectSources.AllocatedSource)); Intelligence.AddModifier(new StatModifier(AllocatedStatPoints[2], StatModType.Flat, GameConstants.ObjectSources.AllocatedSource)); Spirit.AddModifier(new StatModifier(AllocatedStatPoints[3], StatModType.Flat, GameConstants.ObjectSources.AllocatedSource)); Vitality.AddModifier(new StatModifier(AllocatedStatPoints[4], StatModType.Flat, GameConstants.ObjectSources.AllocatedSource)); characterData.availablePointsToAllocate = AvailablePointsToAllocate; for (int i = 0; i < AllocatedStatPoints.Count; i++) { characterData.allocatedStatPoints[i] = AllocatedStatPoints[i]; } GameStatePersistenceManager.Instance.SaveData(characterDataKey, characterData); onUpdateStatValues.Invoke(); } public void UpdateStatsBasedOnLevel() { Strength.RemoveAllModifiersFromSource(GameConstants.ObjectSources.LevelSource); Agility.RemoveAllModifiersFromSource(GameConstants.ObjectSources.LevelSource); Intelligence.RemoveAllModifiersFromSource(GameConstants.ObjectSources.LevelSource); Spirit.RemoveAllModifiersFromSource(GameConstants.ObjectSources.LevelSource); Vitality.RemoveAllModifiersFromSource(GameConstants.ObjectSources.LevelSource); Strength.AddModifier(new StatModifier((level.currentLevel - 1), StatModType.Flat, GameConstants.ObjectSources.LevelSource)); Agility.AddModifier(new StatModifier((level.currentLevel - 1), StatModType.Flat, GameConstants.ObjectSources.LevelSource)); Intelligence.AddModifier(new StatModifier((level.currentLevel - 1), StatModType.Flat, GameConstants.ObjectSources.LevelSource)); Spirit.AddModifier(new StatModifier((level.currentLevel - 1), StatModType.Flat, GameConstants.ObjectSources.LevelSource)); Vitality.AddModifier(new StatModifier((level.currentLevel - 1), StatModType.Flat, GameConstants.ObjectSources.LevelSource)); onUpdateStatValues.Invoke(); } } }