Pedro Gomes 8ce897c3aa Persist equipment through scenes
equipment is persistent on scene change, and stats stay updated.
still missing item persistence through sessions.
2024-05-13 11:51:04 +01:00

276 lines
10 KiB
C#

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<int> AllocatedStatPoints = new List<int>();
public int AvailablePointsToAllocate;
CharacterData characterData = new CharacterData();
string characterDataKey;
List<CharacterStat> statsCollection = new List<CharacterStat>();
protected override void Awake()
{
player = GetComponentInParent<RiftPlayer>();
photonView = GetComponentInParent<PhotonView>();
health = player.GetComponent<Health>();
mana = player.GetComponent<Mana>();
characterDataKey = GameConstants.PlayerPrefsKeys.GetCharacterDataKey(photonView.Owner.NickName);
level = new Level();
base.Awake();
statsCollection.Add(Strength);
statsCollection.Add(Agility);
statsCollection.Add(Intelligence);
statsCollection.Add(Spirit);
statsCollection.Add(Vitality);
if (!photonView.IsMine) return;
if (GameStatePersistenceManager.Instance.HasDataForKey(characterDataKey))
{
characterData = GameStatePersistenceManager.Instance.LoadData<CharacterData>(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>();
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>();
inventory.OnItemRightClickedEvent.AddListener(EquipFromInventory);
if (equipmentPanel == null)
equipmentPanel = FindObjectOfType<EquipmentPanel>();
equipmentPanel.OnItemRightClickedEvent.AddListener(UnequipFromEquipPanel);
RefreshCurrentEquipmentStats();
level.OnLevelUpEvent.AddListener(OnLevelUp);
level.OnExperienceChanged.AddListener(OnExperienceChanged);
experienceOnNPCDeath.Response.AddListener(level.GainExperience);
UpdateLevelOnOthers();
statPanel.UpdateStatValues();
}
private void Start()
{
if (photonView.IsMine)
onUpdateStatValues.Invoke();
}
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();
}
EquipmentSlot[] slots;
public void RefreshCurrentEquipmentStats()
{
slots = equipmentPanel.GetCurrentSlots();
for (int i = 0; i < slots.Length; i++)
{
if (slots[i].Item == null) continue;
for (int j = 0; j < statsCollection.Count; j++)
{
if (statsCollection[j].HasModifiersFromSource(slots[i].Item))
{
break;
}
}
((EquippableItem)slots[i].Item).Equip(this);
}
}
}
}