diff --git a/Content/BP_BugMarkerActor.uasset b/Content/BP_BugMarkerActor.uasset index dc744e5..55d3325 100644 Binary files a/Content/BP_BugMarkerActor.uasset and b/Content/BP_BugMarkerActor.uasset differ diff --git a/Content/BP_BugPlacerPawn.uasset b/Content/BP_BugPlacerPawn.uasset index 2018227..92ffc90 100644 Binary files a/Content/BP_BugPlacerPawn.uasset and b/Content/BP_BugPlacerPawn.uasset differ diff --git a/Content/UI/CUI_BugSubmissionForm.uasset b/Content/UI/CUI_BugSubmissionForm.uasset index 72df207..4be0024 100644 Binary files a/Content/UI/CUI_BugSubmissionForm.uasset and b/Content/UI/CUI_BugSubmissionForm.uasset differ diff --git a/Source/Unrealzilla/Private/BugMarkerActor.cpp b/Source/Unrealzilla/Private/BugMarkerActor.cpp index ce84ad2..795e744 100644 --- a/Source/Unrealzilla/Private/BugMarkerActor.cpp +++ b/Source/Unrealzilla/Private/BugMarkerActor.cpp @@ -2,5 +2,9 @@ #include "BugMarkerActor.h" +#include "BugSubmissionForm.h" +#include "UnrealzillaGlobalSettings.h" +#include "Kismet/GameplayStatics.h" + diff --git a/Source/Unrealzilla/Private/BugPlacerPawn.cpp b/Source/Unrealzilla/Private/BugPlacerPawn.cpp index f468ea3..c92dc7b 100644 --- a/Source/Unrealzilla/Private/BugPlacerPawn.cpp +++ b/Source/Unrealzilla/Private/BugPlacerPawn.cpp @@ -51,15 +51,17 @@ void ABugPlacerPawn::BeginPlay() this->OriginalPlayer = UGameplayStatics::GetPlayerCharacter(this, 0); // Create the bug marker we will be placing. - if (this->BugPlacerBlueprintClass.IsValid()) - { - FActorSpawnParameters SpawnParams; - SpawnParams.Name = TEXT("BugMarker"); - SpawnParams.SpawnCollisionHandlingOverride = ESpawnActorCollisionHandlingMethod::AlwaysSpawn; - SpawnParams.bHideFromSceneOutliner = true; - this->BugMarker = this->GetWorld()->SpawnActor(this->BugPlacerBlueprintClass.Get(), this->SphereComponent->GetComponentTransform(), SpawnParams); - this->BugMarker->AttachToComponent(this->PlacementMarkerRoot, FAttachmentTransformRules::SnapToTargetNotIncludingScale); - } + //if (this->BugPlacerBlueprintClass.IsValid()) + //{ + // FActorSpawnParameters SpawnParams; + // SpawnParams.Name = TEXT("BugMarker"); + // SpawnParams.SpawnCollisionHandlingOverride = ESpawnActorCollisionHandlingMethod::AlwaysSpawn; + //#if WITH_EDITOR + // SpawnParams.bHideFromSceneOutliner = true; + //#endif + // this->BugMarker = this->GetWorld()->SpawnActor(this->BugPlacerBlueprintClass.Get(), this->SphereComponent->GetComponentTransform(), SpawnParams); + // this->BugMarker->AttachToComponent(this->PlacementMarkerRoot, FAttachmentTransformRules::SnapToTargetNotIncludingScale); + //} this->Activate(); @@ -152,9 +154,12 @@ void ABugPlacerPawn::PlaceBugMarker() { FActorSpawnParameters SpawnParams; SpawnParams.SpawnCollisionHandlingOverride = ESpawnActorCollisionHandlingMethod::AlwaysSpawn; + #if WITH_EDITOR SpawnParams.bHideFromSceneOutliner = true; + #endif - this->GetWorld()->SpawnActor(this->BugPlacerBlueprintClass.Get(), this->PlacementMarkerRoot->GetComponentTransform(), SpawnParams); + ABugMarkerActor *Marker = this->GetWorld()->SpawnActor(this->BugPlacerBlueprintClass.Get(), this->PlacementMarkerRoot->GetComponentTransform(), SpawnParams); + Marker->LoadBugSubmissionForm(); } } diff --git a/Source/Unrealzilla/Private/BugSubmissionForm.cpp b/Source/Unrealzilla/Private/BugSubmissionForm.cpp new file mode 100644 index 0000000..0e1b6db --- /dev/null +++ b/Source/Unrealzilla/Private/BugSubmissionForm.cpp @@ -0,0 +1,130 @@ +// ©2022 Batty Bovine Productions, LLC. All Rights Reserved. + +#include "BugSubmissionForm.h" + +#include "BugMarkerActor.h" +#include "CommonButtonBase.h" +#include "CommonTextBlock.h" +#include "HttpModule.h" +#include "UnrealzillaGlobalSettings.h" +#include "Kismet/GameplayStatics.h" + + +const FText FormatFloatToText(float Float, int32 IntegralDigits, int32 FractionalDigits) +{ + const float Rounded = FMath::RoundToInt(Float); + if(FMath::Abs(Float - Rounded) < FMath::Pow(10.0f, -1 * FractionalDigits)) + { + Float = Rounded; + } + FNumberFormattingOptions NumberFormat; + NumberFormat.MinimumIntegralDigits = IntegralDigits; + NumberFormat.MaximumIntegralDigits = INT32_MAX; + NumberFormat.MinimumFractionalDigits = FractionalDigits; + NumberFormat.MaximumFractionalDigits = FractionalDigits; + + return FText::AsNumber(Float, &NumberFormat); +} + + +void UBugSubmissionForm::NativeOnInitialized() +{ + this->SubmitButton->OnClicked().AddUObject(this, &UBugSubmissionForm::SubmitForm); + this->CancelButton->OnClicked().AddUObject(this, &UBugSubmissionForm::CancelForm); +} + + +void UBugSubmissionForm::SetMarkerData(ABugMarkerActor *BugMarker) +{ + this->BugMarkerActor = BugMarker; + + const FVector MarkerLocation = this->BugMarkerActor->GetActorLocation(); + FFormatNamedArguments MarkerLocationArgs; + MarkerLocationArgs.Add("X", FormatFloatToText(MarkerLocation.X, 1, 4)); + MarkerLocationArgs.Add("Y", FormatFloatToText(MarkerLocation.Y, 1, 4)); + MarkerLocationArgs.Add("Z", FormatFloatToText(MarkerLocation.Z, 1, 4)); + const FText MarkerLocationText = FText::Format(NSLOCTEXT("BugSubmissionForm", "MarkerLocation", "{X},{Y},{Z}"), MarkerLocationArgs); + + const FVector MarkerUpVector = this->BugMarkerActor->GetActorUpVector(); + FFormatNamedArguments MarkerUpVectorArgs; + MarkerUpVectorArgs.Add("X", FormatFloatToText(MarkerUpVector.X, 1, 4)); + MarkerUpVectorArgs.Add("Y", FormatFloatToText(MarkerUpVector.Y, 1, 4)); + MarkerUpVectorArgs.Add("Z", FormatFloatToText(MarkerUpVector.Z, 1, 4)); + const FText MarkerUpVectorText = FText::Format(NSLOCTEXT("BugSubmissionForm", "MarkerUpVector", "{X},{Y},{Z}"), MarkerUpVectorArgs); + + FFormatNamedArguments MapDataArgs; + MapDataArgs.Add("MapName", FText::FromString(this->GetWorld()->GetMapName().RightChop(this->GetWorld()->StreamingLevelsPrefix.Len()))); + MapDataArgs.Add("MarkerLocation", MarkerLocationText); + MapDataArgs.Add("MarkerUpVector", MarkerUpVectorText); + const FText MapDataText = FText::Format(NSLOCTEXT("BugSubmissionForm", "MapDataFormat", "{MapName}\n{MarkerLocation}\n{MarkerUpVector}"), MapDataArgs); + + this->LocationValue->SetText(MapDataText); +} + + +void UBugSubmissionForm::SubmitForm() +{ + const FString RESTURL = "/rest.cgi"; + const FString RequestURL = "/bug/7"; + const FString QueryString = "api_key=" + GetDefault()->APIKey; + + FHttpModule &HttpModule = FHttpModule::Get(); + TSharedRef Request = HttpModule.CreateRequest(); + Request->SetVerb(TEXT("GET")); + Request->SetHeader(TEXT("Content-Type"), TEXT("application/json")); + Request->SetURL(GetDefault()->SubmissionServer + RESTURL + RequestURL + + "?" + QueryString); + Request->OnProcessRequestComplete().BindUObject(this, &UBugSubmissionForm::ServerResponse); + Request->ProcessRequest(); + + this->OnFormSubmit.ExecuteIfBound(); + + this->CloseForm(); +} + +void UBugSubmissionForm::CancelForm() +{ + this->OnFormCancelled.ExecuteIfBound(); + + this->CloseForm(); + + this->BugMarkerActor->Destroy(); +} + +void UBugSubmissionForm::CloseForm() +{ + UGameplayStatics::GetPlayerController(this, 0)->SetInputMode(FInputModeGameOnly()); + UGameplayStatics::GetPlayerController(this, 0)->bShowMouseCursor = true; + this->RemoveFromParent(); +} + + +void UBugSubmissionForm::ServerResponse(FHttpRequestPtr Request, FHttpResponsePtr Response, bool Success) +{ + if (Success) + { + UE_LOG(LogTemp, Log, TEXT("%s"), *Response->GetContentAsString()); + } + else + { + switch (Request->GetStatus()) { + case EHttpRequestStatus::Failed_ConnectionError: + UE_LOG(LogTemp, Error, TEXT("Unable to connect")); + break; + case EHttpRequestStatus::NotStarted: + UE_LOG(LogTemp, Error, TEXT("Connection not started")); + break; + case EHttpRequestStatus::Processing: + UE_LOG(LogTemp, Error, TEXT("Connection processing")); + break; + case EHttpRequestStatus::Failed: + UE_LOG(LogTemp, Error, TEXT("Connection failed")); + break; + case EHttpRequestStatus::Succeeded: + UE_LOG(LogTemp, Warning, TEXT("Connection succeeded")); + break; + default: + UE_LOG(LogTemp, Error, TEXT("Request failed")); + } + } +} diff --git a/Source/Unrealzilla/Public/BugMarkerActor.h b/Source/Unrealzilla/Public/BugMarkerActor.h index ea81e29..687ffc8 100644 --- a/Source/Unrealzilla/Public/BugMarkerActor.h +++ b/Source/Unrealzilla/Public/BugMarkerActor.h @@ -13,7 +13,6 @@ class UNREALZILLA_API ABugMarkerActor : public AActor GENERATED_BODY() public: - DECLARE_DELEGATE(FMarkerResponse) - FMarkerResponse OnFormSubmit; - FMarkerResponse OnFormCancelled; + UFUNCTION(BlueprintImplementableEvent) + void LoadBugSubmissionForm(); }; diff --git a/Source/Unrealzilla/Public/BugSubmissionForm.h b/Source/Unrealzilla/Public/BugSubmissionForm.h new file mode 100644 index 0000000..084daf3 --- /dev/null +++ b/Source/Unrealzilla/Public/BugSubmissionForm.h @@ -0,0 +1,50 @@ +// ©2022 Batty Bovine Productions, LLC. All Rights Reserved. + +#pragma once + +#include "CoreMinimal.h" +#include "CommonActivatableWidget.h" +#include "Interfaces/IHttpRequest.h" +#include "Interfaces/IHttpResponse.h" + +#include "BugSubmissionForm.generated.h" + + +UCLASS() +class UNREALZILLA_API UBugSubmissionForm : public UCommonActivatableWidget +{ + GENERATED_BODY() + +public: + UFUNCTION(BlueprintCallable) + void SetMarkerData(class ABugMarkerActor *BugMarker); + + DECLARE_DELEGATE(FBugSubmissionFormResponse) + FBugSubmissionFormResponse OnFormSubmit; + FBugSubmissionFormResponse OnFormCancelled; + +protected: + virtual void NativeOnInitialized() override; + + UPROPERTY(BlueprintReadOnly, meta=(BindWidget)) + TObjectPtr ProductNameValue; + UPROPERTY(BlueprintReadOnly, meta=(BindWidget)) + TObjectPtr LocationValue; + + UPROPERTY(BlueprintReadOnly, meta=(BindWidget)) + TObjectPtr CancelButton; + UPROPERTY(BlueprintReadOnly, meta=(BindWidget)) + TObjectPtr SubmitButton; + +private: + void ServerResponse(FHttpRequestPtr Request, FHttpResponsePtr Response, bool Success); + + UFUNCTION(BlueprintCallable) + void SubmitForm(); + UFUNCTION(BlueprintCallable) + void CancelForm(); + + void CloseForm(); + + TObjectPtr BugMarkerActor; +}; diff --git a/Source/Unrealzilla/Public/UnrealzillaGlobalSettings.h b/Source/Unrealzilla/Public/UnrealzillaGlobalSettings.h index 8f409ac..d73201b 100644 --- a/Source/Unrealzilla/Public/UnrealzillaGlobalSettings.h +++ b/Source/Unrealzilla/Public/UnrealzillaGlobalSettings.h @@ -10,17 +10,24 @@ /** * Global settings for Unrealzilla classes */ -UCLASS(Config=Game, defaultconfig, meta = (DisplayName="Unrealzilla")) +UCLASS(Config=Unrealzilla, defaultconfig, meta=(DisplayName="Unrealzilla")) class UNREALZILLA_API UUnrealzillaGlobalSettings : public UDeveloperSettingsBackedByCVars { GENERATED_BODY() public: - UPROPERTY(Config, BlueprintReadOnly, EditDefaultsOnly, Category="Unrealzilla") + UPROPERTY(Config, BlueprintReadOnly, EditDefaultsOnly, Category="Bug Placement", meta=(DisplayName="Precise Placement Distance")) float BugPlacementTraceDistance = 1000.0f; - UPROPERTY(Config, BlueprintReadOnly, EditDefaultsOnly, Category="Unrealzilla") + UPROPERTY(Config, BlueprintReadOnly, EditDefaultsOnly, Category="Bug Placement", meta=(DisplayName="Arbitrary Placement Distance")) float ArbitraryBugPlacementDistance = 250.0f; + UPROPERTY(Config, EditDefaultsOnly, BlueprintReadOnly, Category="Reporting") + FString SubmissionServer; + UPROPERTY(Config, EditDefaultsOnly, BlueprintReadOnly, Category="Reporting", meta=(DisplayName="API Key")) + FString APIKey; + UPROPERTY(Config, EditDefaultsOnly, BlueprintReadOnly, Category="Reporting") + int32 BugReportWidgetDepth = 0; + public: virtual void PostInitProperties() override; virtual FName GetCategoryName() const override; diff --git a/Source/Unrealzilla/Unrealzilla.Build.cs b/Source/Unrealzilla/Unrealzilla.Build.cs index 787ce70..5b5f764 100644 --- a/Source/Unrealzilla/Unrealzilla.Build.cs +++ b/Source/Unrealzilla/Unrealzilla.Build.cs @@ -38,6 +38,9 @@ namespace UnrealBuildTool.Rules PrivateDependencyModuleNames.AddRange( new string[] { + "HTTP", + "UMG", + "CommonUI" } ); } diff --git a/Unrealzilla.uplugin b/Unrealzilla.uplugin index 343927c..4d920a0 100644 --- a/Unrealzilla.uplugin +++ b/Unrealzilla.uplugin @@ -16,5 +16,11 @@ "Type": "Runtime", "LoadingPhase": "PreDefault" } - ] + ], + "Plugins": [ + { + "Name": "CommonUI", + "Enabled": true + } + ] } \ No newline at end of file