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

summaryrefslogtreecommitdiff
path: root/source/base/StarAnimatedPartSet.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/base/StarAnimatedPartSet.hpp
parent6741a057e5639280d85d0f88ba26f000baa58f61 (diff)
everything everywhere
all at once
Diffstat (limited to 'source/base/StarAnimatedPartSet.hpp')
-rw-r--r--source/base/StarAnimatedPartSet.hpp163
1 files changed, 163 insertions, 0 deletions
diff --git a/source/base/StarAnimatedPartSet.hpp b/source/base/StarAnimatedPartSet.hpp
new file mode 100644
index 0000000..bb3df6c
--- /dev/null
+++ b/source/base/StarAnimatedPartSet.hpp
@@ -0,0 +1,163 @@
+#ifndef STAR_ANIMATED_PART_SET_HPP
+#define STAR_ANIMATED_PART_SET_HPP
+
+#include "StarOrderedMap.hpp"
+#include "StarJson.hpp"
+
+namespace Star {
+
+STAR_EXCEPTION(AnimatedPartSetException, StarException);
+
+// Defines a "animated" data set constructed in such a way that it is very
+// useful for doing generic animations with lots of additional animation data.
+// It is made up of two concepts, "states" and "parts".
+//
+// States:
+//
+// There are N "state types" defined, which each defines a set of mutually
+// exclusive states that each "state type" can be in. For example, one state
+// type might be "movement", and the "movement" states might be "idle", "walk",
+// and "run. Another state type might be "attack" which could have as its
+// states "idle", and "melee". Each state type will have exactly one currently
+// active state, so this class may, for example, be in the total state of
+// "movement:idle" and "attack:melee". Each state within each state type is
+// animated, so that over time the state frame increases and may loop around,
+// or transition into another state so that that state type without interaction
+// may go from "melee" to "idle" when the "melee" state animation is finished.
+// This is defined by the individual state config in the configuration passed
+// into the constructor.
+//
+// Parts:
+//
+// Each instance of this class also can have N "Parts" defined, which are
+// groups of properties that "listen" to active states. Each part can "listen"
+// to one or more state types, and the first matching state x state type pair
+// (in order of state type priority which is specified in the config) is
+// chosen, and the properties from that state type and state are merged into
+// the part to produce the final active part information. Rather than having a
+// single image or image set for each part, since this class is intended to be
+// as generic as possible, all of this data is assumed to be queried from the
+// part properties, so that things such as image data as well as other things
+// like damage or collision polys can be stored along with the animation
+// frames, the part state, the base part, whichever is most applicable.
+class AnimatedPartSet {
+public:
+ struct ActiveStateInformation {
+ String stateTypeName;
+ String stateName;
+ float timer;
+ unsigned frame;
+ JsonObject properties;
+ };
+
+ struct ActivePartInformation {
+ String partName;
+ // If a state match is found, this will be set.
+ Maybe<ActiveStateInformation> activeState;
+ JsonObject properties;
+ };
+
+ AnimatedPartSet();
+ AnimatedPartSet(Json config);
+
+ // Returns the available state types.
+ StringList stateTypes() const;
+
+ // If a state type is disabled, no parts will match against it even
+ // if they have entries for that state type.
+ void setStateTypeEnabled(String const& stateTypeName, bool enabled);
+ void setEnabledStateTypes(StringList const& stateTypeNames);
+ bool stateTypeEnabled(String const& stateTypeName) const;
+
+ // Returns the available states for the given state type.
+ StringList states(String const& stateTypeName) const;
+
+ StringList parts() const;
+
+ // Sets the active state for this state type. If the state is different than
+ // the previously set state, will start the new states animation off at the
+ // beginning. If alwaysStart is true, then starts the state animation off at
+ // the beginning even if no state change has occurred. Returns true if a
+ // state animation reset was done.
+ bool setActiveState(String const& stateTypeName, String const& stateName, bool alwaysStart = false);
+
+ // Restart this given state type's timer off at the beginning.
+ void restartState(String const& stateTypeName);
+
+ ActiveStateInformation const& activeState(String const& stateTypeName) const;
+ ActivePartInformation const& activePart(String const& partName) const;
+
+ // Function will be given the name of each state type, and the
+ // ActiveStateInformation for the active state for that state type.
+ void forEachActiveState(function<void(String const&, ActiveStateInformation const&)> callback) const;
+
+ // Function will be given the name of each part, and the
+ // ActivePartInformation for the active part.
+ void forEachActivePart(function<void(String const&, ActivePartInformation const&)> callback) const;
+
+ // Useful for serializing state changes. Since each set of states for a
+ // state type is ordered, it is possible to simply serialize and deserialize
+ // the state index for that state type.
+ size_t activeStateIndex(String const& stateTypeName) const;
+ bool setActiveStateIndex(String const& stateTypeName, size_t stateIndex, bool alwaysStart = false);
+
+ // Animate each state type forward 'dt' time, and either change state frames
+ // or transition to new states, depending on the config.
+ void update(float dt);
+
+ // Pushes all the animations into their final state
+ void finishAnimations();
+
+private:
+ enum AnimationMode {
+ End,
+ Loop,
+ Transition
+ };
+
+ struct State {
+ unsigned frames;
+ float cycle;
+ AnimationMode animationMode;
+ String transitionState;
+ JsonObject stateProperties;
+ JsonObject stateFrameProperties;
+ };
+
+ struct StateType {
+ float priority;
+ bool enabled;
+ String defaultState;
+ JsonObject stateTypeProperties;
+ OrderedHashMap<String, shared_ptr<State const>> states;
+
+ ActiveStateInformation activeState;
+ State const* activeStatePointer;
+ bool activeStateDirty;
+ };
+
+ struct PartState {
+ JsonObject partStateProperties;
+ JsonObject partStateFrameProperties;
+ };
+
+ struct Part {
+ JsonObject partProperties;
+ StringMap<StringMap<PartState>> partStates;
+
+ ActivePartInformation activePart;
+ bool activePartDirty;
+ };
+
+ static AnimationMode stringToAnimationMode(String const& string);
+
+ void freshenActiveState(StateType& stateType);
+ void freshenActivePart(Part& part);
+
+ OrderedHashMap<String, StateType> m_stateTypes;
+ StringMap<Part> m_parts;
+};
+
+}
+
+#endif