item stat generation rules

This commit is contained in:
Pedro Gomes 2025-09-23 21:52:06 +01:00
parent 785284b42e
commit 3dcf585d78
4 changed files with 331 additions and 0 deletions

View File

@ -0,0 +1,60 @@
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!114 &11400000
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 0}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: b261a15482e5e154c9f86c6cd8b401b5, type: 3}
m_Name: New Stat Rule Set
m_EditorClassIdentifier: Assembly-CSharp::StatRuleSet
ruleSetName: Default Rules
description: Describe what this rule set does
equipmentRules:
- equipmentType: 0
ruleName: Helmet Stat Rules
statModifiers:
- statType: 3
modificationType: 0
value: 0
useCondition: 0
conditionDescription:
- statType: 4
modificationType: 0
value: 0
useCondition: 0
conditionDescription:
- statType: 16
modificationType: 0
value: 0
useCondition: 0
conditionDescription:
- statType: 17
modificationType: 0
value: 0
useCondition: 0
conditionDescription:
- statType: 13
modificationType: 1
value: 2
useCondition: 0
conditionDescription:
- statType: 14
modificationType: 1
value: 1.5
useCondition: 0
conditionDescription:
- statType: 9
modificationType: 1
value: 1.5
useCondition: 0
conditionDescription:
mandatoryStats: 0d000000
forbiddenStats: 03000000040000001000000011000000
weaponRules: []
relationshipRules: []
tierRules: []

View File

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 0e0fedd18e1c7d84bbcb311bc1744ae6
NativeFormatImporter:
externalObjects: {}
mainObjectFileID: 11400000
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,261 @@
using Kryz.CharacterStats.Examples;
using System.Collections.Generic;
using UnityEngine;
[CreateAssetMenu(fileName = "New Stat Rule Set", menuName = "RiftMayhem/Stat Rule Set")]
public class StatRuleSet : ScriptableObject
{
[Header("Rule Set Info")]
public string ruleSetName = "Default Rules";
[TextArea(2, 4)]
public string description = "Describe what this rule set does";
[Header("Equipment Type Rules")]
public List<EquipmentTypeRule> equipmentRules = new List<EquipmentTypeRule>();
[Header("Weapon Type Rules")]
public List<WeaponTypeRule> weaponRules = new List<WeaponTypeRule>();
[Header("Global Stat Relationships")]
public List<StatRelationshipRule> relationshipRules = new List<StatRelationshipRule>();
[Header("Tier Rules")]
public List<TierRule> tierRules = new List<TierRule>();
// Method to get effective weights after applying all rules
public EquippableItemGenerator.StatWeights GetEffectiveWeights(EquipmentType equipmentType, WeaponType? weaponType,
EquippableItemGenerator.ItemTier tier, HashSet<CharacterStatType> alreadyRolledStats = null)
{
// Start with base weights (you might want to store base weights in the rule set too)
EquippableItemGenerator.StatWeights effectiveWeights = new EquippableItemGenerator.StatWeights();
// Apply equipment type rules
ApplyEquipmentRules(effectiveWeights, equipmentType);
// Apply weapon type rules if it's a weapon
if (weaponType.HasValue)
{
ApplyWeaponRules(effectiveWeights, weaponType.Value);
}
// Apply tier rules
ApplyTierRules(effectiveWeights, tier);
// Apply relationship rules based on already rolled stats
if (alreadyRolledStats != null)
{
ApplyRelationshipRules(effectiveWeights, alreadyRolledStats);
}
return effectiveWeights;
}
private void ApplyEquipmentRules(EquippableItemGenerator.StatWeights weights, EquipmentType equipmentType)
{
foreach (var rule in equipmentRules)
{
if (rule.equipmentType == equipmentType)
{
rule.ApplyRule(weights);
break; // Only apply the first matching rule
}
}
}
private void ApplyWeaponRules(EquippableItemGenerator.StatWeights weights, WeaponType weaponType)
{
foreach (var rule in weaponRules)
{
if (rule.weaponType == weaponType)
{
rule.ApplyRule(weights);
break;
}
}
}
private void ApplyTierRules(EquippableItemGenerator.StatWeights weights, EquippableItemGenerator.ItemTier tier)
{
foreach (var rule in tierRules)
{
if (rule.tier == tier)
{
rule.ApplyRule(weights);
}
}
}
private void ApplyRelationshipRules(EquippableItemGenerator.StatWeights weights, HashSet<CharacterStatType> alreadyRolledStats)
{
foreach (var rule in relationshipRules)
{
if (alreadyRolledStats.Contains(rule.triggerStat))
{
rule.ApplyRule(weights);
}
}
}
}
[System.Serializable]
public class EquipmentTypeRule
{
public EquipmentType equipmentType;
public string ruleName = "";
[Header("Stat Modifications")]
public StatModifierRule[] statModifiers;
[Header("Mandatory Stats")]
public CharacterStatType[] mandatoryStats;
[Header("Forbidden Stats")]
public CharacterStatType[] forbiddenStats;
public void ApplyRule(EquippableItemGenerator.StatWeights weights)
{
// Apply forbidden stats (set to 0)
foreach (CharacterStatType forbiddenStat in forbiddenStats)
{
SetStatWeight(weights, forbiddenStat, 0f);
}
// Apply stat modifications
foreach (var modifier in statModifiers)
{
float currentWeight = GetStatWeight(weights, modifier.statType);
float newWeight = modifier.modificationType switch
{
ModificationType.Set => modifier.value,
ModificationType.Multiply => currentWeight * modifier.value,
ModificationType.Add => currentWeight + modifier.value,
_ => currentWeight
};
SetStatWeight(weights, modifier.statType, newWeight);
}
}
private float GetStatWeight(EquippableItemGenerator.StatWeights weights, CharacterStatType statType)
{
return statType switch
{
CharacterStatType.AttackDamage => weights.attackDamage,
CharacterStatType.SpellDamage => weights.spellDamage,
CharacterStatType.CritChance => weights.critChance,
CharacterStatType.CritDamage => weights.critDamage,
CharacterStatType.MaxHealth => weights.maxHealth,
CharacterStatType.Armor => weights.armor,
CharacterStatType.MagicResistance => weights.magicResistance,
CharacterStatType.DodgeChance => weights.dodgeChance,
CharacterStatType.BlockChance => weights.blockChance,
CharacterStatType.BlockEffectiveness => weights.blockEffectiveness,
CharacterStatType.HealthRegen => weights.healthRegen,
CharacterStatType.MaxMana => weights.maxMana,
CharacterStatType.ManaRegen => weights.manaRegen,
CharacterStatType.AttackSpeed => weights.attackSpeed,
CharacterStatType.AreaEffectiveness => weights.areaEffectiveness,
CharacterStatType.CooldownReduction => weights.cooldownReduction,
CharacterStatType.MovementSpeed => weights.movementSpeed,
CharacterStatType.ReputationGainIncrease => weights.reputationGain,
CharacterStatType.GoldCostReduction => weights.goldCostReduction,
// Note: Cunning, Flow, Presence, AuraPower don't seem to be in StatWeights
// You might need to add these to StatWeights or handle them separately
_ => 0f
};
}
private void SetStatWeight(EquippableItemGenerator.StatWeights weights, CharacterStatType statType, float value)
{
switch (statType)
{
case CharacterStatType.AttackDamage: weights.attackDamage = value; break;
case CharacterStatType.SpellDamage: weights.spellDamage = value; break;
case CharacterStatType.CritChance: weights.critChance = value; break;
case CharacterStatType.CritDamage: weights.critDamage = value; break;
case CharacterStatType.MaxHealth: weights.maxHealth = value; break;
case CharacterStatType.Armor: weights.armor = value; break;
case CharacterStatType.MagicResistance: weights.magicResistance = value; break;
case CharacterStatType.DodgeChance: weights.dodgeChance = value; break;
case CharacterStatType.BlockChance: weights.blockChance = value; break;
case CharacterStatType.BlockEffectiveness: weights.blockEffectiveness = value; break;
case CharacterStatType.HealthRegen: weights.healthRegen = value; break;
case CharacterStatType.MaxMana: weights.maxMana = value; break;
case CharacterStatType.ManaRegen: weights.manaRegen = value; break;
case CharacterStatType.AttackSpeed: weights.attackSpeed = value; break;
case CharacterStatType.AreaEffectiveness: weights.areaEffectiveness = value; break;
case CharacterStatType.CooldownReduction: weights.cooldownReduction = value; break;
case CharacterStatType.MovementSpeed: weights.movementSpeed = value; break;
case CharacterStatType.ReputationGainIncrease: weights.reputationGain = value; break;
case CharacterStatType.GoldCostReduction: weights.goldCostReduction = value; break;
}
}
}
[System.Serializable]
public class WeaponTypeRule
{
public WeaponType weaponType;
public string ruleName = "";
public StatModifierRule[] statModifiers;
public CharacterStatType[] mandatoryStats;
public CharacterStatType[] forbiddenStats;
public void ApplyRule(EquippableItemGenerator.StatWeights weights)
{
// Same implementation as EquipmentTypeRule
// (Could extract to a base class if you want)
}
}
[System.Serializable]
public class StatRelationshipRule
{
public CharacterStatType triggerStat;
public string ruleName = "";
[Header("When this stat is present, modify these:")]
public StatModifierRule[] statModifications;
public void ApplyRule(EquippableItemGenerator.StatWeights weights)
{
foreach (var modifier in statModifications)
{
// Apply modification logic here
}
}
}
[System.Serializable]
public class TierRule
{
public EquippableItemGenerator.ItemTier tier;
public string ruleName = "";
public StatModifierRule[] statModifiers;
public CharacterStatType[] unlockedStats; // Stats that become available at this tier
public void ApplyRule(EquippableItemGenerator.StatWeights weights)
{
foreach (var modifier in statModifiers)
{
// Apply tier-based modifications
}
}
}
[System.Serializable]
public class StatModifierRule
{
public CharacterStatType statType;
public ModificationType modificationType;
public float value;
[Header("Optional: Condition")]
public bool useCondition = false;
public string conditionDescription = "";
}
public enum ModificationType
{
Set, // Set weight to exact value
Multiply, // Multiply current weight
Add // Add to current weight
}

View File

@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: b261a15482e5e154c9f86c6cd8b401b5