# (39) 's Extra Blueprint Nodes for You as a Plugin, No C++ Required!

**URL:** <https://forums.unrealengine.com/t/39-s-extra-blueprint-nodes-for-you-as-a-plugin-no-c-required/3448>\
**Category:** Blueprint\
**Tags:** unreal-engine\
**Created:** [April 29, 2014, 1:27am UTC](https://forums.unrealengine.com/t/39-s-extra-blueprint-nodes-for-you-as-a-plugin-no-c-required/3448 "2014-04-29T01:27:59Z")\
**Posts on this page:** 1\
**Showing post:** 486

<div class="post-metadata">

**Author:** ![SaxonRah](https://d3kjluh73b9h9o.cloudfront.net/original/4X/2/8/5/28502927f1d97ba1051b3b47ccfe17233bf41ef0.png) [@SaxonRah](https://forums.unrealengine.com/u/SaxonRah)\
**Post date:** [December 17, 2014, 7:17am UTC](https://forums.unrealengine.com/t/39-s-extra-blueprint-nodes-for-you-as-a-plugin-no-c-required/3448/486 "2014-12-17T07:17:42Z")

</div>

Code for you!

Let me know if you want an actual copy.  
(note: of my code should be within BeginRandom and EndRandom comments for ctrl-f ability)

Also you are more than welcome to change anything you see fit. Code is 10000% free

> [@VictoryBPFunctionLibrary.H](#):
>
> ```auto
> 
> /*    
> By 
> 
> */
> #pragma once
> 
> // ~~~~~~~~~~~~UMG~~~~~~~~~~~~~~~
> #include "Runtime/UMG/Public/UMG.h"
> #include "Runtime/UMG/Public/UMGStyle.h"
> #include "Runtime/UMG/Public/Slate/SObjectWidget.h"
> #include "Runtime/UMG/Public/IUMGModule.h"
> #include "Runtime/UMG/Public/Blueprint/UserWidget.h"
> // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
> 
> // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
> // Includes for other's Nodes
> // Chrono and Random
> #include <chrono>
> #include <random>
> 
> //Audio
> #include "Components/AudioComponent.h"
> #include "AudioDecompress.h"
> #include "AudioDevice.h"
> #include "ActiveSound.h"
> #include "Audio.h"
> #include "Developer/TargetPlatform/Public/Interfaces/IAudioFormat.h"
> #include "VorbisAudioInfo.h"
>      
> //Texture2D
> //#include "Engine/Texture2D.h"
> #include "DDSLoader.h"
> // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
> 
> #include "VictoryBPFunctionLibrary.generated.h"
> 
> // BP Library for You
> //
> // Written by 
> 
> //note about UBlueprintFunctionLibrary
> // class is a base class for any function libraries exposed to blueprints.
> // Methods in subclasses are expected to be static, and no methods should be added to the base class.
> 
> USTRUCT(BlueprintType)
> struct FVictoryInput
> {
> GENERATED_USTRUCT_BODY()
> 
> UPROPERTY(EditAnywhere, BlueprintReadWrite, Category="Input Song")
> FString ActionName;
>     
> UPROPERTY(EditAnywhere, BlueprintReadWrite, Category="Input Song")
> FKey Key;
> 
> UPROPERTY(EditAnywhere, BlueprintReadWrite, Category="Input Song")
> FString KeyAsString;
>     
> UPROPERTY(EditAnywhere, BlueprintReadWrite, Category="Input Song")
> uint32 bShift:1;
> 
> UPROPERTY(EditAnywhere, BlueprintReadWrite, Category="Input Song")
> uint32 bCtrl:1;
> 
> UPROPERTY(EditAnywhere, BlueprintReadWrite, Category="Input Song")
> uint32 bAlt:1;
> 
> UPROPERTY(EditAnywhere, BlueprintReadWrite, Category="Input Song")
> uint32 bCmd:1;
>     
>        
> FVictoryInput(){}
> FVictoryInput(const FString InActionName, const FKey InKey, const bool bInShift, const bool bInCtrl, const bool bInAlt, const bool bInCmd)
> : Key(InKey)
> , KeyAsString(Key.GetDisplayName().ToString())
> , bShift(bInShift)
> , bCtrl(bInCtrl)
> , bAlt(bInAlt)
> , bCmd(bInCmd)
> { 
> ActionName = InActionName;
> }
>     
> FVictoryInput(const FInputActionKeyMapping& Action)
> : Key(Action.Key)
> , KeyAsString(Action.Key.GetDisplayName().ToString())
> , bShift(Action.bShift)
> , bCtrl(Action.bCtrl)
> , bAlt(Action.bAlt)
> , bCmd(Action.bCmd)
> {  
> ActionName = Action.ActionName.ToString();
> }
> }; 
>  
> UENUM(BlueprintType)
> namespace EJoyGraphicsFullScreen
> {
> //256 entries 
> enum Type
> {
> FullScreen UMETA(DisplayName="Regular Full Screen"),
> WindowedFullScreen UMETA(DisplayName="Windowed Full Screen High Quality"),
> WindowedFullScreenPerformance UMETA(DisplayName="Windowed Full Screen (Default)"),
> //~~~
>         
> //256th entry
> EJoyGraphicsFullScreen_Max UMETA(Hidden),
> };
> }
> 
> UCLASS()
> class VICTORYBPLIBRARY_API UVictoryBPFunctionLibrary : public UBlueprintFunctionLibrary
> {
> GENERATED_UCLASS_BODY()
> 
> // ~~~~Key Re Binding !~~~~
> 
> UFUNCTION(BlueprintPure, Category = "VictoryBPLibrary|Key Rebinding")
> static FVictoryInput VictoryGetVictoryInput(const FKeyEvent& KeyEvent);
> 
> static FORCEINLINE void UpdateActionMapping(FInputActionKeyMapping& Destination, const FVictoryInput& VictoryInputBind)
> {
> Destination.Key = VictoryInputBind.Key;
> Destination.bShift = VictoryInputBind.bShift;
> Destination.bCtrl = VictoryInputBind.bCtrl;
> Destination.bAlt = VictoryInputBind.bAlt;
> Destination.bCmd = VictoryInputBind.bCmd;
> }
> 
> UFUNCTION(BlueprintPure, Category = "VictoryBPLibrary|Key Rebinding")
> static void VictoryGetAllKeyBindings(TArray<FVictoryInput>& Bindings);
> 
> /** You can leave the AsString field blank :) Returns false if the key could not be found as an existing mapping! Enjoy! <3 */
> UFUNCTION(BlueprintCallable, Category = "VictoryBPLibrary|Key Rebinding")
> static bool VictoryReBindKey(FVictoryInput Action);
> 
> /*
> To do = axis key bindings, check out same place where FInputActionKeyMapping is defined
> */
> 
> // ~~~~~~~~~~~~~~~~~~~~
> 
> /** Change volume of Sound class of your choosing, sets the volume instantly! Returns false if the sound class was not found and volume was not set. */
> UFUNCTION(BlueprintCallable, Category = "VictoryBPLibrary|Sound")
> static bool VictorySoundVolumeChange(USoundClass* SoundClassObject, float NewVolume);
> 
> /** Get Current Sound Volume! Returns -1 if sound class was not found*/
> UFUNCTION(BlueprintPure, Category = "VictoryBPLibrary|Sound")
> static float VictoryGetSoundVolume(USoundClass* SoundClassObject);
> 
> // ~~~~~~~~~~~~~~~~~~~~
> 
> /** Get Custom Config Var! These are stored in Saved/Config/Windows/Game.ini */
> UFUNCTION(BlueprintPure, Category = "VictoryBPLibrary|Custom Config Vars!")
> static bool VictoryGetCustomConfigVar_Bool(FString SectionName, FString VariableName);
> 
> /** Get Custom Config Var! These are stored in Saved/Config/Windows/Game.ini */
> UFUNCTION(BlueprintPure, Category = "VictoryBPLibrary|Custom Config Vars!")
> static int32 VictoryGetCustomConfigVar_Int(FString SectionName, FString VariableName);
> 
> /** Get Custom Config Var! These are stored in Saved/Config/Windows/Game.ini */
> UFUNCTION(BlueprintPure, Category = "VictoryBPLibrary|Custom Config Vars!")
> static float VictoryGetCustomConfigVar_Float(FString SectionName, FString VariableName);
> 
> /** Get Custom Config Var! These are stored in Saved/Config/Windows/Game.ini */
> UFUNCTION(BlueprintPure, Category = "VictoryBPLibrary|Custom Config Vars!")
> static FVector VictoryGetCustomConfigVar_Vector(FString SectionName, FString VariableName);
> 
> /** Get Custom Config Var! These are stored in Saved/Config/Windows/Game.ini */
> UFUNCTION(BlueprintPure, Category = "VictoryBPLibrary|Custom Config Vars!")
> static FRotator VictoryGetCustomConfigVar_Rotator(FString SectionName, FString VariableName);
> 
> /** Get Custom Config Var! These are stored in Saved/Config/Windows/Game.ini */
> UFUNCTION(BlueprintPure, Category = "VictoryBPLibrary|Custom Config Vars!")
> static FLinearColor VictoryGetCustomConfigVar_Color(FString SectionName, FString VariableName);
> 
> /** Get Custom Config Var! These are stored in Saved/Config/Windows/Game.ini */
> UFUNCTION(BlueprintPure, Category = "VictoryBPLibrary|Custom Config Vars!")
> static FString VictoryGetCustomConfigVar_String(FString SectionName, FString VariableName);
> 
> // ~~~~~~~~~~~~~~~~~~~~
> 
> /** Set Custom Config Var! These are stored in Saved/Config/Windows/Game.ini */
> UFUNCTION(BlueprintCallable, Category = "VictoryBPLibrary|Custom Config Vars!")
> static void VictorySetCustomConfigVar_Bool(FString SectionName, FString VariableName, bool Value);
> 
> /** Set Custom Config Var! These are stored in Saved/Config/Windows/Game.ini */
> UFUNCTION(BlueprintCallable, Category = "VictoryBPLibrary|Custom Config Vars!")
> static void VictorySetCustomConfigVar_Int(FString SectionName, FString VariableName, int32 Value);
> 
> /** Set Custom Config Var! These are stored in Saved/Config/Windows/Game.ini */
> UFUNCTION(BlueprintCallable, Category = "VictoryBPLibrary|Custom Config Vars!")
> static void VictorySetCustomConfigVar_Float(FString SectionName, FString VariableName, float Value);
> 
> /** Set Custom Config Var! These are stored in Saved/Config/Windows/Game.ini */
> UFUNCTION(BlueprintCallable, Category = "VictoryBPLibrary|Custom Config Vars!")
> static void VictorySetCustomConfigVar_Vector(FString SectionName, FString VariableName, FVector Value);
> 
> /** Set Custom Config Var! These are stored in Saved/Config/Windows/Game.ini */
> UFUNCTION(BlueprintCallable, Category = "VictoryBPLibrary|Custom Config Vars!")
> static void VictorySetCustomConfigVar_Rotator(FString SectionName, FString VariableName, FRotator Value);
> 
> /** Set Custom Config Var! These are stored in Saved/Config/Windows/Game.ini */
> UFUNCTION(BlueprintCallable, Category = "VictoryBPLibrary|Custom Config Vars!")
> static void VictorySetCustomConfigVar_Color(FString SectionName, FString VariableName, FLinearColor Value);
> 
> /** Set Custom Config Var! These are stored in Saved/Config/Windows/Game.ini */
> UFUNCTION(BlueprintCallable, Category = "VictoryBPLibrary|Custom Config Vars!")
> static void VictorySetCustomConfigVar_String(FString SectionName, FString VariableName, FString Value);
> 
> /** The FName that is expected is the exact same format as when you right click on asset -> Copy Reference! You can directly paste copied references into node! IsValid lets you know if the path was correct or not and I was able to load the . MAKE SURE TO SAVE THE RETURNED AS A VARIABLE. Otherwise your shiny new asset will get garbage collected. I recommend you cast the return value to the appropriate and then promote it to a variable :) - */
> UFUNCTION(BlueprintCallable, Category = "VictoryBPLibrary")
> static UObject* LoadObjectFromAssetPath(TSubclassOf<UObject> ObjectClass, FName Path, bool& IsValid);
> 
> /** Uses the same format as I use for LoadObjectFromAssetPath! Use node to get the asset path of objects in the world! - */
> UFUNCTION(BlueprintPure, Category = "VictoryBPLibrary")
> static FName GetObjectPath(UObject* Obj);
> 
> /** Find widgets of a certain class! Top level only means only widgets that are directly added to the viewport will be found */
> UFUNCTION(BlueprintCallable, Category = "VictoryBPLibrary|UMG", meta = (HidePin = "WorldContextObject", DefaultToSelf = "WorldContextObject"))
> static void GetAllWidgetsOfClass(UObject* WorldContextObject, TSubclassOf<UUserWidget> WidgetClass, TArray<UUserWidget*>& FoundWidgets, bool TopLevelOnly = true);
> 
> /** Remove widgets of a certain class from viewport! */
> UFUNCTION(BlueprintCallable, Category = "VictoryBPLibrary|UMG", meta = (HidePin = "WorldContextObject", DefaultToSelf = "WorldContextObject"))
> static void RemoveAllWidgetsOfClass(UObject* WorldContextObject, TSubclassOf<UUserWidget> WidgetClass);
> 
> UFUNCTION(BlueprintCallable, Category = "VictoryBPLibrary|UMG", meta = (HidePin = "WorldContextObject", DefaultToSelf = "WorldContextObject"))
> static bool IsWidgetOfClassInViewport(UObject* WorldContextObject, TSubclassOf<UUserWidget> WidgetClass);
> 
> /** Retrieves the unique net ID for the local player as a number! The number itself will vary based on what Online Subsystem is being used, but you are guaranteed that number is unique per player! */
> UFUNCTION(BlueprintPure, Category = "VictoryBPLibrary")
> static int32 GetPlayerUniqueNetID();
> 
> /** Call periodically in a huge loop you are intentionally using to reset the BP runaway loop system. Caution, if you have an infinite loop will permanently hang your system until you turn your computer off. Use very very carefully! When constructing a new loop and you are not sure if it is totally stable, do NOT use node! Always test new loops normally to ensure you dont truly have a runaway loop that would hang your computer forever. */
> UFUNCTION(BlueprintCallable, Category = "VictoryBPLibrary")
> static void Loops_ResetBPRunawayCounter();
> 
> /** Set the Frame Rate. Min value is 10. */
> UFUNCTION(BlueprintCallable, Category = "VictoryBPLibrary|Graphics Settings")
> static void GraphicsSettings__SetFrameRateCap(float NewValue);
> 
> /** Only hardware dependent, no smoothing */
> UFUNCTION(BlueprintCallable, Category = "VictoryBPLibrary|Graphics Settings")
> static void GraphicsSettings__SetFrameRateToBeUnbound();
> 
> UFUNCTION(BlueprintCallable, Category = "VictoryBPLibrary")
> static FVector2D ProjectWorldToScreenPosition(const FVector& WorldLocation);
> 
> /** Make sure to save off the return value as a global variable in one of your BPs or else it will get garbage collected! */
> UFUNCTION(BlueprintCallable, Category = "VictoryBPLibrary", meta = (HidePin = "WorldContextObject", DefaultToSelf = "WorldContextObject"))
> static UObject* CreateObject(UObject* WorldContextObject, UClass* TheObjectClass, FName Name);
> 
> /** Make sure to save off the return value as a global variable in one of your BPs or else it will get garbage collected! */
> UFUNCTION(BlueprintCallable, Category = "VictoryBPLibrary", meta = (HidePin = "WorldContextObject", DefaultToSelf = "WorldContextObject"))
> static UPrimitiveComponent* CreatePrimitiveComponent(UObject* WorldContextObject, TSubclassOf<UPrimitiveComponent> CompClass, FName Name, FVector Location, FRotator Rotation);
> 
> /** Spawn an Actor and choose which level you want them to spawn into! */
> UFUNCTION(BlueprintCallable, Category = "VictoryBPLibrary", meta = (HidePin = "WorldContextObject", DefaultToSelf = "WorldContextObject"))
> static AActor* SpawnActorIntoLevel(UObject* WorldContextObject, TSubclassOf<AActor> ActorClass, FName Level = NAME_None, FVector Location = FVector::ZeroVector, FRotator Rotation = FRotator::ZeroRotator, bool SpawnEvenIfColliding = true);
> 
> /** Get the names of currently loaded and visible levels! */
> UFUNCTION(BlueprintPure, Category = "VictoryBPLibrary", meta = (HidePin = "WorldContextObject", DefaultToSelf = "WorldContextObject"))
> static void GetNamesOfLoadedLevels(UObject* WorldContextObject, TArray<FString>& NamesOfLoadedLevels);
> 
> /** Obtain the scaled,rotated, and translated vertex positions for any static mesh! Returns false if operation could not occur because the comp or static mesh asset was invalid. <3 */
> UFUNCTION(BlueprintPure, Category = "VictoryBPLibrary")
> static bool GetStaticMeshVertexLocations(UStaticMeshComponent* Comp, TArray<FVector>& VertexPositions);
> 
> UFUNCTION(BlueprintCallable, Category = "VictoryBPLibrary")
> static void AddToActorRotation(AActor* TheActor, FRotator AddRot);
> 
> UFUNCTION(BlueprintCallable, Category = "VictoryBPLibrary", meta = (HidePin = "WorldContextObject", DefaultToSelf = "WorldContextObject"))
> static void DrawCircle(
> UObject* WorldContextObject,
> FVector Center,
> float Radius,
> int32 NumPoints = 32,
> float Thickness = 7,
> FLinearColor LineColor = FLinearColor::Red,
> FVector YAxis = FVector(0, 1, 0),
> FVector ZAxis = FVector(0, 0, 1),
> float Duration = 0,
> bool PersistentLines = false
> );
> 
> /** Implementation of a Selection Marquee / Selection Box as a BP Node. AnchorPoint is the first clicked point, which user then drags from to make the box. Class filter is optional way to narrow the scope of actors that can be selected by the selection box! -*/
> UFUNCTION(BlueprintCallable, Category = "VictoryBPLibrary", meta = (HidePin = "WorldContextObject", DefaultToSelf = "WorldContextObject"))
> static void Selection_SelectionBox(UObject* WorldContextObject, TArray<AActor*>& SelectedActors, FVector2D AnchorPoint, FVector2D DraggedPoint, TSubclassOf<AActor> ClassFilter);
> 
> /** Get the Controller ID for a supplied Player Controller <3 . Returns false if operation could not occur. */
> UFUNCTION(BlueprintCallable, Category = "VictoryBPLibrary")
> static bool PlayerController_GetControllerID(APlayerController* ThePC, int32& ControllerID);
> 
> /** Get the Unique PlayerID from the PlayerState for a supplied Player Controller <3 . Returns false if operation could not occur. */
> UFUNCTION(BlueprintCallable, Category = "VictoryBPLibrary")
> static bool PlayerState_GetPlayerID(APlayerController* ThePC, int32& PlayerID);
> 
> /** Launches the specified URL in the OS default web browser :) <3 */
> UFUNCTION(BlueprintCallable, Category = "VictoryBPLibrary")
> static void Open_URL_In_Web_Browser(FString TheURL);
> 
> /** Returns which platform the game code is running in.*/
> UFUNCTION(BlueprintCallable, BlueprintPure, Category = "VictoryBPLibrary")
> static void OperatingSystem__GetCurrentPlatform(
> bool& Windows_,
> bool& Mac,
> bool& Linux,
> bool& iOS,
> bool& Android,
> bool& PS4,
> bool& XBoxOne,
> bool& HTML5,
> bool& WinRT_Arm,
> bool& WinRT
> );
> 
> //~~~
> 
> /** Retrieves the OS system Date and as a string at the instant BP node runs. Use my other RealWorldTime node to get the passed since the return value of node! You can use to record milliseconds/seconds/minutes/hours between events in game logic! */
> UFUNCTION(BlueprintCallable, BlueprintPure, Category = "VictoryBPLibrary")
> static FString RealWorldTime__GetCurrentOSTime(
> int32& MilliSeconds,
> int32& Seconds,
> int32& Minutes,
> int32& Hours12,
> int32& Hours24,
> int32& Day,
> int32& Month,
> int32& Year
> );
> 
> /** Get the amount of seconds/minutes/hours since the the supplied DateTime string! You can use to record milliseconds/seconds/minutes/hours between events in game logic! */
> UFUNCTION(BlueprintCallable, BlueprintPure, Category = "VictoryBPLibrary")
> static void RealWorldTime__GetTimePassedSincePreviousTime(
> const FString& PreviousTime,
> float& Milliseconds,
> float& Seconds,
> float& Minutes,
> float& Hours
> );
> 
> /** Get the difference between two recorded times! You can use to record milliseconds/seconds/minutes/hours between events in game logic! */
> UFUNCTION(BlueprintCallable, BlueprintPure, Category = "VictoryBPLibrary")
> static void RealWorldTime__GetDifferenceBetweenTimes(
> const FString& PreviousTime1,
> const FString& PreviousTime2,
> float& Milliseconds,
> float& Seconds,
> float& Minutes,
> float& Hours
> );
> 
> //~~~
> 
> /** Loads a text file from hard disk and parses it into a String array, where each entry in the string array is 1 line from the text file. Option to exclude lines that are only whitespace characters or '
> '. Returns the size of the final String Array that was created. Returns false if the file could be loaded from hard disk. */
> UFUNCTION(BlueprintPure, Category = "VictoryBPLibrary")
> static bool LoadStringArrayFromFile(TArray<FString>& StringArray, int32& ArraySize, FString FullFilePath = "Enter Full File Path", bool ExcludeEmptyLines = false);
> 
> //~~~
> 
> /** of array entries. Returns -1 if the supplied array is empty. Returns the index of the value as well as the value itself. */
> UFUNCTION(BlueprintPure, Category = "VictoryBPLibrary")
> static void MaxOfFloatArray(const TArray<float>& FloatArray, int32& IndexOfMaxValue, float& MaxValue);
> 
> /** of array entries. Returns -1 if the supplied array is empty. Returns the index of the value as well as the value itself. */
> UFUNCTION(BlueprintPure, Category = "VictoryBPLibrary")
> static void MaxOfIntArray(const TArray<int32>& IntArray, int32& IndexOfMaxValue, int32& MaxValue);
> 
> /** Min of array entries. Returns -1 if the supplied array is empty. Returns the index of the min value as well as the value itself. */
> UFUNCTION(BlueprintPure, Category = "VictoryBPLibrary")
> static void MinOfFloatArray(const TArray<float>& FloatArray, int32& IndexOfMinValue, float& MinValue);
> 
> /** Min of array entries. Returns -1 if the supplied array is empty. Returns the index of the min value as well as the value itself. */
> UFUNCTION(BlueprintPure, Category = "VictoryBPLibrary")
> static void MinOfIntArray(const TArray<int32>& IntArray, int32& IndexOfMinValue, int32& MinValue);
> 
> //~~~
> 
> /** Set Move Speed. Supply the Character whose Character Movement to change! Returns false if operation could not occur due to invalid Character or MovementComponent could not be obtained.*/
> UFUNCTION(BlueprintCallable, Category = "VictoryBPLibrary", meta = (DefaultToSelf = "TheCharacter"))
> static bool CharacterMovement__SetMaxMoveSpeed(ACharacter* TheCharacter, float NewMaxMoveSpeed);
> 
> //~~~
> 
> /** Converts a float to a rounded Integer, examples: 1.4 becomes 1, 1.6 becomes 2 */
> UFUNCTION(BlueprintCallable, BlueprintPure, Category = "VictoryBPLibrary")
> static int32 Conversion__FloatToRoundedInteger(float IN_Float);
> 
> /** Combines two strings together! The Separator and the Labels are optional*/
> UFUNCTION(BlueprintCallable, BlueprintPure, Category = "VictoryBPLibrary")
> static FString String__CombineStrings(FString StringFirst, FString StringSecond, FString Separator = "", FString StringFirstLabel = "", FString StringSecondLabel = "");
> 
> /** Returns three arrays containing of the resolutions and refresh rates for the current computer's current display adapter. You can loop over just 1 of the arrays and use the current index for the other two arrays, as 3 arrays will always have the same length. Returns false if operation could not occur. */
> UFUNCTION(BlueprintCallable, BlueprintPure, Category = "VictoryBPLibrary", meta = (Keywords = "screen resolutions display adapater"))
> static bool OptionsMenu__GetDisplayAdapterScreenResolutions(TArray<int32>& Widths, TArray<int32>& Heights, TArray<int32>& RefreshRates, bool IncludeRefreshRates = false);
> 
> /** Clones an actor by obtaining its class and creating a copy. Returns the created Actor. The cloned actor is set to have the rotation and location of the initial actor. You can optionally specify location / rotation offsets for the new clone from original actor. Use IsValid to know if the actor was able to be cloned. */
> UFUNCTION(BlueprintCallable, Category = "VictoryBPLibrary", meta = (HidePin = "WorldContextObject", DefaultToSelf = "WorldContextObject"))
> static AStaticMeshActor* Clone__StaticMeshActor(UObject* WorldContextObject, bool&IsValid, AStaticMeshActor* ToClone, FVector LocationOffset = FVector(0, 0, 0), FRotator RotationOffset = FRotator(0, 0, 0));
> 
> /** Teleport Actor To Actor. Moves an actor instantly to the position and rotation of another actor. Useful for player starts, notes, triggers, and any other destination actors who dont have collision. Returns false if the operation could not occur. */
> UFUNCTION(BlueprintCallable, BlueprintPure, Category = "VictoryBPLibrary")
> static bool Actor__TeleportToActor(AActor* ActorToTeleport, AActor* DestinationActor);
> 
> /** Is game logic running in the Editor world? */
> UFUNCTION(BlueprintCallable, BlueprintPure, Category = "VictoryBPLibrary", meta = (HidePin = "WorldContextObject", DefaultToSelf = "WorldContextObject"))
> static bool WorldType__InEditorWorld(UObject* WorldContextObject);
> 
> /** Is game logic running in the PIE world? */
> UFUNCTION(BlueprintCallable, BlueprintPure, Category = "VictoryBPLibrary", meta = (HidePin = "WorldContextObject", DefaultToSelf = "WorldContextObject"))
> static bool WorldType__InPIEWorld(UObject* WorldContextObject);
> 
> /** Is game logic running in an actual independent game instance? */
> UFUNCTION(BlueprintCallable, BlueprintPure, Category = "VictoryBPLibrary", meta = (HidePin = "WorldContextObject", DefaultToSelf = "WorldContextObject"))
> static bool WorldType__InGameInstanceWorld(UObject* WorldContextObject);
> 
> /** Cause a supplied Character (casted from Actor internally) to enter Ragdoll physics. A check will be done to see if the character has a physics asset. */
> UFUNCTION(BlueprintCallable, Category = "VictoryBPLibrary")
> static bool Physics__EnterRagDoll(AActor* TheCharacter);
> 
> /** Cause a supplied Character (casted from Actor internally) to exit Ragdoll physics. HeightAboveRBMesh is how far above the RB Mesh the Actor Capsule should be moved to upon exiting. Pass in the InitLocation and InitRotation from InitializeVictoryRagdoll */
> UFUNCTION(BlueprintCallable, Category = "VictoryBPLibrary")
> static bool Physics__LeaveRagDoll(AActor* TheCharacter, float HeightAboveRBMesh = 64, const FVector& InitLocation = FVector(0, 0, 0), const FRotator& InitRotation = FRotator(0, 0, 0));
> 
> /** Returns whether or not a supplied Character is in Ragdoll Physics. Cast from Actor done internally for your convenience. */
> UFUNCTION(BlueprintCallable, Category = "VictoryBPLibrary")
> static bool Physics__IsRagDoll(AActor* TheCharacter);
> 
> /** Get the Ragdoll Position of the supplied actor, casted to Character internally. Returns false if operation could not occur. */
> UFUNCTION(BlueprintCallable, Category = "VictoryBPLibrary")
> static bool Physics__GetLocationofRagDoll(AActor* TheCharacter, FVector& RagdollLocation);
> 
> /** Initialize Victory Ragdoll Mode, by Obtaining the Default Relative Rotation and Location for Character's Mesh. The Output Location and Rotation must be saved for use with LeaveRagdoll. Returns false if operation could not occur */
> UFUNCTION(BlueprintCallable, Category = "VictoryBPLibrary")
> static bool Physics__InitializeVictoryRagDoll(AActor* TheCharacter, FVector&InitLocation, FRotator&InitRotation);
> 
> /** Update the TheCharacter's Capsule Location and Camera to the Current Location of the Ragdoll. InterpSpeed is how fast the camera keeps up with the moving ragdoll! HeightOffset is the height above the ragdoll that the camera should stay. Returns false if operation could not occur or if Mesh was not in ragdoll */
> UFUNCTION(BlueprintCallable, Category = "VictoryBPLibrary")
> static bool Physics__UpdateCharacterCameraToRagdollLocation(AActor* TheCharacter, float HeightOffset = 128, float InterpSpeed = 3);
> 
> /** Get Name as String*/
> UFUNCTION(BlueprintCallable, Category = "VictoryBPLibrary")
> static FString Accessor__GetNameAsString(const UObject* TheObject);
> 
> /** Get Socket Local Transform. Returns false if operation could not occur.*/
> //UFUNCTION(BlueprintCallable, Category = "VictoryBPLibrary")
> //static bool Accessor__GetSocketLocalTransform(const USkeletalMeshComponent* Mesh, FTransform& LocalTransform, FName SocketName=FName("SocketName"));
> 
> /** Get Player Character's Player Controller. Requires: The Passed in Actor must be a character and it must be a player controlled character. IsValid will tell you if the return value is valid, make sure to do a Branch to confirm ! */
> UFUNCTION(BlueprintCallable, Category = "VictoryBPLibrary")
> static APlayerController* Accessor__GetPlayerController(AActor* TheCharacter, bool&IsValid);
> 
> /** SET the Mouse Position! Returns false if the operation could not occur */
> UFUNCTION(BlueprintCallable, Category = "VictoryBPLibrary")
> static bool Viewport__SetMousePosition(const APlayerController* ThePC, const float& PosX, const float& PosY);
> 
> /** Get the Cursor Position within the Player's Viewport. will return a result consistent with SET Mouse Position Returns false if the operation could not occur */
> UFUNCTION(BlueprintCallable, Category = "VictoryBPLibrary")
> static bool Viewport__GetMousePosition(const APlayerController* ThePC, float& PosX, float& PosY);
> 
> /** Get the coordinates of the center of the player's screen / viewport. Returns false if the operation could not occur */
> UFUNCTION(BlueprintCallable, Category = "VictoryBPLibrary")
> static bool Viewport__GetCenterOfViewport(const APlayerController* ThePC, float& PosX, float& PosY);
> 
> /** Convert Rotator to Vector */
> UFUNCTION(BlueprintCallable, Category = "VictoryBPLibrary")
> static FRotator Conversions__VectorToRotator(const FVector& TheVector);
> 
> /** Convert Vector to Rotator*/
> UFUNCTION(BlueprintCallable, Category = "VictoryBPLibrary")
> static FVector Conversions__RotatorToVector(const FRotator& TheRotator);
> 
> /** Input Actor is expected to be a ACharacter, conversion done internally for your convenience */
> UFUNCTION(BlueprintCallable, Category = "VictoryBPLibrary")
> static FRotator Character__GetControllerRotation(AActor * TheCharacter);
> 
> /** Draw 3D Line of Chosen Thickness From Socket on Character's Mesh to Destination, conversion of AActor to ACharacter done internally for your convenience. Duration is in Seconds */
> UFUNCTION(BlueprintCallable, Category = "VictoryBPLibrary")
> static void Draw__Thick3DLineFromCharacterSocket(AActor* TheCharacter, const FVector& EndPoint, FName Socket = FName("SocketName"), FLinearColor LineColor = FLinearColor(1, 0, 0, 1), float Thickness = 7, float Duration = -1.f);
> /** Draw 3D Line of Chosen Thickness From Mesh Socket to Destination. Duration is in Seconds */
> UFUNCTION(BlueprintCallable, Category = "VictoryBPLibrary")
> static void Draw__Thick3DLineFromSocket(USkeletalMeshComponent* Mesh, const FVector& EndPoint, FName Socket = FName("SocketName"), FLinearColor LineColor = FLinearColor(0, 1, 0, 1), float Thickness = 7, float Duration = -1.f);
> /** Draw 3D Line of Chosen Thickness Between Two Actors. Duration is in Seconds */
> UFUNCTION(BlueprintCallable, Category = "VictoryBPLibrary")
> static void Draw__Thick3DLineBetweenActors(AActor* StartActor, AActor* EndActor, FLinearColor LineColor = FLinearColor(0, 0, 1, 1), float Thickness = 7, float Duration = -1.f);
> 
> /** AnimBPOwner - Must be a Character, Conversion Internally For Convenience.
> 
> Retrieves the Aim Offsets Pitch & Yaw Based On the Rotation of the Controller of The Character Owning The Anim Instance.
> 
> The Pitch and Yaw are meant to be used with a Blend Space going from -90,-90 to 90,90.
> Returns true if function filled the pitch and yaw vars successfully */
> UFUNCTION(BlueprintCallable, Category = "VictoryBPLibrary")
> static bool Animation__GetAimOffsets(AActor* AnimBPOwner, float& Pitch, float& Yaw);
> 
> /** AnimBPOwner - Must be a Character, Conversion Internally For Convenience.
> 
> Retrieves the Aim Offsets Pitch & Yaw for the AnimBPOwner Based On the supplied Rotation.
> 
> The Pitch and Yaw are meant to be used with a Blend Space going from -90,-90 to 90,90.
> Returns true if function filled the pitch and yaw vars successfully */
> UFUNCTION(BlueprintCallable, Category = "VictoryBPLibrary")
> static bool Animation__GetAimOffsetsFromRotation(AActor * AnimBPOwner, const FRotator & TheRotation, float & Pitch, float & Yaw);
> 
> /** Saves text to filename of your choosing, make sure include whichever file extension you want in the filename, ex: SelfNotes.txt . Make sure to include the entire file path in the save directory, ex: C:\MyGameDir\BPSavedTextFiles */
> UFUNCTION(BlueprintCallable, Category = "VictoryBPLibrary")
> static bool FileIO__SaveStringTextToFile(FString SaveDirectory, FString JoyfulFileName, FString SaveText, bool AllowOverWriting = false);
> 
> /** Obtain an Array of Actors Rendered Recently. You can specifiy what qualifies as "Recent" in seconds. */
> UFUNCTION(BlueprintCallable, Category = "VictoryBPLibrary")
> static void Visibility__GetRenderedActors(TArray<AActor*>& CurrentlyRenderedActors, float MinRecentTime = 0.01);
> 
> /** Obtain an Array of Actors NOT Rendered Recently! You can specifiy what qualifies as "Recent" in seconds. */
> UFUNCTION(BlueprintCallable, Category = "VictoryBPLibrary")
> static void Visibility__GetNotRenderedActors(TArray<AActor*>& CurrentlyNotRenderedActors, float MinRecentTime = 0.01);
> 
> /** Is the Current Game Window the Foreground window in the OS, or in the Editor? will be accurate in standalone running of the game as well as in the editor PIE */
> UFUNCTION(BlueprintCallable, Category = "VictoryBPLibrary")
> static bool ClientWindow__GameWindowIsForeGroundInOS();
> 
> /** Freeze Game Render, Does Not Stop Game Logic, Just Rendering. is not like Pausing. Mainly useful for freezing render when window is not in the foreground */
> UFUNCTION(BlueprintCallable, Category = "VictoryBPLibrary")
> static void Rendering__FreezeGameRendering();
> 
> /** Unfreeze Game Render. is not an unpause function, it's just for actual screen rendering */
> UFUNCTION(BlueprintCallable, Category = "VictoryBPLibrary")
> static void Rendering__UnFreezeGameRendering();
> 
> /** Compare Source Vector against Array of Vectors. Returns: Returns the Closest Vector to Source and what that closest Distance is, or -1 if there was an error such as array being empty. Ignores: Ignores Source if source is in the array */
> UFUNCTION(BlueprintCallable, Category = "VictoryBPLibrary")
> static float Calcs__ClosestPointToSourcePoint(const FVector & Source, const TArray<FVector>& OtherPoints, FVector& ClosestPoint);
> 
> /** Takes in an actor (for convenience) and tries to cast it to Character and return an array of Vectors of of the current bone locations of the character's Mesh. Locations are in World Space. Returns: false if the operation could not occur. Requires: Character Mesh Component must be valid */
> UFUNCTION(BlueprintCallable, Category = "VictoryBPLibrary")
> static bool Data__GetCharacterBoneLocations(AActor * TheCharacter, TArray<FVector>& BoneLocations);
> 
> /** Retrieves the "Mesh" component of a Character. IsValid lets you know if the data is valid, make sure to check if it is! Requires: the passed in Actor must be a Character */
> UFUNCTION(BlueprintCallable, Category = "VictoryBPLibrary")
> static USkeletalMeshComponent* Accessor__GetCharacterSkeletalMesh(AActor* TheCharacter, bool& IsValid);
> 
> /** Does Not Do A Trace, But Obtains the Start and End for doing a Trace:
> 
> Takes in an actor (for convenience) and tries to cast it to Character. Takes in a socket name to find on the Character's Mesh component, the socket location will be the start of the trace.
> 
> Also takes in the Angle / Rotator and the length of the trace you want to do. Option to draw the trace with variable thickness as it occurs.
> 
> Returns what the Trace Start and End should be so you can plug these into any existing trace node you want.
> 
> Requires: Character Mesh Component must be valid. Returns False if trace could not be done */
> UFUNCTION(BlueprintCallable, Category = "VictoryBPLibrary|Traces")
> static bool TraceData__GetTraceDataFromCharacterSocket(FVector& TraceStart, FVector& TraceEnd, AActor * TheCharacter, const FRotator& TraceRotation, float TraceLength = 10240, FName Socket = "SocketName", bool DrawTraceData = true, FLinearColor TraceDataColor = FLinearColor(1, 0, 0, 1), float TraceDataThickness = 7);
> 
> /** Does Not Do A Trace, But Obtains the Start and End for doing a Trace:
> 
> Takes in a Skeletal Mesh Component and a socket name to trace from. Also takes in the Angle / Rotator and the length of the trace you want to do.
> 
> Option to draw the trace as a variable thickness line
> 
> Returns what the Trace Start and End should be so you can plug these into any existing trace node you want.
> 
> Requires: Mesh must be valid. Returns False if trace could not be done */
> UFUNCTION(BlueprintCallable, Category = "VictoryBPLibrary|Traces")
> static bool TraceData__GetTraceDataFromSkeletalMeshSocket(FVector& TraceStart, FVector& TraceEnd, USkeletalMeshComponent* Mesh, const FRotator& TraceRotation, float TraceLength = 10240, FName Socket = "SocketName", bool DrawTraceData = true, FLinearColor TraceDataColor = FLinearColor(1, 0, 0, 1), float TraceDataThickness = 7);
> 
> /** Does a simple line trace given Trace Start and End, and if a Character is hit by the trace, then a component trace is performed on that character's mesh. Trace Owner is ignored when doing the trace.
> 
> Returns the Character that was hit, as an Actor, as well as the name of the bone that was closest to the impact point of the trace. Also returns the impact point itself as well as the impact normal.
> 
> Using component trace ensures accuracy for testing against bones and sockets.
> 
> IsValid: Will be true only if the component trace also hit someting. But the Returned Actor will contain an actor if any actor at was hit by the simple trace. */
> UFUNCTION(BlueprintCallable, Category = "VictoryBPLibrary|Traces")
> static AActor* Traces __CharacterMeshTrace___ ClosestBone(AActor* TraceOwner, const FVector& TraceStart, const FVector& TraceEnd, FVector& OutImpactPoint, FVector& OutImpactNormal, FName& ClosestBoneName, FVector & ClosestBoneLocation, bool&IsValid);
> 
> /** Does a simple line trace given Trace Start and End, and if a Character is hit by the trace, then a component trace is performed on that character's mesh. Returns the name of the socket that was closest to the impact point of the trace. Also returns the impact point itself as well as the impact normal. Also returns the Socket Location. Using component trace ensures accuracy for testing against bones and sockets.*/
> UFUNCTION(BlueprintCallable, Category = "VictoryBPLibrary|Traces")
> static AActor* Traces __CharacterMeshTrace___ ClosestSocket(const AActor * TraceOwner, const FVector& TraceStart, const FVector& TraceEnd, FVector& OutImpactPoint, FVector& OutImpactNormal, FName& ClosestSocketName, FVector & SocketLocation, bool&IsValid);
> 
> /** Returns the float as a String with Precision, Precision 0 = no decimal value. Precison 1 = 1 decimal place. The re-precisioned result is rounded appropriately. */
> UFUNCTION(BlueprintCallable, Category = "VictoryBPLibrary")
> static void StringConversion__GetFloatAsStringWithPrecision(float TheFloat, FString & TheString, uint8 Precision = 2);
> 
> /** Rotator out value is the degrees of difference between the player camera and the direction of player to light source. Returns false if the operation could not occur. */
> UFUNCTION(BlueprintCallable, Category = "VictoryBPLibrary")
> static bool LensFlare__GetLensFlareOffsets(APlayerController* PlayerController, AActor* LightSource, float& PitchOffset, float& YawOffset, float& RollOffset);
> 
> // ~~~~~~~~~~~~~
> 
> /** Returns false if the operation could not occur. */
> //UFUNCTION(BlueprintCallable, Category = "VictoryBPLibrary")
> //static bool AnimatedVertex__GetAnimatedVertexLocations(USkeletalMeshComponent* Mesh, TArray<FVector>& Locations );
> 
> /** Returns false if the operation could not occur. */
> //UFUNCTION(BlueprintCallable, Category = "VictoryBPLibrary")
> //static bool AnimatedVertex__GetAnimatedVertexLocationsAndNormals(USkeletalMeshComponent* Mesh, TArray<FVector>& Locations, TArray<FVector>& Normals );
> 
> /** 0 never skip, 0.5 = 50% to skip, 1 = skip . Returns false if the operation could not occur. */
> //UFUNCTION(BlueprintCallable, Category = "VictoryBPLibrary", meta=(HidePin="WorldContextObject", DefaultToSelf="WorldContextObject" ))
> //static bool AnimatedVertex__DrawAnimatedVertexLocations(UObject* WorldContextObject, USkeletalMeshComponent* Mesh, float ChanceToSkipAVertex=0.777, bool DrawNormals=false);
> 
> // ~~~~~~~~~~~~~
> 
> /** Returns false if the operation could not occur. */
> //UFUNCTION(BlueprintCallable, Category = "VictoryBPLibrary", meta=(DefaultToSelf="TheCharacter"))
> //static bool AnimatedVertex__GetCharacterAnimatedVertexLocations(AActor* TheCharacter, TArray<FVector>& Locations );
> 
> /** Returns false if the operation could not occur. */
> //UFUNCTION(BlueprintCallable, Category = "VictoryBPLibrary", meta=(DefaultToSelf="TheCharacter"))
> //static bool AnimatedVertex__GetCharacterAnimatedVertexLocationsAndNormals(AActor* TheCharacter, TArray<FVector>& Locations, TArray<FVector>& Normals );
> 
> /** 0 never skip, 0.5 = 50% to skip, 1 = skip .. Returns false if the operation could not occur. */
> //UFUNCTION(BlueprintCallable, Category = "VictoryBPLibrary")
> //static bool AnimatedVertex__DrawCharacterAnimatedVertexLocations(AActor* TheCharacter, float ChanceToSkipAVertex=0.777, bool DrawNormals=false);
> 
> /** Retrieve Distance of given point to any Surface point on a Static Mesh Actor. Returns the distance as well as the exact closest point on the mesh surface to the given point. Returns -1 if an error occurred*/
> UFUNCTION(BlueprintCallable, Category = "VictoryBPLibrary")
> static float DistanceToSurface__DistaceOfPointToMeshSurface(AStaticMeshActor* TheSMA, const FVector& TestPoint, FVector& ClosestSurfacePoint);
> 
> /** Change the Mobility of a Static Mesh Component, can be used in Constructor Script or in Event Graph! Returns false if operation could not occur.*/
> UFUNCTION(BlueprintCallable, Category = "VictoryBPLibrary")
> static bool Mobility__SetSceneCompMobility(USceneComponent* SceneComp, EComponentMobility::Type NewMobility);
> 
> // ~~~~~~~~~~~~~~~~~~~~~~~~~~~
> // ~~~~~~~~~~~~~~~~~~~~~~~~~~~
> // ~~~~~~~~~~~~~~~~~~~~~~~~~~~
> // Graphics Settings Sample
> 
> // ~~~~~~~~~~~~~~~~~~
> // FullScreen
> // ~~~~~~~~~~~~~~~~~~
> 
> /** Get Full Screen Type */
> UFUNCTION(BlueprintPure, Category = "VictoryBPLibrary|Graphics Settings")
> static TEnumAsByte<EJoyGraphicsFullScreen::Type> JoyGraphicsSettings__FullScreen_Get();
> 
> /** Set Full Screen Type */
> UFUNCTION(BlueprintCallable, Category = "VictoryBPLibrary|Graphics Settings")
> static void JoyGraphicsSettings__FullScreen_Set(TEnumAsByte<EJoyGraphicsFullScreen::Type> NewSetting);
> 
> // ~~~~~~~~~~~~~~~~~~~~~~~~~~~
> // ~~~~~~~~~~~~~~~~~~~~~~~~~~~
> // ~~~~~~~~~~~~~~~~~~~~~~~~~~~
> // CPP FUNCTION LIBRARY
> 
> static FORCEINLINE void JoyCC(const FString& Str, const int32 Value)
> {
> TObjectIterator<APlayerController> PC;
> if (!PC) return;
> // ~~~~~~
> 
> PC->ConsoleCommand(Str + " " + FString::FromInt(Value));
> }
> static FORCEINLINE void JoyGraphics_FullScreen_SetFullScreenType(int32 Value)
> {
> JoyCC("r.FullScreenMode", Value);
> }
> static FORCEINLINE int32 JoyGraphics_FullScreen_GetFullScreenType()
> {
> static const auto CVar = IConsoleManager::Get().FindTConsoleVariableDataInt(TEXT("r.FullScreenMode"));
> return CVar->GetValueOnGameThread();
> }
> static FORCEINLINE void JoyGraphics_SetFullScreen_NonWindowed()
> {
> /*"r.FullScreenMode"),
> 2,
> TEXT("Defines how we do full screen when requested (e.g. command line option -fullscreen or in ini [SystemSettings] fullscreen=true)
> ")
> */
> JoyCC("r.FullScreenMode", 0);
> }
> static FORCEINLINE void JoyGraphics_SetFullScreen_Windowed()
> {
> //TEXT(" 2: windowed full screen, specified resolution (like 1 but no unintuitive performance cliff, can be blurry, default)
> ")
> JoyCC("r.FullScreenMode", 2);
> }
> static FORCEINLINE void JoyGraphics_SetFullScreen_WindowedHighestQuality()
> {
> //TEXT(" 1: windowed full screen, desktop resolution (quick switch between applications and window mode, full quality)
> ")
> JoyCC("r.FullScreenMode", 1);
> }
> 
> //Min and of Array
> static FORCEINLINE float Min(const TArray<float>& Values, int32* MinIndex = NULL)
> {
> if (MinIndex)
> {
> *MinIndex = 0;
> }
> 
> if (Values.Num() <= 0)
> {
> return -1;
> }
> 
> float CurMin = Values[0];
> for (const float EachValue : Values)
> {
> CurMin = FMath::Min(CurMin, EachValue);
> }
> 
> if (MinIndex)
> {
> *MinIndex = Values.Find(CurMin);
> }
> return CurMin;
> }
> static FORCEINLINE float (const TArray<float>& Values, int32* MaxIndex = NULL)
> {
> if (MaxIndex)
> {
> *MaxIndex = 0;
> }
> 
> if (Values.Num() <= 0)
> {
> return -1;
> }
> 
> float CurMax = Values[0];
> for (const float EachValue : Values)
> {
> CurMax = FMath::(CurMax, EachValue);
> }
> 
> if (MaxIndex)
> {
> *MaxIndex = Values.Find(CurMax);
> }
> return CurMax;
> }
> 
> static FORCEINLINE int32 Min(const TArray<int32>& Values, int32* MinIndex = NULL)
> {
> if (MinIndex)
> {
> *MinIndex = 0;
> }
> 
> if (Values.Num() <= 0)
> {
> return -1;
> }
> 
> int32 CurMin = Values[0];
> for (const int32 EachValue : Values)
> {
> CurMin = FMath::Min(CurMin, EachValue);
> }
> 
> if (MinIndex)
> {
> *MinIndex = Values.Find(CurMin);
> }
> return CurMin;
> }
> static FORCEINLINE int32 (const TArray<int32>& Values, int32* MaxIndex = NULL)
> {
> if (MaxIndex)
> {
> *MaxIndex = 0;
> }
> 
> if (Values.Num() <= 0)
> {
> return -1;
> }
> 
> int32 CurMax = Values[0];
> for (const int32 EachValue : Values)
> {
> CurMax = FMath::(CurMax, EachValue);
> }
> 
> if (MaxIndex)
> {
> *MaxIndex = Values.Find(CurMax);
> }
> return CurMax;
> }
> 
>     
>     
>     
>     
>     
>     
>     
>     
>     
>     
>     
>     
>     
>     
>     
>     
>     
>     
>     
>     
>     
>     
> // ~~~~~~~~~~~~~~~~~~~~~~~~~~~
> // ~~~~~~~~~~~~~~~~~~~~~~~~~~~
> // ~~~~~~~~~~~~~~~~~~~~~~~~~~~
> // Contributed by Others
>     
> /**
> *
> * Contributed by: Mindfane
> *
> * Split a string into an array of substrings based on the given delimitter.
> * Unlike ParseIntoArray() function which expects single character delimitters, function can accept a delimitter that is also a string.
> *
> * @param InputString - The string that is to be exploded.
> * @param Separator - The delimitter that is used for splitting (multi character strings are allowed)
> * @param limit - If greater than zero, returns only the first x strings. Otherwsie returns the substrings
> * @param bTrimElelements - If True, then each subsctring is processed and any leading or trailing whitespcaes are trimmed.
> */
> UFUNCTION(BlueprintPure, meta = (FriendlyName = "Explode string", Keywords = "split explode string"), Category = String)
> static void String__ExplodeString(TArray<FString>& OutputStrings, FString InputString, FString Separator = ",", int32 limit = 0, bool bTrimElements = false);
>     
> 
> /** Load a texture 2D from a file path! Contributed by UE4 forum member ! */
> UFUNCTION(BlueprintCallable, Category = "VictoryBPLibrary")
> static UTexture2D* GetTexture2DFromFile(const FString& FilePath);
>     
> /** Contributed by UE4 forum member ! Plays a sound from file, attached to and following the specified component. is a fire and forget sound. Replication is also not handled at point.
> * @param FilePath - Path to sound file to play
> * @param AttachComponent - Component to attach to.
> * @param AttachPointName - Optional named point within the AttachComponent to play the sound at
> * @param Location - Depending on the value of Location Type is either a relative offset from the attach component/point or an absolute world position that will be translated to a relative offset
> * @param LocationType - Specifies whether Location is a relative offset or an absolute world position
> * @param bStopWhenAttachedToDestroyed - Specifies whether the sound should stop playing when the owner of the attach to component is destroyed.
> * @param VolumeMultiplier - Volume multiplier
> * @param PitchMultiplier - PitchMultiplier
> * @param AttenuationSettings - Override attenuation settings package to play sound with
> */ 
> UFUNCTION(BlueprintCallable, Category = "VictoryBPLibrary", meta = (VolumeMultiplier = "1.0", PitchMultiplier = "1.0", AdvancedDisplay = "2", UnsafeDuringActorConstruction = "true"))
> static class UAudioComponent* PlaySoundAttachedFromFile(const FString& FilePath, class USceneComponent* AttachToComponent, FName AttachPointName = NAME_None, FVector Location = FVector(ForceInit), EAttachLocation::Type LocationType = EAttachLocation::SnapToTarget, bool bStopWhenAttachedToDestroyed = false, float VolumeMultiplier = 1.f, float PitchMultiplier = 1.f, float StartTime = 0.f, class USoundAttenuation* AttenuationSettings = NULL);
>     
> /** Contributed by UE4 forum member ! Plays a sound at the given location. is a fire and forget sound and does not travel with any actor. Replication is also not handled at point.
> * @param FilePath - Path to sound file to play
> * @param Location - World position to play sound at
> * @param World - The World in which the sound is to be played
> * @param VolumeMultiplier - Volume multiplier
> * @param PitchMultiplier - PitchMultiplier
> * @param AttenuationSettings - Override attenuation settings package to play sound with
> */
> UFUNCTION(BlueprintCallable, Category = "VictoryBPLibrary", meta = (HidePin = "WorldContextObject", DefaultToSelf = "WorldContextObject", VolumeMultiplier = "1.0", PitchMultiplier = "1.0", AdvancedDisplay = "3", UnsafeDuringActorConstruction = "true"))
> static void PlaySoundAtLocationFromFile(UObject* WorldContextObject, const FString& FilePath, FVector Location, float VolumeMultiplier = 1.f, float PitchMultiplier = 1.f, float StartTime = 0.f, class USoundAttenuation* AttenuationSettings = NULL);
>     
> /** Contributed by UE4 forum member ! Creates a USoundWave* from file path.
> * Read .ogg header file and refresh USoundWave metadata.
> * @param FilePath path to file to create sound wave from
> */
> UFUNCTION(BlueprintCallable, Category = "VictoryBPLibrary")
> static class USoundWave* GetSoundWaveFromFile(const FString& FilePath);
> 
> private:
> // Thanks to @keru for the base code for loading an Ogg into a USoundWave: 
> // https://forums.unrealengine.com/showthread.php?7936-Custom-Music-Player&p=97659&viewfull=1#post97659
> 
> /**
> * Read .ogg header file and refresh USoundWave metadata.
> * @param sw wave to put metadata
> * @param rawFile pointer to src file in memory
> * @return 0 if everything is ok
> * 1 if couldn't read metadata.
> */
> static int32 fillSoundWaveInfo(USoundWave* sw, TArray<uint8>* rawFile);
> 
> /**
> * Tries to find out FSoundSource associated to the USoundWave.
> * @param sw wave, search key
> * @return 0 if wave found and correctly set
> * -1 if error: sound device not set
> * -2 if error: sound wave not found
> */
> static int32 findSource(class USoundWave* sw, class FSoundSource* out_audioSource);
> 
> /**
> * Contributed by: SaxonRah
> * Better random numbers. Seeded with a random device. if the random device's entropy is 0; defaults to current for seed.
> * can override with seed functions;
> */
> //----------------------------------------------------------------------------------------------BeginRANDOM
> public:
> /** Construct a random device, returns either a random device or the default random engine; system dependant;
> */
> UFUNCTION(BlueprintCallable, Category = "VictoryBPLibrary|Random")
> static void constructRand();
> 
> /** Seed Rand with value passed
> * @param seed - value to pass to the prng as the seed
> */
> UFUNCTION(BlueprintCallable, Category = "VictoryBPLibrary|Random")
> static void seedRand(int32 seed);
> 
> /** Seed Rand with current
> */
> UFUNCTION(BlueprintCallable, Category = "VictoryBPLibrary|Random")
> static void seedRandWithTime();
> 
> /** Seed Rand with entropy
> * @param seed - value to pass to the prng as the seed
> */
> UFUNCTION(BlueprintCallable, Category = "VictoryBPLibrary|Random")
> static void seedRandWithEntropy();
> 
> /** Random Bool - Bernoulli distribution
> * @param fBias - Bias of Bernoulli distribution
> * @return uniformly distributed bool based on bias parameter
> */
> UFUNCTION(BlueprintCallable, Category = "VictoryBPLibrary|Random")
> static bool RandBool_Bernoulli(float fBias);
> 
> /** Random Integer - Zero to One Uniform distribution
> * @return int32 - uniform distribution from 0 to 1
> */
> UFUNCTION(BlueprintCallable, Category = "VictoryBPLibrary|Random")
> static int32 RandInt_uniDis();
> 
> /** Random Integer - MIN to Uniform distribution
> * @param iMin - Minimum value of uniform distribution
> * @param iMax - Maximum value of uniform distribution
> * @return int32 - uniform distribution from iMin to iMax parameters
> */
> UFUNCTION(BlueprintCallable, Category = "VictoryBPLibrary|Random")
> static int32 RandInt_MINMAX_uniDis(int32 iMin, int32 iMax);
> 
> /** Random Double - Zero to One Uniform distribution
> * @return double - uniform distribution from 0 to 1
> */
> UFUNCTION(BlueprintCallable, Category = "VictoryBPLibrary|Random")
> static float RandFloat_uniDis();
> 
> /** Random Double - Uniform distribution based on MIN to parameters
> * @param iMin - Minimum value of uniform distribution
> * @param iMax - Maximum value of uniform distribution
> * @return double - uniform distribution from iMin to iMax parameters
> */
> UFUNCTION(BlueprintCallable, Category = "VictoryBPLibrary|Random")
> static float RandFloat_MINMAX_uniDis(float iMin, float iMax);
>         
> /** Random Bool - Bernoulli distribution - Mersenne Twister
> * @param fBias - Bias of Bernoulli distribution
> * @return uniformly distributed bool based on bias parameter
> */
> UFUNCTION(BlueprintCallable, Category = "VictoryBPLibrary|Random")
> static bool RandBool_Bernoulli_MT(float fBias);
> 
> /** Random Integer - Zero to One Uniform distribution - Mersenne Twister
> * @return int32 - uniform distribution from 0 to 1
> */
> UFUNCTION(BlueprintCallable, Category = "VictoryBPLibrary|Random")
> static int32 RandInt_uniDis_MT();
> 
> /** Random Integer - MIN to Uniform distribution - Mersenne Twister
> * @param iMin - Minimum value of uniform distribution
> * @param iMax - Maximum value of uniform distribution
> * @return int32 - uniform distribution from iMin to iMax parameters
> */
> UFUNCTION(BlueprintCallable, Category = "VictoryBPLibrary|Random")
> static int32 RandInt_MINMAX_uniDis_MT(int32 iMin, int32 iMax);
> 
> /** Random Float - Zero to One Uniform distribution - Mersenne Twister
> * @return float - uniform distribution from 0 to 1
> */
> UFUNCTION(BlueprintCallable, Category = "VictoryBPLibrary|Random")
> static float RandFloat_uniDis_MT();
> 
> /** Random Float - Uniform distribution based on MIN to parameters - Mersenne Twister
> * @param iMin - Minimum value of uniform distribution
> * @param iMax - Maximum value of uniform distribution
> * @return float - uniform distribution from iMin to iMax parameters
> */
> UFUNCTION(BlueprintCallable, Category = "VictoryBPLibrary|Random")
> static float RandFloat_MINMAX_uniDis_MT(float iMin, float iMax);
> //----------------------------------------------------------------------------------------------ENDRANDOM
> 
> };
> 
> ```

> [@VictoryBPFunctionLibrary.CPP](#):
>
> ```auto
> 
> /* By 
> */
> #include "VictoryBPLibraryPrivatePCH.h"
> 
> #include "StaticMeshResources.h"
> 
> //////////////////////////////////////////////////////////////////////////
> // UVictoryBPFunctionLibrary
> 
> UVictoryBPFunctionLibrary::UVictoryBPFunctionLibrary(const FObjectInitializer& ObjectInitializer)
> : Super(ObjectInitializer)
> {
>     
> }
>  
> FVictoryInput UVictoryBPFunctionLibrary::VictoryGetVictoryInput(const FKeyEvent& KeyEvent)
> {
> FVictoryInput VInput;
>      
> VInput.Key = KeyEvent.GetKey();
> VInput.KeyAsString = VInput.Key.GetDisplayName().ToString();
>     
> VInput.bAlt = KeyEvent.IsAltDown();
> VInput.bCtrl = KeyEvent.IsControlDown();
> VInput.bShift = KeyEvent.IsShiftDown();
> VInput.bCmd = KeyEvent.IsCommandDown();
>     
> return VInput;
> }
> 
> void UVictoryBPFunctionLibrary::VictoryGetAllKeyBindings(TArray<FVictoryInput>& Bindings)
> {
> Bindings.Empty();
>      
> const UInputSettings* Settings = GetDefault<UInputSettings>();
> if(!Settings) return;
>     
> const TArray<FInputActionKeyMapping>& Actions = Settings->ActionMappings;
>     
> for(const FInputActionKeyMapping& Each : Actions)
> {
> Bindings.Add(FVictoryInput(Each));
> }
> }
> bool UVictoryBPFunctionLibrary::VictoryReBindKey(FVictoryInput Action)
> {
> UInputSettings* Settings = const_cast<UInputSettings*>(GetDefault<UInputSettings>());
> if(!Settings) return false;
> 
> TArray<FInputActionKeyMapping>& Actions = Settings->ActionMappings;
>     
> //~~~
>     
> bool Found = false;
> for(FInputActionKeyMapping& Each : Actions)
> {
> if(Each.ActionName.ToString() == Action.ActionName)
> {  
> UVictoryBPFunctionLibrary::UpdateActionMapping(Each,Action);
> Found = true;
> break;
> }  
> }
>     
> if(Found) 
> {
> //SAVES TO DISK
> const_cast<UInputSettings*>(Settings)->SaveKeyMappings();
>            
> //REBUILDS INPUT, creates modified config in Saved/Config/Windows/Input.ini
> for (TObjectIterator<UPlayerInput> It; It; ++It)
> {
> It->ForceRebuildingKeyMaps(true);
> }
> }
> return Found;
> }
> 
> void UVictoryBPFunctionLibrary::GetAllWidgetsOfClass(UObject* WorldContextObject, TSubclassOf<UUserWidget> WidgetClass, TArray<UUserWidget*>& FoundWidgets,bool TopLevelOnly)
> {
> //Prevent possibility of an ever-growing array if user uses in a loop
> FoundWidgets.Empty();
> // ~~~~~~~~~~~~
>      
> if(!WidgetClass) return;
> if(!WorldContextObject) return;
>      
> UWorld* const World = GEngine->GetWorldFromContextObject(WorldContextObject);
> if(!World) return;
> // ~~~~~~~~~~~
>     
> for(TObjectIterator<UUserWidget> Itr; Itr; ++Itr)
> {
> if(Itr->() != World) continue;
> // ~~~~~~~~~~~~~~~~~~~~~
>         
> if( ! Itr->IsA(WidgetClass)) continue;
> // ~~~~~~~~~~~~~~~~~~~
>          
> //Top Level?
> if(TopLevelOnly)
> {
> //only add top level widgets
> if(Itr->IsInViewport())            
> {
> FoundWidgets.Add(*Itr);
> }
> }
> else
> {
> //add internal widgets
> FoundWidgets.Add(*Itr);
> }
> }
> } 
> void UVictoryBPFunctionLibrary::RemoveAllWidgetsOfClass(UObject* WorldContextObject, TSubclassOf<UUserWidget> WidgetClass)
> {
> if(!WidgetClass) return;
> if(!WorldContextObject) return;
>      
> UWorld* const World = GEngine->GetWorldFromContextObject(WorldContextObject);
> if(!World) return;
> // ~~~~~~~~~~~
>      
> for(TObjectIterator<UUserWidget> Itr; Itr; ++Itr)
> {
> if(Itr->() != World) continue;
> // ~~~~~~~~~~~~~~~~~~~~~
>         
> if( ! Itr->IsA(WidgetClass)) continue;
> // ~~~~~~~~~~~~~~~~~~~
>          
> //only add top level widgets
> if(Itr->IsInViewport()) //IsInViewport in 4.6
> {
> Itr->RemoveFromViewport();
> }
> }
> }
> 
> bool UVictoryBPFunctionLibrary::IsWidgetOfClassInViewport(UObject* WorldContextObject, TSubclassOf<UUserWidget> WidgetClass)
> { 
> if(!WidgetClass) return false;
> if(!WorldContextObject) return false;
>      
> UWorld* const World = GEngine->GetWorldFromContextObject(WorldContextObject);
> if(!World) return false;
> // ~~~~~~~~~~~
>       
> for(TObjectIterator<UUserWidget> Itr; Itr; ++Itr)
> {
> if(Itr->() != World) continue;
> // ~~~~~~~~~~~~~~~~~~~~~
>         
> if( ! Itr->IsA(WidgetClass)) continue;
> // ~~~~~~~~~~~~~~~~~~~
>             
> if(Itr->GetIsVisible()) //IsInViewport in 4.6
> {
> return true;
> }
> }
>     
> return false;
> }
>  
> 
> bool UVictoryBPFunctionLibrary::VictorySoundVolumeChange(USoundClass* SoundClassObject, float NewVolume)
> {
> FAudioDevice* Device = GEngine->GetAudioDevice();
> if (!Device || !SoundClassObject)
> {
> return false;
> }
>         
> bool bFound = Device->SoundClasses.Contains(SoundClassObject);
> if(bFound)
> { 
> Device->SetClassVolume(SoundClassObject, NewVolume);
> return true;
> }
> return false;
> }
> float UVictoryBPFunctionLibrary::VictoryGetSoundVolume(USoundClass* SoundClassObject)
> {
> FAudioDevice* Device = GEngine->GetAudioDevice();
> if (!Device || !SoundClassObject)
> {
> return -1;
> }
>         
> FSoundClassProperties* Props = Device->GetSoundClassCurrentProperties(SoundClassObject);
> if(!Props) return -1;
> return Props->Volume;
> }
> 
> // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
> // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
> // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
> 
> bool UVictoryBPFunctionLibrary::VictoryGetCustomConfigVar_Bool(FString SectionName,FString VariableName)
> {
> if(!GConfig) return false;
> // ~~~~~~~~~~~
>  
> bool Value;
> GConfig->GetBool(
> *SectionName,
> *VariableName,
> Value,
> GGameIni
> );
> return Value;
> }
> int32 UVictoryBPFunctionLibrary::VictoryGetCustomConfigVar_Int(FString SectionName,FString VariableName)
> {
> if(!GConfig) return 0;
> // ~~~~~~~~~~~
>  
> int32 Value;
> GConfig->GetInt(
> *SectionName,
> *VariableName,
> Value,
> GGameIni
> );
> return Value;
> }
> float UVictoryBPFunctionLibrary::VictoryGetCustomConfigVar_Float(FString SectionName,FString VariableName)
> {
> if(!GConfig) return 0;
> // ~~~~~~~~~~~
>  
> float Value;
> GConfig->GetFloat(
> *SectionName,
> *VariableName,
> Value,
> GGameIni
> );
> return Value;
> }
> FVector UVictoryBPFunctionLibrary::VictoryGetCustomConfigVar_Vector(FString SectionName,FString VariableName)
> {
> if(!GConfig) return FVector::ZeroVector;
> // ~~~~~~~~~~~
>  
> FVector Value;
> GConfig->GetVector(
> *SectionName,
> *VariableName,
> Value,
> GGameIni
> );
> return Value;
> }
> FRotator UVictoryBPFunctionLibrary::VictoryGetCustomConfigVar_Rotator(FString SectionName,FString VariableName)
> {
> if(!GConfig) return FRotator::ZeroRotator;
> // ~~~~~~~~~~~
>  
> FRotator Value;
> GConfig->GetRotator(
> *SectionName,
> *VariableName,
> Value,
> GGameIni
> );
> return Value;
> }
> FLinearColor UVictoryBPFunctionLibrary::VictoryGetCustomConfigVar_Color(FString SectionName,FString VariableName)
> {
> if(!GConfig) return FColor::Black;
> // ~~~~~~~~~~~
>   
> FColor Value;
> GConfig->GetColor(
> *SectionName,
> *VariableName,
> Value,
> GGameIni
> );
> return FLinearColor(Value);
> }
> FString UVictoryBPFunctionLibrary::VictoryGetCustomConfigVar_String(FString SectionName,FString VariableName)
> {
> if(!GConfig) return "";
> // ~~~~~~~~~~~
>  
> FString Value;
> GConfig->GetString(
> *SectionName,
> *VariableName,
> Value,
> GGameIni
> );
> return Value;
> }
> 
> // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
> 
> void UVictoryBPFunctionLibrary::VictorySetCustomConfigVar_Bool(FString SectionName,FString VariableName, bool Value)
> {
> if(!GConfig) return;
> // ~~~~~~~~~~~
>  
> GConfig->SetBool(
> *SectionName,
> *VariableName,
> Value,
> GGameIni
> );
> }
> void UVictoryBPFunctionLibrary::VictorySetCustomConfigVar_Int(FString SectionName,FString VariableName, int32 Value)
> {
> if(!GConfig) return;
> // ~~~~~~~~~~~
>  
> GConfig->SetInt(
> *SectionName,
> *VariableName,
> Value,
> GGameIni
> );
> }
> void UVictoryBPFunctionLibrary::VictorySetCustomConfigVar_Float(FString SectionName,FString VariableName, float Value)
> {
> if(!GConfig) return;
> // ~~~~~~~~~~~
>     
> GConfig->SetFloat(
> *SectionName,
> *VariableName,
> Value,
> GGameIni
> );
> }
> void UVictoryBPFunctionLibrary::VictorySetCustomConfigVar_Vector(FString SectionName,FString VariableName, FVector Value)
> {
> if(!GConfig) return;
> // ~~~~~~~~~~~
>     
> GConfig->SetVector(
> *SectionName,
> *VariableName,
> Value,
> GGameIni
> );
> }
> void UVictoryBPFunctionLibrary::VictorySetCustomConfigVar_Rotator(FString SectionName,FString VariableName, FRotator Value)
> {
> if(!GConfig) return;
> // ~~~~~~~~~~~
>     
> GConfig->SetRotator(
> *SectionName,
> *VariableName,
> Value,
> GGameIni
> );
> }
> void UVictoryBPFunctionLibrary::VictorySetCustomConfigVar_Color(FString SectionName,FString VariableName, FLinearColor Value)
> {
> if(!GConfig) return;
> // ~~~~~~~~~~~
>      
> GConfig->SetColor(
> *SectionName,
> *VariableName,
> FColor(Value),
> GGameIni
> );
> }
> void UVictoryBPFunctionLibrary::VictorySetCustomConfigVar_String(FString SectionName,FString VariableName, FString Value)
> {
> if(!GConfig) return;
> // ~~~~~~~~~~~
>  
> GConfig->SetString(
> *SectionName,
> *VariableName,
> *Value,
> GGameIni
> );
> }
> 
> // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
> // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
> // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
> 
> UObject* UVictoryBPFunctionLibrary::LoadObjectFromAssetPath(TSubclassOf<UObject> ObjectClass,FName Path,bool& IsValid)
> {
> IsValid = false;
>     
> if(Path == NAME_None) return NULL;
> // ~~~~~~~~~~~~~~~~~~~~~
>     
> UObject* LoadedObj = StaticLoadObject( ObjectClass, NULL,*Path.ToString());
>      
> IsValid = LoadedObj != nullptr;
>     
> return LoadedObj;
> }
> FName UVictoryBPFunctionLibrary::GetObjectPath(UObject* Obj)
> {
> if(!Obj) return NAME_None;
> if(!Obj->IsValidLowLevel()) return NAME_None;
> // ~~~~~~~~~~~~~~~~~~~~~~~~~
>     
> FStringAssetReference ThePath = FStringAssetReference(Obj);
>         
> if(!ThePath.IsValid()) return "";
>     
> //The Class FString Name For  
> FString str=Obj->GetClass()->GetDescription();
>     
> //Remove spaces in Material Instance Constant class description!
> str = str.Replace(TEXT(" "),TEXT(""));
>     
> str += "'";
> str += ThePath.ToString();
> str += "'";
>     
> return FName(*str);
> }
> int32 UVictoryBPFunctionLibrary::GetPlayerUniqueNetID()
> {
> TObjectIterator<APlayerController> ThePC;
> if(!ThePC) return -1; 
> if(!ThePC->PlayerState) return -1;
> // ~~~~~~~~~~~~~~~~~~~
>     
> return ThePC->PlayerState->PlayerId;
> }
> UObject* UVictoryBPFunctionLibrary::CreateObject(UObject* WorldContextObject,UClass* TheObjectClass, FName Name)
> {
> if(!TheObjectClass) return NULL;
> // ~~~~~~~~~~~~~~~~~
>     
> //using a context to get the world!
> UWorld* const World = GEngine->GetWorldFromContextObject(WorldContextObject);
> if(!World) return NULL;
> // ~~~~~~~~~~~
>      
> return StaticConstructObject( TheObjectClass, World, Name);
> }
> UPrimitiveComponent* UVictoryBPFunctionLibrary::CreatePrimitiveComponent(
> UObject* WorldContextObject, 
> TSubclassOf<UPrimitiveComponent> CompClass, 
> FName Name,
> FVector Location, 
> FRotator Rotation
> ){
> if(!CompClass) return NULL;
> // ~~~~~~~~~~~~~~~~~
>     
> //using a context to get the world!
> UWorld* const World = GEngine->GetWorldFromContextObject(WorldContextObject);
> if(!World) return NULL;
> // ~~~~~~~~~~~
>      
> UPrimitiveComponent* NewComp = ConstructObject<UPrimitiveComponent>( CompClass, World, Name);
> if(!NewComp) return NULL;
> // ~~~~~~~~~~~~~
>      
> NewComp->SetWorldLocation(Location);
> NewComp->SetWorldRotation(Rotation);
> NewComp->RegisterComponentWithWorld(World);
>     
> return NewComp;
> }
> 
> AActor* UVictoryBPFunctionLibrary::SpawnActorIntoLevel(UObject* WorldContextObject, TSubclassOf<AActor> ActorClass, FName Level, FVector Location, FRotator Rotation,bool SpawnEvenIfColliding)
> {
> if(!ActorClass) return NULL;
> // ~~~~~~~~~~~~~~~~~
>     
> //using a context to get the world!
> UWorld* const World = GEngine->GetWorldFromContextObject(WorldContextObject);
> if(!World) return NULL;
> // ~~~~~~~~~~~
>     
> FActorSpawnParameters SpawnParameters;
> SpawnParameters.bNoCollisionFail = SpawnEvenIfColliding;
> SpawnParameters.bDeferConstruction = false;
>      
>      
> //Get Level from Name!
> ULevel* FoundLevel = NULL;
>     
> for(const ULevelStreaming* EachLevel : World->StreamingLevels)
> {
> if( ! EachLevel) continue;
> // ~~~~~~~~~~~~~~~~
>     
> ULevel* LevelPtr = EachLevel->GetLoadedLevel();
>         
> //Valid?
> if(!LevelPtr) continue;
>         
> if(EachLevel->GetWorldAssetPackageFName() == Level)
> {
> FoundLevel = LevelPtr; 
> break;
> } 
> }
> // ~~~~~~~~~~~~~~~~~~~~~
> if(FoundLevel)
> {
> SpawnParameters.OverrideLevel = FoundLevel;
> }
> // ~~~~~~~~~~~~~~~~~~~~~
>     
> return World->SpawnActor( ActorClass, &Location, &Rotation, SpawnParameters);
>     
> }
> void UVictoryBPFunctionLibrary::GetNamesOfLoadedLevels(UObject* WorldContextObject, TArray<FString>& NamesOfLoadedLevels)
> {
>     
> //using a context to get the world!
> UWorld* const World = GEngine->GetWorldFromContextObject(WorldContextObject);
> if(!World) return;
> // ~~~~~~~~~~~
>     
> NamesOfLoadedLevels.Empty();
>     
> //Get Level from Name!
> ULevel* FoundLevel = NULL;
>     
> for(const ULevelStreaming* EachLevel : World->StreamingLevels)
> {
> if( ! EachLevel) continue;
> // ~~~~~~~~~~~~~~~~
>     
> ULevel* LevelPtr = EachLevel->GetLoadedLevel();
>         
> //Valid?
> if(!LevelPtr) continue;
>         
> //Is Level Visible?
> if(!LevelPtr->bIsVisible) continue;
> // ~~~~~~~~~~~~~~~~~~~
>          
> NamesOfLoadedLevels.Add(EachLevel->GetWorldAssetPackageFName().ToString());
> }
> }
>         
>     
> void UVictoryBPFunctionLibrary::Loops_ResetBPRunawayCounter()
> {
> //Reset Runaway loop counter (use carefully)
> GInitRunaway();
> }
> 
> void UVictoryBPFunctionLibrary::GraphicsSettings__SetFrameRateToBeUnbound()
> {
> if(!GEngine) return;
> // ~~~~~~~~~
>     
> GEngine->bSmoothFrameRate = 0; 
> }
> void UVictoryBPFunctionLibrary::GraphicsSettings__SetFrameRateCap(float NewValue)
> {
> if(!GEngine) return;
> // ~~~~~~~~~
>        
> GEngine->bSmoothFrameRate = 1; 
> GEngine->SmoothedFrameRateRange = FFloatRange(10,NewValue);
> }
> 
> FVector2D UVictoryBPFunctionLibrary::ProjectWorldToScreenPosition(const FVector& WorldLocation)
> {
> TObjectIterator<APlayerController> ThePC;
> if(!ThePC) return FVector2D::ZeroVector;
>     
> ULocalPlayer* LocalPlayer = Cast<ULocalPlayer>(ThePC->Player);
> if (LocalPlayer != NULL && LocalPlayer->ViewportClient != NULL && LocalPlayer->ViewportClient->Viewport != NULL)
> {
> // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
>         
> // Create a view family for the game viewport
> FSceneViewFamilyContext ViewFamily( FSceneViewFamily::ConstructionValues(
> LocalPlayer->ViewportClient->Viewport,
> ThePC->()->Scene,
> LocalPlayer->ViewportClient->EngineShowFlags )
> .SetRealtimeUpdate(true) );
> 
> // Calculate a view where the player is to update the streaming from the players start location
> FVector ViewLocation;
> FRotator ViewRotation;
> FSceneView* SceneView = LocalPlayer->CalcSceneView( &ViewFamily, /*out*/ ViewLocation, /*out*/ ViewRotation, LocalPlayer->ViewportClient->Viewport );
> 
> //Valid Scene View?
> if (SceneView) 
> {
> //Return
> FVector2D ScreenLocation;
> SceneView->WorldToPixel(WorldLocation,ScreenLocation );
> return ScreenLocation;
> }
> } 
>     
> return FVector2D::ZeroVector;
> }
> 
> bool UVictoryBPFunctionLibrary::GetStaticMeshVertexLocations(UStaticMeshComponent* Comp, TArray<FVector>& VertexPositions)
> {
> if(!Comp) return false;
> if(!Comp->IsValidLowLevel()) return false;
>     
> // ~~~~~~~~~~~~~~~~~~~~
> // Vertex Buffer
> if(! Comp) return false;
> if(! Comp->StaticMesh) return false;
> if(! Comp->StaticMesh->RenderData) return false;
> if( Comp->StaticMesh->RenderData->LODResources.Num() < 1) return false;
> // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
>     
> // ~~~~~~~~~~~~
> VertexPositions.Empty();
> // ~~~~~~~~~~~~
>     
> FPositionVertexBuffer* VertexBuffer = NULL;
> VertexBuffer = & Comp->StaticMesh->RenderData->LODResources[0].PositionVertexBuffer;
> if(!VertexBuffer) return false;
> // ~~~~~~~~~~~~~~~~
>     
> int32 VertexCount = VertexBuffer->GetNumVertices();
>      
> FTransform RV_Transform = Comp->GetComponentTransform(); 
> for(int32 Itr = 0; Itr < VertexCount; Itr++)
> {
> VertexPositions.Add(
> Comp->GetComponentLocation() + RV_Transform.TransformVector(VertexBuffer->VertexPosition(Itr))
> );
> }
>     
> return true;
> }
> 
> void UVictoryBPFunctionLibrary::AddToActorRotation(AActor* TheActor, FRotator AddRot)
> {
> if (!TheActor) return;
> // ~~~~~~~~~~~
> 
> FTransform TheTransform = TheActor->GetTransform();
> TheTransform.ConcatenateRotation(AddRot.Quaternion());
> TheTransform.NormalizeRotation();
> TheActor->SetActorTransform(TheTransform);
> }
> 
> void UVictoryBPFunctionLibrary::DrawCircle(
> UObject* WorldContextObject,
> FVector Center, 
> float Radius, 
> int32 NumPoints,
> float Thickness,
> FLinearColor LineColor,
> FVector YAxis,
> FVector ZAxis,
> float Duration,
> bool PersistentLines
> ){ 
>     
>     
> if(!WorldContextObject) return ;
>     
> //using a context to get the world!
> UWorld* const World = GEngine->GetWorldFromContextObject(WorldContextObject);
> if(!World) return;
> // ~~~~~~~~~~~
>      
> /* //FOR PULL REQUEST TO EPIC
> FMatrix TM;
> TM.SetOrigin(Center);
> TM.SetAxis(0, FVector(1,0,0));
> TM.SetAxis(1, YAxis);
> TM.SetAxis(2, ZAxis);
>     
> DrawDebugCircle(
> World, 
> TM, 
> Radius, NumPoints, 
> FColor::Red, 
> false, 
> -1.f, 
> 0
> );
> */
>      
> // Need at least 4 segments  
> NumPoints = FMath::(NumPoints, 4);
> const float AngleStep = 2.f * PI / float(NumPoints);
> 
> float Angle = 0.f;
> for(int32 v = 0; v < NumPoints; v++)
> {  
> const FVector Vertex1 = Center + Radius * (YAxis * FMath::Cos(Angle) + ZAxis * FMath::Sin(Angle));
> Angle += AngleStep;
> const FVector Vertex2 = Center + Radius * (YAxis * FMath::Cos(Angle) + ZAxis * FMath::Sin(Angle));
>            
> DrawDebugLine(
> World, 
> Vertex1, 
> Vertex2,
> LineColor,  
> PersistentLines, 
> Duration,
> 0, //depth  
> Thickness          
> );
> }
> }
> 
> bool UVictoryBPFunctionLibrary::LoadStringArrayFromFile(TArray<FString>& StringArray, int32& ArraySize, FString FullFilePath, bool ExcludeEmptyLines)
> {
> ArraySize = 0;
>     
> if(FullFilePath == "" || FullFilePath == " ") return false;
>     
> //Empty any previous contents!
> StringArray.Empty();
>     
> TArray<FString> FileArray;
>     
> if( ! FFileHelper::LoadANSITextFileToStrings(*FullFilePath, NULL, FileArray))
> {
> return false;
> }
>     
> if(ExcludeEmptyLines)
> {
> for(const FString& Each : FileArray )
> {
> if(Each == "") continue;
> // ~~~~~~~~~~~~~
>             
> //check for any non whitespace
> bool FoundNonWhiteSpace = false;
> for(int32 v = 0; v < Each.Len(); v++)
> {
> if(Each[v] != ' ' && Each[v] != '
> ')
> {
> FoundNonWhiteSpace = true;
> break;
> }
> // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
> }
>             
> if(FoundNonWhiteSpace)
> {
> StringArray.Add(Each);
> }
> }
> }
> else
> {
> StringArray.Append(FileArray);
> }
>     
> ArraySize = StringArray.Num();
> return true; 
> }
> 
> void UVictoryBPFunctionLibrary::Selection_SelectionBox(UObject* WorldContextObject,TArray<AActor*>& SelectedActors, FVector2D AnchorPoint,FVector2D DraggedPoint,TSubclassOf<AActor> ClassFilter)
> {
> if(!WorldContextObject) return ;
>     
>     
> //using a context to get the world!
> UWorld* const World = GEngine->GetWorldFromContextObject(WorldContextObject);
> if(!World) return;
> // ~~~~~~~~~~~
>     
> SelectedActors.Empty();
>     
> FBox2D Box;
> Box+=DraggedPoint;
> Box+=AnchorPoint;
>     
> for(TActorIterator<AActor> Itr(World); Itr; ++Itr)
> {
> if(!Itr->IsA(ClassFilter)) continue;
> // ~~~~~~~~~~~~~~~~~~
>         
> if(Box.IsInside(UVictoryBPFunctionLibrary::ProjectWorldToScreenPosition(Itr->GetActorLocation())))
> {
> SelectedActors.Add(*Itr);
> }
> }
> }
> 
> bool UVictoryBPFunctionLibrary::PlayerController_GetControllerID(APlayerController* ThePC, int32& ControllerID)
> {
> if(!ThePC) return false;
>     
> ULocalPlayer * LP = Cast<ULocalPlayer>(ThePC->Player);
> if(!LP) return false;
>  
> ControllerID = LP->ControllerId;
>     
> return true;
> }
>     
> bool UVictoryBPFunctionLibrary::PlayerState_GetPlayerID(APlayerController* ThePC, int32& PlayerID)
> {
> if(!ThePC) return false;
>     
> if(!ThePC->PlayerState) return false;
>     
> PlayerID = ThePC->PlayerState->PlayerId;
>     
> return true;
> }
> 
> void UVictoryBPFunctionLibrary::Open_URL_In_Web_Browser(FString TheURL)
> {
> FPlatformProcess::LaunchURL( *TheURL, nullptr, nullptr );
> }
> 
> void UVictoryBPFunctionLibrary::OperatingSystem__GetCurrentPlatform(
> bool& Windows_, //some weird bug of making it caps engine-side
> bool& Mac,
> bool& Linux, 
> bool& iOS, 
> bool& Android,
> bool& PS4,
> bool& XBoxOne,
> bool& HTML5,
> bool& WinRT_Arm,
> bool& WinRT
> ){
> //#define's in UE4 source code
> Windows_ = PLATFORM_WINDOWS;
> Mac = PLATFORM_MAC;
> Linux = PLATFORM_LINUX;
>     
> PS4 = PLATFORM_PS4;
> XBoxOne = PLATFORM_XBOXONE;
>     
> iOS = PLATFORM_IOS;
> Android = PLATFORM_ANDROID;
>     
> HTML5 = PLATFORM_HTML5;
>     
> WinRT_Arm = PLATFORM_WINRT_ARM;
> WinRT = PLATFORM_WINRT;
> }
> 
> FString UVictoryBPFunctionLibrary::RealWorldTime__GetCurrentOSTime( 
> int32& MilliSeconds,
> int32& Seconds, 
> int32& Minutes, 
> int32& Hours12,
> int32& Hours24,
> int32& Day,
> int32& Month,
> int32& Year
> ){
> const FDateTime Now = FDateTime::Now();
>     
> MilliSeconds = Now.GetMillisecond( );
> Seconds = Now.GetSecond( );
> Minutes = Now.GetMinute( );
> Hours12 = Now.GetHour12( );
> Hours24 = Now.GetHour( ); //24
> Day = Now.GetDay( );
> Month = Now.GetMonth( );
> Year = Now.GetYear( );
>     
> return Now.ToString();
> }
> 
> void UVictoryBPFunctionLibrary::RealWorldTime__GetTimePassedSincePreviousTime(
> const FString& PreviousTime,
> float& Milliseconds,
> float& Seconds,
> float& Minutes,
> float& Hours
> ){
> FDateTime ParsedDateTime;
> FDateTime::Parse(PreviousTime,ParsedDateTime);
> const FTimespan TimeDiff = FDateTime::Now() - ParsedDateTime;
>     
> Milliseconds = TimeDiff.GetTotalMilliseconds( );
> Seconds = TimeDiff.GetTotalSeconds( );
> Minutes = TimeDiff.GetTotalMinutes( );
> Hours = TimeDiff.GetTotalHours( );
> }
>     
> void UVictoryBPFunctionLibrary::RealWorldTime__GetDifferenceBetweenTimes(
> const FString& PreviousTime1,
> const FString& PreviousTime2,
> float& Milliseconds,
> float& Seconds,
> float& Minutes,
> float& Hours
> ){
> FDateTime ParsedDateTime1;
> FDateTime::Parse(PreviousTime1,ParsedDateTime1);
>     
> FDateTime ParsedDateTime2;
> FDateTime::Parse(PreviousTime2,ParsedDateTime2);
>     
> FTimespan TimeDiff; 
>     
> if(PreviousTime1 < PreviousTime2)
> {
> TimeDiff = ParsedDateTime2 - ParsedDateTime1;
> }
> else
> {
> TimeDiff = ParsedDateTime1 - ParsedDateTime2;
> }
>     
> Milliseconds = TimeDiff.GetTotalMilliseconds( );
> Seconds = TimeDiff.GetTotalSeconds( );
> Minutes = TimeDiff.GetTotalMinutes( );
> Hours = TimeDiff.GetTotalHours( );
> }
> 
> void UVictoryBPFunctionLibrary::MaxOfFloatArray(const TArray<float>& FloatArray, int32& IndexOfMaxValue, float& MaxValue)
> {
> MaxValue = UVictoryBPFunctionLibrary::(FloatArray,&IndexOfMaxValue);
> }
> 
> void UVictoryBPFunctionLibrary::MaxOfIntArray(const TArray<int32>& IntArray, int32& IndexOfMaxValue, int32& MaxValue)
> {
> MaxValue = UVictoryBPFunctionLibrary::(IntArray,&IndexOfMaxValue);
> }
> 
> void UVictoryBPFunctionLibrary::MinOfFloatArray(const TArray<float>& FloatArray, int32& IndexOfMinValue, float& MinValue)
> {
> MinValue = UVictoryBPFunctionLibrary::Min(FloatArray,&IndexOfMinValue);
> }
> 
> void UVictoryBPFunctionLibrary::MinOfIntArray(const TArray<int32>& IntArray, int32& IndexOfMinValue, int32& MinValue)
> {
> MinValue = UVictoryBPFunctionLibrary::Min(IntArray,&IndexOfMinValue);
> }
> 
> bool UVictoryBPFunctionLibrary::CharacterMovement__SetMaxMoveSpeed(ACharacter* TheCharacter, float NewMaxMoveSpeed)
> {
> if(!TheCharacter)
> {
> return false;
> }
> if(!TheCharacter->CharacterMovement)
> {
> return false;
> }
>     
> TheCharacter->CharacterMovement->MaxWalkSpeed = NewMaxMoveSpeed;
>     
> return true;
> }
>     
> 
> int32 UVictoryBPFunctionLibrary::Conversion__FloatToRoundedInteger(float IN_Float)
> {
> return FGenericPlatformMath::RoundToInt(IN_Float);
> }
> 
> FString UVictoryBPFunctionLibrary::String__CombineStrings(FString StringFirst, FString StringSecond, FString Separator, FString StringFirstLabel, FString StringSecondLabel)
> {
> return StringFirstLabel + StringFirst + Separator + StringSecondLabel + StringSecond;
> }
> 
> bool UVictoryBPFunctionLibrary::OptionsMenu__GetDisplayAdapterScreenResolutions(TArray<int32>& Widths, TArray<int32>& Heights, TArray<int32>& RefreshRates,bool IncludeRefreshRates)
> {
> //Clear any Previous
> Widths.Empty();
> Heights.Empty();
> RefreshRates.Empty();
>     
> TArray<FString> Unique;    
>     
> FScreenResolutionArray Resolutions;
> if(RHIGetAvailableResolutions(Resolutions, false))
> {
> for (const FScreenResolutionRHI& EachResolution : Resolutions)
> {
> FString Str = "";
> Str += FString::FromInt(EachResolution.Width);
> Str += FString::FromInt(EachResolution.Height);
>             
> //Include Refresh Rates?
> if(IncludeRefreshRates)
> {
> Str += FString::FromInt(EachResolution.RefreshRate);
> }        
>             
> if(Unique.Contains(Str))
> {
> //Skip! is duplicate!
> continue;
> }
> else
> {
> //Add to Unique List!
> Unique.AddUnique(Str);
> }
>             
> //Add to Actual Data Output!
> Widths.Add( EachResolution.Width);
> Heights.Add( EachResolution.Height);
> RefreshRates.Add( EachResolution.RefreshRate);
> }
> 
> return true;
> }
> return false;
> }
> 
> AStaticMeshActor* UVictoryBPFunctionLibrary::Clone__StaticMeshActor(UObject* WorldContextObject, bool&IsValid, AStaticMeshActor* ToClone, FVector LocationOffset,FRotator RotationOffset)
> {
> IsValid = NULL;
> if(!ToClone) return NULL;
> if(!ToClone->IsValidLowLevel()) return NULL;
> // ~~~~~~~~~~~~~~~~~~~~~~~~~~~
>     
> if(!WorldContextObject) return NULL;
>     
> //using a context to get the world!
> UWorld* const World = GEngine->GetWorldFromContextObject(WorldContextObject);
> if(!World) return NULL;
> // ~~~~~~~~~~~
>     
> //For BPS
> UClass* SpawnClass = ToClone->GetClass();
>     
> FActorSpawnParameters SpawnInfo;
> SpawnInfo.bNoCollisionFail = true;
> SpawnInfo.Owner = ToClone;
> SpawnInfo.Instigator = NULL;
> SpawnInfo.bDeferConstruction = NULL;
>     
> AStaticMeshActor* NewSMA = World->SpawnActor<AStaticMeshActor>(SpawnClass, ToClone->GetActorLocation() + FVector(0,0,512) ,ToClone->GetActorRotation(), SpawnInfo );
>     
> if(!NewSMA) return NULL;
>     
> //Copy Transform
> NewSMA->SetActorTransform(ToClone->GetTransform());
>     
> //Mobility
> NewSMA->StaticMeshComponent->SetMobility(EComponentMobility::Movable );
>     
> //copy static mesh
> NewSMA->StaticMeshComponent->SetStaticMesh(ToClone->StaticMeshComponent->StaticMesh);
>     
> //~~~
>     
> //copy materials
> TArray<UMaterialInterface*> Mats;
> ToClone->StaticMeshComponent->GetUsedMaterials(Mats);
>     
> const int32 Total = Mats.Num();
> for(int32 v = 0; v < Total; v++ )
> {
> NewSMA->StaticMeshComponent->SetMaterial(v,Mats[v]);
> }
>     
> //~~~
>     
> //copy physics state
> if(ToClone->StaticMeshComponent->IsSimulatingPhysics())
> {
> NewSMA->StaticMeshComponent->SetSimulatePhysics(true);
> }
>     
> //~~~
>     
> //Add Location Offset
> const FVector SpawnLoc = ToClone->GetActorLocation() + LocationOffset;
> NewSMA->SetActorLocation(SpawnLoc);
>     
> //Add Rotation offset
> FTransform TheTransform = NewSMA->GetTransform();
> TheTransform.ConcatenateRotation(RotationOffset.Quaternion());
> TheTransform.NormalizeRotation();
>     
> //Set Transform
> NewSMA->SetActorTransform(TheTransform);
>     
> IsValid = true;
> return NewSMA;
> }
> 
> bool UVictoryBPFunctionLibrary::Actor__TeleportToActor(AActor* ActorToTeleport, AActor* DestinationActor)
> {
> if(!ActorToTeleport) return false;
> if(!ActorToTeleport->IsValidLowLevel()) return false;
> if(!DestinationActor) return false;
> if(!DestinationActor->IsValidLowLevel()) return false;
>     
> //Set Loc
> ActorToTeleport->SetActorLocation(DestinationActor->GetActorLocation());
>     
> //Set Rot
> ActorToTeleport->SetActorRotation(DestinationActor->GetActorRotation());
>     
> return true;
> }
> 
> bool UVictoryBPFunctionLibrary::WorldType__InEditorWorld(UObject* WorldContextObject)
> {
> if(!WorldContextObject) return false;
>     
> //using a context to get the world!
> UWorld* const World = GEngine->GetWorldFromContextObject(WorldContextObject);
> if(!World) return false;
> // ~~~~~~~~~~~
>     
> return (World->WorldType == EWorldType::Editor );
> }
> 
> bool UVictoryBPFunctionLibrary::WorldType__InPIEWorld(UObject* WorldContextObject)
> {
> if(!WorldContextObject) return false;
>     
> //using a context to get the world!
> UWorld* const World = GEngine->GetWorldFromContextObject(WorldContextObject);
> if(!World) return false;
> // ~~~~~~~~~~~
>     
> return (World->WorldType == EWorldType::PIE );
> }
> bool UVictoryBPFunctionLibrary::WorldType__InGameInstanceWorld(UObject* WorldContextObject)
> {
> if(!WorldContextObject) return false;
>     
> //using a context to get the world!
> UWorld* const World = GEngine->GetWorldFromContextObject(WorldContextObject);
> if(!World) return false;
> // ~~~~~~~~~~~
>     
> return (World->WorldType == EWorldType::Game );
> }
>     
> FString UVictoryBPFunctionLibrary::Accessor__GetNameAsString(const UObject* TheObject)
> {
> if (!TheObject) return "";
> return TheObject->GetName();
> }
> 
> FRotator UVictoryBPFunctionLibrary::Conversions__VectorToRotator(const FVector& TheVector)
> {
> return TheVector.Rotation();
> }
> FVector UVictoryBPFunctionLibrary::Conversions__RotatorToVector(const FRotator& TheRotator)
> {
> return TheRotator.Vector();
> }
> FRotator UVictoryBPFunctionLibrary::Character__GetControllerRotation(AActor * TheCharacter)
> {
> ACharacter * AsCharacter = Cast<ACharacter>(TheCharacter);
> 
> if (!AsCharacter) return FRotator::ZeroRotator;
>     
> return AsCharacter->GetControlRotation();
> }
> 
> //Draw From Socket on Character's Mesh
> void UVictoryBPFunctionLibrary::Draw__Thick3DLineFromCharacterSocket(AActor* TheCharacter, const FVector& EndPoint, FName Socket, FLinearColor LineColor, float Thickness, float Duration)
> {
> ACharacter * AsCharacter = Cast<ACharacter>(TheCharacter);
> if (!AsCharacter) return;
> if (!AsCharacter->Mesh) return;
> // ~~~~~~~~~~~~~~~~~~~~
>     
> //Get World
> UWorld* TheWorld = AsCharacter->();
> if (!TheWorld) return;
> // ~~~~~~~~~~~~~~~~~
>     
> const FVector SocketLocation = AsCharacter->Mesh->GetSocketLocation(Socket);
> DrawDebugLine(
> TheWorld, 
> SocketLocation, 
> EndPoint, 
> FColor(LineColor), 
> false, 
> Duration, 
> 0, 
> Thickness
> );
>     
> }
> /** Draw 3D Line of Chosen Thickness From Mesh Socket to Destination */
> void UVictoryBPFunctionLibrary::Draw__Thick3DLineFromSocket(USkeletalMeshComponent* Mesh, const FVector& EndPoint, FName Socket, FLinearColor LineColor, float Thickness, float Duration)
> {
> if (!Mesh) return;
> // ~~~~~~~~~~~~~~
>     
> //Get an actor to () from
> TObjectIterator<APlayerController> Itr;
> if (!Itr) return;
> // ~~~~~~~~~~~~
>     
> //Get World
> UWorld* TheWorld = Itr->();
> if (!TheWorld) return;
> // ~~~~~~~~~~~~~~~~~
>     
> const FVector SocketLocation = Mesh->GetSocketLocation(Socket);
>     
> DrawDebugLine(
> TheWorld, 
> SocketLocation, 
> EndPoint, 
> FColor(LineColor), 
> false, 
> Duration, 
> 0, 
> Thickness
> );
> }
> /** Draw 3D Line of Chosen Thickness Between Two Actors */
> void UVictoryBPFunctionLibrary::Draw__Thick3DLineBetweenActors(AActor * StartActor, AActor * EndActor, FLinearColor LineColor, float Thickness, float Duration)
> {
> if (!StartActor) return;
> if (!EndActor) return;
> // ~~~~~~~~~~~~~~~~
>     
> DrawDebugLine(
> StartActor->(), 
> StartActor->GetActorLocation(), 
> EndActor->GetActorLocation(), 
> FColor(LineColor), 
> false, 
> Duration, 
> 0, 
> Thickness
> );
> }
>     
> bool UVictoryBPFunctionLibrary::Animation__GetAimOffsets(AActor* AnimBPOwner, float& Pitch, float& Yaw)
> {
> //Get Owning Character
> ACharacter * TheCharacter = Cast<ACharacter>(AnimBPOwner);
>     
> if (!TheCharacter) return false;
> // ~~~~~~~~~~~~~~~
>     
> //Get Owning Controller Rotation
> const FRotator TheCtrlRotation = TheCharacter->GetControlRotation();
>     
> const FVector RotationDir = TheCtrlRotation.Vector();
>     
> //Inverse of ActorToWorld matrix is Actor to Local Space
> //so takes the direction vector, the PC or AI rotation
> //and outputs what dir is 
> //in local actor space &
>         
> //local actor space is what we want for aiming offsets
>         
> const FVector LocalDir = TheCharacter->ActorToWorld().InverseTransformVectorNoScale(RotationDir);
> const FRotator LocalRotation = LocalDir.Rotation();
>         
> //Pass out Yaw and Pitch
> Yaw = LocalRotation.Yaw;
> Pitch = LocalRotation.Pitch;
>     
> return true;
> }
> bool UVictoryBPFunctionLibrary::Animation__GetAimOffsetsFromRotation(AActor * AnimBPOwner, const FRotator & TheRotation, float & Pitch, float & Yaw)
> {
> //Get Owning Character
> ACharacter * TheCharacter = Cast<ACharacter>(AnimBPOwner);
>     
> if (!TheCharacter) return false;
> // ~~~~~~~~~~~~~~~
>     
> //using supplied rotation
> const FVector RotationDir = TheRotation.Vector();
>     
> //Inverse of ActorToWorld matrix is Actor to Local Space
> //so takes the direction vector, the PC or AI rotation
> //and outputs what dir is 
> //in local actor space &
>         
> //local actor space is what we want for aiming offsets
>         
> const FVector LocalDir = TheCharacter->ActorToWorld().InverseTransformVectorNoScale(RotationDir);
> const FRotator LocalRotation = LocalDir.Rotation();
>         
> //Pass out Yaw and Pitch
> Yaw = LocalRotation.Yaw;
> Pitch = LocalRotation.Pitch;
>     
> return true;
> }
> 
> void UVictoryBPFunctionLibrary::Visibility__GetRenderedActors(TArray<AActor*>& CurrentlyRenderedActors, float MinRecentTime)
> {
> //Empty any previous entries
> CurrentlyRenderedActors.Empty();
>     
> //Iterate Over Actors
> for ( TObjectIterator<AActor> Itr; Itr; ++Itr )
> {
> if (Itr->GetLastRenderTime() > MinRecentTime)
> {
> CurrentlyRenderedActors.Add( * Itr);
> }
> }
> }
> void UVictoryBPFunctionLibrary::Visibility__GetNotRenderedActors(TArray<AActor*>& CurrentlyNotRenderedActors, float MinRecentTime)
> {
> //Empty any previous entries
> CurrentlyNotRenderedActors.Empty();
>     
> //Iterate Over Actors
> for ( TObjectIterator<AActor> Itr; Itr; ++Itr )
> {
> if (Itr->GetLastRenderTime() <= MinRecentTime)
> {
> CurrentlyNotRenderedActors.Add( * Itr);
> }
> }
> }
> 
> void UVictoryBPFunctionLibrary::Rendering__FreezeGameRendering()
> {
> FViewport::SetGameRenderingEnabled(false);
> }
> void UVictoryBPFunctionLibrary::Rendering__UnFreezeGameRendering()
> {
> FViewport::SetGameRenderingEnabled(true);
> }
>     
> bool UVictoryBPFunctionLibrary::ClientWindow__GameWindowIsForeGroundInOS()
> {
> //Iterate Over Actors
> UWorld* TheWorld = NULL;
> for ( TObjectIterator<AActor> Itr; Itr; ++Itr )
> {
> TheWorld = Itr->();
> if (TheWorld) break;
> // ~~~~~~~~~~~~~~~~~~~~~~~
> }
> //Get Player
> ULocalPlayer* VictoryPlayer = 
> TheWorld->GetFirstLocalPlayerFromController(); 
> 
> if (!VictoryPlayer) return false;
> // ~~~~~~~~~~~~~~~~~~~~
>     
> //get view port ptr
> UGameViewportClient * VictoryViewportClient = 
> Cast < UGameViewportClient > (VictoryPlayer->ViewportClient);
>         
> if (!VictoryViewportClient) return false;
> // ~~~~~~~~~~~~~~~~~~~~
>      
> FViewport * VictoryViewport = VictoryViewportClient->Viewport;
>     
> if (!VictoryViewport) return false;
> // ~~~~~~~~~~~~~~~~~~~~
>     
> return VictoryViewport->IsForegroundWindow();
> }
> bool UVictoryBPFunctionLibrary::FileIO__SaveStringTextToFile(
> FString SaveDirectory, 
> FString JoyfulFileName, 
> FString SaveText,
> bool AllowOverWriting
> ){
> //Dir Exists?
> if ( !FPlatformFileManager::Get().GetPlatformFile().DirectoryExists( *SaveDirectory))
> {
> //create directory if it not exist
> FPlatformFileManager::Get().GetPlatformFile().CreateDirectory( *SaveDirectory);
>         
> //still could not make directory?
> if (!FPlatformFileManager::Get().GetPlatformFile().DirectoryExists( *SaveDirectory))
> {
> //Could not make the specified directory
> return false;
> // ~~~~~~~~~~~~~~~~~~~~~~
> }
> }
>     
> //get complete file path
> SaveDirectory += "\\";
> SaveDirectory += JoyfulFileName;
>     
> //No over-writing?
> if (!AllowOverWriting)
> {
> //Check if file exists already
> if (FPlatformFileManager::Get().GetPlatformFile().FileExists( * SaveDirectory))
> {
> //no overwriting
> return false;
> }
> }
>     
> return FFileHelper::SaveStringToFile(SaveText, * SaveDirectory);
> }
> 
> float UVictoryBPFunctionLibrary::Calcs__ClosestPointToSourcePoint(const FVector & Source, const TArray<FVector>& OtherPoints, FVector& ClosestPoint)
> {
> float CurDist = 0;
> float ClosestDistance = -1;
> int32 ClosestVibe = 0;
> ClosestPoint = FVector::ZeroVector;
>     
> if (OtherPoints.Num() <= 0) return ClosestDistance;
> // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
>     
> for (int32 Itr = 0; Itr < OtherPoints.Num(); Itr++)
> {
> if (Source == OtherPoints[Itr]) continue;
> // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
>         
> //Dist
> CurDist = FVector::Dist(Source, OtherPoints[Itr]);
>         
> //Min
> if (ClosestDistance < 0 || ClosestDistance >= CurDist)
> {
> ClosestVibe = Itr;
> ClosestDistance = CurDist;
> }
> }
>     
> //Out
> ClosestPoint = OtherPoints[ClosestVibe];
> return ClosestDistance;
> }
> 
> bool UVictoryBPFunctionLibrary::Data__GetCharacterBoneLocations(AActor * TheCharacter, TArray<FVector>& BoneLocations)
> {
> ACharacter * Source = Cast<ACharacter>(TheCharacter);
> if (!Source) return false;
>     
> if (!Source-> Mesh) return false;
> // ~~~~~~~~~~~~~~~~~~~~~~~~~
> TArray<FName> BoneNames;
>     
> BoneLocations.Empty();
>     
>     
> //Get Bone Names
> Source-> Mesh->GetBoneNames(BoneNames);
>     
> //Get Bone Locations
> for (int32 Itr = 0; Itr < BoneNames.Num(); Itr++ )
> {
> BoneLocations.Add(Source->Mesh->GetBoneLocation(BoneNames[Itr]));
> }
>     
> return true;
> }
> 
> USkeletalMeshComponent* UVictoryBPFunctionLibrary::Accessor__GetCharacterSkeletalMesh(AActor * TheCharacter, bool& IsValid)
> {
> IsValid = false;
>     
> ACharacter * AsCharacter = Cast<ACharacter>(TheCharacter);
> if (!AsCharacter) return NULL;
> // ~~~~~~~~~~~~~~~~~
>     
> //Is Valid?
> if (AsCharacter->Mesh)
> if (AsCharacter->Mesh->IsValidLowLevel() ) 
> IsValid = true;
>             
> return AsCharacter->Mesh;
> }
> 
> bool UVictoryBPFunctionLibrary::TraceData__GetTraceDataFromCharacterSocket(
> FVector & TraceStart, //out
> FVector & TraceEnd, //out
> AActor * TheCharacter,
> const FRotator& TraceRotation, 
> float TraceLength,
> FName Socket, 
> bool DrawTraceData, 
> FLinearColor TraceDataColor, 
> float TraceDataThickness
> ) {
> ACharacter * AsCharacter = Cast<ACharacter>(TheCharacter);
> if (!AsCharacter) return false;
>     
> //Mesh Exists?
> if (!AsCharacter->Mesh) return false;
>     
> //Socket Exists?
> if (!AsCharacter->Mesh->DoesSocketExist(Socket)) return false;
> // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
>     
> TraceStart = AsCharacter->Mesh->GetSocketLocation(Socket);
> TraceEnd = TraceStart + TraceRotation.Vector() * TraceLength;
>     
> if (DrawTraceData) 
> {
> //Get World
> UWorld* TheWorld = AsCharacter->();
> if (!TheWorld) return false;
> // ~~~~~~~~~~~~~~~~~
>     
> DrawDebugLine(
> TheWorld, 
> TraceStart, 
> TraceEnd, 
> FColor(TraceDataColor), 
> false, 
> 0.0333, 
> 0, 
> TraceDataThickness
> );
> }
>     
> return true;
> }
> bool UVictoryBPFunctionLibrary::TraceData__GetTraceDataFromSkeletalMeshSocket(
> FVector & TraceStart, //out
> FVector & TraceEnd, //out
> USkeletalMeshComponent * Mesh,
> const FRotator & TraceRotation,    
> float TraceLength,
> FName Socket, 
> bool DrawTraceData, 
> FLinearColor TraceDataColor, 
> float TraceDataThickness
> ) {
> //Mesh Exists?
> if (!Mesh) return false;
>     
> //Socket Exists?
> if (!Mesh->DoesSocketExist(Socket)) return false;
> // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
> 
> TraceStart = Mesh->GetSocketLocation(Socket);
> TraceEnd = TraceStart + TraceRotation.Vector() * TraceLength;
>     
> if (DrawTraceData) 
> {
> //Get a PC to () from
> TObjectIterator<APlayerController> Itr;
> if (!Itr) return false;
>         
> // ~~~~~~~~~~~~
>         
> //Get World
> UWorld* TheWorld = Itr->();
> if (!TheWorld) return false;
> // ~~~~~~~~~~~~~~~~~
>     
> DrawDebugLine(
> TheWorld, 
> TraceStart, 
> TraceEnd, 
> FColor(TraceDataColor), 
> false, 
> 0.0333, 
> 0, 
> TraceDataThickness
> );
> }
>     
> return true;
> }
> AActor* UVictoryBPFunctionLibrary::Traces __CharacterMeshTrace___ ClosestBone(
> AActor* TraceOwner,
> const FVector & TraceStart, 
> const FVector & TraceEnd, 
> FVector & OutImpactPoint, 
> FVector & OutImpactNormal, 
> FName & ClosestBoneName,
> FVector & ClosestBoneLocation,
> bool& IsValid
> )
> {
> IsValid = false;
> AActor * HitActor = NULL;
> // ~~~~~~~~~~~~~~~~~~~~~~
>     
> //Get a PC to () from
> TObjectIterator<APlayerController> Itr;
> if (!Itr) return NULL;
>     
> // ~~~~~~~~~~~~
>     
> //Get World
> UWorld* TheWorld = Itr->();
> if (TheWorld == nullptr) return NULL;
> // ~~~~~~~~~~~~~~~~~
>     
>     
> //Simple Trace First
> FCollisionQueryParams TraceParams(FName(TEXT("VictoryBPTrace::CharacterMeshTrace")), true, HitActor);
> TraceParams.bTraceComplex = true;
> TraceParams.bTraceAsyncScene = true;
> TraceParams.bReturnPhysicalMaterial = false;
> TraceParams.AddIgnoredActor(TraceOwner);
>     
> //initialize hit info
> FHitResult RV_Hit(ForceInit);
>     
> TheWorld->LineTraceSingle(
> RV_Hit, //result
> TraceStart, 
> TraceEnd, 
> ECC_Pawn, //collision channel
> TraceParams
> );
>         
> //Hit Something!
> if (!RV_Hit.bBlockingHit) return HitActor;
>     
>     
> //Character?
> HitActor = RV_Hit.GetActor();
> ACharacter * AsCharacter = Cast<ACharacter>(HitActor);
> if (!AsCharacter) return HitActor;
>     
> //Mesh
> if (!AsCharacter->Mesh) return HitActor;
>     
> //Component Trace
> IsValid = AsCharacter->Mesh->K2_LineTraceComponent(
> TraceStart, 
> TraceEnd, 
> true, 
> false, 
> OutImpactPoint, 
> OutImpactNormal,
> ClosestBoneName
> ); 
>     
> //Location
> ClosestBoneLocation = AsCharacter->Mesh->GetBoneLocation(ClosestBoneName);
>     
> return HitActor;
> }
> 
> AActor* UVictoryBPFunctionLibrary::Traces __CharacterMeshTrace___ ClosestSocket(
> const AActor * TraceOwner, 
> const FVector & TraceStart, 
> const FVector & TraceEnd, 
> FVector & OutImpactPoint, 
> FVector & OutImpactNormal, 
> FName & ClosestSocketName, 
> FVector & SocketLocation, 
> bool & IsValid
> )
> {
> IsValid = false;
> AActor * HitActor = NULL;
> // ~~~~~~~~~~~~~~~~~~~~~~
>      
> //There may not be a trace owner so dont rely on it
>     
> //Get a PC to () from
> TObjectIterator<APlayerController> Itr;
> if (!Itr) return NULL;
>     
> // ~~~~~~~~~~~~
>     
> //Get World
> UWorld* TheWorld = Itr->();
> if (TheWorld == nullptr) return NULL;
> // ~~~~~~~~~~~~~~~~~
>     
>     
> //Simple Trace First
> FCollisionQueryParams TraceParams(FName(TEXT("VictoryBPTrace::CharacterMeshSocketTrace")), true, HitActor);
> TraceParams.bTraceComplex = true;
> TraceParams.bTraceAsyncScene = true;
> TraceParams.bReturnPhysicalMaterial = false;
> TraceParams.AddIgnoredActor(TraceOwner);
>     
> //initialize hit info
> FHitResult RV_Hit(ForceInit);
>     
> TheWorld->LineTraceSingle(
> RV_Hit, //result
> TraceStart, 
> TraceEnd, 
> ECC_Pawn, //collision channel
> TraceParams
> );
>         
> //Hit Something!
> if (!RV_Hit.bBlockingHit) return HitActor;
>     
>     
> //Character?
> HitActor = RV_Hit.GetActor();
> ACharacter * AsCharacter = Cast<ACharacter>(HitActor);
> if (!AsCharacter) return HitActor;
>     
> //Mesh
> if (!AsCharacter->Mesh) return HitActor;
>     
> //Component Trace
> FName BoneName;
> if (! AsCharacter->Mesh->K2_LineTraceComponent(
> TraceStart, 
> TraceEnd, 
> true, 
> false, 
> OutImpactPoint, 
> OutImpactNormal,
> BoneName
> )) return HitActor;
>     
> // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
> // Socket Names
> TArray<FComponentSocketDescription> SocketNames;
>     
> //Get Bone Names
> AsCharacter->Mesh->QuerySupportedSockets(SocketNames);
>     
> // Min
> FVector CurLoc;
> float CurDist = 0;
> float ClosestDistance = -1;
> int32 ClosestVibe = 0;
>     
> // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
> //Check Bones Locations
> for (int32 Itr = 0; Itr < SocketNames.Num(); Itr++ )
> {
> //Is a Bone not a socket?
> if(SocketNames[Itr].Type == EComponentSocketType::Bone) continue;
> // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
>         
> CurLoc = AsCharacter->Mesh->GetSocketLocation(SocketNames[Itr].Name);
>         
> //Dist
> CurDist = FVector::Dist(OutImpactPoint, CurLoc);
>         
> //Min
> if (ClosestDistance < 0 || ClosestDistance >= CurDist)
> {
> ClosestVibe = Itr;
> ClosestDistance = CurDist;
> }
> }
>     
> //Name
> ClosestSocketName = SocketNames[ClosestVibe].Name;
>     
> //Location
> SocketLocation = AsCharacter->Mesh->GetSocketLocation(ClosestSocketName);
>     
> //Valid
> IsValid = true;
>     
> //Actor
> return HitActor;
> }
>     
> //Most HUD stuff is in floats so I do the conversion internally
> bool UVictoryBPFunctionLibrary::Viewport__SetMousePosition(const APlayerController* ThePC, const float& PosX, const float& PosY)
> {
> if (!ThePC) return false;
> // ~~~~~~~~~~~~~
>     
> //Get Player
> const ULocalPlayer * VictoryPlayer = Cast<ULocalPlayer>(ThePC->Player); 
> //PlayerController::Player is UPlayer
>            
> if (!VictoryPlayer) return false;
> // ~~~~~~~~~~~~~~~~~~~~
>     
> //get view port ptr
> const UGameViewportClient * VictoryViewportClient = 
> Cast < UGameViewportClient > (VictoryPlayer->ViewportClient);
>         
> if (!VictoryViewportClient) return false;
> // ~~~~~~~~~~~~~~~~~~~~
>      
> FViewport * VictoryViewport = VictoryViewportClient->Viewport;
>     
> if (!VictoryViewport) return false;
> // ~~~~~~~~~~~~~~~~~~~~
>     
> //Set Mouse
> VictoryViewport->SetMouse(int32(PosX), int32(PosY));
>     
> return true;
> }
> 
> APlayerController * UVictoryBPFunctionLibrary::Accessor__GetPlayerController(
> AActor * TheCharacter, 
> bool & IsValid
> )
> {
> IsValid = false;
>     
> //Cast to Character
> ACharacter * AsCharacter = Cast<ACharacter>(TheCharacter);
> if (!AsCharacter) return NULL;
>     
> //cast to PC
> APlayerController * ThePC = Cast < APlayerController > (AsCharacter->GetController());
>     
> if (!ThePC ) return NULL;
>     
> IsValid = true;
> return ThePC;
> }
>     
> bool UVictoryBPFunctionLibrary::Viewport__GetCenterOfViewport(const APlayerController * ThePC, float & PosX, float & PosY)
> {
> if (!ThePC) return false;
> // ~~~~~~~~~~~~~
>     
> //Get Player
> const ULocalPlayer * VictoryPlayer = Cast<ULocalPlayer>(ThePC->Player); 
> //PlayerController::Player is UPlayer
>            
> if (!VictoryPlayer) return false;
> // ~~~~~~~~~~~~~~~~~~~~
>     
> //get view port ptr
> const UGameViewportClient * VictoryViewportClient = 
> Cast < UGameViewportClient > (VictoryPlayer->ViewportClient);
>         
> if (!VictoryViewportClient) return false;
> // ~~~~~~~~~~~~~~~~~~~~
>      
> FViewport * VictoryViewport = VictoryViewportClient->Viewport;
>     
> if (!VictoryViewport) return false;
> // ~~~~~~~~~~~~~~~~~~~~
>     
> //Get Size
> FIntPoint Size = VictoryViewport->GetSizeXY();
>     
> //Center
> PosX = Size.X / 2;
> PosY = Size.Y / 2;
>     
> return true;
> }
> 
> bool UVictoryBPFunctionLibrary::Viewport__GetMousePosition(const APlayerController * ThePC, float & PosX, float & PosY)
> {
> if (!ThePC) return false;
> // ~~~~~~~~~~~~~
>     
> //Get Player
> const ULocalPlayer * VictoryPlayer = Cast<ULocalPlayer>(ThePC->Player); 
> //PlayerController::Player is UPlayer
>            
> if (!VictoryPlayer) return false;
> // ~~~~~~~~~~~~~~~~~~~~
>     
> //get view port ptr
> const UGameViewportClient * VictoryViewportClient = 
> Cast < UGameViewportClient > (VictoryPlayer->ViewportClient);
>         
> if (!VictoryViewportClient) return false;
> // ~~~~~~~~~~~~~~~~~~~~
>      
> FViewport * VictoryViewport = VictoryViewportClient->Viewport;
>     
> if (!VictoryViewport) return false;
> // ~~~~~~~~~~~~~~~~~~~~
>     
> PosX = float(VictoryViewport->GetMouseX());
> PosY = float(VictoryViewport->GetMouseY());
>     
> return true;
> }
> 
> bool UVictoryBPFunctionLibrary::Physics__EnterRagDoll(AActor * TheCharacter)
> {
> ACharacter * AsCharacter = Cast<ACharacter>(TheCharacter);
> if (!AsCharacter) return false;
>     
> //Mesh?
> if (!AsCharacter->Mesh) return false;
>     
> //Physics Asset?
> if(!AsCharacter->Mesh->GetPhysicsAsset()) return false;
>     
> //Victory Ragdoll
> AsCharacter->Mesh->SetPhysicsBlendWeight(1);
> AsCharacter->Mesh->bBlendPhysics = true;
>     
> return true;
> }
> 
> bool UVictoryBPFunctionLibrary::Physics__LeaveRagDoll(
> AActor* TheCharacter,
> float HeightAboveRBMesh,
> const FVector& InitLocation, 
> const FRotator& InitRotation
> ){
> ACharacter * AsCharacter = Cast<ACharacter>(TheCharacter);
> if (!AsCharacter) return false;
>     
> //Mesh?
> if (!AsCharacter->Mesh) return false;
>     
> //Set Actor Location to Be Near Ragdolled Mesh
> //Calc Ref Bone Relative Pos for use with IsRagdoll
> TArray<FName> BoneNames;
> AsCharacter->Mesh->GetBoneNames(BoneNames);
> if(BoneNames.Num() > 0)
> {
> AsCharacter->SetActorLocation(FVector(0,0,HeightAboveRBMesh) + AsCharacter->Mesh->GetBoneLocation(BoneNames[0]));
> }
>     
> //Exit Ragdoll
> AsCharacter->Mesh->SetPhysicsBlendWeight(0); //1 for full physics
> 
> //Restore Defaults
> AsCharacter->Mesh->SetRelativeRotation(InitRotation);
> AsCharacter->Mesh->SetRelativeLocation(InitLocation);
>     
> //Set Falling After Final Capsule Relocation
> if(AsCharacter->CharacterMovement) AsCharacter->CharacterMovement->SetMovementMode(MOVE_Falling);    
>     
> return true;
> }    
> 
> bool UVictoryBPFunctionLibrary::Physics__IsRagDoll(AActor* TheCharacter)
> {
> ACharacter * AsCharacter = Cast<ACharacter>(TheCharacter);
> if (!AsCharacter) return false;
>     
> //Mesh?
> if (!AsCharacter->Mesh) return false;
>     
> return AsCharacter->Mesh->IsAnySimulatingPhysics();
> }    
> 
> bool UVictoryBPFunctionLibrary::Physics__GetLocationofRagDoll(AActor* TheCharacter, FVector& RagdollLocation)
> {
> ACharacter * AsCharacter = Cast<ACharacter>(TheCharacter);
> if (!AsCharacter) return false;
>     
> //Mesh?
> if (!AsCharacter->Mesh) return false;
>     
> TArray<FName> BoneNames;
> AsCharacter->Mesh->GetBoneNames(BoneNames);
> if(BoneNames.Num() > 0)
> {
> RagdollLocation = AsCharacter->Mesh->GetBoneLocation(BoneNames[0]);
> }
> else return false;
>     
> return true;
> }
> 
> bool UVictoryBPFunctionLibrary::Physics__InitializeVictoryRagDoll(
> AActor* TheCharacter, 
> FVector& InitLocation, 
> FRotator& InitRotation
> ){
> ACharacter * AsCharacter = Cast<ACharacter>(TheCharacter);
> if (!AsCharacter) return false;
>     
> //Mesh?
> if (!AsCharacter->Mesh) return false;
>     
> InitLocation = AsCharacter->Mesh->GetRelativeTransform().GetLocation();
> InitRotation = AsCharacter->Mesh->GetRelativeTransform().Rotator();
>     
> return true;
> }
> 
> bool UVictoryBPFunctionLibrary::Physics__UpdateCharacterCameraToRagdollLocation(
> AActor* TheCharacter, 
> float HeightOffset,
> float InterpSpeed
> ){
> ACharacter * AsCharacter = Cast<ACharacter>(TheCharacter);
> if (!AsCharacter) return false;
>     
> //Mesh?
> if (!AsCharacter->Mesh) return false;
>     
> //Ragdoll?
> if(!AsCharacter->Mesh->IsAnySimulatingPhysics()) return false;
>     
> FVector RagdollLocation = FVector(0,0,0);
> TArray<FName> BoneNames;
> AsCharacter->Mesh->GetBoneNames(BoneNames);
> if(BoneNames.Num() > 0)
> {
> RagdollLocation = AsCharacter->Mesh->GetBoneLocation(BoneNames[0]);
> }
>     
> //Interp
> RagdollLocation = FMath::VInterpTo(AsCharacter->GetActorLocation(), RagdollLocation + FVector(0,0,HeightOffset), AsCharacter->()->DeltaTimeSeconds, InterpSpeed);
> 
> //Set Loc
> AsCharacter->SetActorLocation(RagdollLocation);
>     
> return true;
> }
> /*
> bool UVictoryBPFunctionLibrary::Accessor__GetSocketLocalTransform(const USkeletalMeshComponent* Mesh, FTransform& LocalTransform, FName SocketName)
> {
> if(!Mesh) return false;
>     
> LocalTransform = Mesh->GetSocketLocalTransform(SocketName);
>     
> return true;
> }
> */
> 
> void UVictoryBPFunctionLibrary::StringConversion__GetFloatAsStringWithPrecision(float TheFloat, FString & FloatString, uint8 Precision)
> {
> const TCHAR* TheDot = TEXT(".");
>         
> FloatString = FString::SanitizeFloat(TheFloat);
>     
> //No . ?
> if( ! FloatString.Contains(TheDot))
> {
> return;
> }
>     
> //Split
> FString LeftS;
> FString RightS;
>     
> FloatString.Split(TheDot,&LeftS,&RightS);
>     
> //Add back to LeftS
> LeftS += TheDot;
>     
> //Get the Single Number after the precision amount
> // so in .1273, get the 7
> FString RightSFirstTruncated = "";
> if(RightS.Len() - 1 >= Precision)
> {
> RightSFirstTruncated = RightS.Mid(Precision,1);
> }
>     
> //Truncate the RightS
> // .1273 becomes .12 with precision 2
> RightS = RightS.Left(Precision);
>     
> //Round Up if There was any truncated portion
> if(RightSFirstTruncated != "")
> {
> if(FCString::Atod(*RightSFirstTruncated) >= 5)
> {
> //.1273 becomes .13
> RightS = FString::FromInt(FCString::Atod(*RightS) + 1);
> }
> }
>     
> FloatString = LeftS + RightS;
> }
> 
> bool UVictoryBPFunctionLibrary::LensFlare__GetLensFlareOffsets(
> APlayerController* PlayerController,
> AActor* LightSource, 
> float& PitchOffset, 
> float& YawOffset, 
> float& RollOffset
> ){
> if(!PlayerController) return false;
> if(!LightSource) return false;
> // ~~~~~~~~~~~~~~~~~~~
>     
> //angle from player to light source
> const FRotator AngleToLightSource = (LightSource->GetActorLocation() - PlayerController->GetFocalLocation()).Rotation();
>     
> const FRotator Offsets = AngleToLightSource - PlayerController->GetControlRotation();
>     
> PitchOffset = Offsets.Pitch;
> YawOffset = Offsets.Yaw;
> RollOffset = Offsets.Roll;
> return true;
> }
> 
> /*
> bool UVictoryBPFunctionLibrary::AnimatedVertex__GetAnimatedVertexLocations(
> USkeletalMeshComponent* Mesh, 
> TArray<FVector>& Locations
> )
> {
> if(!Mesh) return false;
> if(!Mesh->SkeletalMesh) return false;
> // ~~~~~~~~~
>     
> Locations.Empty(); 
> // ~~~~~~~~~~~~~~~~~~~
>     
> // Get the Verticies For Each Bone, Most Influenced by That Bone!
> // Vertices are in Bone space.
> TArray<FBoneVertInfo> BoneVertexInfos;
> FSkeletalMeshTools::CalcBoneVertInfos(Mesh->SkeletalMesh,BoneVertexInfos,true); //true = only dominant influence
>     
> // ~~~~~~~~~~~~~~~~~~~~~
> int32 VertItr = 0;
> FBoneVertInfo* EachBoneVertInfo;
> FVector BoneWorldPos;
> int32 NumOfVerticies;
> FTransform RV_Transform;
> FVector RV_Vect;
> for(int32 Itr=0; Itr < BoneVertexInfos.Num() ; Itr++)
> {
> EachBoneVertInfo = &BoneVertexInfos[Itr];
> // ~~~~~~~~~~~~~~~~~~~~~~~~
>         
> //Bone Transform To World Space, and Location
> RV_Transform = Mesh->GetBoneTransform(Itr);
> BoneWorldPos = RV_Transform.GetLocation();
>         
> //How many verts is bone influencing?
> NumOfVerticies = EachBoneVertInfo->Positions.Num();
> for(VertItr=0; VertItr < NumOfVerticies ; VertItr++)
> {
> //Animated Vertex Location!
> Locations.Add( BoneWorldPos + RV_Transform.TransformVector(EachBoneVertInfo->Positions[VertItr]) );
> }
> }
>     
> // ~~~Cleanup~~~
> BoneVertexInfos.Empty();
>     
> return true;
> }
>     
> bool UVictoryBPFunctionLibrary::AnimatedVertex__GetAnimatedVertexLocationsAndNormals(
> USkeletalMeshComponent* Mesh, 
> TArray<FVector>& Locations, 
> TArray<FVector>& Normals 
> )
> {
> if(!Mesh) return false;
> if(!Mesh->SkeletalMesh) return false;
> // ~~~~~~~~~
>     
> Locations.Empty(); 
> Normals.Empty();
> // ~~~~~~~~~~~~~~~~~~~
>     
> // Get the Verticies For Each Bone, Most Influenced by That Bone!
> // Vertices are in Bone space.
> TArray<FBoneVertInfo> BoneVertexInfos;
> FSkeletalMeshTools::CalcBoneVertInfos(Mesh->SkeletalMesh,BoneVertexInfos,true); //true = only dominant influence
>     
> // ~~~~~~~~~~~~~~~~~~~~~
> int32 VertItr = 0;
> FBoneVertInfo* EachBoneVertInfo;
> FVector BoneWorldPos;
> int32 NumOfVerticies;
> FTransform RV_Transform;
> FVector RV_Vect;
> for(int32 Itr=0; Itr < BoneVertexInfos.Num() ; Itr++)
> {
> EachBoneVertInfo = &BoneVertexInfos[Itr];
> // ~~~~~~~~~~~~~~~~~~~~~~~~
>         
> //Bone Transform To World Space, and Location
> RV_Transform = Mesh->GetBoneTransform(Itr);
> BoneWorldPos = RV_Transform.GetLocation();
>         
> //How many verts is bone influencing?
> NumOfVerticies = EachBoneVertInfo->Positions.Num();
> for(VertItr=0; VertItr < NumOfVerticies ; VertItr++)
> {
> //Animated Vertex Location!
> Locations.Add( BoneWorldPos + RV_Transform.TransformVector(EachBoneVertInfo->Positions[VertItr]) );
>         
> //Animated Vertex Normal for rotating the emitter!!!!!
> Normals.Add( RV_Transform.TransformVector(EachBoneVertInfo->Normals[VertItr]) );
> }
> }
>     
> // ~~~Cleanup~~~
> BoneVertexInfos.Empty();
>     
> return true;
> }
>     
> bool UVictoryBPFunctionLibrary::AnimatedVertex__DrawAnimatedVertexLocations(
> UObject* WorldContextObject,
> USkeletalMeshComponent* Mesh, 
> float ChanceToSkipAVertex, 
> bool DrawNormals
> )
> {
> UWorld* const TheWorld = GEngine->GetWorldFromContextObject(WorldContextObject);
>     
> if(!TheWorld) return false;
> if(!Mesh) return false;
> if(!Mesh->SkeletalMesh) return false;
> // ~~~~~~~~~
>     
> // Get the Verticies For Each Bone, Most Influenced by That Bone!
> // Vertices are in Bone space.
> TArray<FBoneVertInfo> BoneVertexInfos;
> FSkeletalMeshTools::CalcBoneVertInfos(Mesh->SkeletalMesh,BoneVertexInfos,true); //true = only dominant influence
>     
> // ~~~~~~~~~~~~~~~~~~~~~
> int32 VertItr = 0;
> FBoneVertInfo* EachBoneVertInfo;
> FVector BoneWorldPos;
> int32 NumOfVerticies;
> FTransform RV_Transform;
> FVector RV_Vect;
>     
> const FColor HappyRed = FColor(255,0,0);
> const FColor HappyBlue = FColor(0,0,255);
> for(int32 Itr=0; Itr < BoneVertexInfos.Num() ; Itr++)
> {
> EachBoneVertInfo = &BoneVertexInfos[Itr];
> // ~~~~~~~~~~~~~~~~~~~~~~~~
>         
> //Bone Transform To World Space, and Location
> RV_Transform = Mesh->GetBoneTransform(Itr);
> BoneWorldPos = RV_Transform.GetLocation();
>         
> //How many verts is bone influencing?
> NumOfVerticies = EachBoneVertInfo->Positions.Num();
> for(VertItr=0; VertItr < NumOfVerticies ; VertItr++)
> {
> if(FMath::FRandRange(0, 1) < ChanceToSkipAVertex) continue;
> // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
>             
> RV_Vect = BoneWorldPos + RV_Transform.TransformVector(EachBoneVertInfo->Positions[VertItr]);
>             
> DrawDebugPoint(
> TheWorld, 
> RV_Vect,
> 12, 
> HappyRed, 
> false, 
> 0.03
> );
>             
> if(DrawNormals)
> {
> DrawDebugLine(
> TheWorld, 
> RV_Vect, 
> RV_Vect + RV_Transform.TransformVector(EachBoneVertInfo->Normals[VertItr] * 64),  
> HappyBlue, 
> false, 
> 0.03, 
> 0, 
> 1
> );
> }
> }
> }
>     
> // ~~~Cleanup~~~
> BoneVertexInfos.Empty();
>     
> return true;
> }
>     
> bool UVictoryBPFunctionLibrary::AnimatedVertex__GetCharacterAnimatedVertexLocations(
> AActor* TheCharacter, 
> TArray<FVector>& Locations
> )
> {
> ACharacter * AsCharacter = Cast<ACharacter>(TheCharacter);
> if (!AsCharacter) return false;
>     
> USkeletalMeshComponent* Mesh = AsCharacter->Mesh;
> if (!Mesh) return false;
> // ~~~~~~~~~~~~~~~~~~~~
>     
> AnimatedVertex__GetAnimatedVertexLocations(Mesh,Locations);
>     
> return true;
> }
>     
> bool UVictoryBPFunctionLibrary::AnimatedVertex__GetCharacterAnimatedVertexLocationsAndNormals(
> AActor* TheCharacter, 
> TArray<FVector>& Locations, 
> TArray<FVector>& Normals 
> )
> {
> ACharacter * AsCharacter = Cast<ACharacter>(TheCharacter);
> if (!AsCharacter) return false;
>     
> USkeletalMeshComponent* Mesh = AsCharacter->Mesh;
> if (!Mesh) return false;
> // ~~~~~~~~~~~~~~~~~~~~
>     
> AnimatedVertex__GetAnimatedVertexLocationsAndNormals(Mesh,Locations,Normals);
>     
> return true;
> }
>     
> bool UVictoryBPFunctionLibrary::AnimatedVertex__DrawCharacterAnimatedVertexLocations(
> AActor* TheCharacter, 
> float ChanceToSkipAVertex, 
> bool DrawNormals
> )
> {    
> ACharacter * AsCharacter = Cast<ACharacter>(TheCharacter);
> if (!AsCharacter) return false;
>     
> USkeletalMeshComponent* Mesh = AsCharacter->Mesh;
> if (!Mesh) return false;
> // ~~~~~~~~~~~~~~~~~~~~
>     
> AnimatedVertex__DrawAnimatedVertexLocations(TheCharacter,Mesh,ChanceToSkipAVertex,DrawNormals);
>     
> return true;
> }
> */
> 
> //SMA Version
> float UVictoryBPFunctionLibrary::DistanceToSurface__DistaceOfPointToMeshSurface(AStaticMeshActor* TheSMA, const FVector& TestPoint, FVector& ClosestSurfacePoint)
> {
> if(!TheSMA) return -1;
> if(!TheSMA->StaticMeshComponent) return -1;
> // ~~~~~~~~~~
>     
> //Dist of pt to Surface, retrieve closest Surface Point to Actor
> return TheSMA->StaticMeshComponent->GetDistanceToCollision(TestPoint, ClosestSurfacePoint);
> }
> 
> bool UVictoryBPFunctionLibrary::Mobility__SetSceneCompMobility(
> USceneComponent* SceneComp,
> EComponentMobility::Type NewMobility
> )
> {
> if(!SceneComp) return false;
> // ~~~~~~~~~~~
>     
> SceneComp->SetMobility(NewMobility);
>     
> return true;
> }
> 
> // ~~~~~~~~~~~~~~~~~~
> // FullScreen
> // ~~~~~~~~~~~~~~~~~~    
> TEnumAsByte<EJoyGraphicsFullScreen::Type> UVictoryBPFunctionLibrary::JoyGraphicsSettings__FullScreen_Get()
> {
> return TEnumAsByte<EJoyGraphicsFullScreen::Type>(JoyGraphics_FullScreen_GetFullScreenType());
> }
>       
> void UVictoryBPFunctionLibrary::JoyGraphicsSettings__FullScreen_Set(TEnumAsByte<EJoyGraphicsFullScreen::Type> NewSetting)
> {  
> JoyGraphics_FullScreen_SetFullScreenType(NewSetting.GetValue()); 
> }
> 
> // ~~~~~~~~~~~~~~~~~~~~~~~~~~~
> // ~~~~~~~~~~~~~~~~~~~~~~~~~~~
> // ~~~~~~~~~~~~~~~~~~~~~~~~~~~
> // Contributed by Others
> 
> /**
> * Contributed by: SaxonRah
> * Better random numbers. Seeded with a random device. if the random device's entropy is 0; defaults to current for seed.
> * can override with seed functions;
> */
> //----------------------------------------------------------------------------------------------BeginRANDOM
> std::random_device rd;        
> unsigned seed = std::chrono::system_clock::now().time_since_epoch().count();
> 
> std::mt19937 rand_MT;
> std::default_random_engine rand_DRE;
> 
> /** Construct a random device and set seed for engines dependent on entropy */
> void UVictoryBPFunctionLibrary::constructRand()
> {
> seed = std::chrono::system_clock::now().time_since_epoch().count();
> 
> if (rd.entropy() == 0)
> {
> seedRand(seed);
> }else{
> seedRand(rd());
> }
> }
> /** Set seed for Rand */
> void UVictoryBPFunctionLibrary::seedRand(int32 _seed)
> {
> seed = _seed;
> }
> 
> /** Set seed with for Rand */
> void UVictoryBPFunctionLibrary::seedRandWithTime()
> {
> seed = std::chrono::system_clock::now().time_since_epoch().count();
> }
> 
> /** Set seed with entropy for Rand */
> void UVictoryBPFunctionLibrary::seedRandWithEntropy()
> {
> seedRand(rd());
> }
> 
> /** Random Bool - Bernoulli distribution */
> bool UVictoryBPFunctionLibrary::RandBool_Bernoulli(float fBias)
> {
> std::bernoulli_distribution dis(fBias);
> return dis(rand_DRE);
> }
> 
> /** Random Integer - Uniform distribution */
> int32 UVictoryBPFunctionLibrary::RandInt_uniDis()
> {
> std::uniform_int_distribution<int32> dis(0, 1);
> return dis(rand_DRE);
> }
> /** Random Integer - Uniform distribution */
> int32 UVictoryBPFunctionLibrary::RandInt_MINMAX_uniDis(int32 iMin, int32 iMax)
> {
> std::uniform_int_distribution<int32> dis(iMin, iMax);
> return dis(rand_DRE);
> }
> 
> /** Random Float - Zero to One Uniform distribution */
> float UVictoryBPFunctionLibrary::RandFloat_uniDis()
> {
> std::uniform_real_distribution<float> dis(0, 1);
> return dis(rand_DRE);
> }
> /** Random Float - MIN to Uniform distribution */
> float UVictoryBPFunctionLibrary::RandFloat_MINMAX_uniDis(float iMin, float iMax)
> {
> std::uniform_real_distribution<float> dis(iMin, iMax);
> return dis(rand_DRE);
> }
> 
> /** Random Bool - Bernoulli distribution - Mersenne Twister */
> bool UVictoryBPFunctionLibrary::RandBool_Bernoulli_MT(float fBias)
> {
> std::bernoulli_distribution dis(fBias);
> return dis(rand_MT);
> }
> 
> /** Random Integer - Uniform distribution - Mersenne Twister */
> int32 UVictoryBPFunctionLibrary::RandInt_uniDis_MT()
> {
> std::uniform_int_distribution<int32> dis(0, 1);
> return dis(rand_MT);
> }
> /** Random Integer - Uniform distribution - Mersenne Twister */
> int32 UVictoryBPFunctionLibrary::RandInt_MINMAX_uniDis_MT(int32 iMin, int32 iMax)
> {
> std::uniform_int_distribution<int32> dis(iMin, iMax);
> return dis(rand_MT);
> }
> 
> /** Random Float - Zero to One Uniform distribution - Mersenne Twister */
> float UVictoryBPFunctionLibrary::RandFloat_uniDis_MT()
> {
> std::uniform_real_distribution<float> dis(0, 1);
> return dis(rand_MT);
> }
> /** Random Float - MIN to Uniform distribution - Mersenne Twister */
> float UVictoryBPFunctionLibrary::RandFloat_MINMAX_uniDis_MT(float iMin, float iMax)
> {
> std::uniform_real_distribution<float> dis(iMin, iMax);
> return dis(rand_MT);
> }
> //----------------------------------------------------------------------------------------------ENDRANDOM
> 
> void UVictoryBPFunctionLibrary::String__ExplodeString(TArray<FString>& OutputStrings, FString InputString, FString Separator, int32 limit, bool bTrimElements)
> {
> OutputStrings.Empty();
> // ~~~~~~~~~~~
>     
> if (InputString.Len() > 0 && Separator.Len() > 0) {
> int32 StringIndex = 0;
> int32 SeparatorIndex = 0;
> 
> FString Section = "";
> FString Extra = "";
> 
> int32 PartialMatchStart = -1;
> 
> while (StringIndex < InputString.Len()) {
> 
> if (InputString[StringIndex] == Separator[SeparatorIndex]) {
> if (SeparatorIndex == 0) {
> //A new partial match has started.
> PartialMatchStart = StringIndex;
> }
> Extra.AppendChar(InputString[StringIndex]);
> if (SeparatorIndex == (Separator.Len() - 1)) {
> //We have matched the entire separator.
> SeparatorIndex = 0;
> PartialMatchStart = -1;
> if (bTrimElements == true) {
> OutputStrings.Add(FString(Section).Trim().TrimTrailing());
> }
> else {
> OutputStrings.Add(FString(Section));
> }
> 
> //if we have reached the limit, stop.
> if (limit > 0 && OutputStrings.Num() >= limit) 
> {
> return;
> // ~~~~
> }
> 
> Extra.Empty();
> Section.Empty();
> }
> else {
> ++SeparatorIndex;
> }
> }
> else {
> //Not matched.
> //We should revert back to PartialMatchStart+1 (if there was a partial match) and clear away extra.
> if (PartialMatchStart >= 0) {
> StringIndex = PartialMatchStart;
> PartialMatchStart = -1;
> Extra.Empty();
> SeparatorIndex = 0;
> }
> Section.AppendChar(InputString[StringIndex]);
> }
> 
> ++StringIndex;
> }
> 
> //If there is anything left in Section or Extra. They should be added as a new entry.
> if (bTrimElements == true) {
> OutputStrings.Add(FString(Section + Extra).Trim().TrimTrailing());
> }
> else {
> OutputStrings.Add(FString(Section + Extra));
> }
> 
> Section.Empty();
> Extra.Empty();
> }
> }
> 
> UTexture2D* UVictoryBPFunctionLibrary::GetTexture2DFromFile(const FString& FilePath)
> {
> UTexture2D* Texture = NULL;
> 
> FString TexturePath = FilePath;//FPaths::GameContentDir( ) + TEXT( "../Data/" ) + TextureFilename;
> TArray<uint8> FileData;
> 
> /* Load DDS texture */
> if( FFileHelper::LoadFileToArray( FileData, *TexturePath, 0 ) )
> {
> FDDSLoadHelper DDSLoadHelper( &FileData 0 ], FileData.Num( ) );
> if( DDSLoadHelper.IsValid2DTexture( ) )
> {
> int32 NumMips = DDSLoadHelper.ComputeMipMapCount( );
> EPixelFormat Format = DDSLoadHelper.ComputePixelFormat( );
> int32 BlockSize = 16;
> 
> if( NumMips == 0 )
> {
> NumMips = 1;
> }
> 
> if( Format == PF_DXT1 )
> {
> BlockSize = 8;
> }
> 
> /* Create transient texture */
> Texture = UTexture2D::CreateTransient( DDSLoadHelper.DDSHeader->dwWidth, DDSLoadHelper.DDSHeader->dwHeight, Format );
>             
> #if WITH_EDITOR
> Texture->MipGenSettings = TMGS_LeaveExistingMips;
> #endif //WITH_EDITOR
>             
> Texture->PlatformData->NumSlices = 1;
> Texture->NeverStream = true;
> //Texture->Rename( );
> 
> /* Get pointer to actual data */
> uint8* DataPtr = (uint8*) DDSLoadHelper.GetDDSDataPointer( );
> 
> uint32 CurrentWidth = DDSLoadHelper.DDSHeader->dwWidth;
> uint32 CurrentHeight = DDSLoadHelper.DDSHeader->dwHeight;
> 
> /* Iterate through mips */
> for( int32 i = 0; i < NumMips; i++ )
> {
> /* Lock to 1x1 as smallest size */
> CurrentWidth = ( CurrentWidth < 1 ) ? 1 : CurrentWidth;
> CurrentHeight = ( CurrentHeight < 1 ) ? 1 : CurrentHeight;
> 
> /* Get number of bytes to read */
> int32 NumBytes = CurrentWidth * CurrentHeight * 4;
> if( Format == PF_DXT1 || Format == PF_DXT3 || Format == PF_DXT5 )
> {
> /* Compressed formats */
> NumBytes = ( ( CurrentWidth + 3 ) / 4 ) * ( ( CurrentHeight + 3 ) / 4 ) * BlockSize;
> }
> 
> /* Write to existing mip */
> if( i < Texture->PlatformData->Mips.Num( ) )
> {
> FTexture2DMipMap& Mip = Texture->PlatformData->Mips i ];
> 
> void* Data = Mip.BulkData.Lock( LOCK_READ_WRITE );
> FMemory::Memcpy( Data, DataPtr, NumBytes );
> Mip.BulkData.Unlock( );
> }
> 
> /* Add new mip */
> else
> {
> FTexture2DMipMap* Mip = new( Texture->PlatformData->Mips ) FTexture2DMipMap( );
> Mip->SizeX = CurrentWidth;
> Mip->SizeY = CurrentHeight;
> 
> Mip->BulkData.Lock( LOCK_READ_WRITE );
> Mip->BulkData.Realloc( NumBytes );
> Mip->BulkData.Unlock( );
> 
> void* Data = Mip->BulkData.Lock( LOCK_READ_WRITE );
> FMemory::Memcpy( Data, DataPtr, NumBytes );
> Mip->BulkData.Unlock( );
> }
> 
> /* Set next mip level */
> CurrentWidth /= 2;
> CurrentHeight /= 2;
> 
> DataPtr += NumBytes;
> }
> 
> Texture->UpdateResource( );
> }
> }
> 
> return Texture;
> }
> 
> class UAudioComponent* UVictoryBPFunctionLibrary::PlaySoundAttachedFromFile(const FString& FilePath, class USceneComponent* AttachToComponent, FName AttachPointName, FVector Location, EAttachLocation::Type LocationType, bool bStopWhenAttachedToDestroyed, float VolumeMultiplier, float PitchMultiplier, float StartTime, class USoundAttenuation* AttenuationSettings)
> {    
> USoundWave* sw = GetSoundWaveFromFile(FilePath);
> 
> if (!sw)
> return NULL;
> 
> return UGameplayStatics::PlaySoundAttached(sw, AttachToComponent, AttachPointName, Location, LocationType, bStopWhenAttachedToDestroyed, VolumeMultiplier, PitchMultiplier, StartTime, AttenuationSettings);
> }
> 
> void UVictoryBPFunctionLibrary::PlaySoundAtLocationFromFile(UObject* WorldContextObject, const FString& FilePath, FVector Location, float VolumeMultiplier, float PitchMultiplier, float StartTime, class USoundAttenuation* AttenuationSettings)
> {
> USoundWave* sw = GetSoundWaveFromFile(FilePath);
> 
> if (!sw)
> return;
> 
> UGameplayStatics::PlaySoundAtLocation(WorldContextObject, sw, Location, VolumeMultiplier, PitchMultiplier, StartTime, AttenuationSettings);
> }
> 
> class USoundWave* UVictoryBPFunctionLibrary::GetSoundWaveFromFile(const FString& FilePath)
> {
> USoundWave* sw = (USoundWave*)StaticConstructObject(USoundWave::StaticClass());
> 
> if (!sw)
> return NULL;
> 
> //* If true the song was successfully loaded
> bool loaded = false;
> 
> //* loaded song file (binary, encoded)
> TArray < uint8 > rawFile;
> 
> loaded = FFileHelper::LoadFileToArray(rawFile, FilePath.GetCharArray().GetData());
> 
> if (loaded)
> {
> FByteBulkData* bulkData = &sw->CompressedFormatData.GetFormat(TEXT("OGG"));
> 
> bulkData->Lock(LOCK_READ_WRITE);
> FMemory::Memcpy(bulkData->Realloc(rawFile.Num()), rawFile.GetData(), rawFile.Num());
> bulkData->Unlock();
> 
> loaded = fillSoundWaveInfo(sw, &rawFile) == 0 ? true : false;
> }
> 
> if (!loaded)
> return NULL;
> 
> return sw;
> }
> 
> int32 UVictoryBPFunctionLibrary::fillSoundWaveInfo(class USoundWave* sw, TArray<uint8>* rawFile)
> {
> FSoundQualityInfo info;
> FVorbisAudioInfo vorbis_obj = FVorbisAudioInfo();
> if (!vorbis_obj.ReadCompressedInfo(rawFile->GetData(), rawFile->Num(), &info))
> {
> //Debug("Can't load header");
> return 1;
> }
> 
> if(!sw) return 1;
> sw->SoundGroup = ESoundGroup::SOUNDGROUP_Default;
> sw->NumChannels = info.NumChannels;
> sw->Duration = info.Duration;
> sw->RawPCMDataSize = info.SampleDataSize;
> sw->SampleRate = info.SampleRate;
> 
> return 0;
> }
> 
>       
> int32 UVictoryBPFunctionLibrary::findSource(class USoundWave* sw, class FSoundSource* out_audioSource)
> {
> FAudioDevice* device = GEngine ? GEngine->GetAudioDevice() : NULL; //gently ask for the audio device
> 
> FActiveSound* activeSound;
> FSoundSource* audioSource;
> FWaveInstance* sw_instance;
> if (!device)
> {
> activeSound = NULL;
> audioSource = NULL;
> out_audioSource = audioSource;
> return -1;
> }
> 
> TArray<FActiveSound*> tmpActualSounds = device->GetActiveSounds();
> if (tmpActualSounds.Num())
> {
> for (auto activeSoundIt(tmpActualSounds.CreateIterator()); activeSoundIt; ++activeSoundIt)
> {
> activeSound = *activeSoundIt;
> for (auto WaveInstanceIt(activeSound->WaveInstances.CreateIterator()); WaveInstanceIt; ++WaveInstanceIt)
> {
> sw_instance = WaveInstanceIt.Value();
> if (sw_instance->WaveData->CompressedDataGuid == sw->CompressedDataGuid)
> {
> audioSource = device->WaveInstanceSourceMap.FindRef(sw_instance);
> out_audioSource = audioSource;
> return 0;
> }
> }
> }
> }
> 
> audioSource = NULL;
> activeSound = NULL;
> out_audioSource = audioSource;
> return -2;
> }
> 
> //TESTING
> static void TESTINGInternalDrawDebugCircle(const UWorld* InWorld, const FMatrix& TransformMatrix, float Radius, int32 Segments, const FColor& Color, bool bPersistentLines, float LifeTime, uint8 DepthPriority, float Thickness=0)
> {
> // is how you can make cpp only internal functions!
>     
> }
> 
> ```

---

_[View the full topic](https://forums.unrealengine.com/t/39-s-extra-blueprint-nodes-for-you-as-a-plugin-no-c-required/3448)._
