Веб-сайт самохостера Lotigara

summaryrefslogtreecommitdiff
path: root/source/game/StarStatSet.hpp
diff options
context:
space:
mode:
authorKae <80987908+Novaenia@users.noreply.github.com>2023-06-20 14:33:09 +1000
committerKae <80987908+Novaenia@users.noreply.github.com>2023-06-20 14:33:09 +1000
commit6352e8e3196f78388b6c771073f9e03eaa612673 (patch)
treee23772f79a7fbc41bc9108951e9e136857484bf4 /source/game/StarStatSet.hpp
parent6741a057e5639280d85d0f88ba26f000baa58f61 (diff)
everything everywhere
all at once
Diffstat (limited to 'source/game/StarStatSet.hpp')
-rw-r--r--source/game/StarStatSet.hpp153
1 files changed, 153 insertions, 0 deletions
diff --git a/source/game/StarStatSet.hpp b/source/game/StarStatSet.hpp
new file mode 100644
index 0000000..759582b
--- /dev/null
+++ b/source/game/StarStatSet.hpp
@@ -0,0 +1,153 @@
+#ifndef STAR_STAT_SET_HPP
+#define STAR_STAT_SET_HPP
+
+#include "StarStatusTypes.hpp"
+
+namespace Star {
+
+STAR_CLASS(StatSet);
+
+// Manages a collection of Stats and Resources.
+//
+// Stats are named floating point values of any base value, with an arbitrary
+// number of "stat modifiers" attached to them. Stat modifiers can be added
+// and removed in groups, and they can either raise or lower stats by a
+// constant value or a percentage of the stat value without any other
+// percentage modifications applied. The effective stat value is always the
+// value with all mods applied. If a modifier is created for a stat that does
+// not exist, there will be an effective stat value for the modified stat, but
+// NO base stat. If the modifier is a base percentage modifier, it will have
+// no effect because it is assumed that base stats that do not exist are zero.
+//
+// Resources are also named floating point values, but are in a different
+// namespaced and are intended to be used as values that change regularly.
+// They are always >= 0.0f, and optionally have a maximum value based on a
+// given value or stat. In addition to a max value, they can also have a
+// "delta" value or stat, which automatically adds or removes that delta to the
+// resource every second.
+//
+// If a resource has a maximum value, then rather than trying to keep the
+// *value* of the resource constant, this class will instead attempt to keep
+// the *percentage* of the resource constant across stat changes. For example,
+// if "health" is a stat with a max of 100, and the current health value is 50,
+// and the max health stat is changed to 200 through any means, the health
+// value will automatically update to 100.
+class StatSet {
+public:
+ void addStat(String statName, float baseValue = 0.0f);
+ void removeStat(String const& statName);
+
+ // Only lists base stats added with addStat, not stats that come only from
+ // modifiers
+ StringList baseStatNames() const;
+ bool isBaseStat(String const& statName) const;
+
+ // Throws when the stat is not a base stat that is added via addStat.
+ float statBaseValue(String const& statName) const;
+ void setStatBaseValue(String const& statName, float value);
+
+ List<StatModifierGroupId> statModifierGroupIds() const;
+ List<StatModifier> statModifierGroup(StatModifierGroupId modifierGroupId) const;
+
+ StatModifierGroupId addStatModifierGroup(List<StatModifier> modifiers = {});
+ void addStatModifierGroup(StatModifierGroupId groupId, List<StatModifier> modifiers);
+ bool setStatModifierGroup(StatModifierGroupId groupId, List<StatModifier> modifiers);
+ bool removeStatModifierGroup(StatModifierGroupId modifierGroupId);
+ void clearStatModifiers();
+
+ StatModifierGroupMap const& allStatModifierGroups() const;
+ void setAllStatModifierGroups(StatModifierGroupMap map);
+
+ StringList effectiveStatNames() const;
+
+ // Does this stat exist either from the base stats or the modifiers
+ bool isEffectiveStat(String const& statName) const;
+
+ // Will never throw, returns either the base stat value, or the modified
+ // stat value if a modifier is applied, or 0.0. This is to support stats that
+ // may come only from modifiers and have no base value.
+ float statEffectiveValue(String const& statName) const;
+
+ void addResource(String resourceName, MVariant<String, float> max = {}, MVariant<String, float> delta = {});
+ void removeResource(String const& resourceName);
+
+ MVariant<String, float> resourceMax(String const& resourceName) const;
+ MVariant<String, float> resourceDelta(String const& resourceName) const;
+
+ StringList resourceNames() const;
+ bool isResource(String const& resourceName) const;
+
+ // Will never throw, returns either the resource value, or 0.0 for a missing
+ // resource
+ float resourceValue(String const& resourceName) const;
+
+ float setResourceValue(String const& resourceName, float value);
+ float modifyResourceValue(String const& resourceName, float amount);
+
+ // Similar to consumeResource, will add the given amount to a resource if
+ // it exists. Returns the amount by which the resource was actually increased.
+ float giveResourceValue(String const& resourceName, float amount);
+
+ // If a resource exists and has more than the given amount available, and the
+ // resource is not locked, then subtracts this amount from the resource and
+ // returns true. Otherwise, does nothing and returns false. Will only throw
+ // if 'amount' is less than zero, will simply return false on missing
+ // resource.
+ bool consumeResourceValue(String const& resourceName, float amount);
+
+ // Like consumeResource, but always succeeds if the resource is unlocked and
+ // the amount is nonzero. If the amount is greater than the available
+ // resource, then the resource will be consumed to zero.
+ bool overConsumeResourceValue(String const& resourceName, float amount);
+
+ // A locked resource cannot be consumed in any way.
+ bool resourceLocked(String const& resourceName) const;
+ void setResourceLocked(String const& resourceName, bool locked);
+
+ // If a resource has a maximum value, this will return it.
+ Maybe<float> resourceMaxValue(String const& resourceName) const;
+ // Returns the resource percentage if the resource has a max value.
+ Maybe<float> resourcePercentage(String const& resourceName) const;
+ // If the resource has a max value, then modifies the value percentage,
+ // otherwise this is nonsense so throws.
+ float setResourcePercentage(String const& resourceName, float resourcePercentage);
+ float modifyResourcePercentage(String const& resourceName, float resourcePercentage);
+
+ void update(float dt);
+
+private:
+ struct EffectiveStat {
+ float baseValue;
+ // Value with just the base percent modifiers applied and the value
+ // modifiers
+ float baseModifiedValue;
+ // Final modified value that includes the effective modifiers.
+ float effectiveModifiedValue;
+ };
+
+ struct Resource {
+ MVariant<String, float> max;
+ MVariant<String, float> delta;
+ bool locked;
+ float value;
+ Maybe<float> maxValue;
+
+ // Sets value and clamps between [0.0, maxStatValue] or just >= 0.0 if
+ // maxStatValue is not given.
+ float setValue(float v);
+ };
+
+ Resource const& getResource(String const& resourceName) const;
+ Resource& getResource(String const& resourceName);
+
+ bool consumeResourceValue(String const& resourceName, float amount, bool allowOverConsume);
+
+ StringMap<float> m_baseStats;
+ StringMap<EffectiveStat> m_effectiveStats;
+ StatModifierGroupMap m_statModifierGroups;
+ StringMap<Resource> m_resources;
+};
+
+}
+
+#endif