diff --git a/Source/VictoryBPLibrary/Private/VictoryBPFunctionLibrary.cpp b/Source/VictoryBPLibrary/Private/VictoryBPFunctionLibrary.cpp index db8b5ee..75abf22 100644 --- a/Source/VictoryBPLibrary/Private/VictoryBPFunctionLibrary.cpp +++ b/Source/VictoryBPLibrary/Private/VictoryBPFunctionLibrary.cpp @@ -1,24 +1,24 @@ /* By Rama */ - + #include "VictoryBPLibraryPrivatePCH.h" - + #include "VictoryBPFunctionLibrary.h" //Foreground Window check, clipboard copy/paste #include "Runtime/ApplicationCore/Public/HAL/PlatformApplicationMisc.h" -//FGPUDriverInfo GPU +//FGPUDriverInfo GPU #include "Runtime/Core/Public/GenericPlatform/GenericPlatformDriver.h" - + //MD5 Hash #include "Runtime/Core/Public/Misc/SecureHash.h" #include "StaticMeshResources.h" #include "HeadMountedDisplay.h" - + #include "GenericTeamAgentInterface.h" //For PIE error messages @@ -71,24 +71,24 @@ // Saxon Rah Random Nodes // Chrono and Random -//Order Matters, +//Order Matters, // has to be after PhysX includes to avoid isfinite name definition issues #include #include - + #include - + /* - ~~~ Rama File Operations CopyRight ~~~ - - If you use any of my file operation code below, + ~~~ Rama File Operations CopyRight ~~~ + + If you use any of my file operation code below, please credit me somewhere appropriate as "Rama" */ template class PlatformFileFunctor : public IPlatformFile::FDirectoryVisitor //GenericPlatformFile.h { public: - + virtual bool Visit(const TCHAR* FilenameOrDirectory, bool bIsDirectory) override { return Functor(FilenameOrDirectory, bIsDirectory); @@ -116,14 +116,14 @@ static FDateTime GetFileTimeStamp(const FString& File) static void SetTimeStamp(const FString& File, const FDateTime& TimeStamp) { FPlatformFileManager::Get().GetPlatformFile().SetTimeStamp(*File,TimeStamp); -} - +} + //Radial Result Struct struct FFileStampSort { FString* FileName; FDateTime FileStamp; - + FFileStampSort(FString* IN_Name, FDateTime Stamp) : FileName(IN_Name) , FileStamp(Stamp) @@ -133,7 +133,7 @@ struct FFileStampSort //For Array::Sort() FORCEINLINE bool operator< (const FFileStampSort& Left, const FFileStampSort& Right) { - return Left.FileStamp < Right.FileStamp; + return Left.FileStamp < Right.FileStamp; } //Written by Rama, please credit me if you use this code elsewhere @@ -141,10 +141,10 @@ static bool GetFiles(const FString& FullPathOfBaseDir, TArray& Filename { //Format File Extension, remove the "." if present const FString FileExt = FilterByExtension.Replace(TEXT("."),TEXT("")).ToLower(); - + FString Str; auto FilenamesVisitor = MakeDirectoryVisitor( - [&](const TCHAR* FilenameOrDirectory, bool bIsDirectory) + [&](const TCHAR* FilenameOrDirectory, bool bIsDirectory) { //Files if ( ! bIsDirectory) @@ -153,32 +153,32 @@ static bool GetFiles(const FString& FullPathOfBaseDir, TArray& Filename if(FileExt != "") { Str = FPaths::GetCleanFilename(FilenameOrDirectory); - + //Filter by Extension - if(FPaths::GetExtension(Str).ToLower() == FileExt) + if(FPaths::GetExtension(Str).ToLower() == FileExt) { - if(Recursive) + if(Recursive) { FilenamesOut.Push(FilenameOrDirectory); //need whole path for recursive } - else + else { FilenamesOut.Push(Str); } } } - + //Include All Filenames! else { //Just the Directory Str = FPaths::GetCleanFilename(FilenameOrDirectory); - - if(Recursive) + + if(Recursive) { FilenamesOut.Push(FilenameOrDirectory); //need whole path for recursive } - else + else { FilenamesOut.Push(Str); } @@ -187,15 +187,15 @@ static bool GetFiles(const FString& FullPathOfBaseDir, TArray& Filename return true; } ); - if(Recursive) + if(Recursive) { return FPlatformFileManager::Get().GetPlatformFile().IterateDirectoryRecursively(*FullPathOfBaseDir, FilenamesVisitor); } - else + else { return FPlatformFileManager::Get().GetPlatformFile().IterateDirectory(*FullPathOfBaseDir, FilenamesVisitor); } -} +} static bool FileExists(const FString& File) { @@ -209,15 +209,15 @@ static bool RenameFile(const FString& Dest, const FString& Source) { //Make sure file modification time gets updated! SetTimeStamp(Source,FDateTime::Now()); - + return FPlatformFileManager::Get().GetPlatformFile().MoveFile(*Dest,*Source); } - + //Create Directory, Creating Entire Structure as Necessary // so if JoyLevels and Folder1 do not exist in JoyLevels/Folder1/Folder2 // they will be created so that Folder2 can be created! -//This is my solution for fact that trying to create a directory fails +//This is my solution for fact that trying to create a directory fails // if its super directories do not exist static bool VCreateDirectory(FString FolderToMake) //not const so split can be used, and does not damage input { @@ -225,44 +225,44 @@ static bool VCreateDirectory(FString FolderToMake) //not const so split can be u { return true; } - + // Normalize all / and \ to TEXT("/") and remove any trailing TEXT("/") if the character before that is not a TEXT("/") or a colon FPaths::NormalizeDirectoryName(FolderToMake); - + //Normalize removes the last "/", but is needed by algorithm // Guarantees While loop will end in a timely fashion. FolderToMake += "/"; - + FString Base; FString Left; FString Remaining; - + //Split off the Root FolderToMake.Split(TEXT("/"),&Base,&Remaining); Base += "/"; //add root text and Split Text to Base - + while(Remaining != "") { Remaining.Split(TEXT("/"),&Left,&Remaining); - + //Add to the Base Base += Left + FString("/"); //add left and split text to Base - + //Create Incremental Directory Structure! - if ( ! FPlatformFileManager::Get().GetPlatformFile().CreateDirectory(*Base) && + if ( ! FPlatformFileManager::Get().GetPlatformFile().CreateDirectory(*Base) && ! FPlatformFileManager::Get().GetPlatformFile().DirectoryExists(*Base) ) { return false; //~~~~~ } } - + return true; } /* - ~~~ Rama File Operations CopyRight ~~~ - - If you use any of my file operation code above, + ~~~ Rama File Operations CopyRight ~~~ + + If you use any of my file operation code above, please credit me somewhere appropriate as "Rama" */ @@ -274,9 +274,9 @@ static bool VCreateDirectory(FString FolderToMake) //not const so split can be u UVictoryBPFunctionLibrary::UVictoryBPFunctionLibrary(const FObjectInitializer& ObjectInitializer) : Super(ObjectInitializer) { - + } - + //~~~~~~~~~~~~~~~~~~ // Level Generation //~~~~~~~~~~~~~~~~~~ @@ -284,139 +284,139 @@ UVictoryBPFunctionLibrary::UVictoryBPFunctionLibrary(const FObjectInitializer& O /* CHANGE RETURN TYPE TO KISMET (or remove the kismet part) AND THEN GIVE OPTION TO ADD OR SET ROTATION OF A KISMET - + LoadedLevel->LevelTransform.SetRotation(FRotator(0, 120, 0).Quaternion()); - + //Trigger update! GetWorld()->UpdateLevelStreaming(); - + */ ULevelStreaming* UVictoryBPFunctionLibrary::VictoryLoadLevelInstance( - UObject* WorldContextObject, - FString MapFolderOffOfContent, - FString LevelName, + UObject* WorldContextObject, + FString MapFolderOffOfContent, + FString LevelName, int32 InstanceNumber, FVector Location, FRotator Rotation,bool& Success -){ +){ //! See .h deprecation - + /* - Success = false; + Success = false; if(!WorldContextObject) return nullptr; - + UWorld* const World = GEngine->GetWorldFromContextObject(WorldContextObject, EGetWorldErrorMode::ReturnNull); if(!World) return nullptr; //~~~~~~~~~~~ - + //Full Name FString FullName = "/Game/" + MapFolderOffOfContent + "/" + LevelName; - + FName LevelFName = FName(*FullName); - FString PackageFileName = FullName; - + FString PackageFileName = FullName; + ULevelStreamingDynamic* StreamingLevel = NewObject(World, ULevelStreamingDynamic::StaticClass(), NAME_None, RF_Transient, NULL); - + if(!StreamingLevel) { return nullptr; } - + //Long Package Name FString LongLevelPackageName = FPackageName::FilenameToLongPackageName(PackageFileName); - + //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // Here is where a unique name is chosen for the new level asset // Ensure unique names to gain ability to have multiple instances of same level! // <3 Rama - + //Create Unique Name based on BP-supplied instance value FString UniqueLevelPackageName = LongLevelPackageName; UniqueLevelPackageName += "_VictoryInstance_" + FString::FromInt(InstanceNumber); - + //Set! StreamingLevel->SetWorldAssetByPackageName(FName(*UniqueLevelPackageName)); //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - + if (World->IsPlayInEditor()) { FWorldContext WorldContext = GEngine->GetWorldContextFromWorldChecked(World); StreamingLevel->RenameForPIE(WorldContext.PIEInstance); } - + StreamingLevel->LevelColor = FColor::MakeRandomColor(); StreamingLevel->bShouldBeLoaded = true; StreamingLevel->SetShouldBeVisible(true); StreamingLevel->bShouldBlockOnLoad = false; StreamingLevel->bInitiallyLoaded = true; StreamingLevel->bInitiallyVisible = true; - + //Transform StreamingLevel->LevelTransform = FTransform(Rotation,Location); - + StreamingLevel->PackageNameToLoad = LevelFName; - + if (!FPackageName::DoesPackageExist(StreamingLevel->PackageNameToLoad.ToString(), NULL, &PackageFileName)) - { + { return nullptr; } - + //~~~ - + //Actual map package to load StreamingLevel->PackageNameToLoad = FName(*LongLevelPackageName); - + //~~~ - + // Add the new level to world. World->StreamingLevels.Add(StreamingLevel); - + Success = true; return StreamingLevel; */ return nullptr; - } - + } + //~~~~~~~ // AI -//~~~~~~~ +//~~~~~~~ EPathFollowingRequestResult::Type UVictoryBPFunctionLibrary::Victory_AI_MoveToWithFilter( - APawn* Pawn, - const FVector& Dest, + APawn* Pawn, + const FVector& Dest, TSubclassOf FilterClass , - float AcceptanceRadius , + float AcceptanceRadius , bool bProjectDestinationToNavigation , bool bStopOnOverlap , - bool bCanStrafe + bool bCanStrafe ){ - if(!Pawn) + if(!Pawn) { return EPathFollowingRequestResult::Failed; } - + AAIController* AIControl = Cast(Pawn->GetController()); - if(!AIControl) + if(!AIControl) { return EPathFollowingRequestResult::Failed; - } - + } + return AIControl->MoveToLocation( - Dest, + Dest, AcceptanceRadius, bStopOnOverlap, //bStopOnOverlap - true, //bUsePathfinding - bProjectDestinationToNavigation, + true, //bUsePathfinding + bProjectDestinationToNavigation, bCanStrafe, //bCanStrafe FilterClass //<~~~ ); } - + //~~~~~~ //GPU -//~~~~~~ +//~~~~~~ void UVictoryBPFunctionLibrary::Victory_GetGPUInfo(FString& DeviceDescription, FString& Provider, FString& DriverVersion, FString& DriverDate ) -{ +{ FGPUDriverInfo GPUDriverInfo = FPlatformMisc::GetGPUDriverInfo(GRHIAdapterName); - + DeviceDescription = GPUDriverInfo.DeviceDescription; Provider = GPUDriverInfo.ProviderName; DriverVersion = GPUDriverInfo.UserDriverVersion; @@ -425,25 +425,25 @@ void UVictoryBPFunctionLibrary::Victory_GetGPUInfo(FString& DeviceDescription, F //~~~~~~ //Core -//~~~~~~ - +//~~~~~~ + //~~~~~~ //Physics -//~~~~~~ +//~~~~~~ float UVictoryBPFunctionLibrary::GetDistanceToCollision(UPrimitiveComponent* CollisionComponent, const FVector& Point, FVector& ClosestPointOnCollision) { if(!CollisionComponent) return -1; - + return CollisionComponent->GetDistanceToCollision(Point,ClosestPointOnCollision); } float UVictoryBPFunctionLibrary::GetDistanceBetweenComponentSurfaces(UPrimitiveComponent* CollisionComponent1, UPrimitiveComponent* CollisionComponent2, FVector& PointOnSurface1, FVector& PointOnSurface2) { if(!CollisionComponent1 || !CollisionComponent2) return -1; - + //Closest Point on 2 to 1 CollisionComponent2->GetDistanceToCollision(CollisionComponent1->GetComponentLocation(), PointOnSurface2); - + //Closest Point on 1 to closest point on surface of 2 return CollisionComponent1->GetDistanceToCollision(PointOnSurface2, PointOnSurface1); } @@ -451,13 +451,13 @@ float UVictoryBPFunctionLibrary::GetDistanceBetweenComponentSurfaces(UPrimitiveC void UVictoryBPFunctionLibrary::VictoryCreateProc(int32& ProcessId, FString FullPathOfProgramToRun,TArray CommandlineArgs,bool Detach,bool Hidden, int32 Priority, FString OptionalWorkingDirectory) -{ +{ //Please note ProcessId should really be uint32 but that is not supported by BP yet - + FString Args = ""; if(CommandlineArgs.Num() > 1) { - Args = CommandlineArgs[0]; + Args = CommandlineArgs[0]; for(int32 v = 1; v < CommandlineArgs.Num(); v++) { Args += " " + CommandlineArgs[v]; @@ -467,24 +467,24 @@ void UVictoryBPFunctionLibrary::VictoryCreateProc(int32& ProcessId, FString Full { Args = CommandlineArgs[0]; } - + uint32 NeedBPUINT32 = 0; - FProcHandle ProcHandle = FPlatformProcess::CreateProc( - *FullPathOfProgramToRun, - *Args, + FProcHandle ProcHandle = FPlatformProcess::CreateProc( + *FullPathOfProgramToRun, + *Args, Detach,//* @param bLaunchDetached if true, the new process will have its own window false,//* @param bLaunchHidded if true, the new process will be minimized in the task bar Hidden,//* @param bLaunchReallyHidden if true, the new process will not have a window or be in the task bar - &NeedBPUINT32, - Priority, - (OptionalWorkingDirectory != "") ? *OptionalWorkingDirectory : nullptr,//const TCHAR* OptionalWorkingDirectory, + &NeedBPUINT32, + Priority, + (OptionalWorkingDirectory != "") ? *OptionalWorkingDirectory : nullptr,//const TCHAR* OptionalWorkingDirectory, nullptr ); - + //Not sure what to do to expose UINT32 to BP - ProcessId = NeedBPUINT32; + ProcessId = NeedBPUINT32; } - + bool UVictoryBPFunctionLibrary::CompareMD5Hash(FString MD5HashFile1, FString MD5HashFile2 ) { //Load Hash Files @@ -498,7 +498,7 @@ bool UVictoryBPFunctionLibrary::CompareMD5Hash(FString MD5HashFile1, FString MD5 FMemoryReader FromBinary = FMemoryReader(TheBinaryArray, true); //true, free data after done FMD5Hash FirstHash; FromBinary << FirstHash; - + TheBinaryArray.Empty(); if (!FFileHelper::LoadFileToArray(TheBinaryArray, *MD5HashFile2)) { @@ -506,11 +506,11 @@ bool UVictoryBPFunctionLibrary::CompareMD5Hash(FString MD5HashFile1, FString MD5 return false; //~~ } - + FMemoryReader FromBinarySecond = FMemoryReader(TheBinaryArray, true); //true, free data after done FMD5Hash SecondHash; FromBinarySecond << SecondHash; - + return FirstHash == SecondHash; } bool UVictoryBPFunctionLibrary::CreateMD5Hash(FString FileToHash, FString FileToStoreHashTo ) @@ -520,97 +520,97 @@ bool UVictoryBPFunctionLibrary::CreateMD5Hash(FString FileToHash, FString FileTo UE_LOG(LogTemp,Error,TEXT("File to hash not found %d"), *FileToHash); return false; } - + int64 SizeOfFileToHash = FPlatformFileManager::Get().GetPlatformFile().FileSize(*FileToHash); if(SizeOfFileToHash > 2 * 1000000000) { UE_LOG(LogTemp,Warning,TEXT("File is >2gb, hashing will be very slow %d"), SizeOfFileToHash); } - + FMD5Hash FileHash = FMD5Hash::HashFile(*FileToHash); - + //write to file FBufferArchive ToBinary; ToBinary << FileHash; - - if (FFileHelper::SaveArrayToFile(ToBinary, * FileToStoreHashTo)) + + if (FFileHelper::SaveArrayToFile(ToBinary, * FileToStoreHashTo)) { - // Free Binary Array + // Free Binary Array ToBinary.FlushCache(); ToBinary.Empty(); } else - { + { UE_LOG(LogTemp,Warning,TEXT("File hashed successfully but could not be saved to disk, file IO error %s"), *FileToHash); return false; } - + return true; } bool UVictoryBPFunctionLibrary::VictoryPhysics_UpdateAngularDamping(UPrimitiveComponent* CompToUpdate, float NewAngularDamping) { if(!CompToUpdate) return false; - + FBodyInstance* Body = CompToUpdate->GetBodyInstance(); if(!Body) return false; - + //Deep safety check if(!Body->IsValidBodyInstance()) return false; - + //Set! Body->AngularDamping = NewAngularDamping; - + //~~~~~~~~~~~~~~~~~ Body->UpdateDampingProperties(); //~~~~~~~~~~~~~~~~~ - + return true; } - + bool UVictoryBPFunctionLibrary::VictoryDestructible_DestroyChunk(UDestructibleComponent* DestructibleComp, int32 HitItem) -{ +{ #if WITH_APEX - if(!DestructibleComp) + if(!DestructibleComp) { return false; } - + //Visibility DestructibleComp->SetChunkVisible( HitItem, false ); - + //Collision physx::PxShape** PShapes; const physx::PxU32 PShapeCount = DestructibleComp->ApexDestructibleActor->getChunkPhysXShapes(PShapes, HitItem); if (PShapeCount > 0) - { + { PxFilterData PQueryFilterData,PSimFilterData; //null data - + for(uint32 ShapeIndex = 0; ShapeIndex < PShapeCount; ++ShapeIndex) - { + { PxShape* Shape = PShapes[ShapeIndex]; if(!Shape) continue; - - { + + { SCOPED_SCENE_WRITE_LOCK(Shape->getActor()->getScene()); - + Shape->setQueryFilterData(PQueryFilterData); //null data Shape->setSimulationFilterData(PSimFilterData); //null data Shape->setFlag(PxShapeFlag::eSCENE_QUERY_SHAPE, false); Shape->setFlag(PxShapeFlag::eSIMULATION_SHAPE, false); - Shape->setFlag(PxShapeFlag::eVISUALIZATION, false); + Shape->setFlag(PxShapeFlag::eVISUALIZATION, false); } } } return true; #endif //WITH_APEX - + UE_LOG(LogTemp,Error,TEXT("UVictoryBPFunctionLibrary::VictoryDestructible_DestroyChunk ~ Current Platform does not support APEX")); return false; } static int32 GetChildBones(const FReferenceSkeleton& ReferenceSkeleton, int32 ParentBoneIndex, TArray & Children) -{ +{ Children.Empty(); const int32 NumBones = ReferenceSkeleton.GetNum(); @@ -625,21 +625,21 @@ static int32 GetChildBones(const FReferenceSkeleton& ReferenceSkeleton, int32 Pa return Children.Num(); } static void GetChildBoneNames_Recursive(USkeletalMeshComponent* SkeletalMeshComp, int32 ParentBoneIndex, TArray& ChildBoneNames) -{ - TArray BoneIndicies; +{ + TArray BoneIndicies; GetChildBones(SkeletalMeshComp->SkeletalMesh->RefSkeleton, ParentBoneIndex, BoneIndicies); - + if(BoneIndicies.Num() < 1) { //Stops the recursive skeleton search return; } - + for(const int32& BoneIndex : BoneIndicies) { FName ChildBoneName = SkeletalMeshComp->GetBoneName(BoneIndex); ChildBoneNames.Add(ChildBoneName); - + //Recursion GetChildBoneNames_Recursive(SkeletalMeshComp, BoneIndex,ChildBoneNames); } @@ -648,36 +648,36 @@ static void GetChildBoneNames_Recursive(USkeletalMeshComponent* SkeletalMeshComp int32 UVictoryBPFunctionLibrary::GetAllBoneNamesBelowBone( USkeletalMeshComponent* SkeletalMeshComp, FName StartingBoneName, TArray& BoneNames ) { BoneNames.Empty(); - + if(!SkeletalMeshComp || !SkeletalMeshComp->SkeletalMesh) { return -1; //~~~~ } - + int32 StartingBoneIndex = SkeletalMeshComp->GetBoneIndex(StartingBoneName); - + //Recursive GetChildBoneNames_Recursive(SkeletalMeshComp, StartingBoneIndex, BoneNames); - + return BoneNames.Num(); } //~~~~~~ // File IO -//~~~~~~ +//~~~~~~ bool UVictoryBPFunctionLibrary::JoyFileIO_GetFiles(TArray& Files, FString RootFolderFullPath, FString Ext) { if(RootFolderFullPath.Len() < 1) return false; - + FPaths::NormalizeDirectoryName(RootFolderFullPath); - + IFileManager& FileManager = IFileManager::Get(); - + if(!Ext.Contains(TEXT("*"))) { - if(Ext == "") + if(Ext == "") { Ext = "*.*"; } @@ -686,23 +686,23 @@ bool UVictoryBPFunctionLibrary::JoyFileIO_GetFiles(TArray& Files, FStri Ext = (Ext.Left(1) == ".") ? "*" + Ext : "*." + Ext; } } - + FString FinalPath = RootFolderFullPath + "/" + Ext; - + FileManager.FindFiles(Files, *FinalPath, true, false); - return true; + return true; } bool UVictoryBPFunctionLibrary::JoyFileIO_GetFilesInRootAndAllSubFolders(TArray& Files, FString RootFolderFullPath, FString Ext) { if(RootFolderFullPath.Len() < 1) return false; - + FPaths::NormalizeDirectoryName(RootFolderFullPath); - + IFileManager& FileManager = IFileManager::Get(); - + if(!Ext.Contains(TEXT("*"))) { - if(Ext == "") + if(Ext == "") { Ext = "*.*"; } @@ -711,40 +711,40 @@ bool UVictoryBPFunctionLibrary::JoyFileIO_GetFilesInRootAndAllSubFolders(TArray< Ext = (Ext.Left(1) == ".") ? "*" + Ext : "*." + Ext; } } - + FileManager.FindFilesRecursive(Files, *RootFolderFullPath, *Ext, true, false); return true; } bool UVictoryBPFunctionLibrary::ScreenShots_Rename_Move_Most_Recent( FString& OriginalFileName, - FString NewName, - FString NewAbsoluteFolderPath, + FString NewName, + FString NewAbsoluteFolderPath, bool HighResolution -){ +){ OriginalFileName = "None"; //File Name given? if(NewName.Len() <= 0) return false; - + //Normalize FPaths::NormalizeDirectoryName(NewAbsoluteFolderPath); - - //Ensure target directory exists, + + //Ensure target directory exists, // _or can be created!_ <3 Rama if(!VCreateDirectory(NewAbsoluteFolderPath)) return false; - + FString ScreenShotsDir = VictoryPaths__ScreenShotsDir(); - + //Find all screenshots TArray Files; //false = not recursive, not expecting subdirectories bool Success = GetFiles(ScreenShotsDir, Files, false); - + if(!Success) { return false; } - + //Filter TArray ToRemove; //16 bytes each, more stable than ptrs though since RemoveSwap is involved for(FString& Each : Files) @@ -758,7 +758,7 @@ bool UVictoryBPFunctionLibrary::ScreenShots_Rename_Move_Most_Recent( } } else - { + { //Remove those that have it! if(Each.Left(4) == "High") { @@ -766,19 +766,19 @@ bool UVictoryBPFunctionLibrary::ScreenShots_Rename_Move_Most_Recent( } } } - + //Remove! for(FString& Each : ToRemove) { Files.RemoveSwap(Each); //Fast remove! Does not preserve order } - + //No files? if(Files.Num() < 1) - { + { return false; } - + //~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // Rama's Sort Files by Time Stamp Feature //~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -790,20 +790,20 @@ bool UVictoryBPFunctionLibrary::ScreenShots_Rename_Move_Most_Recent( for(FString& Each : Files) { FileSort.Add(FFileStampSort(&Each,GetFileTimeStamp(Each))); - + } //Sort all the file names by their Time Stamp! FileSort.Sort(); - + //Biggest value = last entry OriginalFileName = *FileSort.Last().FileName; //~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - + //Generate new Full File Path! FString NewFullFilePath = NewAbsoluteFolderPath + "/" + NewName + ".png"; - + //Move File! return RenameFile(NewFullFilePath, ScreenShotsDir + "/" + OriginalFileName); } @@ -811,129 +811,129 @@ bool UVictoryBPFunctionLibrary::ScreenShots_Rename_Move_Most_Recent( void UVictoryBPFunctionLibrary::VictoryISM_GetAllVictoryISMActors(UObject* WorldContextObject, TArray& Out) { if(!WorldContextObject) return; - + UWorld* const World = GEngine->GetWorldFromContextObject(WorldContextObject, EGetWorldErrorMode::ReturnNull); if(!World) return; //~~~~~~~~~~~ - + Out.Empty(); for(TActorIterator Itr(World); Itr; ++Itr) { Out.Add(*Itr); } } - + void UVictoryBPFunctionLibrary::VictoryISM_ConvertToVictoryISMActors( - UObject* WorldContextObject, - TSubclassOf ActorClass, - TArray& CreatedISMActors, + UObject* WorldContextObject, + TSubclassOf ActorClass, + TArray& CreatedISMActors, bool DestroyOriginalActors, int32 MinCountToCreateISM ){ //User Input Safety if(MinCountToCreateISM < 1) MinCountToCreateISM = 1; //require for array access safety - + CreatedISMActors.Empty(); - + if(!WorldContextObject) return; - + UWorld* const World = GEngine->GetWorldFromContextObject(WorldContextObject, EGetWorldErrorMode::ReturnNull); if(!World) return; //~~~~~~~~~~~ - + //I want one array of actors for each unique static mesh asset! -Rama TMap< UStaticMesh*,TArray > VictoryISMMap; - + //Note the ActorClass filter on the Actor Iterator! -Rama for (TActorIterator Itr(World, ActorClass); Itr; ++Itr) { //Get Static Mesh Component! UStaticMeshComponent* Comp = Itr->FindComponentByClass(); - if(!Comp) continue; + if(!Comp) continue; if(!Comp->IsValidLowLevel()) continue; //~~~~~~~~~ - + //Add Key if not present! if(!VictoryISMMap.Contains(Comp->GetStaticMesh())) { VictoryISMMap.Add(Comp->GetStaticMesh()); VictoryISMMap[Comp->GetStaticMesh()].Empty(); //ensure array is properly initialized } - + //Add the actor! VictoryISMMap[Comp->GetStaticMesh()].Add(*Itr); } - + //For each Static Mesh Asset in the Victory ISM Map for (TMap< UStaticMesh*,TArray >::TIterator It(VictoryISMMap); It; ++It) { //Get the Actor Array for this particular Static Mesh Asset! TArray& ActorArray = It.Value(); - + //No entries? if(ActorArray.Num() < MinCountToCreateISM) continue; //~~~~~~~~~~~~~~~~~~ - + //Get the Root UStaticMeshComponent* RootSMC = ActorArray[0]->FindComponentByClass(); if(!RootSMC) continue; //~~~~~~~~~~ - + //Gather transforms! TArray WorldTransforms; for(AActor* Each : ActorArray) { WorldTransforms.Add(Each->GetTransform()); - + //Destroy original? if(DestroyOriginalActors) { Each->Destroy(); } } - + //Create Victory ISM FActorSpawnParameters SpawnInfo; //SpawnInfo.bNoCollisionFail = true; //always create! SpawnInfo.SpawnCollisionHandlingOverride = ESpawnActorCollisionHandlingMethod::AlwaysSpawn; SpawnInfo.bDeferConstruction = false; - + AVictoryISM* NewISM = World->SpawnActor( - AVictoryISM::StaticClass(), + AVictoryISM::StaticClass(), RootSMC->GetComponentLocation() , - RootSMC->GetComponentRotation(), - SpawnInfo + RootSMC->GetComponentRotation(), + SpawnInfo ); - + if(!NewISM) continue; //~~~~~~~~~~ - + //Mesh NewISM->Mesh->SetStaticMesh(RootSMC->GetStaticMesh()); - + //Materials const int32 MatTotal = RootSMC->GetNumMaterials(); for(int32 v = 0; v < MatTotal; v++) { NewISM->Mesh->SetMaterial(v,RootSMC->GetMaterial(v)); } - + //Set Transforms! for(const FTransform& Each : WorldTransforms) { NewISM->Mesh->AddInstanceWorldSpace(Each); } - + //Add new ISM! CreatedISMActors.Add(NewISM); } - + //Clear memory VictoryISMMap.Empty(); } - - - + + + void UVictoryBPFunctionLibrary::SaveGameObject_GetAllSaveSlotFileNames(TArray& FileNames) { FileNames.Empty(); @@ -971,7 +971,7 @@ FString UVictoryBPFunctionLibrary::VictoryPaths__ScreenShotsDir() { return FPaths::ConvertRelativePathToFull(FPaths::ScreenShotDir()); } - + FString UVictoryBPFunctionLibrary::VictoryPaths__LogsDir() { return FPaths::ConvertRelativePathToFull(FPaths::ProjectLogDir()); @@ -979,8 +979,8 @@ FString UVictoryBPFunctionLibrary::VictoryPaths__LogsDir() //~~~~~~~~~~~~~~~~~ - - + + FVector2D UVictoryBPFunctionLibrary::Vector2DInterpTo(FVector2D Current, FVector2D Target, float DeltaTime, float InterpSpeed) { return FMath::Vector2DInterpTo( Current, Target, DeltaTime, InterpSpeed ); @@ -991,58 +991,58 @@ FVector2D UVictoryBPFunctionLibrary::Vector2DInterpTo_Constant(FVector2D Current } float UVictoryBPFunctionLibrary::MapRangeClamped(float Value, float InRangeA, float InRangeB, float OutRangeA, float OutRangeB) -{ +{ return FMath::GetMappedRangeValueClamped(FVector2D(InRangeA,InRangeB),FVector2D(OutRangeA,OutRangeB),Value); } 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; } FVictoryInputAxis UVictoryBPFunctionLibrary::VictoryGetVictoryInputAxis(const FKeyEvent& KeyEvent) { FVictoryInputAxis VInput; - + VInput.Key = KeyEvent.GetKey(); VInput.KeyAsString = VInput.Key.GetDisplayName().ToString(); - + VInput.Scale = 1; - + return VInput; } void UVictoryBPFunctionLibrary::VictoryGetAllAxisKeyBindings(TArray& Bindings) { Bindings.Empty(); - + const UInputSettings* Settings = GetDefault(); if(!Settings) return; - + const TArray& Axi = Settings->AxisMappings; - + for(const FInputAxisKeyMapping& Each : Axi) { Bindings.Add(FVictoryInputAxis(Each)); } } void UVictoryBPFunctionLibrary::VictoryRemoveAxisKeyBind(FVictoryInputAxis ToRemove) -{ +{ //GetMutableDefault UInputSettings* Settings = GetMutableDefault(); if(!Settings) return; - + TArray& Axi = Settings->AxisMappings; - + bool Found = false; for(int32 v = 0; v < Axi.Num(); v++) { @@ -1054,12 +1054,12 @@ void UVictoryBPFunctionLibrary::VictoryRemoveAxisKeyBind(FVictoryInputAxis ToRem continue; } } - + if(Found) { //SAVES TO DISK Settings->SaveKeyMappings(); - + //REBUILDS INPUT, creates modified config in Saved/Config/Windows/Input.ini for (TObjectIterator It; It; ++It) { @@ -1071,12 +1071,12 @@ void UVictoryBPFunctionLibrary::VictoryRemoveAxisKeyBind(FVictoryInputAxis ToRem void UVictoryBPFunctionLibrary::VictoryGetAllActionKeyBindings(TArray& Bindings) { Bindings.Empty(); - + const UInputSettings* Settings = GetDefault(); if(!Settings) return; - + const TArray& Actions = Settings->ActionMappings; - + for(const FInputActionKeyMapping& Each : Actions) { Bindings.Add(FVictoryInput(Each)); @@ -1088,9 +1088,9 @@ void UVictoryBPFunctionLibrary::VictoryRemoveActionKeyBind(FVictoryInput ToRemov //GetMutableDefault UInputSettings* Settings = GetMutableDefault(); if(!Settings) return; - + TArray& Actions = Settings->ActionMappings; - + bool Found = false; for(int32 v = 0; v < Actions.Num(); v++) { @@ -1102,12 +1102,12 @@ void UVictoryBPFunctionLibrary::VictoryRemoveActionKeyBind(FVictoryInput ToRemov continue; } } - + if(Found) { //SAVES TO DISK Settings->SaveKeyMappings(); - + //REBUILDS INPUT, creates modified config in Saved/Config/Windows/Input.ini for (TObjectIterator It; It; ++It) { @@ -1117,15 +1117,15 @@ void UVictoryBPFunctionLibrary::VictoryRemoveActionKeyBind(FVictoryInput ToRemov } void UVictoryBPFunctionLibrary::VictoryGetAllAxisAndActionMappingsForKey(FKey Key, TArray& ActionBindings, TArray& AxisBindings) -{ +{ ActionBindings.Empty(); AxisBindings.Empty(); - + const UInputSettings* Settings = GetDefault(); if(!Settings) return; - + const TArray& Actions = Settings->ActionMappings; - + for(const FInputActionKeyMapping& Each : Actions) { if(Each.Key == Key) @@ -1135,9 +1135,9 @@ void UVictoryBPFunctionLibrary::VictoryGetAllAxisAndActionMappingsForKey(FKey Ke } const TArray& Axi = Settings->AxisMappings; - + for(const FInputAxisKeyMapping& Each : Axi) - { + { if(Each.Key == Key) { AxisBindings.Add(FVictoryInputAxis(Each)); @@ -1150,28 +1150,28 @@ bool UVictoryBPFunctionLibrary::VictoryReBindAxisKey(FVictoryInputAxis Original, if(!Settings) return false; TArray& Axi = Settings->AxisMappings; - + //~~~ - + bool Found = false; for(FInputAxisKeyMapping& Each : Axi) { //Search by original if(Each.AxisName.ToString() == Original.AxisName && Each.Key == Original.Key - ){ + ){ //Update to new! UVictoryBPFunctionLibrary::UpdateAxisMapping(Each,NewBinding); Found = true; break; - } + } } - - if(Found) + + if(Found) { //SAVES TO DISK const_cast(Settings)->SaveKeyMappings(); - + //REBUILDS INPUT, creates modified config in Saved/Config/Windows/Input.ini for (TObjectIterator It; It; ++It) { @@ -1187,28 +1187,28 @@ bool UVictoryBPFunctionLibrary::VictoryReBindActionKey(FVictoryInput Original, F if(!Settings) return false; TArray& Actions = Settings->ActionMappings; - + //~~~ - + bool Found = false; for(FInputActionKeyMapping& Each : Actions) { //Search by original if(Each.ActionName.ToString() == Original.ActionName && Each.Key == Original.Key - ){ + ){ //Update to new! UVictoryBPFunctionLibrary::UpdateActionMapping(Each,NewBinding); Found = true; break; - } + } } - - if(Found) + + if(Found) { //SAVES TO DISK const_cast(Settings)->SaveKeyMappings(); - + //REBUILDS INPUT, creates modified config in Saved/Config/Windows/Input.ini for (TObjectIterator It; It; ++It) { @@ -1223,27 +1223,27 @@ void UVictoryBPFunctionLibrary::GetAllWidgetsOfClass(UObject* WorldContextObject //Prevent possibility of an ever-growing array if user uses this in a loop FoundWidgets.Empty(); //~~~~~~~~~~~~ - + if(!WidgetClass) return; if(!WorldContextObject) return; - + UWorld* const World = GEngine->GetWorldFromContextObject(WorldContextObject, EGetWorldErrorMode::ReturnNull); if(!World) return; //~~~~~~~~~~~ - + for(TObjectIterator Itr; Itr; ++Itr) { if(Itr->GetWorld() != World) continue; //~~~~~~~~~~~~~~~~~~~~~ - + if( ! Itr->IsA(WidgetClass)) continue; //~~~~~~~~~~~~~~~~~~~ - + //Top Level? if(TopLevelOnly) { //only add top level widgets - if(Itr->IsInViewport()) + if(Itr->IsInViewport()) { FoundWidgets.Add(*Itr); } @@ -1254,24 +1254,24 @@ void UVictoryBPFunctionLibrary::GetAllWidgetsOfClass(UObject* WorldContextObject FoundWidgets.Add(*Itr); } } -} +} void UVictoryBPFunctionLibrary::RemoveAllWidgetsOfClass(UObject* WorldContextObject, TSubclassOf WidgetClass) { if(!WidgetClass) return; if(!WorldContextObject) return; - + UWorld* const World = GEngine->GetWorldFromContextObject(WorldContextObject, EGetWorldErrorMode::ReturnNull); if(!World) return; //~~~~~~~~~~~ - + for(TObjectIterator Itr; Itr; ++Itr) { if(Itr->GetWorld() != World) continue; //~~~~~~~~~~~~~~~~~~~~~ - + if( ! Itr->IsA(WidgetClass)) continue; //~~~~~~~~~~~~~~~~~~~ - + //only add top level widgets if(Itr->IsInViewport()) //IsInViewport in 4.6 { @@ -1281,49 +1281,60 @@ void UVictoryBPFunctionLibrary::RemoveAllWidgetsOfClass(UObject* WorldContextObj } bool UVictoryBPFunctionLibrary::IsWidgetOfClassInViewport(UObject* WorldContextObject, TSubclassOf WidgetClass) -{ +{ if(!WidgetClass) return false; if(!WorldContextObject) return false; - + UWorld* const World = GEngine->GetWorldFromContextObject(WorldContextObject, EGetWorldErrorMode::ReturnNull); if(!World) return false; //~~~~~~~~~~~ - + for(TObjectIterator Itr; Itr; ++Itr) { if(Itr->GetWorld() != World) continue; //~~~~~~~~~~~~~~~~~~~~~ - + if( ! Itr->IsA(WidgetClass)) continue; //~~~~~~~~~~~~~~~~~~~ - + if(Itr->GetIsVisible()) //IsInViewport in 4.6 { return true; } } - + return false; } - + void UVictoryBPFunctionLibrary::ServerTravel(UObject* WorldContextObject, FString MapName,bool bNotifyPlayers) -{ +{ if(!WorldContextObject) return; - + UWorld* const World = GEngine->GetWorldFromContextObject(WorldContextObject, EGetWorldErrorMode::ReturnNull); if(!World) return; //~~~~~~~~~~~ - + World->ServerTravel(MapName,false,bNotifyPlayers); //abs //notify players } + +void UVictoryBPFunctionLibrary::ClientTravel(UObject* WorldContextObject, APlayerController* PlayerController, FString MapName, bool bSeamless, FGuid MapPackageGuid) +{ + if (!WorldContextObject) return; + + UWorld* const World = GEngine->GetWorldFromContextObject(WorldContextObject, EGetWorldErrorMode::ReturnNull); + if (!World) return; + //~~~~~~~~~~ + PlayerController->ClientTravel(MapName, ETravelType::TRAVEL_Relative, bSeamless, MapPackageGuid); //activate seamless travel +} + APlayerStart* UVictoryBPFunctionLibrary::GetPlayerStart(UObject* WorldContextObject,FString PlayerStartName) { if(!WorldContextObject) return nullptr; - + UWorld* const World = GEngine->GetWorldFromContextObject(WorldContextObject, EGetWorldErrorMode::ReturnNull); if(!World) return nullptr; //~~~~~~~~~~~ - + for(TActorIterator Itr(World); Itr; ++Itr) { if(Itr->GetName() == PlayerStartName) @@ -1336,37 +1347,37 @@ APlayerStart* UVictoryBPFunctionLibrary::GetPlayerStart(UObject* WorldContextObj bool UVictoryBPFunctionLibrary::VictorySoundVolumeChange(USoundClass* SoundClassObject, float NewVolume) { - if(!SoundClassObject) + if(!SoundClassObject) { return false; } - + SoundClassObject->Properties.Volume = NewVolume; - return true; - + return true; + /* 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; */ - + /* bool SetBaseSoundMix( class USoundMix* SoundMix ); - + */ } float UVictoryBPFunctionLibrary::VictoryGetSoundVolume(USoundClass* SoundClassObject) -{ +{ if (!SoundClassObject) { return -1; @@ -1378,22 +1389,22 @@ float UVictoryBPFunctionLibrary::VictoryGetSoundVolume(USoundClass* SoundClassOb { return -1; } - + FSoundClassProperties* Props = Device->GetSoundClassCurrentProperties(SoundClassObject); if(!Props) return -1; return Props->Volume; */ } - + void UVictoryBPFunctionLibrary::VictoryIntPlusEquals(UPARAM(ref) int32& Int, int32 Add, int32& IntOut) -{ +{ Int += Add; - IntOut = Int; -} + IntOut = Int; +} void UVictoryBPFunctionLibrary::VictoryIntMinusEquals(UPARAM(ref) int32& Int, int32 Sub, int32& IntOut) -{ +{ Int -= Sub; - IntOut = Int; + IntOut = Int; } void UVictoryBPFunctionLibrary::VictoryFloatPlusEquals(UPARAM(ref) float& Float, float Add, float& FloatOut) @@ -1404,7 +1415,7 @@ void UVictoryBPFunctionLibrary::VictoryFloatPlusEquals(UPARAM(ref) float& Float, void UVictoryBPFunctionLibrary::VictoryFloatMinusEquals(UPARAM(ref) float& Float, float Sub, float& FloatOut) { Float -= Sub; - FloatOut = Float; + FloatOut = Float; } void UVictoryBPFunctionLibrary::VictorySortIntArray(UPARAM(ref) TArray& IntArray, TArray& IntArrayRef) @@ -1417,34 +1428,34 @@ void UVictoryBPFunctionLibrary::VictorySortFloatArray(UPARAM(ref) TArray& FloatArray.Sort(); FloatArrayRef = FloatArray; } - + //String Back To Type void UVictoryBPFunctionLibrary::Conversions__StringToVector(const FString& String, FVector& ConvertedVector, bool& IsValid) -{ +{ IsValid = ConvertedVector.InitFromString( String ); } void UVictoryBPFunctionLibrary::Conversions__StringToRotator(const FString& String, FRotator& ConvertedRotator, bool& IsValid) { IsValid = ConvertedRotator.InitFromString( String ); -} +} void UVictoryBPFunctionLibrary::Conversions__StringToColor(const FString& String, FLinearColor& ConvertedColor, bool& IsValid) -{ +{ IsValid = ConvertedColor.InitFromString( String ); } void UVictoryBPFunctionLibrary::Conversions__ColorToString(const FLinearColor& Color, FString& ColorAsString) { ColorAsString = Color.ToString(); } - + //String Back To Type //! not working yet, always getting 255 /* uint8 UVictoryBPFunctionLibrary::Victory_ConvertStringToByte(UEnum* Enum, FString String) -{ +{ if( !Enum ) return 255; - + return Enum->GetIndexByName(*String); } */ @@ -1457,7 +1468,7 @@ bool UVictoryBPFunctionLibrary::VictoryGetCustomConfigVar_Bool(FString SectionNa { if(!GConfig) return false; //~~~~~~~~~~~ - + bool Value; IsValid = GConfig->GetBool( *SectionName, @@ -1466,12 +1477,12 @@ bool UVictoryBPFunctionLibrary::VictoryGetCustomConfigVar_Bool(FString SectionNa GGameIni ); return Value; -} +} int32 UVictoryBPFunctionLibrary::VictoryGetCustomConfigVar_Int(FString SectionName,FString VariableName, bool& IsValid) { if(!GConfig) return 0; //~~~~~~~~~~~ - + int32 Value; IsValid = GConfig->GetInt( *SectionName, @@ -1485,7 +1496,7 @@ float UVictoryBPFunctionLibrary::VictoryGetCustomConfigVar_Float(FString Section { if(!GConfig) return 0; //~~~~~~~~~~~ - + float Value; IsValid = GConfig->GetFloat( *SectionName, @@ -1499,7 +1510,7 @@ FVector UVictoryBPFunctionLibrary::VictoryGetCustomConfigVar_Vector(FString Sect { if(!GConfig) return FVector::ZeroVector; //~~~~~~~~~~~ - + FVector Value; IsValid = GConfig->GetVector( *SectionName, @@ -1513,7 +1524,7 @@ FRotator UVictoryBPFunctionLibrary::VictoryGetCustomConfigVar_Rotator(FString Se { if(!GConfig) return FRotator::ZeroRotator; //~~~~~~~~~~~ - + FRotator Value; IsValid = GConfig->GetRotator( *SectionName, @@ -1527,7 +1538,7 @@ FLinearColor UVictoryBPFunctionLibrary::VictoryGetCustomConfigVar_Color(FString { if(!GConfig) return FColor::Black; //~~~~~~~~~~~ - + FColor Value; IsValid = GConfig->GetColor( *SectionName, @@ -1541,7 +1552,7 @@ FString UVictoryBPFunctionLibrary::VictoryGetCustomConfigVar_String(FString Sect { if(!GConfig) return ""; //~~~~~~~~~~~ - + FString Value; IsValid = GConfig->GetString( *SectionName, @@ -1556,7 +1567,7 @@ FVector2D UVictoryBPFunctionLibrary::VictoryGetCustomConfigVar_Vector2D(FString { if(!GConfig) return FVector2D::ZeroVector; //~~~~~~~~~~~ - + FVector Value; IsValid = GConfig->GetVector( *SectionName, @@ -1565,15 +1576,15 @@ FVector2D UVictoryBPFunctionLibrary::VictoryGetCustomConfigVar_Vector2D(FString GGameIni ); return FVector2D(Value.X,Value.Y); -} - +} + //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ void UVictoryBPFunctionLibrary::VictorySetCustomConfigVar_Vector2D(FString SectionName, FString VariableName, FVector2D Value) { if(!GConfig) return; //~~~~~~~~~~~ - + GConfig->SetVector( *SectionName, *VariableName, @@ -1586,7 +1597,7 @@ void UVictoryBPFunctionLibrary::VictorySetCustomConfigVar_Bool(FString SectionNa { if(!GConfig) return; //~~~~~~~~~~~ - + GConfig->SetBool( *SectionName, *VariableName, @@ -1598,7 +1609,7 @@ void UVictoryBPFunctionLibrary::VictorySetCustomConfigVar_Int(FString SectionNam { if(!GConfig) return; //~~~~~~~~~~~ - + GConfig->SetInt( *SectionName, *VariableName, @@ -1610,7 +1621,7 @@ void UVictoryBPFunctionLibrary::VictorySetCustomConfigVar_Float(FString SectionN { if(!GConfig) return; //~~~~~~~~~~~ - + GConfig->SetFloat( *SectionName, *VariableName, @@ -1622,7 +1633,7 @@ void UVictoryBPFunctionLibrary::VictorySetCustomConfigVar_Vector(FString Section { if(!GConfig) return; //~~~~~~~~~~~ - + GConfig->SetVector( *SectionName, *VariableName, @@ -1634,7 +1645,7 @@ void UVictoryBPFunctionLibrary::VictorySetCustomConfigVar_Rotator(FString Sectio { if(!GConfig) return; //~~~~~~~~~~~ - + GConfig->SetRotator( *SectionName, *VariableName, @@ -1646,7 +1657,7 @@ void UVictoryBPFunctionLibrary::VictorySetCustomConfigVar_Color(FString SectionN { if(!GConfig) return; //~~~~~~~~~~~ - + GConfig->SetColor( *SectionName, *VariableName, @@ -1658,7 +1669,7 @@ void UVictoryBPFunctionLibrary::VictorySetCustomConfigVar_String(FString Section { if(!GConfig) return; //~~~~~~~~~~~ - + GConfig->SetString( *SectionName, *VariableName, @@ -1679,25 +1690,25 @@ void UVictoryBPFunctionLibrary::VictorySetCustomConfigVar_String(FString Section FName UVictoryBPFunctionLibrary::GetHeadMountedDisplayDeviceType() { /* - 4.19 - The IHeadMountedDisplay::GetHMDDeviceType() method has been removed as it was not extensible - enough. Code that needs know which XR plugin is currently active should use + 4.19 + The IHeadMountedDisplay::GetHMDDeviceType() method has been removed as it was not extensible + enough. Code that needs know which XR plugin is currently active should use IXRTrackingSystem::GetSystemName() instead. */ if(!GEngine) return "None"; - + if (GEngine->XRSystem.IsValid() && GEngine->XRSystem->GetHMDDevice()) - { + { //Actively connected? if(!GEngine->XRSystem->GetHMDDevice()->IsHMDConnected()) - { + { return "None"; - } - + } + //!See IIdentifiableXRDevice.h return GEngine->XRSystem->GetSystemName(); } - + return "None"; } @@ -1720,14 +1731,14 @@ FName UVictoryBPFunctionLibrary::GetHeadMountedDisplayDeviceType() UObject* UVictoryBPFunctionLibrary::LoadObjectFromAssetPath(TSubclassOf 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) @@ -1735,30 +1746,30 @@ 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 This Object 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 ThePC; - if(!ThePC) return -1; + if(!ThePC) return -1; if(!ThePC->PlayerState) return -1; //~~~~~~~~~~~~~~~~~~~ - + return ThePC->PlayerState->PlayerId; } UObject* UVictoryBPFunctionLibrary::CreateObject(UObject* WorldContextObject,UClass* TheObjectClass) @@ -1769,39 +1780,39 @@ UObject* UVictoryBPFunctionLibrary::CreateObject(UObject* WorldContextObject,UCl /* if(!TheObjectClass) return NULL; //~~~~~~~~~~~~~~~~~ - + //using a context object to get the world! UWorld* const World = GEngine->GetWorldFromContextObject(WorldContextObject, EGetWorldErrorMode::ReturnNull); if(!World) return NULL; //~~~~~~~~~~~ - + //Need to submit pull request for custom name and custom class both return NewObject(World,TheObjectClass); */ } UPrimitiveComponent* UVictoryBPFunctionLibrary::CreatePrimitiveComponent( - UObject* WorldContextObject, - TSubclassOf CompClass, + UObject* WorldContextObject, + TSubclassOf CompClass, FName Name, - FVector Location, + FVector Location, FRotator Rotation ){ if(!CompClass) return NULL; //~~~~~~~~~~~~~~~~~ - + //using a context object to get the world! UWorld* const World = GEngine->GetWorldFromContextObject(WorldContextObject, EGetWorldErrorMode::ReturnNull); if(!World) return NULL; //~~~~~~~~~~~ - + UPrimitiveComponent* NewComp = NewObject(World, Name); if(!NewComp) return NULL; //~~~~~~~~~~~~~ - + NewComp->SetWorldLocation(Location); NewComp->SetWorldRotation(Rotation); NewComp->RegisterComponentWithWorld(World); - + return NewComp; } @@ -1809,39 +1820,39 @@ AActor* UVictoryBPFunctionLibrary::SpawnActorIntoLevel(UObject* WorldContextObje { if(!ActorClass) return NULL; //~~~~~~~~~~~~~~~~~ - + //using a context object to get the world! UWorld* const World = GEngine->GetWorldFromContextObject(WorldContextObject, EGetWorldErrorMode::ReturnNull); if(!World) return NULL; //~~~~~~~~~~~ - + FActorSpawnParameters SpawnParameters; if (SpawnEvenIfColliding) { SpawnParameters.SpawnCollisionHandlingOverride = ESpawnActorCollisionHandlingMethod::AlwaysSpawn; } - + SpawnParameters.bDeferConstruction = false; - - + + //Get Level from Name! ULevel* FoundLevel = NULL; - + for(const ULevelStreaming* EachLevel : World->GetStreamingLevels()) { if( ! EachLevel) continue; //~~~~~~~~~~~~~~~~ - + ULevel* LevelPtr = EachLevel->GetLoadedLevel(); - + //Valid? if(!LevelPtr) continue; - + if(EachLevel->GetWorldAssetPackageFName() == Level) { - FoundLevel = LevelPtr; + FoundLevel = LevelPtr; break; - } + } } //~~~~~~~~~~~~~~~~~~~~~ if(FoundLevel) @@ -1849,42 +1860,42 @@ AActor* UVictoryBPFunctionLibrary::SpawnActorIntoLevel(UObject* WorldContextObje SpawnParameters.OverrideLevel = FoundLevel; } //~~~~~~~~~~~~~~~~~~~~~ - + return World->SpawnActor( ActorClass, &Location, &Rotation, SpawnParameters); - + } void UVictoryBPFunctionLibrary::GetNamesOfLoadedLevels(UObject* WorldContextObject, TArray& NamesOfLoadedLevels) { - + //using a context object to get the world! UWorld* const World = GEngine->GetWorldFromContextObject(WorldContextObject, EGetWorldErrorMode::ReturnNull); if(!World) return; //~~~~~~~~~~~ - + NamesOfLoadedLevels.Empty(); - + //Get Level from Name! ULevel* FoundLevel = NULL; - + for(const ULevelStreaming* EachLevel : World->GetStreamingLevels()) { if( ! EachLevel) continue; //~~~~~~~~~~~~~~~~ - + ULevel* LevelPtr = EachLevel->GetLoadedLevel(); - + //Valid? if(!LevelPtr) continue; - + //Is This Level Visible? if(!LevelPtr->bIsVisible) continue; //~~~~~~~~~~~~~~~~~~~ - + NamesOfLoadedLevels.Add(EachLevel->GetWorldAssetPackageFName().ToString()); } } - - + + void UVictoryBPFunctionLibrary::Loops_ResetBPRunawayCounter() { //Reset Runaway loop counter (use carefully) @@ -1895,15 +1906,15 @@ void UVictoryBPFunctionLibrary::GraphicsSettings__SetFrameRateToBeUnbound() { if(!GEngine) return; //~~~~~~~~~ - - GEngine->bSmoothFrameRate = 0; + + GEngine->bSmoothFrameRate = 0; } void UVictoryBPFunctionLibrary::GraphicsSettings__SetFrameRateCap(float NewValue) { if(!GEngine) return; //~~~~~~~~~ - - GEngine->bSmoothFrameRate = 1; + + GEngine->bSmoothFrameRate = 1; GEngine->SmoothedFrameRateRange = FFloatRange(10,NewValue); } @@ -1911,12 +1922,12 @@ FVector2D UVictoryBPFunctionLibrary::ProjectWorldToScreenPosition(const FVector& { TObjectIterator ThePC; if(!ThePC) return FVector2D::ZeroVector; - + ULocalPlayer* LocalPlayer = Cast(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, @@ -1930,15 +1941,15 @@ FVector2D UVictoryBPFunctionLibrary::ProjectWorldToScreenPosition(const FVector& FSceneView* SceneView = LocalPlayer->CalcSceneView( &ViewFamily, /*out*/ ViewLocation, /*out*/ ViewRotation, LocalPlayer->ViewportClient->Viewport ); //Valid Scene View? - if (SceneView) + if (SceneView) { //Return FVector2D ScreenLocation; SceneView->WorldToPixel(WorldLocation,ScreenLocation ); return ScreenLocation; } - } - + } + return FVector2D::ZeroVector; } @@ -1947,29 +1958,29 @@ FVector2D UVictoryBPFunctionLibrary::ProjectWorldToScreenPosition(const FVector& bool UVictoryBPFunctionLibrary::GetStaticMeshVertexLocations(UStaticMeshComponent* Comp, TArray& VertexPositions) { VertexPositions.Empty(); - - if(!Comp) + + if(!Comp) { return false; } - - if(!Comp->IsValidLowLevel()) + + if(!Comp->IsValidLowLevel()) { return false; } //~~~~~~~~~~~~~~~~~~~~~~~ - + //Component Transform - FTransform RV_Transform = Comp->GetComponentTransform(); - + FTransform RV_Transform = Comp->GetComponentTransform(); + //Body Setup valid? UBodySetup* BodySetup = Comp->GetBodySetup(); - + if(!BodySetup || !BodySetup->IsValidLowLevel()) { return false; - } - + } + for(PxTriangleMesh* EachTriMesh : BodySetup->TriMeshes) { if (!EachTriMesh) @@ -1984,19 +1995,19 @@ bool UVictoryBPFunctionLibrary::GetStaticMeshVertexLocations(UStaticMeshComponen //Vertex array const PxVec3* Vertices = EachTriMesh->getVertices(); - //For each vertex, transform the position to match the component Transform + //For each vertex, transform the position to match the component Transform for (PxU32 v = 0; v < VertexCount; v++) { VertexPositions.Add(RV_Transform.TransformPosition(P2UVector(Vertices[v]))); } } return true; - + /* //See this wiki for more info on getting triangles // https://wiki.unrealengine.com/Accessing_mesh_triangles_and_vertex_positions_in_build */ -} +} void UVictoryBPFunctionLibrary::AddToActorRotation(AActor* TheActor, FRotator AddRot) @@ -2015,8 +2026,8 @@ void UVictoryBPFunctionLibrary::AddToActorRotation(AActor* TheActor, FRotator Ad void UVictoryBPFunctionLibrary::DrawCircle( UObject* WorldContextObject, - FVector Center, - float Radius, + FVector Center, + float Radius, int32 NumPoints, float Thickness, FLinearColor LineColor, @@ -2024,54 +2035,54 @@ void UVictoryBPFunctionLibrary::DrawCircle( FVector ZAxis, float Duration, bool PersistentLines -){ - - +){ + + if(!WorldContextObject) return ; - + //using a context object to get the world! UWorld* const World = GEngine->GetWorldFromContextObject(WorldContextObject, EGetWorldErrorMode::ReturnNull); 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, + World, + TM, + Radius, NumPoints, + FColor::Red, + false, + -1.f, 0 ); */ - - // Need at least 4 segments + + // Need at least 4 segments NumPoints = FMath::Max(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, + World, + Vertex1, Vertex2, - LineColor.ToFColor(true), - PersistentLines, + LineColor.ToFColor(true), + PersistentLines, Duration, - 0, //depth - Thickness + 0, //depth + Thickness ); } } @@ -2080,14 +2091,14 @@ void UVictoryBPFunctionLibrary::DrawCircle( bool UVictoryBPFunctionLibrary::LoadStringArrayFromFile(TArray& StringArray, int32& ArraySize, FString FullFilePath, bool ExcludeEmptyLines) { ArraySize = 0; - + if(FullFilePath == "" || FullFilePath == " ") return false; - + //Empty any previous contents! StringArray.Empty(); - + TArray FileArray; - + if( ! FFileHelper::LoadANSITextFileToStrings(*FullFilePath, NULL, FileArray)) { return false; @@ -2099,7 +2110,7 @@ bool UVictoryBPFunctionLibrary::LoadStringArrayFromFile(TArray& StringA { if(Each == "") continue; //~~~~~~~~~~~~~ - + //check for any non whitespace bool FoundNonWhiteSpace = false; for(int32 v = 0; v < Each.Len(); v++) @@ -2111,7 +2122,7 @@ bool UVictoryBPFunctionLibrary::LoadStringArrayFromFile(TArray& StringA } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ } - + if(FoundNonWhiteSpace) { StringArray.Add(Each); @@ -2122,29 +2133,29 @@ bool UVictoryBPFunctionLibrary::LoadStringArrayFromFile(TArray& StringA { StringArray.Append(FileArray); } - + ArraySize = StringArray.Num(); - return true; + return true; } - + AActor* UVictoryBPFunctionLibrary::GetClosestActorOfClassInRadiusOfLocation( - UObject* WorldContextObject, - TSubclassOf ActorClass, - FVector Center, - float Radius, + UObject* WorldContextObject, + TSubclassOf ActorClass, + FVector Center, + float Radius, bool& IsValid -){ +){ IsValid = false; - + //using a context object to get the world! UWorld* const World = GEngine->GetWorldFromContextObject(WorldContextObject, EGetWorldErrorMode::ReturnNull); if(!World) return NULL; //~~~~~~~~~~~ - + AActor* ClosestActor = NULL; float MinDistanceSq = Radius*Radius; //Max Radius - + for (TActorIterator Itr(World, ActorClass); Itr; ++Itr) { const float DistanceSquared = FVector::DistSquared(Center, Itr->GetActorLocation()); @@ -2163,38 +2174,38 @@ AActor* UVictoryBPFunctionLibrary::GetClosestActorOfClassInRadiusOfLocation( } return ClosestActor; -} +} AActor* UVictoryBPFunctionLibrary::GetClosestActorOfClassInRadiusOfActor( - UObject* WorldContextObject, - TSubclassOf ActorClass, - AActor* ActorCenter, - float Radius, + UObject* WorldContextObject, + TSubclassOf ActorClass, + AActor* ActorCenter, + float Radius, bool& IsValid -){ +){ IsValid = false; - + if(!ActorCenter) { return nullptr; } - + const FVector Center = ActorCenter->GetActorLocation(); - + //using a context object to get the world! UWorld* const World = GEngine->GetWorldFromContextObject(WorldContextObject, EGetWorldErrorMode::ReturnNull); if(!World) return NULL; //~~~~~~~~~~~ - + AActor* ClosestActor = NULL; float MinDistanceSq = Radius*Radius; //Max Radius - + for (TActorIterator Itr(World, ActorClass); Itr; ++Itr) { //Skip ActorCenter! if(*Itr == ActorCenter) continue; //~~~~~~~~~~~~~~~~~ - + const float DistanceSquared = FVector::DistSquared(Center, Itr->GetActorLocation()); //Is this the closest possible actor within the max radius? @@ -2216,24 +2227,24 @@ AActor* UVictoryBPFunctionLibrary::GetClosestActorOfClassInRadiusOfActor( void UVictoryBPFunctionLibrary::Selection_SelectionBox(UObject* WorldContextObject,TArray& SelectedActors, FVector2D AnchorPoint,FVector2D DraggedPoint,TSubclassOf ClassFilter) { if(!WorldContextObject) return ; - - + + //using a context object to get the world! UWorld* const World = GEngine->GetWorldFromContextObject(WorldContextObject, EGetWorldErrorMode::ReturnNull); if(!World) return; //~~~~~~~~~~~ - + SelectedActors.Empty(); - + FBox2D Box; Box+=DraggedPoint; Box+=AnchorPoint; - + for(TActorIterator Itr(World); Itr; ++Itr) { if(!Itr->IsA(ClassFilter)) continue; //~~~~~~~~~~~~~~~~~~ - + if(Box.IsInside(UVictoryBPFunctionLibrary::ProjectWorldToScreenPosition(Itr->GetActorLocation()))) { SelectedActors.Add(*Itr); @@ -2244,23 +2255,23 @@ void UVictoryBPFunctionLibrary::Selection_SelectionBox(UObject* WorldContextObje bool UVictoryBPFunctionLibrary::PlayerController_GetControllerID(APlayerController* ThePC, int32& ControllerID) { if(!ThePC) return false; - + ULocalPlayer * LP = Cast(ThePC->Player); if(!LP) return false; - + ControllerID = LP->GetControllerId(); - + 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; } @@ -2272,8 +2283,8 @@ void UVictoryBPFunctionLibrary::Open_URL_In_Web_Browser(FString TheURL) void UVictoryBPFunctionLibrary::OperatingSystem__GetCurrentPlatform( bool& Windows_, //some weird bug of making it all caps engine-side bool& Mac, - bool& Linux, - bool& iOS, + bool& Linux, + bool& iOS, bool& Android, bool& Android_ARM, bool& Android_Vulkan, @@ -2286,23 +2297,23 @@ void UVictoryBPFunctionLibrary::OperatingSystem__GetCurrentPlatform( Windows_ = PLATFORM_WINDOWS; Mac = PLATFORM_MAC; Linux = PLATFORM_LINUX; - + PS4 = PLATFORM_PS4; XBoxOne = PLATFORM_XBOXONE; - + iOS = PLATFORM_IOS; Android = PLATFORM_ANDROID; Android_ARM = PLATFORM_ANDROID_ARM; Android_Vulkan = PLATFORM_ANDROID_VULKAN; HTML5 = PLATFORM_HTML5; - + Apple = PLATFORM_APPLE; } -FString UVictoryBPFunctionLibrary::RealWorldTime__GetCurrentOSTime( +FString UVictoryBPFunctionLibrary::RealWorldTime__GetCurrentOSTime( int32& MilliSeconds, - int32& Seconds, - int32& Minutes, + int32& Seconds, + int32& Minutes, int32& Hours12, int32& Hours24, int32& Day, @@ -2310,7 +2321,7 @@ FString UVictoryBPFunctionLibrary::RealWorldTime__GetCurrentOSTime( int32& Year ){ const FDateTime Now = FDateTime::Now(); - + MilliSeconds = Now.GetMillisecond( ); Seconds = Now.GetSecond( ); Minutes = Now.GetMinute( ); @@ -2319,7 +2330,7 @@ FString UVictoryBPFunctionLibrary::RealWorldTime__GetCurrentOSTime( Day = Now.GetDay( ); Month = Now.GetMonth( ); Year = Now.GetYear( ); - + //MS are not included in FDateTime::ToString(), so adding it //The Parse function accepts if MS are present. FString NowWithMS = Now.ToString(); @@ -2337,13 +2348,13 @@ void UVictoryBPFunctionLibrary::RealWorldTime__GetTimePassedSincePreviousTime( 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, @@ -2354,12 +2365,12 @@ void UVictoryBPFunctionLibrary::RealWorldTime__GetDifferenceBetweenTimes( ){ FDateTime ParsedDateTime1; FDateTime::Parse(PreviousTime1,ParsedDateTime1); - + FDateTime ParsedDateTime2; FDateTime::Parse(PreviousTime2,ParsedDateTime2); - - FTimespan TimeDiff; - + + FTimespan TimeDiff; + if(PreviousTime1 < PreviousTime2) { TimeDiff = ParsedDateTime2 - ParsedDateTime1; @@ -2368,7 +2379,7 @@ void UVictoryBPFunctionLibrary::RealWorldTime__GetDifferenceBetweenTimes( { TimeDiff = ParsedDateTime1 - ParsedDateTime2; } - + Milliseconds = TimeDiff.GetTotalMilliseconds( ); Seconds = TimeDiff.GetTotalSeconds( ); Minutes = TimeDiff.GetTotalMinutes( ); @@ -2409,67 +2420,67 @@ bool UVictoryBPFunctionLibrary::CharacterMovement__SetMaxMoveSpeed(ACharacter* T { return false; } - + TheCharacter->GetCharacterMovement()->MaxWalkSpeed = NewMaxMoveSpeed; - + return true; } - + int32 UVictoryBPFunctionLibrary::Conversion__FloatToRoundedInteger(float IN_Float) { return FGenericPlatformMath::RoundToInt(IN_Float); } - + FString UVictoryBPFunctionLibrary::Victory_SecondsToHoursMinutesSeconds(float Seconds, bool TrimZeroes) { FString Str = FTimespan(0, 0, Seconds).ToString(); - + if(TrimZeroes) { FString Left,Right; Str.Split(TEXT("."),&Left,&Right); Str = Left; Str.ReplaceInline(TEXT("00:00"), TEXT("00")); - - //Str Count! + + //Str Count! int32 Count = CountOccurrancesOfSubString(Str,":"); - + //Remove Empty Hours if(Count >= 2) { Str.ReplaceInline(TEXT("00:"), TEXT("")); - } + } } - + return Str; } bool UVictoryBPFunctionLibrary::IsAlphaNumeric(const FString& String) { std::string str = (TCHAR_TO_UTF8(*String)); - + for ( std::string::iterator it=str.begin(); it!=str.end(); ++it) { if(!isalnum(*it)) - { + { return false; } } - + return true; } void UVictoryBPFunctionLibrary::Victory_GetStringFromOSClipboard(FString& FromClipboard) -{ +{ FPlatformApplicationMisc::ClipboardPaste(FromClipboard); -} +} void UVictoryBPFunctionLibrary::Victory_SaveStringToOSClipboard(const FString& ToClipboard) { FPlatformApplicationMisc::ClipboardCopy(*ToClipboard); } - + bool UVictoryBPFunctionLibrary::HasSubstring(const FString& SearchIn, const FString& Substring, ESearchCase::Type SearchCase, ESearchDir::Type SearchDir) { @@ -2481,7 +2492,7 @@ FString UVictoryBPFunctionLibrary::String__CombineStrings(FString StringFirst, F return StringFirstLabel + StringFirst + Separator + StringSecondLabel + StringSecond; } FString UVictoryBPFunctionLibrary::String__CombineStrings_Multi(FString A, FString B) -{ +{ return A + " " + B; } @@ -2491,9 +2502,9 @@ bool UVictoryBPFunctionLibrary::OptionsMenu__GetDisplayAdapterScreenResolutions( Widths.Empty(); Heights.Empty(); RefreshRates.Empty(); - - TArray Unique; - + + TArray Unique; + FScreenResolutionArray Resolutions; if(RHIGetAvailableResolutions(Resolutions, false)) { @@ -2502,13 +2513,13 @@ bool UVictoryBPFunctionLibrary::OptionsMenu__GetDisplayAdapterScreenResolutions( 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! This is duplicate! @@ -2519,7 +2530,7 @@ bool UVictoryBPFunctionLibrary::OptionsMenu__GetDisplayAdapterScreenResolutions( //Add to Unique List! Unique.AddUnique(Str); } - + //Add to Actual Data Output! Widths.Add( EachResolution.Width); Heights.Add( EachResolution.Height); @@ -2532,18 +2543,18 @@ bool UVictoryBPFunctionLibrary::OptionsMenu__GetDisplayAdapterScreenResolutions( } void UVictoryBPFunctionLibrary::GetUserDisplayAdapterBrand(bool& IsAMD, bool& IsNvidia, bool& IsIntel, bool& IsUnknown, int32& UnknownId) -{ +{ IsAMD = IsRHIDeviceAMD(); IsNvidia = IsRHIDeviceNVIDIA(); IsIntel = IsRHIDeviceIntel(); - + IsUnknown = !IsAMD && !IsNvidia && !IsIntel; - + if(IsUnknown) { UnknownId = GRHIVendorId; } -} +} //Make .h's for these two! FRotator UVictoryBPFunctionLibrary::TransformVectorToActorSpaceAngle(AActor* Actor, const FVector& InVector) @@ -2563,70 +2574,70 @@ AStaticMeshActor* UVictoryBPFunctionLibrary::Clone__StaticMeshActor(UObject* Wor if(!ToClone) return NULL; if(!ToClone->IsValidLowLevel()) return NULL; //~~~~~~~~~~~~~~~~~~~~~~~~~~~ - + if(!WorldContextObject) return NULL; - + //using a context object to get the world! UWorld* const World = GEngine->GetWorldFromContextObject(WorldContextObject, EGetWorldErrorMode::ReturnNull); if(!World) return NULL; //~~~~~~~~~~~ - + //For BPS UClass* SpawnClass = ToClone->GetClass(); - + FActorSpawnParameters SpawnInfo; SpawnInfo.SpawnCollisionHandlingOverride = ESpawnActorCollisionHandlingMethod::AlwaysSpawn; SpawnInfo.Owner = ToClone; SpawnInfo.Instigator = NULL; SpawnInfo.bDeferConstruction = false; - + AStaticMeshActor* NewSMA = World->SpawnActor(SpawnClass, ToClone->GetActorLocation() + FVector(0,0,512) ,ToClone->GetActorRotation(), SpawnInfo ); - + if(!NewSMA) return NULL; - + //Copy Transform NewSMA->SetActorTransform(ToClone->GetTransform()); - + //Mobility NewSMA->GetStaticMeshComponent()->SetMobility(EComponentMobility::Movable ); - + //copy static mesh NewSMA->GetStaticMeshComponent()->SetStaticMesh(ToClone->GetStaticMeshComponent()->GetStaticMesh()); - + //~~~ - + //copy materials TArray Mats; ToClone->GetStaticMeshComponent()->GetUsedMaterials(Mats); - + const int32 Total = Mats.Num(); for(int32 v = 0; v < Total; v++ ) { NewSMA->GetStaticMeshComponent()->SetMaterial(v,Mats[v]); } - + //~~~ - + //copy physics state if(ToClone->GetStaticMeshComponent()->IsSimulatingPhysics()) { NewSMA->GetStaticMeshComponent()->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; } @@ -2637,61 +2648,61 @@ bool UVictoryBPFunctionLibrary::Actor__TeleportToActor(AActor* ActorToTeleport, 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 object to get the world! UWorld* const World = GEngine->GetWorldFromContextObject(WorldContextObject, EGetWorldErrorMode::ReturnNull); if(!World) return false; //~~~~~~~~~~~ - + return (World->WorldType == EWorldType::Editor ); } bool UVictoryBPFunctionLibrary::WorldType__InPIEWorld(UObject* WorldContextObject) { if(!WorldContextObject) return false; - + //using a context object to get the world! UWorld* const World = GEngine->GetWorldFromContextObject(WorldContextObject, EGetWorldErrorMode::ReturnNull); if(!World) return false; //~~~~~~~~~~~ - + return (World->WorldType == EWorldType::PIE ); } bool UVictoryBPFunctionLibrary::WorldType__InGameInstanceWorld(UObject* WorldContextObject) { if(!WorldContextObject) return false; - + //using a context object to get the world! UWorld* const World = GEngine->GetWorldFromContextObject(WorldContextObject, EGetWorldErrorMode::ReturnNull); if(!World) return false; //~~~~~~~~~~~ - + return (World->WorldType == EWorldType::Game ); } - + bool UVictoryBPFunctionLibrary::DoesMaterialHaveParameter(UMaterialInterface* Mat, FName Parameter) -{ - if(!Mat || Parameter == NAME_None) +{ + if(!Mat || Parameter == NAME_None) { return false; } - - //Lesson, always use the parent of a Material Instance Dynamic, + + //Lesson, always use the parent of a Material Instance Dynamic, // for some reason the dynamic version finds parameters that aren't actually valid. // -Rama UMaterialInterface* Parent = Mat; @@ -2700,25 +2711,25 @@ bool UVictoryBPFunctionLibrary::DoesMaterialHaveParameter(UMaterialInterface* Ma { Parent = MatInst->Parent; } - - if(!Parent) + + if(!Parent) { return false; - } - + } + float ScalarValue; if(Parent->GetScalarParameterValue(Parameter,ScalarValue)) { return true; } - + FLinearColor VectValue; if(Parent->GetVectorParameterValue(Parameter,VectValue)) { return true; } - - UTexture* T2DValue; + + UTexture* T2DValue; return Parent->GetTextureParameterValue(Parameter,T2DValue); } @@ -2741,7 +2752,7 @@ FRotator UVictoryBPFunctionLibrary::Character__GetControllerRotation(AActor * Th ACharacter * AsCharacter = Cast(TheCharacter); if (!AsCharacter) return FRotator::ZeroRotator; - + return AsCharacter->GetControlRotation(); } @@ -2752,51 +2763,51 @@ void UVictoryBPFunctionLibrary::Draw__Thick3DLineFromCharacterSocket(AActor* The if (!AsCharacter) return; if (!AsCharacter->GetMesh()) return; //~~~~~~~~~~~~~~~~~~~~ - + //Get World UWorld* TheWorld = AsCharacter->GetWorld(); if (!TheWorld) return; //~~~~~~~~~~~~~~~~~ - + const FVector SocketLocation = AsCharacter->GetMesh()->GetSocketLocation(Socket); DrawDebugLine( - TheWorld, - SocketLocation, - EndPoint, - LineColor.ToFColor(true), - false, - Duration, - 0, + TheWorld, + SocketLocation, + EndPoint, + LineColor.ToFColor(true), + 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 GetWorld() from TObjectIterator Itr; if (!Itr) return; //~~~~~~~~~~~~ - + //Get World UWorld* TheWorld = Itr->GetWorld(); if (!TheWorld) return; //~~~~~~~~~~~~~~~~~ - + const FVector SocketLocation = Mesh->GetSocketLocation(Socket); - + DrawDebugLine( - TheWorld, - SocketLocation, - EndPoint, + TheWorld, + SocketLocation, + EndPoint, LineColor.ToFColor(true), - false, - Duration, - 0, + false, + Duration, + 0, Thickness ); } @@ -2806,87 +2817,87 @@ void UVictoryBPFunctionLibrary::Draw__Thick3DLineBetweenActors(AActor * StartAct if (!StartActor) return; if (!EndActor) return; //~~~~~~~~~~~~~~~~ - + DrawDebugLine( - StartActor->GetWorld(), - StartActor->GetActorLocation(), - EndActor->GetActorLocation(), + StartActor->GetWorld(), + StartActor->GetActorLocation(), + EndActor->GetActorLocation(), LineColor.ToFColor(true), - false, - Duration, - 0, + false, + Duration, + 0, Thickness ); } - + bool UVictoryBPFunctionLibrary::Animation__GetAimOffsets(AActor* AnimBPOwner, float& Pitch, float& Yaw) { //Get Owning Character ACharacter * TheCharacter = Cast(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 this takes the direction vector, the PC or AI rotation - //and outputs what this dir is + //and outputs what this 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(AnimBPOwner); - + if (!TheCharacter) return false; //~~~~~~~~~~~~~~~ - + //using supplied rotation const FVector RotationDir = TheRotation.Vector(); - + //Inverse of ActorToWorld matrix is Actor to Local Space //so this takes the direction vector, the PC or AI rotation - //and outputs what this dir is + //and outputs what this 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(UObject* WorldContextObject, TArray& CurrentlyRenderedActors, float MinRecentTime) { if(!WorldContextObject) return; - + UWorld* const World = GEngine->GetWorldFromContextObject(WorldContextObject, EGetWorldErrorMode::ReturnNull); if(!World) return; //~~~~~~~~~~~ - + //Empty any previous entries CurrentlyRenderedActors.Empty(); - + //Iterate Over Actors for ( TActorIterator Itr(World); Itr; ++Itr ) { @@ -2894,19 +2905,19 @@ void UVictoryBPFunctionLibrary::Visibility__GetRenderedActors(UObject* WorldCont { CurrentlyRenderedActors.Add( * Itr); } - } -} + } +} void UVictoryBPFunctionLibrary::Visibility__GetNotRenderedActors(UObject* WorldContextObject, TArray& CurrentlyNotRenderedActors, float MinRecentTime) { if(!WorldContextObject) return; - + UWorld* const World = GEngine->GetWorldFromContextObject(WorldContextObject, EGetWorldErrorMode::ReturnNull); if(!World) return; //~~~~~~~~~~~ - + //Empty any previous entries CurrentlyNotRenderedActors.Empty(); - + //Iterate Over Actors for ( TActorIterator Itr(World); Itr; ++Itr ) { @@ -2925,9 +2936,9 @@ void UVictoryBPFunctionLibrary::Rendering__UnFreezeGameRendering() { FViewport::SetGameRenderingEnabled(true); } - + bool UVictoryBPFunctionLibrary::ClientWindow__GameWindowIsForeGroundInOS() -{ +{ return FPlatformApplicationMisc::IsThisApplicationForeground(); /* //Iterate Over Actors @@ -2939,30 +2950,30 @@ bool UVictoryBPFunctionLibrary::ClientWindow__GameWindowIsForeGroundInOS() //~~~~~~~~~~~~~~~~~~~~~~~ } //Get Player - ULocalPlayer* VictoryPlayer = - TheWorld->GetFirstLocalPlayerFromController(); + ULocalPlayer* VictoryPlayer = + TheWorld->GetFirstLocalPlayerFromController(); if (!VictoryPlayer) return false; //~~~~~~~~~~~~~~~~~~~~ - + //get view port ptr - UGameViewportClient * VictoryViewportClient = + 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 SaveDirectory, + FString JoyfulFileName, FString SaveText, bool AllowOverWriting ){ @@ -2972,11 +2983,11 @@ bool UVictoryBPFunctionLibrary::FileIO__SaveStringTextToFile( return false; //~~~~~~~~~~~~~~~~~~~~~~ } - + //get complete file path SaveDirectory += "\\"; SaveDirectory += JoyfulFileName; - + //No over-writing? if (!AllowOverWriting) { @@ -2987,10 +2998,10 @@ bool UVictoryBPFunctionLibrary::FileIO__SaveStringTextToFile( return false; } } - + return FFileHelper::SaveStringToFile(SaveText, * SaveDirectory); } -bool UVictoryBPFunctionLibrary::FileIO__SaveStringArrayToFile(FString SaveDirectory, FString JoyfulFileName, TArray SaveText, bool AllowOverWriting) +bool UVictoryBPFunctionLibrary::FileIO__SaveStringArrayToFile(FString SaveDirectory, FString JoyfulFileName, TArray SaveText, bool AllowOverWriting) { //Dir Exists? if ( !VCreateDirectory(SaveDirectory)) @@ -2999,11 +3010,11 @@ bool UVictoryBPFunctionLibrary::FileIO__SaveStringArrayToFile(FString SaveDirect return false; //~~~~~~~~~~~~~~~~~~~~~~ } - + //get complete file path SaveDirectory += "\\"; SaveDirectory += JoyfulFileName; - + //No over-writing? if (!AllowOverWriting) { @@ -3014,18 +3025,18 @@ bool UVictoryBPFunctionLibrary::FileIO__SaveStringArrayToFile(FString SaveDirect return false; } } - + FString FinalStr = ""; for(FString& Each : SaveText) { FinalStr += Each; FinalStr += LINE_TERMINATOR; } - + return FFileHelper::SaveStringToFile(FinalStr, * SaveDirectory); - + } float UVictoryBPFunctionLibrary::Calcs__ClosestPointToSourcePoint(const FVector & Source, const TArray& OtherPoints, FVector& ClosestPoint) { @@ -3033,18 +3044,18 @@ float UVictoryBPFunctionLibrary::Calcs__ClosestPointToSourcePoint(const FVector 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) { @@ -3052,7 +3063,7 @@ float UVictoryBPFunctionLibrary::Calcs__ClosestPointToSourcePoint(const FVector ClosestDistance = CurDist; } } - + //Out ClosestPoint = OtherPoints[ClosestVibe]; return ClosestDistance; @@ -3062,39 +3073,39 @@ bool UVictoryBPFunctionLibrary::Data__GetCharacterBoneLocations(AActor * TheChar { ACharacter * Source = Cast(TheCharacter); if (!Source) return false; - + if (!Source->GetMesh()) return false; //~~~~~~~~~~~~~~~~~~~~~~~~~ TArray BoneNames; - + BoneLocations.Empty(); - - + + //Get Bone Names Source->GetMesh()->GetBoneNames(BoneNames); - + //Get Bone Locations for (int32 Itr = 0; Itr < BoneNames.Num(); Itr++ ) { BoneLocations.Add(Source->GetMesh()->GetBoneLocation(BoneNames[Itr])); } - + return true; } USkeletalMeshComponent* UVictoryBPFunctionLibrary::Accessor__GetCharacterSkeletalMesh(AActor * TheCharacter, bool& IsValid) { IsValid = false; - + ACharacter * AsCharacter = Cast(TheCharacter); if (!AsCharacter) return NULL; //~~~~~~~~~~~~~~~~~ - + //Is Valid? if (AsCharacter->GetMesh()) - if (AsCharacter->GetMesh()->IsValidLowLevel() ) + if (AsCharacter->GetMesh()->IsValidLowLevel() ) IsValid = true; - + return AsCharacter->GetMesh(); } @@ -3102,101 +3113,101 @@ bool UVictoryBPFunctionLibrary::TraceData__GetTraceDataFromCharacterSocket( FVector & TraceStart, //out FVector & TraceEnd, //out AActor * TheCharacter, - const FRotator& TraceRotation, + const FRotator& TraceRotation, float TraceLength, - FName Socket, - bool DrawTraceData, - FLinearColor TraceDataColor, + FName Socket, + bool DrawTraceData, + FLinearColor TraceDataColor, float TraceDataThickness ) { ACharacter * AsCharacter = Cast(TheCharacter); if (!AsCharacter) return false; - + //Mesh Exists? if (!AsCharacter->GetMesh()) return false; - + //Socket Exists? if (!AsCharacter->GetMesh()->DoesSocketExist(Socket)) return false; //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - + TraceStart = AsCharacter->GetMesh()->GetSocketLocation(Socket); TraceEnd = TraceStart + TraceRotation.Vector() * TraceLength; - - if (DrawTraceData) + + if (DrawTraceData) { //Get World UWorld* TheWorld = AsCharacter->GetWorld(); if (!TheWorld) return false; //~~~~~~~~~~~~~~~~~ - + DrawDebugLine( - TheWorld, - TraceStart, - TraceEnd, + TheWorld, + TraceStart, + TraceEnd, TraceDataColor.ToFColor(true), - false, - 0.0333, - 0, + false, + 0.0333, + 0, TraceDataThickness ); } - + return true; } bool UVictoryBPFunctionLibrary::TraceData__GetTraceDataFromSkeletalMeshSocket( FVector & TraceStart, //out FVector & TraceEnd, //out USkeletalMeshComponent * Mesh, - const FRotator & TraceRotation, + const FRotator & TraceRotation, float TraceLength, - FName Socket, - bool DrawTraceData, - FLinearColor TraceDataColor, + 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) + + if (DrawTraceData) { //Get a PC to GetWorld() from TObjectIterator Itr; if (!Itr) return false; - + //~~~~~~~~~~~~ - + //Get World UWorld* TheWorld = Itr->GetWorld(); if (!TheWorld) return false; //~~~~~~~~~~~~~~~~~ - + DrawDebugLine( - TheWorld, - TraceStart, - TraceEnd, + TheWorld, + TraceStart, + TraceEnd, TraceDataColor.ToFColor(true), - false, - 0.0333, - 0, + false, + 0.0333, + 0, TraceDataThickness ); } - + return true; } AActor* UVictoryBPFunctionLibrary::Traces__CharacterMeshTrace___ClosestBone( AActor* TraceOwner, - const FVector & TraceStart, - const FVector & TraceEnd, - FVector & OutImpactPoint, - FVector & OutImpactNormal, + const FVector & TraceStart, + const FVector & TraceEnd, + FVector & OutImpactPoint, + FVector & OutImpactNormal, FName & ClosestBoneName, FVector & ClosestBoneLocation, bool& IsValid @@ -3205,149 +3216,149 @@ AActor* UVictoryBPFunctionLibrary::Traces__CharacterMeshTrace___ClosestBone( IsValid = false; AActor * HitActor = NULL; //~~~~~~~~~~~~~~~~~~~~~~ - + //Get a PC to GetWorld() from TObjectIterator Itr; if (!Itr) return NULL; - + //~~~~~~~~~~~~ - + //Get World UWorld* TheWorld = Itr->GetWorld(); 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->LineTraceSingleByChannel( RV_Hit, //result - TraceStart, - TraceEnd, + TraceStart, + TraceEnd, ECC_Pawn, //collision channel TraceParams ); - + //Hit Something! if (!RV_Hit.bBlockingHit) return HitActor; - - + + //Character? HitActor = RV_Hit.GetActor(); ACharacter * AsCharacter = Cast(HitActor); if (!AsCharacter) return HitActor; - + //Mesh if (!AsCharacter->GetMesh()) return HitActor; - + //Component Trace FHitResult Hit; IsValid = AsCharacter->GetMesh()->K2_LineTraceComponent( - TraceStart, - TraceEnd, - true, - false, + TraceStart, + TraceEnd, + true, + false, false, - OutImpactPoint, + OutImpactPoint, OutImpactNormal, ClosestBoneName, Hit - ); - + ); + //Location ClosestBoneLocation = AsCharacter->GetMesh()->GetBoneLocation(ClosestBoneName); - + return HitActor; } AActor* UVictoryBPFunctionLibrary::Traces__CharacterMeshTrace___ClosestSocket( UObject* WorldContextObject, - const AActor * TraceOwner, - const FVector & TraceStart, - const FVector & TraceEnd, - FVector & OutImpactPoint, - FVector & OutImpactNormal, - FName & ClosestSocketName, - FVector & SocketLocation, + const AActor * TraceOwner, + const FVector & TraceStart, + const FVector & TraceEnd, + FVector & OutImpactPoint, + FVector & OutImpactNormal, + FName & ClosestSocketName, + FVector & SocketLocation, bool & IsValid ) { IsValid = false; AActor * HitActor = NULL; //~~~~~~~~~~~~~~~~~~~~~~ - + if(!WorldContextObject) return nullptr; - + UWorld* const TheWorld = GEngine->GetWorldFromContextObject(WorldContextObject, EGetWorldErrorMode::ReturnNull); if(!TheWorld) return nullptr; //~~~~~~~~~~~ - + //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->LineTraceSingleByChannel( RV_Hit, //result - TraceStart, - TraceEnd, + TraceStart, + TraceEnd, ECC_Pawn, //collision channel TraceParams ); - + //Hit Something! if (!RV_Hit.bBlockingHit) return HitActor; - - + + //Character? HitActor = RV_Hit.GetActor(); ACharacter * AsCharacter = Cast(HitActor); if (!AsCharacter) return HitActor; - + //Mesh if (!AsCharacter->GetMesh()) return HitActor; - + //Component Trace FHitResult Hit; FName BoneName; if (! AsCharacter->GetMesh()->K2_LineTraceComponent( - TraceStart, - TraceEnd, - true, - false, + TraceStart, + TraceEnd, + true, + false, false, - OutImpactPoint, + OutImpactPoint, OutImpactNormal, BoneName, Hit )) return HitActor; - + //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // Socket Names TArray SocketNames; - + //Get Bone Names AsCharacter->GetMesh()->QuerySupportedSockets(SocketNames); - + // Min FVector CurLoc; float CurDist = 0; float ClosestDistance = -1; int32 ClosestVibe = 0; - + //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //Check All Bones Locations for (int32 Itr = 0; Itr < SocketNames.Num(); Itr++ ) @@ -3355,12 +3366,12 @@ AActor* UVictoryBPFunctionLibrary::Traces__CharacterMeshTrace___ClosestSocket( //Is this a Bone not a socket? if(SocketNames[Itr].Type == EComponentSocketType::Bone) continue; //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - + CurLoc = AsCharacter->GetMesh()->GetSocketLocation(SocketNames[Itr].Name); - + //Dist CurDist = FVector::Dist(OutImpactPoint, CurLoc); - + //Min if (ClosestDistance < 0 || ClosestDistance >= CurDist) { @@ -3368,20 +3379,20 @@ AActor* UVictoryBPFunctionLibrary::Traces__CharacterMeshTrace___ClosestSocket( ClosestDistance = CurDist; } } - + //Name ClosestSocketName = SocketNames[ClosestVibe].Name; - + //Location SocketLocation = AsCharacter->GetMesh()->GetSocketLocation(ClosestSocketName); - + //Valid IsValid = true; - + //Actor return HitActor; } - + void UVictoryBPFunctionLibrary::VictorySimulateMouseWheel(const float& Delta) { FSlateApplication::Get().OnMouseWheel(int32(Delta)); @@ -3391,7 +3402,7 @@ void UVictoryBPFunctionLibrary::VictorySimulateKeyPress(APlayerController* ThePC if (!ThePC) return; ThePC->InputKey(Key, EventType, 1, false); //amount depressed, bGamepad //! This will fire twice if the event is not handled, for umg widgets place an invisible button in background. - + if (Key == EKeys::LeftMouseButton || Key == EKeys::MiddleMouseButton || Key == EKeys::RightMouseButton || Key == EKeys::ThumbMouseButton || Key == EKeys::ThumbMouseButton2) { EMouseButtons::Type Button = EMouseButtons::Invalid; @@ -3450,24 +3461,24 @@ void UVictoryBPFunctionLibrary::VictorySimulateKeyPress(APlayerController* ThePC } bool UVictoryBPFunctionLibrary::Viewport__EnableWorldRendering(const APlayerController* ThePC, bool RenderTheWorld) -{ +{ if (!ThePC) return false; //~~~~~~~~~~~~~ - + //Get Player - ULocalPlayer * VictoryPlayer = Cast(ThePC->Player); + ULocalPlayer * VictoryPlayer = Cast(ThePC->Player); //PlayerController::Player is UPlayer - + if (!VictoryPlayer) return false; //~~~~~~~~~~~~~~~~~~~~ - + //get view port ptr - UGameViewportClient * VictoryViewportClient = + UGameViewportClient * VictoryViewportClient = Cast < UGameViewportClient > (VictoryPlayer->ViewportClient); - + if (!VictoryViewportClient) return false; //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - + VictoryViewportClient->bDisableWorldRendering = !RenderTheWorld; return true; } @@ -3477,83 +3488,83 @@ bool UVictoryBPFunctionLibrary::Viewport__SetMousePosition(const APlayerControll { if (!ThePC) return false; //~~~~~~~~~~~~~ - + //Get Player - const ULocalPlayer * VictoryPlayer = Cast(ThePC->Player); + const ULocalPlayer * VictoryPlayer = Cast(ThePC->Player); //PlayerController::Player is UPlayer - + if (!VictoryPlayer) return false; //~~~~~~~~~~~~~~~~~~~~ - + //get view port ptr - const UGameViewportClient * VictoryViewportClient = + 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, + AActor * TheCharacter, bool & IsValid ) { IsValid = false; - + //Cast to Character ACharacter * AsCharacter = Cast(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(ThePC->Player); + const ULocalPlayer * VictoryPlayer = Cast(ThePC->Player); //PlayerController::Player is UPlayer - + if (!VictoryPlayer) return false; //~~~~~~~~~~~~~~~~~~~~ - + //get view port ptr - const UGameViewportClient * VictoryViewportClient = + 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; } @@ -3561,29 +3572,29 @@ bool UVictoryBPFunctionLibrary::Viewport__GetMousePosition(const APlayerControll { if (!ThePC) return false; //~~~~~~~~~~~~~ - + //Get Player - const ULocalPlayer * VictoryPlayer = Cast(ThePC->Player); + const ULocalPlayer * VictoryPlayer = Cast(ThePC->Player); //PlayerController::Player is UPlayer - + if (!VictoryPlayer) return false; //~~~~~~~~~~~~~~~~~~~~ - + //get view port ptr - const UGameViewportClient * VictoryViewportClient = + 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; } @@ -3595,13 +3606,13 @@ bool UVictoryBPFunctionLibrary::Physics__EnterRagDoll(AActor * TheCharacter) { ACharacter * AsCharacter = Cast(TheCharacter); if (!AsCharacter) return false; - + //Mesh? if (!AsCharacter->GetMesh()) return false; - + //Physics Asset? if(!AsCharacter->GetMesh()->GetPhysicsAsset()) return false; - + //Victory Ragdoll AsCharacter->GetMesh()->SetSimulatePhysics(true); @@ -3613,15 +3624,15 @@ bool UVictoryBPFunctionLibrary::Physics__LeaveRagDoll( AActor* TheCharacter, bool SetToFallingMovementMode, float HeightAboveRBMesh, - const FVector& InitLocation, + const FVector& InitLocation, const FRotator& InitRotation ){ ACharacter * AsCharacter = Cast(TheCharacter); if (!AsCharacter) return false; - + //Mesh? if (!AsCharacter->GetMesh()) return false; - + //Set Actor Location to Be Near Ragdolled Mesh //Calc Ref Bone Relative Pos for use with IsRagdoll TArray BoneNames; @@ -3630,43 +3641,43 @@ bool UVictoryBPFunctionLibrary::Physics__LeaveRagDoll( { AsCharacter->SetActorLocation(FVector(0,0,HeightAboveRBMesh) + AsCharacter->GetMesh()->GetBoneLocation(BoneNames[0])); } - + //Exit Ragdoll AsCharacter->GetMesh()->SetSimulatePhysics(false); AsCharacter->GetMesh()->AttachToComponent(AsCharacter->GetCapsuleComponent(), FAttachmentTransformRules::KeepRelativeTransform); - + //Restore Defaults AsCharacter->GetMesh()->SetRelativeRotation(InitRotation); AsCharacter->GetMesh()->SetRelativeLocation(InitLocation); - + //Set Falling After Final Capsule Relocation if(SetToFallingMovementMode) - { - if(AsCharacter->GetCharacterMovement()) AsCharacter->GetCharacterMovement()->SetMovementMode(MOVE_Falling); + { + if(AsCharacter->GetCharacterMovement()) AsCharacter->GetCharacterMovement()->SetMovementMode(MOVE_Falling); } - + return true; -} +} bool UVictoryBPFunctionLibrary::Physics__IsRagDoll(AActor* TheCharacter) { ACharacter * AsCharacter = Cast(TheCharacter); if (!AsCharacter) return false; - + //Mesh? if (!AsCharacter->GetMesh()) return false; - + return AsCharacter->GetMesh()->IsAnySimulatingPhysics(); -} +} bool UVictoryBPFunctionLibrary::Physics__GetLocationofRagDoll(AActor* TheCharacter, FVector& RagdollLocation) { ACharacter * AsCharacter = Cast(TheCharacter); if (!AsCharacter) return false; - + //Mesh? if (!AsCharacter->GetMesh()) return false; - + TArray BoneNames; AsCharacter->GetMesh()->GetBoneNames(BoneNames); if(BoneNames.Num() > 0) @@ -3674,41 +3685,41 @@ bool UVictoryBPFunctionLibrary::Physics__GetLocationofRagDoll(AActor* TheCharact RagdollLocation = AsCharacter->GetMesh()->GetBoneLocation(BoneNames[0]); } else return false; - + return true; } bool UVictoryBPFunctionLibrary::Physics__InitializeVictoryRagDoll( - AActor* TheCharacter, - FVector& InitLocation, + AActor* TheCharacter, + FVector& InitLocation, FRotator& InitRotation ){ ACharacter * AsCharacter = Cast(TheCharacter); if (!AsCharacter) return false; - + //Mesh? if (!AsCharacter->GetMesh()) return false; - + InitLocation = AsCharacter->GetMesh()->GetRelativeTransform().GetLocation(); InitRotation = AsCharacter->GetMesh()->GetRelativeTransform().Rotator(); - + return true; } bool UVictoryBPFunctionLibrary::Physics__UpdateCharacterCameraToRagdollLocation( - AActor* TheCharacter, + AActor* TheCharacter, float HeightOffset, float InterpSpeed ){ ACharacter * AsCharacter = Cast(TheCharacter); if (!AsCharacter) return false; - + //Mesh? if (!AsCharacter->GetMesh()) return false; - + //Ragdoll? if(!AsCharacter->GetMesh()->IsAnySimulatingPhysics()) return false; - + FVector RagdollLocation = FVector(0,0,0); TArray BoneNames; AsCharacter->GetMesh()->GetBoneNames(BoneNames); @@ -3716,52 +3727,52 @@ bool UVictoryBPFunctionLibrary::Physics__UpdateCharacterCameraToRagdollLocation( { RagdollLocation = AsCharacter->GetMesh()->GetBoneLocation(BoneNames[0]); } - + //Interp RagdollLocation = FMath::VInterpTo(AsCharacter->GetActorLocation(), RagdollLocation + FVector(0,0,HeightOffset), AsCharacter->GetWorld()->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, int32 Precision, bool IncludeLeadingZero) -{ +{ FNumberFormattingOptions NumberFormat; //Text.h NumberFormat.MinimumIntegralDigits = (IncludeLeadingZero) ? 1 : 0; NumberFormat.MaximumIntegralDigits = 10000; NumberFormat.MinimumFractionalDigits = Precision; - NumberFormat.MaximumFractionalDigits = Precision; + NumberFormat.MaximumFractionalDigits = Precision; FloatString = FText::AsNumber(TheFloat, &NumberFormat).ToString(); } bool UVictoryBPFunctionLibrary::LensFlare__GetLensFlareOffsets( APlayerController* PlayerController, - AActor* LightSource, - float& PitchOffset, - float& YawOffset, + 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; @@ -3774,7 +3785,7 @@ float UVictoryBPFunctionLibrary::DistanceToSurface__DistaceOfPointToMeshSurface( if(!TheSMA) return -1; if(!TheSMA->GetStaticMeshComponent()) return -1; //~~~~~~~~~~ - + //Dist of pt to Surface, retrieve closest Surface Point to Actor return TheSMA->GetStaticMeshComponent()->GetDistanceToCollision(TestPoint, ClosestSurfacePoint); } @@ -3786,9 +3797,9 @@ bool UVictoryBPFunctionLibrary::Mobility__SetSceneCompMobility( { if(!SceneComp) return false; //~~~~~~~~~~~ - + SceneComp->SetMobility(NewMobility); - + return true; } @@ -3812,15 +3823,15 @@ bool UVictoryBPFunctionLibrary::Mobility__SetSceneCompMobility( //~~~~~~~~~~~~~~~~~~ // FullScreen -//~~~~~~~~~~~~~~~~~~ +//~~~~~~~~~~~~~~~~~~ TEnumAsByte UVictoryBPFunctionLibrary::JoyGraphicsSettings__FullScreen_Get() { return TEnumAsByte(JoyGraphics_FullScreen_GetFullScreenType()); } - + void UVictoryBPFunctionLibrary::JoyGraphicsSettings__FullScreen_Set(TEnumAsByte NewSetting) -{ - JoyGraphics_FullScreen_SetFullScreenType(NewSetting.GetValue()); +{ + JoyGraphics_FullScreen_SetFullScreenType(NewSetting.GetValue()); } @@ -3847,7 +3858,7 @@ void UVictoryBPFunctionLibrary::JoyGraphicsSettings__FullScreen_Set(TEnumAsByte< * can override with seed functions; */ //----------------------------------------------------------------------------------------------BeginRANDOM - std::random_device rd; + std::random_device rd; unsigned seed = std::chrono::system_clock::now().time_since_epoch().count(); std::mt19937 rand_MT; @@ -3956,7 +3967,7 @@ void UVictoryBPFunctionLibrary::String__ExplodeString(TArray& OutputStr { OutputStrings.Empty(); //~~~~~~~~~~~ - + if (InputString.Len() > 0 && Separator.Len() > 0) { int32 StringIndex = 0; int32 SeparatorIndex = 0; @@ -3986,7 +3997,7 @@ void UVictoryBPFunctionLibrary::String__ExplodeString(TArray& OutputStr } //if we have reached the limit, stop. - if (limit > 0 && OutputStrings.Num() >= limit) + if (limit > 0 && OutputStrings.Num() >= limit) { return; //~~~~ @@ -4059,7 +4070,7 @@ UTexture2D* UVictoryBPFunctionLibrary::LoadTexture2D_FromDDSFile(const FString& if(!Texture) return NULL; Texture->PlatformData->NumSlices = 1; Texture->NeverStream = true; - + /* Get pointer to actual data */ uint8* DataPtr = (uint8*) DDSLoadHelper.GetDDSDataPointer( ); @@ -4129,30 +4140,30 @@ static EImageFormat GetJoyImageFormat(EJoyImageFormats JoyFormat) ImageWrapper.h namespace EImageFormat { - + Enumerates the types of image formats this class can handle - + enum Type { //Portable Network Graphics PNG, - //Joint Photographic Experts Group + //Joint Photographic Experts Group JPEG, //Single channel jpeg - GrayscaleJPEG, + GrayscaleJPEG, - //Windows Bitmap + //Windows Bitmap BMP, - //Windows Icon resource + //Windows Icon resource ICO, - //OpenEXR (HDR) image file format + //OpenEXR (HDR) image file format EXR, - //Mac icon + //Mac icon ICNS }; }; @@ -4167,7 +4178,7 @@ static EImageFormat GetJoyImageFormat(EJoyImageFormats JoyFormat) case EJoyImageFormats::ICNS : return EImageFormat::ICNS; } return EImageFormat::JPEG; -} +} static FString GetJoyImageExtension(EJoyImageFormats JoyFormat) { @@ -4181,38 +4192,38 @@ static FString GetJoyImageExtension(EJoyImageFormats JoyFormat) case EJoyImageFormats::ICNS : return ".icns"; } return ".png"; -} +} UTexture2D* UVictoryBPFunctionLibrary::Victory_LoadTexture2D_FromFile(const FString& FullFilePath,EJoyImageFormats ImageFormat, bool& IsValid,int32& Width, int32& Height) { - - + + IsValid = false; UTexture2D* LoadedT2D = NULL; - + IImageWrapperModule& ImageWrapperModule = FModuleManager::LoadModuleChecked(FName("ImageWrapper")); TSharedPtr ImageWrapper = ImageWrapperModule.CreateImageWrapper(GetJoyImageFormat(ImageFormat)); - + //Load From File TArray RawFileData; if (!FFileHelper::LoadFileToArray(RawFileData, *FullFilePath)) return NULL; //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - + //Create T2D! if (ImageWrapper.IsValid() && ImageWrapper->SetCompressed(RawFileData.GetData(), RawFileData.Num())) - { + { const TArray* UncompressedBGRA = NULL; if (ImageWrapper->GetRaw(ERGBFormat::BGRA, 8, UncompressedBGRA)) { LoadedT2D = UTexture2D::CreateTransient(ImageWrapper->GetWidth(), ImageWrapper->GetHeight(), PF_B8G8R8A8); - + //Valid? if(!LoadedT2D) return NULL; //~~~~~~~~~~~~~~ - + //Out! Width = ImageWrapper->GetWidth(); Height = ImageWrapper->GetHeight(); - + //Copy! void* TextureData = LoadedT2D->PlatformData->Mips[0].BulkData.Lock(LOCK_READ_WRITE); FMemory::Memcpy(TextureData, UncompressedBGRA->GetData(), UncompressedBGRA->Num()); @@ -4222,7 +4233,7 @@ UTexture2D* UVictoryBPFunctionLibrary::Victory_LoadTexture2D_FromFile(const FStr LoadedT2D->UpdateResource(); } } - + // Success! IsValid = true; return LoadedT2D; @@ -4231,44 +4242,44 @@ UTexture2D* UVictoryBPFunctionLibrary::Victory_LoadTexture2D_FromFile_Pixels(con { //Clear any previous data OutPixels.Empty(); - + IsValid = false; UTexture2D* LoadedT2D = NULL; - + IImageWrapperModule& ImageWrapperModule = FModuleManager::LoadModuleChecked(FName("ImageWrapper")); TSharedPtr ImageWrapper = ImageWrapperModule.CreateImageWrapper(GetJoyImageFormat(ImageFormat)); - + //Load From File TArray RawFileData; if (!FFileHelper::LoadFileToArray(RawFileData, *FullFilePath)) return NULL; //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - + //Create T2D! if (ImageWrapper.IsValid() && ImageWrapper->SetCompressed(RawFileData.GetData(), RawFileData.Num())) - { + { const TArray* UncompressedRGBA = NULL; if (ImageWrapper->GetRaw(ERGBFormat::RGBA, 8, UncompressedRGBA)) { LoadedT2D = UTexture2D::CreateTransient(ImageWrapper->GetWidth(), ImageWrapper->GetHeight(), PF_R8G8B8A8); - + //Valid? if(!LoadedT2D) return NULL; //~~~~~~~~~~~~~~ - + //Out! Width = ImageWrapper->GetWidth(); Height = ImageWrapper->GetHeight(); - + const TArray& ByteArray = *UncompressedRGBA; //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - - for(int32 v = 0; v < ByteArray.Num(); v+=4) - { - if(!ByteArray.IsValidIndex(v+3)) - { + + for(int32 v = 0; v < ByteArray.Num(); v+=4) + { + if(!ByteArray.IsValidIndex(v+3)) + { break; - } - + } + OutPixels.Add( FLinearColor( ByteArray[v], //R @@ -4279,7 +4290,7 @@ UTexture2D* UVictoryBPFunctionLibrary::Victory_LoadTexture2D_FromFile_Pixels(con ); } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - + //Copy! void* TextureData = LoadedT2D->PlatformData->Mips[0].BulkData.Lock(LOCK_READ_WRITE); FMemory::Memcpy(TextureData, UncompressedRGBA->GetData(), UncompressedRGBA->Num()); @@ -4289,11 +4300,11 @@ UTexture2D* UVictoryBPFunctionLibrary::Victory_LoadTexture2D_FromFile_Pixels(con LoadedT2D->UpdateResource(); } } - + // Success! IsValid = true; return LoadedT2D; - + } bool UVictoryBPFunctionLibrary::Victory_Get_Pixel(const TArray& Pixels,int32 ImageHeight, int32 x, int32 y, FLinearColor& FoundColor) { @@ -4302,7 +4313,7 @@ bool UVictoryBPFunctionLibrary::Victory_Get_Pixel(const TArray& Pi { return false; } - + FoundColor = Pixels[Index]; return true; } @@ -4310,112 +4321,112 @@ bool UVictoryBPFunctionLibrary::Victory_Get_Pixel(const TArray& Pi bool UVictoryBPFunctionLibrary::Victory_SavePixels( const FString& FullFilePath - , int32 Width, int32 Height + , int32 Width, int32 Height , const TArray& ImagePixels , bool SaveAsBMP , bool sRGB , FString& ErrorString ){ - if(FullFilePath.Len() < 1) + if(FullFilePath.Len() < 1) { ErrorString = "No file path"; return false; } //~~~~~~~~~~~~~~~~~ - - //Ensure target directory exists, + + //Ensure target directory exists, // _or can be created!_ <3 Rama FString NewAbsoluteFolderPath = FPaths::GetPath(FullFilePath); FPaths::NormalizeDirectoryName(NewAbsoluteFolderPath); - if(!VCreateDirectory(NewAbsoluteFolderPath)) + if(!VCreateDirectory(NewAbsoluteFolderPath)) { ErrorString = "Folder could not be created, check read/write permissions~ " + NewAbsoluteFolderPath; return false; } - + //Create FColor version TArray ColorArray; for(const FLinearColor& Each : ImagePixels) - { - ColorArray.Add(Each.ToFColor(sRGB)); - } - - if(ColorArray.Num() != Width * Height) + { + ColorArray.Add(Each.ToFColor(sRGB)); + } + + if(ColorArray.Num() != Width * Height) { ErrorString = "Error ~ height x width is not equal to the total pixel array length!"; return false; } - + //Remove any supplied file extension and/or add accurate one FString FinalFilename = FPaths::GetBaseFilename(FullFilePath, false); //false = dont remove path - FinalFilename += (SaveAsBMP) ? ".bmp" : ".png"; - + FinalFilename += (SaveAsBMP) ? ".bmp" : ".png"; + //~~~ - + if(SaveAsBMP) - { + { ErrorString = "Success! or if returning false, the saving of file to disk did not succeed for File IO reasons"; - return FFileHelper::CreateBitmap( - *FinalFilename, - Width, - Height, - ColorArray.GetData(), //const struct FColor* Data, - nullptr,//struct FIntRect* SubRectangle = NULL, - &IFileManager::Get(), - nullptr, //out filename info only - true //bool bInWriteAlpha + return FFileHelper::CreateBitmap( + *FinalFilename, + Width, + Height, + ColorArray.GetData(), //const struct FColor* Data, + nullptr,//struct FIntRect* SubRectangle = NULL, + &IFileManager::Get(), + nullptr, //out filename info only + true //bool bInWriteAlpha ); } else { TArray CompressedPNG; - FImageUtils::CompressImageArray( - Width, - Height, - ColorArray, + FImageUtils::CompressImageArray( + Width, + Height, + ColorArray, CompressedPNG ); - + ErrorString = "Success! or if returning false, the saving of file to disk did not succeed for File IO reasons"; return FFileHelper::SaveArrayToFile(CompressedPNG, *FinalFilename); - } - + } + /* //Crashed for JPG, worked great for PNG //Maybe also works for BMP so could offer those two as save options? - + const int32 x = Width; const int32 y = Height; - if(ColorArray.Num() != x * y) + if(ColorArray.Num() != x * y) { ErrorString = "Error ~ height x width is not equal to the total pixel array length!"; return false; } - + //Image Wrapper Module IImageWrapperModule& ImageWrapperModule = FModuleManager::LoadModuleChecked(FName("ImageWrapper")); - + //Create Compressor IImageWrapperPtr ImageWrapper = ImageWrapperModule.CreateImageWrapper(GetJoyImageFormat(ImageFormat)); - - if(!ImageWrapper.IsValid()) + + if(!ImageWrapper.IsValid()) { ErrorString = "Error ~ Image wrapper could not be created!"; return false; } //~~~~~~~~~~~~~~~~~~~~~~ - + if ( ! ImageWrapper->SetRaw( (void*)&ColorArray[0], //mem address of array start sizeof(FColor) * x * y, //total size x, y, //dimensions - ERGBFormat::BGRA, //LinearColor == RGBA + ERGBFormat::BGRA, //LinearColor == RGBA (sizeof(FColor) / 4) * 8 //Bits per pixel )) { ErrorString = "ImageWrapper::SetRaw() did not succeed"; return false; } - + ErrorString = "Success! or if returning false, the saving of file to disk did not succeed for File IO reasons"; return FFileHelper::SaveArrayToFile(ImageWrapper->GetCompressed(), *FinalFilename); */ @@ -4423,149 +4434,149 @@ bool UVictoryBPFunctionLibrary::Victory_SavePixels( bool UVictoryBPFunctionLibrary::Victory_GetPixelFromT2D(UTexture2D* T2D, int32 X, int32 Y, FLinearColor& PixelColor) { - if(!T2D) + if(!T2D) { return false; } - - if(X <= -1 || Y <= -1) + + if(X <= -1 || Y <= -1) { return false; } - + T2D->SRGB = false; T2D->CompressionSettings = TC_VectorDisplacementmap; - + //Update settings T2D->UpdateResource(); - + FTexture2DMipMap& MipsMap = T2D->PlatformData->Mips[0]; int32 TextureWidth = MipsMap.SizeX; int32 TextureHeight = MipsMap.SizeY; - + FByteBulkData* RawImageData = &MipsMap.BulkData; - - if(!RawImageData) + + if(!RawImageData) { return false; } - + FColor* RawColorArray = static_cast(RawImageData->Lock(LOCK_READ_ONLY)); - + //Safety check! if (X >= TextureWidth || Y >= TextureHeight) { return false; } - - //Get!, converting FColor to FLinearColor + + //Get!, converting FColor to FLinearColor PixelColor = RawColorArray[Y * TextureWidth + X]; - + RawImageData->Unlock(); return true; } bool UVictoryBPFunctionLibrary::Victory_GetPixelsArrayFromT2DDynamic(UTexture2DDynamic* T2D, int32& TextureWidth, int32& TextureHeight,TArray& PixelArray) { - if(!T2D) + if(!T2D) { return false; } - + //To prevent overflow in BP if used in a loop PixelArray.Empty(); - + //~~~~~~~~~~~~~~~~~~~~~~ // Modifying original here T2D->SRGB = false; T2D->CompressionSettings = TC_VectorDisplacementmap; - + //Update settings T2D->UpdateResource(); //~~~~~~~~~~~~~~~~~~~~~~ - + //Confused, DDC / platform data is invalid for dynamic, how to get its byte data? //FTextureResource from UTexture base class? return false; - + /* FTexturePlatformData** PtrPtr = T2D->GetRunningPlatformData(); if(!PtrPtr) return false; FTexturePlatformData* Ptr = *PtrPtr; if(!Ptr) return false; - + FTexture2DMipMap& MyMipMap = Ptr->Mips[0]; TextureWidth = MyMipMap.SizeX; TextureHeight = MyMipMap.SizeY; - + FByteBulkData* RawImageData = &MyMipMap.BulkData; - - if(!RawImageData) + + if(!RawImageData) { return false; } - + FColor* RawColorArray = static_cast(RawImageData->Lock(LOCK_READ_ONLY)); - + UE_LOG(LogTemp,Warning,TEXT("Victory Plugin, Get Pixels, tex width for mip %d"), TextureWidth); UE_LOG(LogTemp,Warning,TEXT("Victory Plugin, Get Pixels, tex width from T2D ptr %d"), T2D->GetSurfaceWidth()); - + for(int32 x = 0; x < TextureWidth; x++) { - for(int32 y = 0; y < TextureHeight; y++) + for(int32 y = 0; y < TextureHeight; y++) { - PixelArray.Add(RawColorArray[x * TextureWidth + y]); + PixelArray.Add(RawColorArray[x * TextureWidth + y]); } } - + RawImageData->Unlock(); */ - + return true; } bool UVictoryBPFunctionLibrary::Victory_GetPixelsArrayFromT2D(UTexture2D* T2D, int32& TextureWidth, int32& TextureHeight,TArray& PixelArray) { - if(!T2D) + if(!T2D) { return false; } - + //To prevent overflow in BP if used in a loop PixelArray.Empty(); - + T2D->SRGB = false; T2D->CompressionSettings = TC_VectorDisplacementmap; - + //Update settings T2D->UpdateResource(); - + FTexture2DMipMap& MyMipMap = T2D->PlatformData->Mips[0]; TextureWidth = MyMipMap.SizeX; TextureHeight = MyMipMap.SizeY; - + FByteBulkData* RawImageData = &MyMipMap.BulkData; - - if(!RawImageData) + + if(!RawImageData) { return false; } - + FColor* RawColorArray = static_cast(RawImageData->Lock(LOCK_READ_ONLY)); - + for(int32 x = 0; x < TextureWidth; x++) { - for(int32 y = 0; y < TextureHeight; y++) + for(int32 y = 0; y < TextureHeight; y++) { - PixelArray.Add(RawColorArray[x * TextureWidth + y]); + PixelArray.Add(RawColorArray[x * TextureWidth + y]); } } - + RawImageData->Unlock(); return true; } 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) @@ -4618,13 +4629,13 @@ class USoundWave* UVictoryBPFunctionLibrary::GetSoundWaveFromFile(const FString& return NULL; return sw; - #endif + #endif } #if !PLATFORM_PS4 int32 UVictoryBPFunctionLibrary::fillSoundWaveInfo(class USoundWave* sw, TArray* rawFile) { - FSoundQualityInfo info; + FSoundQualityInfo info; FVorbisAudioInfo vorbis_obj; if (!vorbis_obj.ReadCompressedInfo(rawFile->GetData(), rawFile->Num(), &info)) { @@ -4642,7 +4653,7 @@ int32 UVictoryBPFunctionLibrary::fillSoundWaveInfo(class USoundWave* sw, TArray< return 0; } - + int32 UVictoryBPFunctionLibrary::findSource(class USoundWave* sw, class FSoundSource* out_audioSource) { FAudioDevice* device = GEngine ? GEngine->GetMainAudioDevice() : NULL; //gently ask for the audio device @@ -4668,7 +4679,7 @@ int32 UVictoryBPFunctionLibrary::findSource(class USoundWave* sw, class FSoundSo { sw_instance = WaveInstanceIt.Value(); if (sw_instance->WaveData->CompressedDataGuid == sw->CompressedDataGuid) - { + { audioSource = device->GetSoundSource(sw_instance); //4.13 onwards, <3 Rama out_audioSource = audioSource; return 0; @@ -4683,18 +4694,18 @@ int32 UVictoryBPFunctionLibrary::findSource(class USoundWave* sw, class FSoundSo return -2; } #endif //PLATFORM_PS4 - + //~~~ Kris ~~~ - + bool UVictoryBPFunctionLibrary::Array_IsValidIndex(const TArray& TargetArray, int32 Index) { // We should never hit these! They're stubs to avoid NoExport on the class. Call the Generic* equivalent instead check(0); return false; } - + bool UVictoryBPFunctionLibrary::GenericArray_IsValidIndex(void* TargetArray, const UArrayProperty* ArrayProp, int32 Index) -{ +{ bool bResult = false; if (TargetArray) @@ -4710,7 +4721,7 @@ float UVictoryBPFunctionLibrary::GetCreationTime(const AActor* Target) { return (Target) ? Target->CreationTime : 0.0f; } - + float UVictoryBPFunctionLibrary::GetTimeAlive(const AActor* Target) { return (Target) ? (Target->GetWorld()->GetTimeSeconds() - Target->CreationTime) : 0.0f; @@ -4722,7 +4733,7 @@ bool UVictoryBPFunctionLibrary::CaptureComponent2D_Project(class USceneCaptureCo { return false; } - + const FTransform& Transform = Target->GetComponentToWorld(); FMatrix ViewMatrix = Transform.ToInverseMatrixWithScale(); FVector ViewLocation = Transform.GetTranslation(); @@ -4737,7 +4748,7 @@ bool UVictoryBPFunctionLibrary::CaptureComponent2D_Project(class USceneCaptureCo const float FOV = Target->FOVAngle * (float)PI / 360.0f; FIntPoint CaptureSize(Target->TextureTarget->GetSurfaceWidth(), Target->TextureTarget->GetSurfaceHeight()); - + float XAxisMultiplier; float YAxisMultiplier; @@ -4766,7 +4777,7 @@ bool UVictoryBPFunctionLibrary::CaptureComponent2D_Project(class USceneCaptureCo FMatrix ViewProjectionMatrix = ViewMatrix * ProjectionMatrix; FVector4 ScreenPoint = ViewProjectionMatrix.TransformFVector4(FVector4(Location,1)); - + if (ScreenPoint.W > 0.0f) { float InvW = 1.0f / ScreenPoint.W; @@ -4780,13 +4791,13 @@ bool UVictoryBPFunctionLibrary::CaptureComponent2D_Project(class USceneCaptureCo } return false; -} +} bool UVictoryBPFunctionLibrary::Capture2D_Project(class ASceneCapture2D* Target, FVector Location, FVector2D& OutPixelLocation) { return (Target) ? CaptureComponent2D_Project(Target->GetCaptureComponent2D(), Location, OutPixelLocation) : false; } - + static TSharedPtr GetImageWrapperByExtention(const FString InImagePath) { IImageWrapperModule& ImageWrapperModule = FModuleManager::LoadModuleChecked(FName("ImageWrapper")); @@ -4814,7 +4825,7 @@ static TSharedPtr GetImageWrapperByExtention(const FString InImag { return ImageWrapperModule.CreateImageWrapper(EImageFormat::ICNS); } - + return nullptr; } @@ -4825,7 +4836,7 @@ bool UVictoryBPFunctionLibrary::CaptureComponent2D_SaveImage(class USceneCapture { return false; } - + FRenderTarget* RenderTarget = Target->TextureTarget->GameThread_GetRenderTargetResource(); if (RenderTarget == nullptr) { @@ -4833,7 +4844,7 @@ bool UVictoryBPFunctionLibrary::CaptureComponent2D_SaveImage(class USceneCapture } TArray RawPixels; - + // Format not supported - use PF_B8G8R8A8. if (Target->TextureTarget->GetFormat() != PF_B8G8R8A8) { @@ -4860,18 +4871,18 @@ bool UVictoryBPFunctionLibrary::CaptureComponent2D_SaveImage(class USceneCapture // Set alpha based on RGB values of ClearColour. Pixel.A = ((Pixel.R == ClearFColour.R) && (Pixel.G == ClearFColour.G) && (Pixel.B == ClearFColour.B)) ? 0 : 255; } - + TSharedPtr ImageWrapper = GetImageWrapperByExtention(ImagePath); const int32 Width = Target->TextureTarget->SizeX; const int32 Height = Target->TextureTarget->SizeY; - + if (ImageWrapper.IsValid() && ImageWrapper->SetRaw(&RawPixels[0], RawPixels.Num() * sizeof(FColor), Width, Height, ERGBFormat::RGBA, 8)) { FFileHelper::SaveArrayToFile(ImageWrapper->GetCompressed(), *ImagePath); return true; } - + return false; } @@ -4896,21 +4907,21 @@ UTexture2D* UVictoryBPFunctionLibrary::LoadTexture2D_FromFileByExtension(const F { return nullptr; } - + TSharedPtr ImageWrapper = GetImageWrapperByExtention(ImagePath); if (ImageWrapper.IsValid() && ImageWrapper->SetCompressed(CompressedData.GetData(), CompressedData.Num())) - { + { const TArray* UncompressedRGBA = nullptr; - + if (ImageWrapper->GetRaw(ERGBFormat::RGBA, 8, UncompressedRGBA)) { Texture = UTexture2D::CreateTransient(ImageWrapper->GetWidth(), ImageWrapper->GetHeight(), PF_R8G8B8A8); - + if (Texture != nullptr) { IsValid = true; - + OutWidth = ImageWrapper->GetWidth(); OutHeight = ImageWrapper->GetHeight(); @@ -4988,7 +4999,7 @@ UUserWidget* UVictoryBPFunctionLibrary::WidgetGetParentOfClass(UWidget* ChildWid ResultParent = Cast(PossibleParent); break; } - + NextPossibleParent = PossibleParent->GetParent(); // If we don't have a parent, follow the outer chain until we find another widget, if at all. @@ -5007,7 +5018,7 @@ UUserWidget* UVictoryBPFunctionLibrary::WidgetGetParentOfClass(UWidget* ChildWid return ResultParent; } - + void UVictoryBPFunctionLibrary::WidgetGetChildrenOfClass(UWidget* ParentWidget, TArray& ChildWidgets, TSubclassOf WidgetClass, bool bImmediateOnly) { ChildWidgets.Empty(); @@ -5136,7 +5147,7 @@ void UVictoryBPFunctionLibrary::AddToStreamingLevels(UObject* WorldContextObject break; } } - + if (!bAlreadyExists) { FName PackageName = LevelInstanceInfo.PackageName; @@ -5285,7 +5296,7 @@ void UVictoryBPFunctionLibrary::GenericArray_Sort(void* TargetArray, const UArra UProperty* LeftProperty = FindField(LeftObject->GetClass(), VariableName); UProperty* RightProperty = FindField(RightObject->GetClass(), VariableName); - + if (LeftProperty && RightProperty) { void* LeftValuePtr = LeftProperty->ContainerPtrToValuePtr(LeftObject); @@ -5496,7 +5507,7 @@ bool UVictoryBPFunctionLibrary::StringIsEmpty(const FString& Target) } //~~~~~~~~~ END OF CONTRIBUTED BY KRIS ~~~~~~~~~~~ - + //~~~ Inspired by Sahkan ~~~ @@ -5504,16 +5515,16 @@ void UVictoryBPFunctionLibrary::Actor__GetAttachedActors(AActor* ParentActor,TAr { if(!ParentActor) return; //~~~~~~~~~~~~ - - ActorsArray.Empty(); + + ActorsArray.Empty(); ParentActor->GetAttachedActors(ActorsArray); } - + void UVictoryBPFunctionLibrary::SetBloomIntensity(APostProcessVolume* PostProcessVolume,float Intensity) { if(!PostProcessVolume) return; //~~~~~~~~~~~~~~~~ - + PostProcessVolume->Settings.bOverride_BloomIntensity = true; PostProcessVolume->Settings.BloomIntensity = Intensity; } @@ -5523,12 +5534,12 @@ void UVictoryBPFunctionLibrary::SetBloomIntensity(APostProcessVolume* PostProces //.cpp //Append different text strings with optional pins. FString UVictoryBPFunctionLibrary::AppendMultiple(FString A, FString B) -{ +{ FString Result = ""; Result += A; Result += B; - + return Result; } @@ -5539,7 +5550,7 @@ FString UVictoryBPFunctionLibrary::AppendMultiple(FString A, FString B) 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) { //this is how you can make cpp only internal functions! - + } diff --git a/Source/VictoryBPLibrary/Public/VictoryBPFunctionLibrary.h b/Source/VictoryBPLibrary/Public/VictoryBPFunctionLibrary.h index 98069a4..e41aece 100644 --- a/Source/VictoryBPLibrary/Public/VictoryBPFunctionLibrary.h +++ b/Source/VictoryBPLibrary/Public/VictoryBPFunctionLibrary.h @@ -672,6 +672,10 @@ class VICTORYBPLIBRARY_API UVictoryBPFunctionLibrary : public UBlueprintFunction UFUNCTION(BlueprintCallable, Category = "Victory BP Library|System",meta=(WorldContext="WorldContextObject")) static void ServerTravel(UObject* WorldContextObject,FString MapName, bool bNotifyPlayers=true); + /** Client Travel! This is an async Load Level process which allows you to put up a UMG widget while the Level Loading occurs! */ + UFUNCTION(BlueprintCallable, Category = "Victory BP Library|System", meta = (WorldContext = "WorldContextObject")) + static void ClientTravel(UObject* WorldContextObject, APlayerController* PlayerController, FString MapName, bool bSeamless, FGuid MapPackageGuid); + /** Get a Player Start by Name! */ UFUNCTION(BlueprintCallable, Category = "Victory BP Library|System",meta=(WorldContext="WorldContextObject")) static APlayerStart* GetPlayerStart(UObject* WorldContextObject,FString PlayerStartName); @@ -1269,7 +1273,7 @@ class VICTORYBPLIBRARY_API UVictoryBPFunctionLibrary : public UBlueprintFunction /** 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 = "Victory BP Library|Misc") static bool LensFlare__GetLensFlareOffsets(APlayerController* PlayerController, AActor* LightSource, float& PitchOffset, float& YawOffset, float& RollOffset); - + /** 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 = "Victory BP Library|Misc") static float DistanceToSurface__DistaceOfPointToMeshSurface(AStaticMeshActor* TheSMA, const FVector& TestPoint, FVector& ClosestSurfacePoint); @@ -1980,4 +1984,3 @@ static FString AppendMultiple(FString A, FString B); //~~~ Mhousse ~~~ }; -