- fixed possible null on show tooltip of consumable item that was just used. - fixed an issue preventing all characters from being loaded on character list if one in between was pointing to a null reference in playerprefs
294 lines
11 KiB
C#
294 lines
11 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;
|
|
[SerializeField] private GameEventListener_JobInstance onJobCompleted;
|
|
[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();
|
|
|
|
List<CharacterStat> statsCollection = new List<CharacterStat>();
|
|
|
|
protected override void Awake()
|
|
{
|
|
player = GetComponentInParent<RiftPlayer>();
|
|
photonView = GetComponentInParent<PhotonView>();
|
|
health = player.GetComponent<Health>();
|
|
mana = player.GetComponent<Mana>();
|
|
|
|
level = new Level();
|
|
|
|
base.Awake();
|
|
|
|
statsCollection.Add(Strength);
|
|
statsCollection.Add(Agility);
|
|
statsCollection.Add(Intelligence);
|
|
statsCollection.Add(Spirit);
|
|
statsCollection.Add(Vitality);
|
|
|
|
if (!photonView.IsMine) return;
|
|
|
|
characterData = PlayerDataHandler.Instance.LoadCharacterData(PlayerDataHandler.Instance.currentPlayerName.Value, PlayerDataHandler.Instance.currentCharacterName.Value);
|
|
|
|
if (characterData != null)
|
|
{
|
|
Debug.Log("Success Loading CharacterData");
|
|
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
|
|
{
|
|
characterData = new CharacterData();
|
|
|
|
for (int i = 0; i < statsDictionary.Keys.Count; i++)
|
|
{
|
|
AllocatedStatPoints.Add(0);
|
|
}
|
|
AvailablePointsToAllocate = GameConstants.CharacterBalancing.StatPointsPerLevel;
|
|
|
|
characterData.playerOwnerID = PlayerDataHandler.Instance.currentPlayerName.Value;
|
|
characterData.currentLevel = level.currentLevel;
|
|
characterData.currentExperience = level.GetCurrentExperience();
|
|
|
|
characterData.availablePointsToAllocate = AvailablePointsToAllocate;
|
|
for (int i = 0; i < AllocatedStatPoints.Count; i++)
|
|
{
|
|
characterData.allocatedStatPoints[i] = AllocatedStatPoints[i];
|
|
}
|
|
|
|
PlayerDataHandler.Instance.SaveCharacterData(PlayerDataHandler.Instance.currentPlayerName.Value, PlayerDataHandler.Instance.currentCharacterName.Value, characterData);
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (statPanel == null)
|
|
statPanel = FindObjectOfType<StatPanel>();
|
|
|
|
statPanel.SetPlayerStats(this);
|
|
statPanel.SetStats(Strength, Agility, Intelligence, Spirit, Vitality);
|
|
statPanel.UpdateStatValues();
|
|
statPanel.SetCharacterInfo(PlayerDataHandler.Instance.currentCharacterName.Value, 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);
|
|
onJobCompleted.Response.AddListener(job => level.GainExperience(job.experienceReward));
|
|
|
|
UpdateLevelOnOthers();
|
|
|
|
statPanel.UpdateStatValues();
|
|
}
|
|
private void Start()
|
|
{
|
|
if (photonView.IsMine)
|
|
onUpdateStatValues.Invoke();
|
|
}
|
|
|
|
private void OnExperienceChanged()
|
|
{
|
|
characterData.currentLevel = level.currentLevel;
|
|
characterData.currentExperience = level.GetCurrentExperience();
|
|
|
|
PlayerDataHandler.Instance.SaveCharacterData(PlayerDataHandler.Instance.currentPlayerName.Value, PlayerDataHandler.Instance.currentCharacterName.Value, characterData);
|
|
}
|
|
|
|
private void OnLevelUp()
|
|
{
|
|
UpdateLevelOnOthers();
|
|
|
|
statPanel.UpdateLevelInfo(level.currentLevel.ToString());
|
|
|
|
UpdateStatsBasedOnLevel();
|
|
|
|
AvailablePointsToAllocate += GameConstants.CharacterBalancing.StatPointsPerLevel;
|
|
|
|
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];
|
|
}
|
|
|
|
PlayerDataHandler.Instance.SaveCharacterData(PlayerDataHandler.Instance.currentPlayerName.Value, PlayerDataHandler.Instance.currentCharacterName.Value, 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);
|
|
}
|
|
}
|
|
}
|
|
}
|