2023-09-08 05:38:09 -04:00
|
|
|
#pragma once
|
|
|
|
|
|
|
|
|
|
#include "CoreMinimal.h"
|
|
|
|
|
#include "StringDecoder.h"
|
2023-09-15 00:01:41 -04:00
|
|
|
#include "Containers/Deque.h"
|
2023-09-19 22:08:15 -04:00
|
|
|
#include "AnimQueue.generated.h"
|
2023-09-08 05:38:09 -04:00
|
|
|
|
|
|
|
|
////////////////////////////////////////////////
|
|
|
|
|
//
|
|
|
|
|
// This is copied over from Luprex source. Not ideal.
|
|
|
|
|
//
|
|
|
|
|
////////////////////////////////////////////////
|
|
|
|
|
|
2023-09-15 15:44:01 -04:00
|
|
|
enum class ElxAnimValueType {
|
|
|
|
|
STRING,
|
|
|
|
|
NUMBER,
|
|
|
|
|
BOOLEAN,
|
|
|
|
|
XYZ,
|
|
|
|
|
INVALID
|
|
|
|
|
};
|
|
|
|
|
|
2023-09-08 05:38:09 -04:00
|
|
|
////////////////////////////////////////////////
|
|
|
|
|
//
|
|
|
|
|
// An single animation step.
|
|
|
|
|
//
|
2023-09-19 22:08:15 -04:00
|
|
|
// The body consists of a sequence of FlxAnimationField
|
2023-09-08 05:38:09 -04:00
|
|
|
// records. The body is encoded, to read the
|
2023-09-19 22:08:15 -04:00
|
|
|
// FlxAnimationField records you need an
|
|
|
|
|
// FlxAnimationStepDecoder.
|
2023-09-08 05:38:09 -04:00
|
|
|
//
|
|
|
|
|
////////////////////////////////////////////////
|
|
|
|
|
|
2023-09-19 22:08:15 -04:00
|
|
|
USTRUCT(Blueprintable)
|
|
|
|
|
struct INTEGRATION_API FlxAnimationStep {
|
|
|
|
|
GENERATED_BODY()
|
|
|
|
|
|
|
|
|
|
public:
|
2023-10-02 15:48:42 -04:00
|
|
|
UPROPERTY()
|
|
|
|
|
bool Finished;
|
|
|
|
|
|
2023-09-19 22:08:15 -04:00
|
|
|
UPROPERTY()
|
2023-09-15 00:21:31 -04:00
|
|
|
uint64 Hash;
|
2023-09-15 00:01:41 -04:00
|
|
|
|
2023-09-19 22:08:15 -04:00
|
|
|
UPROPERTY()
|
|
|
|
|
TArray<uint8> Body;
|
|
|
|
|
|
2023-10-02 15:48:42 -04:00
|
|
|
UPROPERTY()
|
|
|
|
|
FString Blueprint;
|
|
|
|
|
|
|
|
|
|
FlxAnimationStep() : Finished(false), Hash(0), Body(), Blueprint() {}
|
2023-09-19 22:08:15 -04:00
|
|
|
FlxAnimationStep(uint64 h, std::string_view b);
|
|
|
|
|
|
|
|
|
|
// Unpack an AnimStep into a UObject
|
|
|
|
|
//
|
|
|
|
|
// Stores the key-value pairs of the animation step into
|
|
|
|
|
// properties of a UObject. For example, if the key-value
|
|
|
|
|
// pair "color=blue" is present in the AnimStep, then this
|
|
|
|
|
// routine tries to find a string property "color" in the
|
|
|
|
|
// UObject, and then it sets that property to "blue."
|
|
|
|
|
//
|
|
|
|
|
// Returns true if all of the key-value pairs in the
|
|
|
|
|
// animation step could be unpacked into fields of the UObject.
|
|
|
|
|
// This could fail, for instance, if the UObject just doesn't
|
|
|
|
|
// contain one of the necessary properties. It can also
|
|
|
|
|
// fail if there's a type mismatch. For example, "color=blue"
|
|
|
|
|
// cannot be stored in a property "color" of type int.
|
|
|
|
|
//
|
|
|
|
|
// The prefix is prepended to the key names. For example,
|
|
|
|
|
// if one of the key-value pairs is "color=blue", and the
|
|
|
|
|
// prefix is "aq", then the property "aqColor=blue" will be
|
|
|
|
|
// stored in the UObject.
|
|
|
|
|
//
|
|
|
|
|
// If pre-clear is true, then all properties of the UObject
|
|
|
|
|
// starting with the specified prefix are cleared before
|
|
|
|
|
// unpacking the animation step.
|
|
|
|
|
//
|
|
|
|
|
bool Unpack(const FString& prefix, UObject* into, bool preclear = true) const;
|
2023-10-09 14:59:48 -04:00
|
|
|
|
|
|
|
|
// Auto-Execute
|
|
|
|
|
//
|
|
|
|
|
// These functions automatically update certain actor
|
|
|
|
|
// properties:
|
|
|
|
|
//
|
|
|
|
|
// AutoUpdateXYZ(AActor *actor); // uses 'xyz' keyword
|
|
|
|
|
// AutoUpdateFacing(AActor *actor); // uses 'facing' keyword.
|
|
|
|
|
// AutoUpdatePlane(FName *plane); // uses 'plane' keyword
|
|
|
|
|
//
|
|
|
|
|
void AutoUpdateXYZ(AActor *actor) const;
|
|
|
|
|
void AutoUpdateFacing(AActor *actor) const;
|
|
|
|
|
void AutoUpdatePlane(FName *plane) const;
|
2023-09-15 00:01:41 -04:00
|
|
|
};
|
|
|
|
|
|
2023-09-19 22:08:15 -04:00
|
|
|
////////////////////////////////////////////////
|
|
|
|
|
//
|
|
|
|
|
// This UClass is never instantiated. It exists to
|
|
|
|
|
// expose certain static functions to the blueprint
|
|
|
|
|
// library.
|
|
|
|
|
//
|
|
|
|
|
////////////////////////////////////////////////
|
|
|
|
|
|
|
|
|
|
UCLASS()
|
|
|
|
|
class INTEGRATION_API UlxAnimationStepLibrary : public UObject
|
|
|
|
|
{
|
|
|
|
|
GENERATED_BODY()
|
|
|
|
|
|
|
|
|
|
public:
|
2023-09-20 01:40:58 -04:00
|
|
|
UFUNCTION(BlueprintCallable, BlueprintPure, Category = Luprex)
|
2023-09-19 22:08:15 -04:00
|
|
|
static FString AnimationStepDebugString(const FlxAnimationStep& step);
|
|
|
|
|
|
2023-10-02 15:48:42 -04:00
|
|
|
UFUNCTION(BlueprintCallable, Meta = (DefaultToSelf = "into"), Category = Luprex)
|
|
|
|
|
static void UnpackAnimationStep(UObject* into, const FlxAnimationStep& step, const FString& VariableNamePrefix);
|
2023-09-20 01:40:58 -04:00
|
|
|
|
2023-10-02 15:48:42 -04:00
|
|
|
UFUNCTION(BlueprintCallable, BlueprintPure, Category = Luprex)
|
|
|
|
|
static bool AnimationStepIsIdle(const FlxAnimationStep &step);
|
|
|
|
|
|
2023-09-20 01:40:58 -04:00
|
|
|
UFUNCTION(BlueprintCallable, BlueprintPure, Category = Luprex)
|
|
|
|
|
static FVector AnimationStepGetVector(const FlxAnimationStep& step, const FString& name);
|
|
|
|
|
|
|
|
|
|
UFUNCTION(BlueprintCallable, BlueprintPure, Category = Luprex)
|
|
|
|
|
static double AnimationStepGetFloat(const FlxAnimationStep& step, const FString& name);
|
|
|
|
|
|
|
|
|
|
UFUNCTION(BlueprintCallable, BlueprintPure, Category = Luprex)
|
|
|
|
|
static FString AnimationStepGetString(const FlxAnimationStep& step, const FString& name);
|
|
|
|
|
|
|
|
|
|
UFUNCTION(BlueprintCallable, BlueprintPure, Category = Luprex)
|
|
|
|
|
static bool AnimationStepGetBool(const FlxAnimationStep& step, const FString& name);
|
2023-09-19 22:08:15 -04:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
////////////////////////////////////////////////
|
|
|
|
|
//
|
|
|
|
|
//
|
|
|
|
|
////////////////////////////////////////////////
|
|
|
|
|
|
|
|
|
|
struct FlxAnimationStepView {
|
2023-09-15 00:01:41 -04:00
|
|
|
uint64 Hash;
|
2023-09-19 22:08:15 -04:00
|
|
|
std::string_view Body;
|
2023-09-15 00:01:41 -04:00
|
|
|
|
2023-09-19 22:08:15 -04:00
|
|
|
FlxAnimationStepView() : Hash(0), Body("") {}
|
|
|
|
|
FlxAnimationStepView(uint64 h, std::string_view b) : Hash(h), Body(b) {}
|
2023-09-08 05:38:09 -04:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
////////////////////////////////////////////////
|
|
|
|
|
//
|
|
|
|
|
// A single animation field.
|
|
|
|
|
//
|
|
|
|
|
// A field consists of a variable name,
|
|
|
|
|
// a persistent flag, a type, and some fields
|
|
|
|
|
// to hold the values.
|
|
|
|
|
//
|
|
|
|
|
// If the value is boolean, it is stored in
|
|
|
|
|
// X, as either 1 or 0. If the value is double,
|
|
|
|
|
// it is stored in X.
|
|
|
|
|
//
|
|
|
|
|
////////////////////////////////////////////////
|
|
|
|
|
|
2023-09-19 22:08:15 -04:00
|
|
|
struct FlxAnimationField {
|
2023-09-08 05:38:09 -04:00
|
|
|
std::string_view Name;
|
|
|
|
|
bool Persistent;
|
2023-09-15 13:28:18 -04:00
|
|
|
ElxAnimValueType Type;
|
2023-09-08 05:38:09 -04:00
|
|
|
double X, Y, Z;
|
|
|
|
|
std::string_view S;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
////////////////////////////////////////////////
|
|
|
|
|
//
|
|
|
|
|
// An Animation Queue Decoder.
|
|
|
|
|
//
|
|
|
|
|
// This acts a lot like a stream reader,
|
|
|
|
|
// it reads one AnimEntry at a time from
|
|
|
|
|
// the animation queue until you reach
|
|
|
|
|
// 'end-of-file'.
|
|
|
|
|
//
|
|
|
|
|
////////////////////////////////////////////////
|
|
|
|
|
|
2023-09-15 13:28:18 -04:00
|
|
|
class FlxAnimQueueDecoder {
|
2023-09-08 05:38:09 -04:00
|
|
|
private:
|
2023-09-15 13:28:18 -04:00
|
|
|
FlxStringDecoder Decoder;
|
2023-10-02 15:48:42 -04:00
|
|
|
|
|
|
|
|
// These values are immediately read from the header.
|
|
|
|
|
//
|
|
|
|
|
int SizeLimit;
|
|
|
|
|
int ActualSize;
|
2023-09-08 05:38:09 -04:00
|
|
|
|
|
|
|
|
public:
|
2023-09-15 13:28:18 -04:00
|
|
|
// Initialize the FlxAnimQueueDecoder with the encoded animation queue.
|
2023-09-08 05:38:09 -04:00
|
|
|
//
|
2023-10-02 15:48:42 -04:00
|
|
|
FlxAnimQueueDecoder(std::string_view s);
|
|
|
|
|
|
|
|
|
|
// Get the size limit of the animation queue.
|
|
|
|
|
//
|
|
|
|
|
int GetSizeLimit() const { return SizeLimit; }
|
|
|
|
|
|
|
|
|
|
// Get the Actual Size of the animation queue.
|
|
|
|
|
//
|
|
|
|
|
int GetActualSize() const { return ActualSize; }
|
2023-09-08 05:38:09 -04:00
|
|
|
|
|
|
|
|
// Return true if the parser has reached the end of the string.
|
|
|
|
|
//
|
|
|
|
|
bool AtEOF() { return Decoder.at_eof(); }
|
|
|
|
|
|
|
|
|
|
// Read one animation step.
|
|
|
|
|
//
|
2023-09-19 22:08:15 -04:00
|
|
|
FlxAnimationStepView ReadStep();
|
2023-09-08 05:38:09 -04:00
|
|
|
|
2023-10-02 15:48:42 -04:00
|
|
|
// Peek at the hash of the next animation step.
|
|
|
|
|
//
|
|
|
|
|
uint64 PeekHash();
|
|
|
|
|
|
2023-09-08 05:38:09 -04:00
|
|
|
// Convert an AnimQueue to an FString.
|
|
|
|
|
//
|
|
|
|
|
static FString DebugString(std::string_view s);
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
////////////////////////////////////////////////
|
|
|
|
|
//
|
|
|
|
|
// An Animation Step Decoder.
|
|
|
|
|
//
|
|
|
|
|
// This acts a lot like a stream reader,
|
2023-09-19 22:08:15 -04:00
|
|
|
// it reads one FlxAnimationField at a time from
|
2023-09-08 05:38:09 -04:00
|
|
|
// the animation queue until you reach
|
|
|
|
|
// 'end-of-file'.
|
|
|
|
|
//
|
|
|
|
|
////////////////////////////////////////////////
|
|
|
|
|
|
2023-09-19 22:08:15 -04:00
|
|
|
class FlxAnimationStepDecoder {
|
2023-09-08 05:38:09 -04:00
|
|
|
private:
|
2023-09-15 13:28:18 -04:00
|
|
|
FlxStringDecoder Decoder;
|
2023-09-08 05:38:09 -04:00
|
|
|
|
|
|
|
|
public:
|
2023-09-19 22:08:15 -04:00
|
|
|
// Initialize the FlxAnimationStepDecoder from the FlxAnimationStepView.
|
2023-09-08 05:38:09 -04:00
|
|
|
//
|
2023-09-19 22:08:15 -04:00
|
|
|
FlxAnimationStepDecoder(std::string_view body) : Decoder(body) {}
|
2023-09-08 05:38:09 -04:00
|
|
|
|
|
|
|
|
// Return true if the parser has reached the end of the string.
|
|
|
|
|
//
|
|
|
|
|
bool AtEOF() { return Decoder.at_eof(); }
|
|
|
|
|
|
|
|
|
|
// Read one field.
|
|
|
|
|
//
|
2023-09-19 22:08:15 -04:00
|
|
|
FlxAnimationField ReadField();
|
2023-09-08 05:38:09 -04:00
|
|
|
|
|
|
|
|
// Convert an AnimStep to an FString.
|
|
|
|
|
//
|
2023-09-19 22:08:15 -04:00
|
|
|
static FString DebugString(uint64 hash, std::string_view body);
|
2023-09-08 05:38:09 -04:00
|
|
|
};
|
2023-09-15 00:01:41 -04:00
|
|
|
|
|
|
|
|
////////////////////////////////////////////////
|
|
|
|
|
//
|
2023-09-15 13:28:18 -04:00
|
|
|
// FlxAnimTracker
|
2023-09-15 00:01:41 -04:00
|
|
|
//
|
|
|
|
|
// This class monitors the animation queue for a single
|
|
|
|
|
// tangible. It can identify when a new animation has
|
|
|
|
|
// appeared on the animation queue, and when animations have
|
|
|
|
|
// been removed from the animation queue. It also
|
|
|
|
|
// keeps track of which animations have been started.
|
|
|
|
|
//
|
|
|
|
|
////////////////////////////////////////////////
|
|
|
|
|
|
2023-09-15 13:28:18 -04:00
|
|
|
class FlxAnimTracker {
|
2023-09-15 00:01:41 -04:00
|
|
|
public:
|
|
|
|
|
// Our own copy of the animation queue. We only
|
|
|
|
|
// store the hashes, not the steps. The First element
|
|
|
|
|
// of the queue is the oldest item.
|
|
|
|
|
//
|
2023-09-19 22:08:15 -04:00
|
|
|
TDeque<FlxAnimationStep> AQ;
|
2023-09-15 00:01:41 -04:00
|
|
|
|
2023-10-02 15:48:42 -04:00
|
|
|
// True if something has recently changed.
|
2023-09-15 00:01:41 -04:00
|
|
|
//
|
2023-10-02 15:48:42 -04:00
|
|
|
bool Changed;
|
2023-09-15 00:01:41 -04:00
|
|
|
|
2023-10-02 15:48:42 -04:00
|
|
|
private:
|
2023-09-15 00:01:41 -04:00
|
|
|
public:
|
|
|
|
|
// Construct a tracker.
|
|
|
|
|
//
|
|
|
|
|
// Initially, the tracker is in the empty (Clear) state.
|
|
|
|
|
//
|
2023-09-15 13:28:18 -04:00
|
|
|
FlxAnimTracker();
|
2023-09-15 00:01:41 -04:00
|
|
|
|
2023-09-28 14:32:48 -04:00
|
|
|
// Clear everything, reset to the initial state.
|
|
|
|
|
//
|
|
|
|
|
void Clear();
|
|
|
|
|
|
2023-09-15 00:01:41 -04:00
|
|
|
// Update from the specified animation queue.
|
|
|
|
|
//
|
|
|
|
|
// After the update is done, AQ will be a copy
|
|
|
|
|
// of the animation queue that is passed in.
|
|
|
|
|
//
|
|
|
|
|
void Update(std::string_view encqueue);
|
|
|
|
|
|
2023-10-02 15:48:42 -04:00
|
|
|
// Get the current animation step.
|
2023-09-15 00:01:41 -04:00
|
|
|
//
|
2023-10-02 15:48:42 -04:00
|
|
|
// Get the current animation step. This is the step that the
|
|
|
|
|
// blueprint should currently be playing.
|
|
|
|
|
//
|
|
|
|
|
FlxAnimationStep GetCurrentAnimation();
|
|
|
|
|
|
|
|
|
|
// Declare that an animation is finished.
|
2023-09-15 00:01:41 -04:00
|
|
|
//
|
2023-10-02 15:48:42 -04:00
|
|
|
// The blueprint uses this function call to indicate that it
|
|
|
|
|
// is done playing the specified animation. This will cause the
|
|
|
|
|
// animation to be marked as finished, which in turn causes
|
|
|
|
|
// 'GetCurrentStep' to advance to the next animation.
|
|
|
|
|
//
|
|
|
|
|
void FinishedAnimation(uint64 Hash);
|
2023-09-15 00:01:41 -04:00
|
|
|
|
2023-10-02 15:48:42 -04:00
|
|
|
// Skip to the end of the animation queue.
|
|
|
|
|
//
|
|
|
|
|
// This is equivalent to calling 'FinishedHash' on every
|
|
|
|
|
// animation in the entire queue.
|
2023-09-15 00:01:41 -04:00
|
|
|
//
|
2023-10-02 15:48:42 -04:00
|
|
|
void SkipToEnd();
|
|
|
|
|
|
|
|
|
|
// Clear the 'Changed' flag.
|
2023-09-15 00:01:41 -04:00
|
|
|
//
|
2023-10-02 15:48:42 -04:00
|
|
|
void ClearChanged() { Changed = false; }
|
2023-09-15 00:01:41 -04:00
|
|
|
|
2023-10-02 15:48:42 -04:00
|
|
|
// Get the 'Changed' flag.
|
2023-09-15 00:01:41 -04:00
|
|
|
//
|
2023-10-02 15:48:42 -04:00
|
|
|
// The changed flag is set to true whenever the Luprex animation
|
|
|
|
|
// queue changes from its previous state. The changed flag is also
|
|
|
|
|
// set to true whenever 'SetFinished' marks an animation as finished.
|
|
|
|
|
// The changed flag can only be set to false by 'ClearChanged,' above.
|
2023-09-15 00:01:41 -04:00
|
|
|
//
|
2023-10-02 15:48:42 -04:00
|
|
|
bool IsChanged() const { return Changed; }
|
2023-09-15 00:01:41 -04:00
|
|
|
};
|