stats, items wip
This commit is contained in:
parent
111473b38a
commit
2ebb21cf9d
@ -4,122 +4,227 @@ using System.Collections.ObjectModel;
|
||||
using System.Linq;
|
||||
using UnityEngine.Events;
|
||||
|
||||
public enum CharacterStatType
|
||||
{
|
||||
Cunning,
|
||||
Flow,
|
||||
Presence,
|
||||
|
||||
AttackDamage,
|
||||
SpellDamage,
|
||||
AttackSpeed,
|
||||
CritChance,
|
||||
CritDamage,
|
||||
AuraPower,
|
||||
|
||||
MaxHealth,
|
||||
HealthRegen,
|
||||
MaxMana,
|
||||
ManaRegen,
|
||||
|
||||
Armor,
|
||||
MagicResistance,
|
||||
DodgeChance,
|
||||
BlockChance,
|
||||
BlockEffectiveness,
|
||||
|
||||
AreaEffectiveness,
|
||||
CooldownReduction,
|
||||
MovementSpeed,
|
||||
|
||||
ReputationGainIncrease,
|
||||
GoldCostReduction
|
||||
}
|
||||
|
||||
public static class CharacterStatHelper
|
||||
{
|
||||
public static List<CharacterStatType> Attributes = new List<CharacterStatType>()
|
||||
{
|
||||
CharacterStatType.Cunning,
|
||||
CharacterStatType.Flow,
|
||||
CharacterStatType.Presence
|
||||
};
|
||||
public static bool IsAttribute(CharacterStatType type)
|
||||
{
|
||||
return Attributes.Contains(type);
|
||||
}
|
||||
public static List<CharacterStatType> Offensive = new List<CharacterStatType>()
|
||||
{
|
||||
CharacterStatType.AttackDamage,
|
||||
CharacterStatType.SpellDamage,
|
||||
CharacterStatType.AttackSpeed,
|
||||
CharacterStatType.CritChance,
|
||||
CharacterStatType.CritDamage,
|
||||
CharacterStatType.AuraPower,
|
||||
};
|
||||
public static bool IsOffensive(CharacterStatType type)
|
||||
{
|
||||
return Offensive.Contains(type);
|
||||
}
|
||||
public static List<CharacterStatType> Defensive = new List<CharacterStatType>()
|
||||
{
|
||||
CharacterStatType.Armor,
|
||||
CharacterStatType.MagicResistance,
|
||||
CharacterStatType.DodgeChance,
|
||||
CharacterStatType.BlockChance,
|
||||
CharacterStatType.BlockEffectiveness,
|
||||
};
|
||||
public static bool IsDefensive(CharacterStatType type)
|
||||
{
|
||||
return Defensive.Contains(type);
|
||||
}
|
||||
public static List<CharacterStatType> Resource = new List<CharacterStatType>()
|
||||
{
|
||||
CharacterStatType.MaxHealth,
|
||||
CharacterStatType.HealthRegen,
|
||||
CharacterStatType.MaxMana,
|
||||
CharacterStatType.ManaRegen,
|
||||
};
|
||||
public static bool IsResource(CharacterStatType type)
|
||||
{
|
||||
return Resource.Contains(type);
|
||||
}
|
||||
public static List<CharacterStatType> Control = new List<CharacterStatType>()
|
||||
{
|
||||
CharacterStatType.AreaEffectiveness,
|
||||
CharacterStatType.CooldownReduction,
|
||||
CharacterStatType.MovementSpeed,
|
||||
};
|
||||
public static bool IsControl(CharacterStatType type)
|
||||
{
|
||||
return Control.Contains(type);
|
||||
}
|
||||
public static List<CharacterStatType> Misc = new List<CharacterStatType>()
|
||||
{
|
||||
CharacterStatType.ReputationGainIncrease,
|
||||
CharacterStatType.GoldCostReduction,
|
||||
};
|
||||
public static bool IsMisc(CharacterStatType type)
|
||||
{
|
||||
return Misc.Contains(type);
|
||||
}
|
||||
}
|
||||
|
||||
namespace Kryz.CharacterStats
|
||||
{
|
||||
[Serializable]
|
||||
public class CharacterStat
|
||||
{
|
||||
public GameTag statTag;
|
||||
[Serializable]
|
||||
public class CharacterStat
|
||||
{
|
||||
public GameTag statTag;
|
||||
public CharacterStatType statType;
|
||||
|
||||
public float BaseValue;
|
||||
public float BaseValue;
|
||||
|
||||
protected bool isDirty = true;
|
||||
protected float lastBaseValue;
|
||||
protected bool isDirty = true;
|
||||
protected float lastBaseValue;
|
||||
|
||||
protected float _value;
|
||||
public virtual float Value {
|
||||
get {
|
||||
if(isDirty || lastBaseValue != BaseValue) {
|
||||
lastBaseValue = BaseValue;
|
||||
_value = CalculateFinalValue();
|
||||
isDirty = false;
|
||||
}
|
||||
return _value;
|
||||
}
|
||||
}
|
||||
|
||||
protected readonly List<StatModifier> statModifiers;
|
||||
public readonly ReadOnlyCollection<StatModifier> StatModifiers;
|
||||
|
||||
public CharacterStat()
|
||||
{
|
||||
statModifiers = new List<StatModifier>();
|
||||
StatModifiers = statModifiers.AsReadOnly();
|
||||
}
|
||||
|
||||
public CharacterStat(float baseValue) : this()
|
||||
{
|
||||
isDirty = true;
|
||||
BaseValue = baseValue;
|
||||
}
|
||||
|
||||
public virtual void AddModifier(StatModifier mod)
|
||||
{
|
||||
isDirty = true;
|
||||
statModifiers.Add(mod);
|
||||
}
|
||||
|
||||
public virtual bool RemoveModifier(StatModifier mod)
|
||||
{
|
||||
if (statModifiers.Remove(mod))
|
||||
{
|
||||
isDirty = true;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public virtual bool HasModifiersFromSource(object source)
|
||||
protected float _value;
|
||||
public virtual float Value
|
||||
{
|
||||
return StatModifiers.Any(mod => mod.Source == source);
|
||||
}
|
||||
get
|
||||
{
|
||||
if (isDirty || lastBaseValue != BaseValue)
|
||||
{
|
||||
lastBaseValue = BaseValue;
|
||||
_value = CalculateFinalValue();
|
||||
isDirty = false;
|
||||
}
|
||||
return _value;
|
||||
}
|
||||
}
|
||||
|
||||
public virtual bool RemoveAllModifiersFromSource(object source)
|
||||
{
|
||||
int numRemovals = statModifiers.RemoveAll(mod => mod.Source == source);
|
||||
protected readonly List<StatModifier> statModifiers;
|
||||
public readonly ReadOnlyCollection<StatModifier> StatModifiers;
|
||||
|
||||
if (numRemovals > 0)
|
||||
{
|
||||
isDirty = true;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
public CharacterStat()
|
||||
{
|
||||
statModifiers = new List<StatModifier>();
|
||||
StatModifiers = statModifiers.AsReadOnly();
|
||||
}
|
||||
|
||||
protected virtual int CompareModifierOrder(StatModifier a, StatModifier b)
|
||||
{
|
||||
if (a.Order < b.Order)
|
||||
return -1;
|
||||
else if (a.Order > b.Order)
|
||||
return 1;
|
||||
return 0; //if (a.Order == b.Order)
|
||||
}
|
||||
|
||||
protected virtual float CalculateFinalValue()
|
||||
{
|
||||
float finalValue = BaseValue;
|
||||
float sumPercentAdd = 0;
|
||||
public CharacterStat(float baseValue) : this()
|
||||
{
|
||||
isDirty = true;
|
||||
BaseValue = baseValue;
|
||||
}
|
||||
|
||||
statModifiers.Sort(CompareModifierOrder);
|
||||
public virtual void AddModifier(StatModifier mod)
|
||||
{
|
||||
isDirty = true;
|
||||
statModifiers.Add(mod);
|
||||
}
|
||||
|
||||
for (int i = 0; i < statModifiers.Count; i++)
|
||||
{
|
||||
StatModifier mod = statModifiers[i];
|
||||
public virtual bool RemoveModifier(StatModifier mod)
|
||||
{
|
||||
if (statModifiers.Remove(mod))
|
||||
{
|
||||
isDirty = true;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
if (mod.Type == StatModType.Flat)
|
||||
{
|
||||
finalValue += mod.Value;
|
||||
}
|
||||
else if (mod.Type == StatModType.PercentAdd)
|
||||
{
|
||||
sumPercentAdd += mod.Value;
|
||||
public virtual bool HasModifiersFromSource(object source)
|
||||
{
|
||||
return StatModifiers.Any(mod => mod.Source == source);
|
||||
}
|
||||
|
||||
if (i + 1 >= statModifiers.Count || statModifiers[i + 1].Type != StatModType.PercentAdd)
|
||||
{
|
||||
finalValue *= 1 + sumPercentAdd;
|
||||
sumPercentAdd = 0;
|
||||
}
|
||||
}
|
||||
else if (mod.Type == StatModType.PercentMult)
|
||||
{
|
||||
finalValue *= 1 + mod.Value;
|
||||
}
|
||||
}
|
||||
public virtual bool RemoveAllModifiersFromSource(object source)
|
||||
{
|
||||
int numRemovals = statModifiers.RemoveAll(mod => mod.Source == source);
|
||||
|
||||
// Workaround for float calculation errors, like displaying 12.00001 instead of 12
|
||||
return (float)Math.Round(finalValue, 4);
|
||||
}
|
||||
}
|
||||
if (numRemovals > 0)
|
||||
{
|
||||
isDirty = true;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
protected virtual int CompareModifierOrder(StatModifier a, StatModifier b)
|
||||
{
|
||||
if (a.Order < b.Order)
|
||||
return -1;
|
||||
else if (a.Order > b.Order)
|
||||
return 1;
|
||||
return 0; //if (a.Order == b.Order)
|
||||
}
|
||||
|
||||
protected virtual float CalculateFinalValue()
|
||||
{
|
||||
float finalValue = BaseValue;
|
||||
float sumPercentAdd = 0;
|
||||
|
||||
statModifiers.Sort(CompareModifierOrder);
|
||||
|
||||
for (int i = 0; i < statModifiers.Count; i++)
|
||||
{
|
||||
StatModifier mod = statModifiers[i];
|
||||
|
||||
if (mod.Type == StatModType.Flat)
|
||||
{
|
||||
finalValue += mod.Value;
|
||||
}
|
||||
else if (mod.Type == StatModType.PercentAdd)
|
||||
{
|
||||
sumPercentAdd += mod.Value;
|
||||
|
||||
if (i + 1 >= statModifiers.Count || statModifiers[i + 1].Type != StatModType.PercentAdd)
|
||||
{
|
||||
finalValue *= 1 + sumPercentAdd;
|
||||
sumPercentAdd = 0;
|
||||
}
|
||||
}
|
||||
else if (mod.Type == StatModType.PercentMult)
|
||||
{
|
||||
finalValue *= 1 + mod.Value;
|
||||
}
|
||||
}
|
||||
|
||||
// Workaround for float calculation errors, like displaying 12.00001 instead of 12
|
||||
return (float)Math.Round(finalValue, 4);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@ -8027,7 +8027,7 @@ PrefabInstance:
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: 2440268520758508678, guid: 1372ea2f917805749a87f6c81e9938cf, type: 3}
|
||||
propertyPath: m_Name
|
||||
value: OffWeapon Slot
|
||||
value: OffHand Slot
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: 2440268520765564492, guid: 1372ea2f917805749a87f6c81e9938cf, type: 3}
|
||||
propertyPath: m_Sprite
|
||||
@ -8149,7 +8149,7 @@ PrefabInstance:
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: 2440268520758508678, guid: 1372ea2f917805749a87f6c81e9938cf, type: 3}
|
||||
propertyPath: m_Name
|
||||
value: MainWeapon Slot
|
||||
value: MainHand Slot
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: 2440268520765564492, guid: 1372ea2f917805749a87f6c81e9938cf, type: 3}
|
||||
propertyPath: m_Sprite
|
||||
|
||||
@ -71,6 +71,36 @@ namespace Kryz.CharacterStats.Examples
|
||||
|
||||
protected virtual void Awake()
|
||||
{
|
||||
Cunning.statType = CharacterStatType.Cunning;
|
||||
Flow.statType = CharacterStatType.Flow;
|
||||
Presence.statType = CharacterStatType.Presence;
|
||||
|
||||
AttackDamage.statType = CharacterStatType.AttackDamage;
|
||||
SpellDamage.statType = CharacterStatType.SpellDamage;
|
||||
AttackSpeed.statType = CharacterStatType.AttackSpeed;
|
||||
CritChance.statType = CharacterStatType.CritChance;
|
||||
CritDamage.statType = CharacterStatType.CritDamage;
|
||||
AuraPower.statType = CharacterStatType.AuraPower;
|
||||
|
||||
MaxHealth.statType = CharacterStatType.MaxHealth;
|
||||
HealthRegen.statType = CharacterStatType.HealthRegen;
|
||||
MaxMana.statType = CharacterStatType.MaxMana;
|
||||
ManaRegen.statType = CharacterStatType.ManaRegen;
|
||||
|
||||
Armor.statType = CharacterStatType.Armor;
|
||||
MagicResistance.statType = CharacterStatType.MagicResistance;
|
||||
DodgeChance.statType = CharacterStatType.DodgeChance;
|
||||
BlockChance.statType = CharacterStatType.BlockChance;
|
||||
BlockEffectiveness.statType = CharacterStatType.BlockEffectiveness;
|
||||
|
||||
AreaEffectiveness.statType = CharacterStatType.AreaEffectiveness;
|
||||
CooldownReduction.statType = CharacterStatType.CooldownReduction;
|
||||
MovementSpeed.statType = CharacterStatType.MovementSpeed;
|
||||
|
||||
ReputationGainIncrease.statType = CharacterStatType.ReputationGainIncrease;
|
||||
GoldCostReduction.statType = CharacterStatType.GoldCostReduction;
|
||||
|
||||
|
||||
primaryStatsDictionary.Add(nameof(Cunning).ToLower(), Cunning);
|
||||
primaryStatsDictionary.Add(nameof(Flow).ToLower(), Flow);
|
||||
primaryStatsDictionary.Add(nameof(Presence).ToLower(), Presence);
|
||||
|
||||
@ -1,4 +1,5 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
namespace Kryz.CharacterStats.Examples
|
||||
@ -55,7 +56,7 @@ namespace Kryz.CharacterStats.Examples
|
||||
{
|
||||
for (int i = 0; i < equipmentSlots.Length; i++)
|
||||
{
|
||||
if(equipmentSlots[i].EquipmentType == slot)
|
||||
if (equipmentSlots[i].EquipmentType == slot)
|
||||
{
|
||||
return (EquippableItemInstance)equipmentSlots[i].Item;
|
||||
}
|
||||
@ -63,22 +64,185 @@ namespace Kryz.CharacterStats.Examples
|
||||
return null;
|
||||
}
|
||||
|
||||
public bool AddItem(EquippableItemInstance item, out EquippableItemInstance previousItem)
|
||||
// NEW: Helper method to get weapon slots
|
||||
public (EquipmentSlot mainHand, EquipmentSlot offHand) GetWeaponSlots()
|
||||
{
|
||||
EquipmentSlot mainHand = null;
|
||||
EquipmentSlot offHand = null;
|
||||
|
||||
for (int i = 0; i < equipmentSlots.Length; i++)
|
||||
{
|
||||
if (equipmentSlots[i].EquipmentType == EquipmentType.MainHand)
|
||||
mainHand = equipmentSlots[i];
|
||||
else if (equipmentSlots[i].EquipmentType == EquipmentType.OffHand)
|
||||
offHand = equipmentSlots[i];
|
||||
}
|
||||
|
||||
return (mainHand, offHand);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Calculates how many items would be displaced if the given item were equipped
|
||||
/// </summary>
|
||||
public int GetDisplacedItemCount(EquippableItemInstance item)
|
||||
{
|
||||
if (!item.IsWeapon)
|
||||
{
|
||||
// Non-weapons: at most 1 item displaced (standard replacement)
|
||||
var existingItem = GetEquippedItemOnSpecificSlot(item.EquipmentType);
|
||||
return (existingItem != null && !string.IsNullOrEmpty(existingItem.ItemName)) ? 1 : 0;
|
||||
}
|
||||
|
||||
// Handle weapons
|
||||
var (mainHandSlot, offHandSlot) = GetWeaponSlots();
|
||||
if (mainHandSlot == null || offHandSlot == null)
|
||||
return 0;
|
||||
|
||||
var currentMainHand = (EquippableItemInstance)mainHandSlot.Item;
|
||||
var currentOffHand = (EquippableItemInstance)offHandSlot.Item;
|
||||
|
||||
if (item.IsTwoHandedWeapon)
|
||||
{
|
||||
// Two-handed weapon displaces both current weapons
|
||||
int count = 0;
|
||||
if (currentMainHand != null && !string.IsNullOrEmpty(currentMainHand.ItemName))
|
||||
count++;
|
||||
if (currentOffHand != null && !string.IsNullOrEmpty(currentOffHand.ItemName))
|
||||
count++;
|
||||
return count;
|
||||
}
|
||||
else // One-handed weapon
|
||||
{
|
||||
if (currentMainHand != null && currentMainHand.IsTwoHandedWeapon)
|
||||
{
|
||||
// Replacing two-handed with one-handed
|
||||
return 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Normal one-handed logic
|
||||
if (currentMainHand == null || currentOffHand == null)
|
||||
return 0; // Filling empty slot
|
||||
else
|
||||
return 1; // Will replace main hand
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// NEW: Helper method to get slot index for saving
|
||||
private int GetSlotIndex(EquipmentSlot slot)
|
||||
{
|
||||
for (int i = 0; i < equipmentSlots.Length; i++)
|
||||
{
|
||||
if (equipmentSlots[i].EquipmentType == item.EquipmentType)
|
||||
{
|
||||
previousItem = (EquippableItemInstance)equipmentSlots[i].Item;
|
||||
equipmentSlots[i].Item = item;
|
||||
if (equipmentSlots[i] == slot)
|
||||
return i;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
// UPDATED: Modified to handle two-handed weapon logic
|
||||
public bool AddItem(EquippableItemInstance item, out EquippableItemInstance previousItem)
|
||||
{
|
||||
return AddItem(item, out previousItem, out _);
|
||||
}
|
||||
|
||||
// NEW: Overloaded method that returns multiple previous items for two-handed weapon swapping
|
||||
public bool AddItem(EquippableItemInstance item, out EquippableItemInstance previousItem, out EquippableItemInstance secondPreviousItem)
|
||||
{
|
||||
previousItem = null;
|
||||
secondPreviousItem = null;
|
||||
|
||||
// Handle non-weapon items with original logic
|
||||
if (!item.IsWeapon)
|
||||
{
|
||||
for (int i = 0; i < equipmentSlots.Length; i++)
|
||||
{
|
||||
if (equipmentSlots[i].EquipmentType == item.EquipmentType)
|
||||
{
|
||||
previousItem = (EquippableItemInstance)equipmentSlots[i].Item;
|
||||
equipmentSlots[i].Item = item;
|
||||
|
||||
equipmentData.equippedItems[i] = item;
|
||||
PlayerDataHandler.Instance.SaveCharacterEquipmentData(PlayerDataHandler.Instance.currentPlayerName.Value, PlayerDataHandler.Instance.currentCharacterName.Value, equipmentData);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// Handle weapon items
|
||||
var (mainHandSlot, offHandSlot) = GetWeaponSlots();
|
||||
if (mainHandSlot == null || offHandSlot == null)
|
||||
return false;
|
||||
|
||||
var currentMainHand = (EquippableItemInstance)mainHandSlot.Item;
|
||||
var currentOffHand = (EquippableItemInstance)offHandSlot.Item;
|
||||
|
||||
if (item.IsTwoHandedWeapon)
|
||||
{
|
||||
// Equipping a two-handed weapon
|
||||
previousItem = currentMainHand;
|
||||
secondPreviousItem = currentOffHand;
|
||||
|
||||
// Set the two-handed weapon in main hand, clear off-hand
|
||||
mainHandSlot.Item = item;
|
||||
offHandSlot.Item = null;
|
||||
|
||||
// Update data arrays
|
||||
int mainHandIndex = GetSlotIndex(mainHandSlot);
|
||||
int offHandIndex = GetSlotIndex(offHandSlot);
|
||||
equipmentData.equippedItems[mainHandIndex] = item;
|
||||
equipmentData.equippedItems[offHandIndex] = null;
|
||||
|
||||
PlayerDataHandler.Instance.SaveCharacterEquipmentData(PlayerDataHandler.Instance.currentPlayerName.Value, PlayerDataHandler.Instance.currentCharacterName.Value, equipmentData);
|
||||
return true;
|
||||
}
|
||||
else // One-handed weapon
|
||||
{
|
||||
// Check if currently have a two-handed weapon equipped
|
||||
if (currentMainHand != null && currentMainHand.IsTwoHandedWeapon)
|
||||
{
|
||||
// Replace two-handed with one-handed in main hand
|
||||
previousItem = currentMainHand;
|
||||
mainHandSlot.Item = item;
|
||||
|
||||
int mainHandIndex = GetSlotIndex(mainHandSlot);
|
||||
equipmentData.equippedItems[mainHandIndex] = item;
|
||||
|
||||
PlayerDataHandler.Instance.SaveCharacterEquipmentData(PlayerDataHandler.Instance.currentPlayerName.Value, PlayerDataHandler.Instance.currentCharacterName.Value, equipmentData);
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Normal one-handed weapon equipping logic
|
||||
// Prioritize main hand, then off-hand if main hand is occupied
|
||||
if (currentMainHand == null)
|
||||
{
|
||||
// Equip in main hand
|
||||
mainHandSlot.Item = item;
|
||||
int mainHandIndex = GetSlotIndex(mainHandSlot);
|
||||
equipmentData.equippedItems[mainHandIndex] = item;
|
||||
}
|
||||
else if (currentOffHand == null)
|
||||
{
|
||||
// Equip in off-hand for dual wielding
|
||||
offHandSlot.Item = item;
|
||||
int offHandIndex = GetSlotIndex(offHandSlot);
|
||||
equipmentData.equippedItems[offHandIndex] = item;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Both slots occupied, replace main hand
|
||||
previousItem = currentMainHand;
|
||||
mainHandSlot.Item = item;
|
||||
int mainHandIndex = GetSlotIndex(mainHandSlot);
|
||||
equipmentData.equippedItems[mainHandIndex] = item;
|
||||
}
|
||||
|
||||
equipmentData.equippedItems[i] = item;
|
||||
PlayerDataHandler.Instance.SaveCharacterEquipmentData(PlayerDataHandler.Instance.currentPlayerName.Value, PlayerDataHandler.Instance.currentCharacterName.Value, equipmentData);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
previousItem = null;
|
||||
return false;
|
||||
}
|
||||
|
||||
public bool RemoveItem(EquippableItemInstance item)
|
||||
@ -135,4 +299,4 @@ namespace Kryz.CharacterStats.Examples
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1,4 +1,55 @@
|
||||
using UnityEngine;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
public enum ItemRarity
|
||||
{
|
||||
Common,
|
||||
Rare,
|
||||
Epic,
|
||||
Unique,
|
||||
Legendary
|
||||
}
|
||||
public enum WeaponType
|
||||
{
|
||||
// Two-Handed Weapons (Build-defining)
|
||||
Staff,
|
||||
Spear,
|
||||
Scythe,
|
||||
Hammer,
|
||||
Bow,
|
||||
Crossbow,
|
||||
Axe,
|
||||
|
||||
// One-Handed Weapons (Flexible)
|
||||
Sword,
|
||||
Shield,
|
||||
Dagger,
|
||||
Book
|
||||
}
|
||||
|
||||
public static class WeaponTypeExtensions
|
||||
{
|
||||
private static readonly HashSet<WeaponType> TwoHandedWeapons = new()
|
||||
{
|
||||
WeaponType.Staff,
|
||||
WeaponType.Spear,
|
||||
WeaponType.Scythe,
|
||||
WeaponType.Hammer,
|
||||
WeaponType.Bow,
|
||||
WeaponType.Crossbow,
|
||||
WeaponType.Axe
|
||||
};
|
||||
|
||||
public static bool IsTwoHanded(this WeaponType weaponType)
|
||||
{
|
||||
return TwoHandedWeapons.Contains(weaponType);
|
||||
}
|
||||
|
||||
public static bool IsOneHanded(this WeaponType weaponType)
|
||||
{
|
||||
return !IsTwoHanded(weaponType);
|
||||
}
|
||||
}
|
||||
|
||||
namespace Kryz.CharacterStats.Examples
|
||||
{
|
||||
@ -13,13 +64,14 @@ namespace Kryz.CharacterStats.Examples
|
||||
Gloves,
|
||||
Boots,
|
||||
|
||||
MainWeapon,
|
||||
OffWeapon,
|
||||
MainHand,
|
||||
OffHand,
|
||||
|
||||
Accessory,
|
||||
Amulet,
|
||||
//Accessory,
|
||||
//Amulet,
|
||||
}
|
||||
|
||||
|
||||
[CreateAssetMenu]
|
||||
public class EquippableItem : Item
|
||||
{
|
||||
@ -77,6 +129,19 @@ namespace Kryz.CharacterStats.Examples
|
||||
|
||||
|
||||
public EquipmentType EquipmentType;
|
||||
[Space]
|
||||
// NEW: Add WeaponType for weapon items
|
||||
public WeaponType WeaponType;
|
||||
|
||||
// NEW: Helper property to check if this item is a weapon
|
||||
public bool IsWeapon => EquipmentType == EquipmentType.MainHand || EquipmentType == EquipmentType.OffHand;
|
||||
|
||||
// NEW: Helper property to check if this weapon is two-handed
|
||||
public bool IsTwoHandedWeapon => IsWeapon && WeaponType.IsTwoHanded();
|
||||
|
||||
// NEW: Helper property to check if this weapon is one-handed
|
||||
public bool IsOneHandedWeapon => IsWeapon && WeaponType.IsOneHanded();
|
||||
|
||||
[Space]
|
||||
public bool CraftableBase = false;
|
||||
[Space(20f)]
|
||||
|
||||
@ -62,6 +62,9 @@ public class EquippableItemInstance : ItemInstance
|
||||
[Space]
|
||||
public EquipmentType EquipmentType;
|
||||
[Space]
|
||||
// NEW: Add WeaponType for weapon items
|
||||
public WeaponType WeaponType;
|
||||
[Space]
|
||||
public bool CraftableBase = false;
|
||||
[Space]
|
||||
/// <summary>
|
||||
@ -72,6 +75,15 @@ public class EquippableItemInstance : ItemInstance
|
||||
public int MaxTotalUniqueStatsIncreasedByStones;
|
||||
public List<string> AddedStoneStats = new List<string>();
|
||||
|
||||
// NEW: Helper property to check if this item is a weapon
|
||||
public bool IsWeapon => EquipmentType == EquipmentType.MainHand || EquipmentType == EquipmentType.OffHand;
|
||||
|
||||
// NEW: Helper property to check if this weapon is two-handed
|
||||
public bool IsTwoHandedWeapon => IsWeapon && WeaponType.IsTwoHanded();
|
||||
|
||||
// NEW: Helper property to check if this weapon is one-handed
|
||||
public bool IsOneHandedWeapon => IsWeapon && WeaponType.IsOneHanded();
|
||||
|
||||
public void Equip(PlayerCharacterStats c)
|
||||
{
|
||||
if (AttackDamageBonus != 0)
|
||||
@ -276,6 +288,7 @@ public class EquippableItemInstance : ItemInstance
|
||||
MagicResistancePercentBonus = 0;
|
||||
|
||||
EquipmentType = EquipmentType.Helmet;
|
||||
WeaponType = WeaponType.Sword; // Default weapon type
|
||||
|
||||
CraftableBase = false;
|
||||
|
||||
@ -307,6 +320,8 @@ public class EquippableItemInstance : ItemInstance
|
||||
MagicResistancePercentBonus = template.MagicResistancePercentBonus;
|
||||
|
||||
EquipmentType = template.EquipmentType;
|
||||
// NEW: Copy WeaponType from template (assuming EquippableItem has this field)
|
||||
WeaponType = template.WeaponType;
|
||||
|
||||
CraftableBase = template.CraftableBase;
|
||||
MaxTotalUniqueStatsIncreasedByStones = template.MaxTotalUniqueStatsIncreasedByStones;
|
||||
@ -364,9 +379,10 @@ public class EquippableItemInstance : ItemInstance
|
||||
|
||||
|
||||
EquipmentType = template.EquipmentType;
|
||||
// NEW: Copy WeaponType from template (assuming EquippableItem has this field)
|
||||
WeaponType = template.WeaponType;
|
||||
|
||||
CraftableBase = template.CraftableBase;
|
||||
MaxTotalUniqueStatsIncreasedByStones = template.MaxTotalUniqueStatsIncreasedByStones;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@ -137,6 +137,10 @@ namespace Kryz.CharacterStats.Examples
|
||||
return items.Count >= itemSlots.Length;
|
||||
//return items.FindAll(x => string.IsNullOrEmpty(x.ItemName)).Count <= 0;
|
||||
}
|
||||
public int AvailableSlots()
|
||||
{
|
||||
return itemSlots.Length - items.Count;
|
||||
}
|
||||
|
||||
public void LoadInventory()
|
||||
{
|
||||
|
||||
@ -204,20 +204,38 @@ namespace Kryz.CharacterStats.Examples
|
||||
|
||||
public void Equip(EquippableItemInstance item)
|
||||
{
|
||||
// First, check if we have enough inventory space for displaced items
|
||||
if (!CanEquipItem(item))
|
||||
{
|
||||
// Could show a message to player here: "Not enough inventory space"
|
||||
return;
|
||||
}
|
||||
|
||||
if (inventory.RemoveItem(item))
|
||||
{
|
||||
ItemTooltip.Instance.HideTooltip();
|
||||
EquippedItemTooltip.Instance.HideTooltip();
|
||||
|
||||
EquippableItemInstance previousItem;
|
||||
if (equipmentPanel.AddItem(item, out previousItem))
|
||||
EquippableItemInstance secondPreviousItem;
|
||||
|
||||
if (equipmentPanel.AddItem(item, out previousItem, out secondPreviousItem))
|
||||
{
|
||||
// Handle first previous item
|
||||
if (previousItem != null && !string.IsNullOrEmpty(previousItem.ItemName))
|
||||
{
|
||||
inventory.AddItem(previousItem);
|
||||
previousItem.Unequip(this);
|
||||
statPanel.UpdateStatValues();
|
||||
}
|
||||
|
||||
// Handle second previous item (for two-handed weapon replacement)
|
||||
if (secondPreviousItem != null && !string.IsNullOrEmpty(secondPreviousItem.ItemName))
|
||||
{
|
||||
inventory.AddItem(secondPreviousItem);
|
||||
secondPreviousItem.Unequip(this);
|
||||
}
|
||||
|
||||
// Equip the new item
|
||||
item.Equip(this);
|
||||
statPanel.UpdateStatValues();
|
||||
onUpdateStatValues.Invoke();
|
||||
@ -229,6 +247,18 @@ namespace Kryz.CharacterStats.Examples
|
||||
}
|
||||
}
|
||||
|
||||
// Simplified version using the EquipmentPanel helper method
|
||||
private bool CanEquipItem(EquippableItemInstance item)
|
||||
{
|
||||
int itemsToDisplace = equipmentPanel.GetDisplacedItemCount(item);
|
||||
|
||||
// Calculate available inventory slots
|
||||
// We get +1 slot from removing the item we're equipping
|
||||
int availableSlots = inventory.AvailableSlots() + 1;
|
||||
|
||||
return availableSlots >= itemsToDisplace;
|
||||
}
|
||||
|
||||
public void Unequip(EquippableItemInstance item)
|
||||
{
|
||||
if (!inventory.IsFull() && equipmentPanel.RemoveItem(item))
|
||||
|
||||
@ -3702,6 +3702,69 @@ MonoBehaviour:
|
||||
m_hasFontAssetChanged: 0
|
||||
m_baseMaterial: {fileID: 0}
|
||||
m_maskOffset: {x: 0, y: 0, z: 0, w: 0}
|
||||
--- !u!1 &2097151069981005797
|
||||
GameObject:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
serializedVersion: 6
|
||||
m_Component:
|
||||
- component: {fileID: 7335229491322327302}
|
||||
- component: {fileID: 4411192570680935153}
|
||||
m_Layer: 0
|
||||
m_Name: EquippableItemInstanceGenerator
|
||||
m_TagString: Untagged
|
||||
m_Icon: {fileID: 0}
|
||||
m_NavMeshLayer: 0
|
||||
m_StaticEditorFlags: 0
|
||||
m_IsActive: 1
|
||||
--- !u!4 &7335229491322327302
|
||||
Transform:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 2097151069981005797}
|
||||
serializedVersion: 2
|
||||
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
|
||||
m_LocalPosition: {x: 0, y: 0, z: 0}
|
||||
m_LocalScale: {x: 1, y: 1, z: 1}
|
||||
m_ConstrainProportionsScale: 0
|
||||
m_Children: []
|
||||
m_Father: {fileID: 7475116342638198534}
|
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||
--- !u!114 &4411192570680935153
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 2097151069981005797}
|
||||
m_Enabled: 1
|
||||
m_EditorHideFlags: 0
|
||||
m_Script: {fileID: 11500000, guid: a85a7f34d000be84fa64ef31a99b20b4, type: 3}
|
||||
m_Name:
|
||||
m_EditorClassIdentifier: Assembly-CSharp::EquippableItemGenerator
|
||||
HelmetIcons: []
|
||||
ShoulderIcons: []
|
||||
ChestIcons: []
|
||||
BeltIcons: []
|
||||
LegsIcons: []
|
||||
BracersIcons: []
|
||||
GlovesIcons: []
|
||||
BootsIcons: []
|
||||
StaffIcons: []
|
||||
SpearIcons: []
|
||||
ScytheIcons: []
|
||||
HammerIcons: []
|
||||
BowIcons: []
|
||||
CrossbowIcons: []
|
||||
AxeIcons: []
|
||||
SwordIcons: []
|
||||
ShieldIcons: []
|
||||
DaggerIcons: []
|
||||
BookIcons: []
|
||||
--- !u!1 &2105173639354992659
|
||||
GameObject:
|
||||
m_ObjectHideFlags: 0
|
||||
@ -7803,6 +7866,7 @@ MonoBehaviour:
|
||||
ReputationGainIncreasePercentBonus: 0
|
||||
GoldCostReductionPercentBonus: 0
|
||||
EquipmentType: 0
|
||||
WeaponType: 7
|
||||
CraftableBase: 0
|
||||
MaxTotalUniqueStatsIncreasedByStones: 0
|
||||
AddedStoneStats: []
|
||||
@ -14453,6 +14517,7 @@ Transform:
|
||||
- {fileID: 315999698282489082}
|
||||
- {fileID: 2800905167933415666}
|
||||
- {fileID: 1867733016440364756}
|
||||
- {fileID: 7335229491322327302}
|
||||
m_Father: {fileID: 7475116341965418816}
|
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||
--- !u!1 &7475116342667879665
|
||||
|
||||
@ -78,7 +78,7 @@ Material:
|
||||
- _Mode: 0
|
||||
- _OcclusionStrength: 1
|
||||
- _Parallax: 0.02
|
||||
- _Rotation: 8.570184
|
||||
- _Rotation: 89.72914
|
||||
- _SmoothnessTextureChannel: 0
|
||||
- _SpecularHighlights: 1
|
||||
- _SrcBlend: 1
|
||||
|
||||
@ -1004,8 +1004,8 @@ MonoBehaviour:
|
||||
m_Calls: []
|
||||
m_text: Skelly Mage
|
||||
m_isRightToLeft: 0
|
||||
m_fontAsset: {fileID: 11400000, guid: 01ed77f6af1621a4cb0e3ee10d3b7147, type: 2}
|
||||
m_sharedMaterial: {fileID: -7243662068360240803, guid: 01ed77f6af1621a4cb0e3ee10d3b7147, type: 2}
|
||||
m_fontAsset: {fileID: 11400000, guid: 41f9368fce25cb44ba223ac55f4e69e1, type: 2}
|
||||
m_sharedMaterial: {fileID: -1192090701822111264, guid: 41f9368fce25cb44ba223ac55f4e69e1, type: 2}
|
||||
m_fontSharedMaterials: []
|
||||
m_fontMaterial: {fileID: 0}
|
||||
m_fontMaterials: []
|
||||
|
||||
@ -17,52 +17,37 @@ MonoBehaviour:
|
||||
sellPricePlayer: 100
|
||||
sellPriceVendor: 2000
|
||||
description:
|
||||
StrengthBonus: 0
|
||||
AgilityBonus: 0
|
||||
IntelligenceBonus: 1
|
||||
SpiritBonus: 1
|
||||
VitalityBonus: 0
|
||||
StrengthPercentBonus: 0
|
||||
AgilityPercentBonus: 0
|
||||
IntelligencePercentBonus: 0
|
||||
SpiritPercentBonus: 0
|
||||
VitalityPercentBonus: 0
|
||||
AttackDamageBonus: 0
|
||||
SpellDamageBonus: 1
|
||||
CritChanceBonus: 0
|
||||
CritDamageBonus: 0
|
||||
MaxHealthBonus: 0
|
||||
HealthRegenBonus: 0
|
||||
MaxManaBonus: 0
|
||||
ManaRegenBonus: 0
|
||||
ArmorBonus: 0
|
||||
MagicResistanceBonus: 0
|
||||
AttackDamagePercentBonus: 0
|
||||
SpellDamagePercentBonus: 0
|
||||
AttackSpeedPercentBonus: 0
|
||||
CritChancePercentBonus: 0
|
||||
CritDamagePercentBonus: 0
|
||||
MaxHealthPercentBonus: 0
|
||||
HealthRegenPercentBonus: 0
|
||||
MaxManaPercentBonus: 0
|
||||
ManaRegenPercentBonus: 0
|
||||
ArmorPercentBonus: 0
|
||||
MagicResistancePercentBonus: 0
|
||||
EquipmentType: 5
|
||||
DodgeChancePercentBonus: 0
|
||||
BlockChancePercentBonus: 0
|
||||
BlockEffectivenessPercentBonus: 0
|
||||
AreaEffectivenessPercentBonus: 0
|
||||
CooldownReductionPercentBonus: 0
|
||||
MovementSpeedPercentBonus: 0
|
||||
ReputationGainIncreasePercentBonus: 0
|
||||
GoldCostReductionPercentBonus: 0
|
||||
EquipmentType: 9
|
||||
CraftableBase: 0
|
||||
MinStrengthBonus: 0
|
||||
MaxStrengthBonus: 0
|
||||
MinAgilityBonus: 0
|
||||
MaxAgilityBonus: 0
|
||||
MinIntelligenceBonus: 0
|
||||
MaxIntelligenceBonus: 0
|
||||
MinSpiritBonus: 0
|
||||
MaxSpiritBonus: 0
|
||||
MinVitalityBonus: 0
|
||||
MaxVitalityBonus: 0
|
||||
MinStrengthPercentBonus: 0
|
||||
MaxStrengthPercentBonus: 0
|
||||
MinAgilityPercentBonus: 0
|
||||
MaxAgilityPercentBonus: 0
|
||||
MinIntelligencePercentBonus: 0
|
||||
MaxIntelligencePercentBonus: 0
|
||||
MinSpiritPercentBonus: 0
|
||||
MaxSpiritPercentBonus: 0
|
||||
MinVitalityPercentBonus: 0
|
||||
MaxVitalityPercentBonus: 0
|
||||
MinAttackDamageBonus: 0
|
||||
MaxAttackDamageBonus: 0
|
||||
MinSpellDamageBonus: 0
|
||||
|
||||
@ -67,11 +67,11 @@ public class CastBarHandler : MonoBehaviour
|
||||
ToggleCastBarVisibility(false);
|
||||
}
|
||||
|
||||
public void ShowCastBar(BaseAbility ability, Action abilityExecution)
|
||||
public void ShowCastBar(BaseAbility ability, Action abilityExecution, float castTime)
|
||||
{
|
||||
currentlyWaitingAbilityExecution = abilityExecution;
|
||||
currentAbility = ability;
|
||||
currentCastTime = ability.castTime;
|
||||
currentCastTime = castTime;
|
||||
castBarIcon.sprite = ability.Icon;
|
||||
StartCoroutine(FillImageOverTime(ability.castTime + 0.05f));
|
||||
}
|
||||
|
||||
@ -1,3 +1,4 @@
|
||||
using Kryz.CharacterStats.Examples;
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
@ -12,24 +13,38 @@ public class CastingStateController : MonoBehaviour
|
||||
public LayerMask movementMask;
|
||||
|
||||
private MovementSpeedModifierEffectInstance movementSpeedModifier;
|
||||
Camera cam;
|
||||
Ray ray;
|
||||
RaycastHit hit;
|
||||
|
||||
ProjectileSpawnLocationController projectileSpawnLocationController;
|
||||
private Camera cam;
|
||||
private Ray ray;
|
||||
private RaycastHit hit;
|
||||
private ProjectileSpawnLocationController projectileSpawnLocationController;
|
||||
private CharacterStats stats;
|
||||
|
||||
public UnityEvent<BaseAbility> OnAbilityQueued = new UnityEvent<BaseAbility>();
|
||||
|
||||
|
||||
private void Awake()
|
||||
{
|
||||
cam = Camera.main;
|
||||
movementSpeedModifier = playerMovement.GetComponent<MovementSpeedModifierEffectInstance>();
|
||||
stats = playerMovement.GetComponent<CharacterStats>();
|
||||
projectileSpawnLocationController = transform.root.GetComponentInChildren<ProjectileSpawnLocationController>();
|
||||
}
|
||||
private void Start()
|
||||
{
|
||||
|
||||
/// <summary>
|
||||
/// Calculate current attack interval based on base speed and modifiers
|
||||
/// </summary>
|
||||
private float GetCurrentAttackInterval()
|
||||
{
|
||||
float totalAttackSpeed = GameConstants.CharacterStatsBalancing.BaseAttacksPerSecond * (1f + (MathHelpers.NormalizePercentage(stats.AttackSpeed.Value) / 100f));
|
||||
float interval = 1f / totalAttackSpeed;
|
||||
return Mathf.Max(interval, GameConstants.CharacterStatsBalancing.FastestAttacksPerSecond);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get current attacks per second
|
||||
/// </summary>
|
||||
public float GetCurrentAttacksPerSecond()
|
||||
{
|
||||
return 1f / GetCurrentAttackInterval();
|
||||
}
|
||||
|
||||
public void RequestAbilityCast(BaseAbility ability, Action abilityExecution)
|
||||
@ -39,12 +54,12 @@ public class CastingStateController : MonoBehaviour
|
||||
if (!ability.castableWhileMoving)
|
||||
{
|
||||
movementSpeedModifier.ToggleCastPenalty(true);
|
||||
//playerMovement.ToggleAgentMoving(true);
|
||||
}
|
||||
|
||||
OnAbilityQueued.Invoke(ability);
|
||||
StartCoroutine(Casting(ability, abilityExecution));
|
||||
}
|
||||
|
||||
public void RequestAbilityChannel(BaseAbility channeledAbility, Action abilityChannelExecution)
|
||||
{
|
||||
if (isCasting) return;
|
||||
@ -52,7 +67,6 @@ public class CastingStateController : MonoBehaviour
|
||||
if (!channeledAbility.castableWhileMoving)
|
||||
{
|
||||
movementSpeedModifier.ToggleCastPenalty(true);
|
||||
//playerMovement.ToggleAgentMoving(true);
|
||||
}
|
||||
|
||||
OnAbilityQueued.Invoke(channeledAbility);
|
||||
@ -62,12 +76,15 @@ public class CastingStateController : MonoBehaviour
|
||||
private IEnumerator Casting(BaseAbility ability, Action abilityExecution)
|
||||
{
|
||||
isCasting = true;
|
||||
CastBarHandler.Instance.ShowCastBar(ability, abilityExecution);
|
||||
|
||||
// Use player attack speed instead of ability cast time
|
||||
float castTime = GetCurrentAttackInterval();
|
||||
|
||||
CastBarHandler.Instance.ShowCastBar(ability, abilityExecution, castTime);
|
||||
playerMovement.InstantFaceCast(projectileSpawnLocationController.GetLookat());
|
||||
|
||||
//cast animation
|
||||
yield return new WaitForSeconds(ability.castTime);
|
||||
// Wait for the calculated attack interval
|
||||
yield return new WaitForSeconds(castTime);
|
||||
|
||||
if (!GameConstants.Animation.IsAnimationEventBasedAbility(ability.animationType))
|
||||
{
|
||||
@ -75,29 +92,26 @@ public class CastingStateController : MonoBehaviour
|
||||
}
|
||||
|
||||
isCasting = false;
|
||||
|
||||
if (!ability.castableWhileMoving)
|
||||
{
|
||||
movementSpeedModifier.ToggleCastPenalty(false);
|
||||
//playerMovement.ToggleAgentMoving(false);
|
||||
}
|
||||
|
||||
|
||||
//Debug.Log("$$sCastbar Done casting");
|
||||
}
|
||||
|
||||
private IEnumerator Channeling(BaseAbility channeledAbility, Action abilityChannelExecution)
|
||||
{
|
||||
isCasting = true;
|
||||
|
||||
// For channeled abilities, you might want different behavior
|
||||
// This maintains the original channeling logic
|
||||
CastBarHandler.Instance.ShowChannelingBar(channeledAbility, abilityChannelExecution);
|
||||
|
||||
playerMovement.InstantFaceCast(projectileSpawnLocationController.GetLookat());
|
||||
|
||||
abilityChannelExecution.Invoke();
|
||||
|
||||
if (!channeledAbility.castableWhileMoving)
|
||||
{
|
||||
movementSpeedModifier.ToggleCastPenalty(true);
|
||||
//playerMovement.ToggleAgentMoving(true);
|
||||
}
|
||||
|
||||
yield return null;
|
||||
@ -107,15 +121,14 @@ public class CastingStateController : MonoBehaviour
|
||||
{
|
||||
isCasting = false;
|
||||
movementSpeedModifier.ToggleCastPenalty(false);
|
||||
//playerMovement.ToggleAgentMoving(false);
|
||||
}
|
||||
|
||||
public void ResetCastingOnMeleeAnimationEvent()
|
||||
{
|
||||
isCasting = false;
|
||||
movementSpeedModifier.ToggleCastPenalty(false);
|
||||
//playerMovement.ToggleAgentMoving(false);
|
||||
StopAllCoroutines();
|
||||
//Debug.Log("$$ResetCastingState On Event");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@ -6,5 +6,6 @@ using UnityEngine;
|
||||
public class StatInfluence
|
||||
{
|
||||
public GameTag statTag;
|
||||
public CharacterStatType statType;
|
||||
public float percentInfluence;
|
||||
}
|
||||
@ -1,3 +1,4 @@
|
||||
using Kryz.CharacterStats;
|
||||
using UnityEngine;
|
||||
using static GameConstants.EnemySpawning;
|
||||
|
||||
@ -167,6 +168,8 @@ public static class GameConstants
|
||||
public const float MaximumPercentDamageReductionFromMagicResistance = 0.75f;
|
||||
public const float MaximumPercentCooldownReduction = 0.9f;
|
||||
public const float MaximumPercentDamageReductionFromBlock = 0.75f;
|
||||
public const float BaseAttacksPerSecond = 1f;
|
||||
public const float FastestAttacksPerSecond = 0.25f;
|
||||
|
||||
public const float BaseMaxHealthGrowthPerLevel = 0.2f;
|
||||
|
||||
@ -240,6 +243,7 @@ public static class GameConstants
|
||||
public const float MovementSpeedCastingPenalty = -0.75f;
|
||||
public const float MovementSpeedLowestCap = 0.25f;
|
||||
public const float BossMovementSpeedBaseLowestPercentCap = 0.8f; //bosses can only be lowered to 80% of their normal speed: 2.85 base speed == 2.28 minimum speed
|
||||
|
||||
}
|
||||
public static class GameBalancing
|
||||
{
|
||||
@ -435,4 +439,11 @@ public static class GameConstants
|
||||
return HuntersInn;
|
||||
}
|
||||
}
|
||||
|
||||
public static class EquipmentStatRules
|
||||
{
|
||||
public const int ItemTotalStats = 4;
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
8
Assets/Scripts/Items/Generator.meta
Normal file
8
Assets/Scripts/Items/Generator.meta
Normal file
@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 1b226c360854c4b4f8bdce0961d34302
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
166
Assets/Scripts/Items/Generator/EquippableItemGenerator.cs
Normal file
166
Assets/Scripts/Items/Generator/EquippableItemGenerator.cs
Normal file
@ -0,0 +1,166 @@
|
||||
using Kryz.CharacterStats.Examples;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
public class EquippableItemGenerator : MonoBehaviour
|
||||
{
|
||||
public List<Sprite> HelmetIcons = new List<Sprite>();
|
||||
public List<Sprite> ShoulderIcons = new List<Sprite>();
|
||||
public List<Sprite> ChestIcons = new List<Sprite>();
|
||||
public List<Sprite> BeltIcons = new List<Sprite>();
|
||||
public List<Sprite> LegsIcons = new List<Sprite>();
|
||||
public List<Sprite> BracersIcons = new List<Sprite>();
|
||||
public List<Sprite> GlovesIcons = new List<Sprite>();
|
||||
public List<Sprite> BootsIcons = new List<Sprite>();
|
||||
public List<Sprite> StaffIcons = new List<Sprite>();
|
||||
public List<Sprite> SpearIcons = new List<Sprite>();
|
||||
public List<Sprite> ScytheIcons = new List<Sprite>();
|
||||
public List<Sprite> HammerIcons = new List<Sprite>();
|
||||
public List<Sprite> BowIcons = new List<Sprite>();
|
||||
public List<Sprite> CrossbowIcons = new List<Sprite>();
|
||||
public List<Sprite> AxeIcons = new List<Sprite>();
|
||||
public List<Sprite> SwordIcons = new List<Sprite>();
|
||||
public List<Sprite> ShieldIcons = new List<Sprite>();
|
||||
public List<Sprite> DaggerIcons = new List<Sprite>();
|
||||
public List<Sprite> BookIcons = new List<Sprite>();
|
||||
|
||||
[ContextMenu("Update Lists From Resources")]
|
||||
private void UpdateListsFromResources()
|
||||
{
|
||||
// Armor pieces
|
||||
HelmetIcons.Clear();
|
||||
foreach (Sprite sprite in Resources.LoadAll<Sprite>("Armor/Helmets"))
|
||||
{
|
||||
HelmetIcons.Add(sprite);
|
||||
}
|
||||
|
||||
ShoulderIcons.Clear();
|
||||
foreach (Sprite sprite in Resources.LoadAll<Sprite>("Armor/Shoulders"))
|
||||
{
|
||||
ShoulderIcons.Add(sprite);
|
||||
}
|
||||
|
||||
ChestIcons.Clear();
|
||||
foreach (Sprite sprite in Resources.LoadAll<Sprite>("Armor/Chests"))
|
||||
{
|
||||
ChestIcons.Add(sprite);
|
||||
}
|
||||
|
||||
BeltIcons.Clear();
|
||||
foreach (Sprite sprite in Resources.LoadAll<Sprite>("Armor/Belts"))
|
||||
{
|
||||
BeltIcons.Add(sprite);
|
||||
}
|
||||
|
||||
LegsIcons.Clear();
|
||||
foreach (Sprite sprite in Resources.LoadAll<Sprite>("Armor/Legs"))
|
||||
{
|
||||
LegsIcons.Add(sprite);
|
||||
}
|
||||
|
||||
BracersIcons.Clear();
|
||||
foreach (Sprite sprite in Resources.LoadAll<Sprite>("Armor/Bracers"))
|
||||
{
|
||||
BracersIcons.Add(sprite);
|
||||
}
|
||||
|
||||
GlovesIcons.Clear();
|
||||
foreach (Sprite sprite in Resources.LoadAll<Sprite>("Armor/Gloves"))
|
||||
{
|
||||
GlovesIcons.Add(sprite);
|
||||
}
|
||||
|
||||
BootsIcons.Clear();
|
||||
foreach (Sprite sprite in Resources.LoadAll<Sprite>("Armor/Boots"))
|
||||
{
|
||||
BootsIcons.Add(sprite);
|
||||
}
|
||||
|
||||
// Two-handed weapons
|
||||
StaffIcons.Clear();
|
||||
foreach (Sprite sprite in Resources.LoadAll<Sprite>("Weapons/Staffs"))
|
||||
{
|
||||
StaffIcons.Add(sprite);
|
||||
}
|
||||
|
||||
SpearIcons.Clear();
|
||||
foreach (Sprite sprite in Resources.LoadAll<Sprite>("Weapons/Spears"))
|
||||
{
|
||||
SpearIcons.Add(sprite);
|
||||
}
|
||||
|
||||
ScytheIcons.Clear();
|
||||
foreach (Sprite sprite in Resources.LoadAll<Sprite>("Weapons/Scythes"))
|
||||
{
|
||||
ScytheIcons.Add(sprite);
|
||||
}
|
||||
|
||||
HammerIcons.Clear();
|
||||
foreach (Sprite sprite in Resources.LoadAll<Sprite>("Weapons/Hammers"))
|
||||
{
|
||||
HammerIcons.Add(sprite);
|
||||
}
|
||||
|
||||
BowIcons.Clear();
|
||||
foreach (Sprite sprite in Resources.LoadAll<Sprite>("Weapons/Bows"))
|
||||
{
|
||||
BowIcons.Add(sprite);
|
||||
}
|
||||
|
||||
CrossbowIcons.Clear();
|
||||
foreach (Sprite sprite in Resources.LoadAll<Sprite>("Weapons/Crossbows"))
|
||||
{
|
||||
CrossbowIcons.Add(sprite);
|
||||
}
|
||||
|
||||
AxeIcons.Clear();
|
||||
foreach (Sprite sprite in Resources.LoadAll<Sprite>("Weapons/Axes"))
|
||||
{
|
||||
AxeIcons.Add(sprite);
|
||||
}
|
||||
|
||||
// One-handed weapons
|
||||
SwordIcons.Clear();
|
||||
foreach (Sprite sprite in Resources.LoadAll<Sprite>("Weapons/Swords"))
|
||||
{
|
||||
SwordIcons.Add(sprite);
|
||||
}
|
||||
|
||||
ShieldIcons.Clear();
|
||||
foreach (Sprite sprite in Resources.LoadAll<Sprite>("Weapons/Shields"))
|
||||
{
|
||||
ShieldIcons.Add(sprite);
|
||||
}
|
||||
|
||||
DaggerIcons.Clear();
|
||||
foreach (Sprite sprite in Resources.LoadAll<Sprite>("Weapons/Daggers"))
|
||||
{
|
||||
DaggerIcons.Add(sprite);
|
||||
}
|
||||
|
||||
BookIcons.Clear();
|
||||
foreach (Sprite sprite in Resources.LoadAll<Sprite>("Weapons/Books"))
|
||||
{
|
||||
BookIcons.Add(sprite);
|
||||
}
|
||||
|
||||
Debug.Log("Updated all icon lists from Resources folders");
|
||||
}
|
||||
|
||||
public EquippableItemInstance GenerateEquippableItemInstance()
|
||||
{
|
||||
EquippableItemInstance generatedItem = new EquippableItemInstance();
|
||||
|
||||
//Do stuff
|
||||
|
||||
return generatedItem;
|
||||
}
|
||||
public EquippableItemInstance GenerateEquippableItemInstance(EquipmentType equipmentType)
|
||||
{
|
||||
EquippableItemInstance generatedItem = new EquippableItemInstance();
|
||||
|
||||
//Do stuff
|
||||
|
||||
return generatedItem;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,2 @@
|
||||
fileFormatVersion: 2
|
||||
guid: a85a7f34d000be84fa64ef31a99b20b4
|
||||
Loading…
x
Reference in New Issue
Block a user