Ok thanks for the info, I will definitely have to find another solution to how I have it set up!
An entity (player, enemy, etc.) casts skills that have different elemental types, these skills interact with each other differently depending on the type. Defensive skills are cast and (currently) added to the dictionary with the Key being the Elemental type and the Value being the amount of defense, this way additional casts of the same element for defense simply add to the value and new elemental types of defense are “stacked” below.
When an entity attacks another it is supposed to cycle through the “defensive stack” that the other entity has. The attack also has its own elemental type and is applied to each stack in order until either the defensive stacks are depleted or the attack amount is depleted. The main reason I chose a Dictionary is it allows to easily call the Elemental type of the defensive stack and update its Value accordingly. If you have a better idea of implementing a way for a “defensive stack” I am all ears, thanks for the help and below is the code for the Combat Handler as well.
static readonly Dictionary <Element, Element[]> doubleDamage = new Dictionary<Element, Element[]>
{
{Element.Earth, new Element[]{Element.Fire, Element.Energy}}, //EARTH 2x
{Element.Water, new Element[]{Element.Earth, Element.Fire, Element.Death}}, //WATER 2x
{Element.Air, new Element[]{Element.Earth, Element.Water, Element.Fire}}, //AIR 2x
{Element.Fire, new Element[]{Element.Life, Element.Death}}, //FIRE 2x
{Element.Life, new Element[]{Element.Physical}}, //LIFE 2x
{Element.Death, new Element[]{Element.Physical, Element.Air, Element.Life}}, //DEATH 2x
{Element.Energy, new Element[]{Element.Water, Element.Air, Element.Death}} //ENERGY 2x
};
static readonly Dictionary <Element, Element[]> halfDamage = new Dictionary<Element, Element[]>
{
{Element.Physical, new Element[]{Element.Life, Element.Death}}, //PHYSICAL 0.5x
{Element.Earth, new Element[]{Element.Water, Element.Air}}, //EARTH 0.5x
{Element.Water, new Element[]{Element.Air, Element.Energy}}, //WATER 0.5x
{Element.Air, new Element[]{Element.Death, Element.Energy}}, //AIR 0.5x
{Element.Fire, new Element[]{Element.Earth, Element.Water, Element.Air}}, //FIRE 0.5x
{Element.Life, new Element[]{Element.Fire, Element.Death}}, //LIFE 0.5x
{Element.Death, new Element[]{Element.Water, Element.Fire, Element.Energy}}, //DEATH 0.5x
{Element.Energy, new Element[]{Element.Earth, Element.Energy}} //ENERGY 0.5x
};
public enum Element
{
Physical, Earth, Water, Air, Fire,
Life, Death, Energy
}
public static void CalculateDamage(CSkill attackSkill, CEntity targetEntity, float criticalChance)
{
int attackDamage = attackSkill.damage;
float damageMultiplier = 1f;
bool criticalHit = false;
List<Element> depletedStacks = new List<Element>();
//CRITICAL CHANCE
if (RNG.Roll100F() < criticalChance) {criticalHit = true;} //CRITICAL HIT
//TODO: Indicate a critical strike has taken place
//CYCLE THROUGH ALL DEFENSE STACKS OF THE PLAYER
foreach (KeyValuePair<Element, int> stack in targetEntity.defenseStack)
{
if (attackDamage == 0) {return;}
//CRITICAL HIT DAMAGE (RESET DMG MULTIPLIER)
damageMultiplier = criticalHit ? 1.5f : 1f;
//UPDATE THE DAMAGE MULTIPLIER
damageMultiplier += ElementInteraction(attackSkill.skillElement, stack.Key);
//APPLY THE CURRENT DAMAGE TO THE CURRENT DEFENSE STACK
DefenseStackFormula(damageMultiplier, attackDamage, stack.Value, stack.Key);
}
//CRITICAL HIT DAMAGE (RESET DMG MULTIPLIER)
damageMultiplier = criticalHit ? 1.5f : 1f;
damageMultiplier += ElementInteraction(attackSkill.skillElement, targetEntity.element);
//DAMAGE TARGET ENEMY HEALTH
attackDamage = Mathf.RoundToInt(attackDamage * damageMultiplier);
targetEntity.DamageEntityCombat(attackDamage, depletedStacks);
void DefenseStackFormula(float damageModifier, int attack, int defense, Element defenseElement)
{
//MODIFIER DEFENSE ACCORDING TO ELEMENT INTERACTION
defense = Mathf.RoundToInt(defense/damageModifier);
if (attack - defense >= 0)
{
attackDamage = (attack - defense); //Update remaining attack value
targetEntity.defenseStack[defenseElement] = 0; //Defense is depleted
depletedStacks.Add(defenseElement);
}
else
{
attackDamage = 0; //Attack is depleted
targetEntity.defenseStack[defenseElement] -= attack; //Update remaining defense value
}
}
}
public static float ElementInteraction(Element attackingElement, Element defendingElement)
{
float multiplier = 0;
if (doubleDamage[attackingElement].Contains(defendingElement)) {multiplier = 1f;} //Damage increased by 100%
else if (halfDamage[attackingElement].Contains(defendingElement)) {multiplier = -0.5f;} //Damage reduced by 50%
return multiplier;
}