Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/build-and-test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ name: Build And Test
on: [push]

env:
BuildVersion: '0.42.${{github.run_number}}'
BuildVersion: '0.43.${{github.run_number}}'
SolutionFile: 'src/OpenRpg.sln'
DemoProject: 'src/OpenRpg.Demos.Web/OpenRpg.Demos.Web.csproj'
EditorProject: 'src/OpenRpg.Editor/OpenRpg.Editor.csproj'
Expand Down
6 changes: 3 additions & 3 deletions docs/genres.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ The `Genres` project is a layering/contractual approach that allows you to expre
You maybe don't, but if we take a step back and think about more RPG games, there are some common themes/settings/mechanics at play, for example if is list some common `Fantasy` themes:
- They often have some form of *Human*, *Dwarf*, *Elf* `Races`
- They often have some form of *Fighter*, *Rogue*, *Mage* `Classes`
- They often have the notion of `Health` and `Magic`
- They often have the notion of `Health` and `Mana`
- They often have different kinds of `Damage` like *Blunt*, *Fire*, *Wind*, *Piercing*
- You can often equip *weapons*, *chest/leg/shoulder/hand* items
- You can often modify your equipment with *runes/gems/enchantments*
Expand All @@ -31,9 +31,9 @@ The other **REALLY IMPORTANT** thing it provides is a contract so everyone using

As mentioned above this provides some out the box functionality and type data for common Fantasy themes, so at a high level things like:
- Fantasy Stat Types (Strength, Dexterity etc)
- Fantasy State Types (Health, Magic)
- Fantasy State Types (Health, Mana)
- Fantasy Damage/Defense Types (Fire, Ice, Wind, Slash, Blunt etc)
- Fantasy Effect Types (Strength Bonus Amount/Percentage, Magic Restore Speed etc)
- Fantasy Effect Types (Strength Bonus Amount/Percentage, Mana Restore Speed etc)

> There is so much more and its recommended you check over the classes in the `Types`, `Extensions` namespaces for exact additions this library provides.

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ public ClassTemplate GenerateMageClass()
new StaticEffect {Potency = 4, EffectType = FantasyEffectTypes.IntelligenceBonusAmount},
new StaticEffect {Potency = 10, EffectType = FantasyEffectTypes.DarkDamageAmount},
new StaticEffect {Potency = 10, EffectType = FantasyEffectTypes.DarkDefenseAmount},
new StaticEffect {Potency = 30, EffectType = FantasyEffectTypes.MagicBonusAmount}
new StaticEffect {Potency = 30, EffectType = FantasyEffectTypes.ManaBonusAmount}
};

var classTemplate = new ClassTemplate
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ public RaceTemplate GenerateHumanTemplate()
new StaticEffect {Potency = 1, EffectType = FantasyEffectTypes.DarkDamageAmount},
new StaticEffect {Potency = 5, EffectType = FantasyEffectTypes.DarkDefenseAmount},
new StaticEffect {Potency = 80, EffectType = FantasyEffectTypes.HealthBonusAmount},
new StaticEffect {Potency = 10, EffectType = FantasyEffectTypes.MagicBonusAmount}
new StaticEffect {Potency = 10, EffectType = FantasyEffectTypes.ManaBonusAmount}
};

var raceTemplate = new RaceTemplate
Expand Down Expand Up @@ -60,7 +60,7 @@ public RaceTemplate GenerateElfTemplate()
new StaticEffect {Potency = 5, EffectType = FantasyEffectTypes.DarkDamageAmount},
new StaticEffect {Potency = 10, EffectType = FantasyEffectTypes.DarkDefenseAmount},
new StaticEffect {Potency = 70, EffectType = FantasyEffectTypes.HealthBonusAmount},
new StaticEffect {Potency = 30, EffectType = FantasyEffectTypes.MagicBonusAmount}
new StaticEffect {Potency = 30, EffectType = FantasyEffectTypes.ManaBonusAmount}
};

var raceTemplate = new RaceTemplate
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,8 @@
<progress class="progress is-danger" value="@State.Health().ToString()" max="@Stats.MaxHealth().ToString()"></progress>
</div>
<div class="column">
<h4 class="subtitle mb-2 has-text-dark has-text-centered">Magic</h4>
<progress class="progress is-info" value="@State.Magic().ToString()" max="@Stats.MaxMagic().ToString()"></progress>
<h4 class="subtitle mb-2 has-text-dark has-text-centered">Mana</h4>
<progress class="progress is-info" value="@State.Mana().ToString()" max="@Stats.MaxMana().ToString()"></progress>
</div>
</div>
}
Expand Down
2 changes: 1 addition & 1 deletion src/OpenRpg.Demos.Web/Pages/Curves/AdvancedEffects.razor
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@
So far everything you have been touching on uses the `StaticEffect` behind the scenes which expresses an `EffectType`
and a `Potency`, however the potency is a fixed value, so if its 10, its always going to be 10. For most use cases
this is perfectly fine, however imagine if you were making a Souls-like game and you wanted to make a weapon whos
`Damage` stat scaled with your `Strength` stat, or if your `Necromancer` class got a `MaxMagic` boost at night time.
`Damage` stat scaled with your `Strength` stat, or if your `Necromancer` class got a `MaxMana` boost at night time.

`ScaledEffects` let you achieve these sorts of use cases by replacing the static `Potency` with a `PotencyFunction`
that allows us to *compute* the effects potency based off other factors and plot it on a curve.
Expand Down
2 changes: 1 addition & 1 deletion src/OpenRpg.Demos.Web/Pages/Entities/AdvancedStats.razor
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@

To get around this we try to think about the differences between static vs dynamic data in persistence terms and you generally
want to cull all static data on persistence actions as it should all be regenerated when the character is loaded in, the only data
that REALLY needs persisting from the stats is dynamic data like Health and Magic and any other `State` variables you add.
that REALLY needs persisting from the stats is dynamic data like Health and Mana and any other `State` variables you add.
</Markdown>

<br/>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@
var character = new DefaultEntity();

character.Stats.MaxHealth(100);
character.Stats.MaxMagic(10);
character.Stats.MaxMana(10);
character.Stats.Strength(11);
character.Stats.Dexterity(12);
character.Stats.Intelligence(12);
Expand Down Expand Up @@ -101,7 +101,7 @@
new Effect {Potency = 1, EffectType = FantasyEffectTypes.DarkDamageAmount},
new Effect {Potency = 5, EffectType = FantasyEffectTypes.DarkDefenseAmount},
new Effect {Potency = 50, EffectType = FantasyEffectTypes.HealthBonusAmount},
new Effect {Potency = 10, EffectType = FantasyEffectTypes.MagicBonusAmount}
new Effect {Potency = 10, EffectType = FantasyEffectTypes.ManaBonusAmount}
};

var classEffects = new[]
Expand Down Expand Up @@ -228,8 +228,8 @@
ManualStatsExample.Stats = new EntityStatsVariables();
ManualStatsExample.Stats.MaxHealth(100);
ManualStatsExample.State.Health(50);
ManualStatsExample.Stats.MaxMagic(10);
ManualStatsExample.State.Magic(7);
ManualStatsExample.Stats.MaxMana(10);
ManualStatsExample.State.Mana(7);

ManualStatsExample.Stats.Strength(11);
ManualStatsExample.Stats.Dexterity(12);
Expand Down Expand Up @@ -259,7 +259,7 @@
new StaticEffect {Potency = 1, EffectType = FantasyEffectTypes.DarkDamageAmount},
new StaticEffect {Potency = 5, EffectType = FantasyEffectTypes.DarkDefenseAmount},
new StaticEffect {Potency = 50, EffectType = FantasyEffectTypes.HealthBonusAmount},
new StaticEffect {Potency = 10, EffectType = FantasyEffectTypes.MagicBonusAmount}
new StaticEffect {Potency = 10, EffectType = FantasyEffectTypes.ManaBonusAmount}
};

var classEffects = new[]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,8 +44,8 @@
character.Class = new DefaultCharacterClass(3, new DefaultClassTemplate { NameLocaleId = "Fighter" });
character.Stats.MaxHealth(100);
character.State.Health(50);
character.Stats.MaxMagic(10);
character.State.Magic(7);
character.Stats.MaxMana(10);
character.State.Mana(7);
character.Stats.Strength(11);
character.Stats.Dexterity(12);
character.Stats.Intelligence(12);
Expand Down Expand Up @@ -147,8 +147,8 @@

_manualCharacter.Stats.MaxHealth(100);
_manualCharacter.State.Health(50);
_manualCharacter.Stats.MaxMagic(10);
_manualCharacter.State.Magic(7);
_manualCharacter.Stats.MaxMana(10);
_manualCharacter.State.Mana(7);

_manualCharacter.Stats.Strength(11);
_manualCharacter.Stats.Dexterity(12);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -157,7 +157,7 @@
new StaticEffect { EffectType = FantasyEffectTypes.DamageBonusAmount, Potency = 15.0f },
new StaticEffect { EffectType = FantasyEffectTypes.DarkDamageAmount, Potency = 30.0f },
new StaticEffect { EffectType = FantasyEffectTypes.IntelligenceBonusAmount, Potency = 5.0f },
new StaticEffect { EffectType = FantasyEffectTypes.MagicBonusAmount, Potency = 40.0f }
new StaticEffect { EffectType = FantasyEffectTypes.ManaBonusAmount, Potency = 40.0f }
}
};
template.Variables.QualityType(FantasyItemQualityTypes.RareQuality);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -160,7 +160,7 @@
new StaticEffect { EffectType = FantasyEffectTypes.DamageBonusAmount, Potency = 15.0f },
new StaticEffect { EffectType = FantasyEffectTypes.DarkDamageAmount, Potency = 30.0f },
new StaticEffect { EffectType = FantasyEffectTypes.IntelligenceBonusAmount, Potency = 5.0f },
new StaticEffect { EffectType = FantasyEffectTypes.MagicBonusAmount, Potency = 40.0f }
new StaticEffect { EffectType = FantasyEffectTypes.ManaBonusAmount, Potency = 40.0f }
}
};
template.Variables.QualityType(FantasyItemQualityTypes.RareQuality);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,6 @@ public interface CoreTemplateDataVariableTypes
public static int Level = 5001;

// For adding the procedural associations
public static int ProceduralAssociations = 5001;
public static int ProceduralAssociations = 5002;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,11 @@ public static class EntityStatVariableExtensions
public static void Wisdom(this EntityStatsVariables stats, int value) => stats[FantasyEntityStatsVariableTypes.Wisdom] = value;
public static void Charisma(this EntityStatsVariables stats, int value) => stats[FantasyEntityStatsVariableTypes.Charisma] = value;

public static void MaxMagic(this EntityStatsVariables stats, int value) => stats[FantasyEntityStatsVariableTypes.MaxMagic] = value;
public static int MaxMagic(this EntityStatsVariables stats) => (int)stats.Get(FantasyEntityStatsVariableTypes.MaxMagic);
public static void MaxMana(this EntityStatsVariables stats, int value) => stats[FantasyEntityStatsVariableTypes.MaxMana] = value;
public static int MaxMana(this EntityStatsVariables stats) => (int)stats.Get(FantasyEntityStatsVariableTypes.MaxMana);

public static void MagicRegen(this EntityStatsVariables stats, float value) => stats[FantasyEntityStatsVariableTypes.MagicRegen] = value;
public static float MagicRegen(this EntityStatsVariables stats) => stats.Get(FantasyEntityStatsVariableTypes.MagicRegen);
public static void ManaRegen(this EntityStatsVariables stats, float value) => stats[FantasyEntityStatsVariableTypes.ManaRegen] = value;
public static float ManaRegen(this EntityStatsVariables stats) => stats.Get(FantasyEntityStatsVariableTypes.ManaRegen);

public static float IceDamage(this EntityStatsVariables stats) => stats.Get(FantasyEntityStatsVariableTypes.IceDamage);
public static float FireDamage(this EntityStatsVariables stats) => stats.Get(FantasyEntityStatsVariableTypes.FireDamage);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,25 +6,25 @@ namespace OpenRpg.Genres.Fantasy.Extensions
{
public static class EntityStateVariableExtensions
{
public static int Magic(this EntityStateVariables state) => (int)state.Get(FantasyEntityStateVariableTypes.Magic);
public static void Magic(this EntityStateVariables state, int value) => state[FantasyEntityStateVariableTypes.Magic] = value;
public static int Mana(this EntityStateVariables state) => (int)state.Get(FantasyEntityStateVariableTypes.Mana);
public static void Mana(this EntityStateVariables state, int value) => state[FantasyEntityStateVariableTypes.Mana] = value;

public static void AddMagic(this EntityStateVariables state, int change, int? maxMagic = null)
public static void AddMana(this EntityStateVariables state, int change, int? maxMana = null)
{
var newValue = state.Magic() + change;
if (maxMagic.HasValue)
{ state.AddValue(FantasyEntityStateVariableTypes.Magic, newValue, 0, maxMagic.Value); }
var newValue = state.Mana() + change;
if (maxMana.HasValue)
{ state.AddValue(FantasyEntityStateVariableTypes.Mana, newValue, 0, maxMana.Value); }
else
{ state.Magic(newValue); }
{ state.Mana(newValue); }
}

public static void DeductMagic(this EntityStateVariables state, int change, int? maxMagic = null)
public static void DeductMana(this EntityStateVariables state, int change, int? maxMana = null)
{
var newValue = state.Magic() - change;
if (maxMagic.HasValue)
{ state.AddValue(FantasyEntityStateVariableTypes.Magic, newValue, 0, maxMagic.Value); }
var newValue = state.Mana() - change;
if (maxMana.HasValue)
{ state.AddValue(FantasyEntityStateVariableTypes.Mana, newValue, 0, maxMana.Value); }
else
{ state.Magic(newValue); }
{ state.Mana(newValue); }
}
}
}
10 changes: 10 additions & 0 deletions src/OpenRpg.Genres.Fantasy/Extensions/FantasyEntityExtensions.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
using OpenRpg.Entities.Entity;

namespace OpenRpg.Genres.Fantasy.Extensions
{
public static class FantasyEntityExtensions
{
public static float GetManaPercentage(this Entity entity)
{ return (float)entity.State.Mana() / entity.Stats.MaxMana(); }
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,8 @@ public override bool IsRequirementMet(Character character, Requirement requireme
if(requirement.RequirementType == FantasyRequirementTypes.CharismaRequirement)
{ return character.Stats.Charisma() >= requirement.Association.AssociatedValue; }

if(requirement.RequirementType == FantasyRequirementTypes.MaxMagicRequirement)
{ return character.Stats.MaxMagic() >= requirement.Association.AssociatedValue; }
if(requirement.RequirementType == FantasyRequirementTypes.MaxManaRequirement)
{ return character.Stats.MaxMana() >= requirement.Association.AssociatedValue; }

return base.IsRequirementMet(character, requirement);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,8 @@ public void Populate(EntityStateVariables state, ComputedEffects computedEffects

var entityStats = statsVars as EntityStatsVariables;
state.Health(entityStats.MaxHealth());
state.Magic(entityStats.MaxMagic());
state.Stamina(entityStats.MaxStamina());
state.Mana(entityStats.MaxMana());
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ public FantasyStatsPopulator(IEnumerable<IEntityPartialStatPopulator> additional
new FantasyMeleeStatPopulator(),
new FantasyElementalStatPopulator(),
new AbilityStatPopulator(),
new CriticalStatPopulator()
};

if (additionalStatPopulators != null)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,11 @@
using OpenRpg.Entities.Effects.Processors;
using OpenRpg.Entities.Entity.Populators.Stats;
using OpenRpg.Entities.Stats.Variables;
using OpenRpg.Genres.Extensions;
using OpenRpg.Genres.Fantasy.Effects;
using OpenRpg.Genres.Fantasy.Extensions;
using OpenRpg.Genres.Fantasy.Types;
using OpenRpg.Genres.Types;

namespace OpenRpg.Genres.Fantasy.Stats.Populators.Partial
{
Expand Down Expand Up @@ -37,7 +39,6 @@ public void Populate(EntityStatsVariables stats, ComputedEffects computedEffects
stats.PiercingDefense(CalculateStatsWithModifier(computedEffects, FantasyEffectTypes.AllMeleeDefenseBonusPercentage, FantasyEffectTypes.AllMeleeDefenseBonusPercentage, EffectRelationships.PiercingDefenseRelationship, piercingModifier));
stats.SlashingDefense(CalculateStatsWithModifier(computedEffects, FantasyEffectTypes.AllMeleeDefenseBonusPercentage, FantasyEffectTypes.AllMeleeDefenseBonusPercentage, EffectRelationships.SlashingDefenseRelationship, slashingOrUnarmedModifier));
stats.UnarmedDefense(CalculateStatsWithModifier(computedEffects, FantasyEffectTypes.AllMeleeDefenseBonusPercentage, FantasyEffectTypes.AllMeleeDefenseBonusPercentage, EffectRelationships.UnarmedDefenseRelationship, slashingOrUnarmedModifier));

}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -20,12 +20,18 @@ public void Populate(EntityStatsVariables stats, ComputedEffects computedEffects
var maxHealth = (int)computedEffects.CalculateTotalValueFor(FantasyEffectTypes.HealthBonusAmount, FantasyEffectTypes.HealthBonusPercentage, constitutionBonus);
stats.MaxHealth(maxHealth);

var maxStamina = (int)computedEffects.CalculateTotalValueFor(FantasyEffectTypes.StaminaBonusAmount, FantasyEffectTypes.StaminaBonusPercentage, constitutionBonus);
stats.MaxStamina(maxStamina);

var intelligenceBonus = stats.Intelligence() * 5;
var maxMagic = (int)computedEffects.CalculateTotalValueFor(FantasyEffectTypes.MagicBonusAmount, FantasyEffectTypes.MagicBonusPercentage, intelligenceBonus);
stats.MaxMagic(maxMagic);
var maxMana = (int)computedEffects.CalculateTotalValueFor(FantasyEffectTypes.ManaBonusAmount, FantasyEffectTypes.ManaBonusPercentage, intelligenceBonus);
stats.MaxMana(maxMana);

stats.HealthRegen(computedEffects.CalculateTotalValueFor(FantasyEffectTypes.HealthRegenBonusAmount, FantasyEffectTypes.HealthRegenBonusPercentage));
stats.MagicRegen(computedEffects.CalculateTotalValueFor(FantasyEffectTypes.MagicRegenBonusAmount, FantasyEffectTypes.MagicRegenBonusPercentage));
stats.ManaRegen(computedEffects.CalculateTotalValueFor(FantasyEffectTypes.ManaRegenBonusAmount, FantasyEffectTypes.ManaRegenBonusPercentage));
stats.StaminaRegen(computedEffects.CalculateTotalValueFor(FantasyEffectTypes.StaminaRegenBonusAmount, FantasyEffectTypes.StaminaRegenBonusPercentage));

stats.MovementSpeed(computedEffects.CalculateTotalValueFor(FantasyEffectTypes.MovementSpeedBonusAmount, FantasyEffectTypes.MovementSpeedBonusPercentage));
}
}
}
Loading
Loading