// Fill out your copyright notice in the Description page of Project Settings. #pragma once #include "CoreMinimal.h" #include "Components/ActorComponent.h" #include "AnimQueue.h" #include "Tangible.generated.h" class UlxTangibleManager; // This class does not need to be modified. UINTERFACE(Blueprintable) class UlxTangibleInterface : public UInterface { GENERATED_BODY() }; /** * * IlxTangibleInterface * * This class implements the interface that an Actor must implement * in order for that Actor to be usable as a Tangible. * */ class INTEGRATION_API IlxTangibleInterface { GENERATED_BODY() // Add interface functions to this class. This is the class that will be inherited to implement this interface. public: UFUNCTION(BlueprintImplementableEvent, Category = "Tangible Functionality") bool AnimationQueueChanged(); UFUNCTION(BlueprintImplementableEvent, Category = "Tangible Functionality") void BecomePossessed(); }; /** * * UlxTangible * * The Tangible stores all the data we need for a tangible, * such as the animation queue and so forth. * * From time to time, a tangible can change its blueprint class. * To do that, we have to delete and recreate the actor. This * is all set up so that it is possible to do that. * * The tangible has a place to store an Actor pointer. This * actor pointer is allowed to be nullptr, especially in the * case that the blueprint hasn't been set yet. * * This also serves as a repository for blueprint functions * that operate on tangible actors. * */ UCLASS() class INTEGRATION_API UlxTangible : public UObject { GENERATED_BODY() public: UlxTangible(); // My Tangible Manager. UPROPERTY() TObjectPtr Manager; // The tangible ID. UPROPERTY() uint64 TangibleId; UPROPERTY() TWeakObjectPtr CurrentActor; // The name of the current blueprint. UPROPERTY() FString ActorBlueprintName; // Animation tracker FlxAnimTracker AnimTracker; // Current Plane. FName Plane; // True if luprex thinks this object is Near the player. bool NearAccordingToLuprex; // True if unreal thinks this object is Near the player. bool NearAccordingToUnreal; public: // Initialize a new tangible. // // This links the tangible to its TangibleManager and // sets the tangible's ID. // void Init(UlxTangibleManager *tm, int64 id); // Destroy a tangible. // // Delete the actor associated with the tangible, if any, // and clean up everything else. // void Destroy(); // Get the actor associated with this tangible. // // Note that this may return nullptr: it is valid for a // tangible to have no actor associated with it. This // is most commonly the case if the blueprint class of // the tangible is set to nullptr. // // Also bear in mind that if a tangible changes its blueprint // class, then the actor will have to be deleted and // recreated. In that case, GetActor will return a different // pointer than before the blueprint change. // AActor* GetActor() const { return CurrentActor.Get(); } // Get the location of the tangible. // // Note that if the actor is nullptr, the location is always // at the origin. // FVector GetLocation() const; // Update the animation queue from Luprex. // // This reads the animation queue, and copies it // into the animtracker. // void UpdateAnimationQueue(std::string_view aq); // Execute AnimStateChanged, if the 'changed' bit is set. // void MaybeExecuteAnimStateChanged(); private: // Set the actor's blueprint, and recreate the actor if necessary. // // If the blueprint is the empty string, deletes the actor. // If the blueprint is not the empty string, creates an actor of the // correct class. This is a no-op if the actor already exists and // is already of the correct blueprint class. // void SetActorBlueprint(const FString &name); public: UFUNCTION(BlueprintCallable, Meta = (DefaultToSelf = "target"), Category = Luprex) static void GetCurrentAnimation(AActor *target, FlxAnimationStep &step); UFUNCTION(BlueprintCallable, Meta = (DefaultToSelf = "target"), Category = Luprex) static void FinishedAnimation(AActor *target, const FlxAnimationStep &step, bool AutoUpdateXYZ = true, bool AutoUpdateFacing = true, bool AutoUpdatePlane = true); UFUNCTION(BlueprintCallable, Meta = (DefaultToSelf = "target"), Category = Luprex) static FString GetTangiblePlane(AActor* target); UFUNCTION(BlueprintCallable, Meta = (DefaultToSelf = "target"), Category = Luprex) static void SetTangiblePlane(AActor* target, const FString& plane); UFUNCTION(BlueprintCallable, Meta = (DefaultToSelf = "target"), Category = Luprex) static bool IsCurrentPlayer(AActor *target); UFUNCTION(BlueprintCallable, Meta = (DefaultToSelf = "target"), Category = Luprex) static void SetAutoFinish(AActor *target, const FString &action, const FVector &xyz); // Quit the game, reporting an error message to the log. UFUNCTION(BlueprintCallable, Category = Luprex) static void Assert(bool condition, const FString &ErrorMessage); // Call a function by name, on any UObject. If the function doesn't exist, calls // the fallback function instead. If that isn't found either, returns false. UFUNCTION(BlueprintCallable, Meta = (DefaultToSelf = "target"), Category = Luprex) static void CallFunctionByName(UObject *target, const FString &NamePart1, const FString &NamePart2, const FString &fallback); }; /** * * UlxTangibleComponent * * The TangibleComponent holds a pointer to the Tangible. * This is the only purpose it serves: to make it possible to * have the Actor point to its corresponding Tangible. * * The TangibleComponent is procedurally inserted into the Actor. * The TangibleComponent is not visible to blueprints. * */ UCLASS( ClassGroup=(Custom), meta=(BlueprintSpawnableComponent) ) class INTEGRATION_API UlxTangibleComponent : public UActorComponent { GENERATED_BODY() public: UlxTangibleComponent() : Tangible(nullptr) {} // The actor that we're a part of. UPROPERTY() TWeakObjectPtr Tangible; };