Raise Error node now actually prints its own error message

This commit is contained in:
2024-11-13 18:18:32 -05:00
parent ce0a06c51c
commit eff7519d5d
3 changed files with 73 additions and 52 deletions

View File

@@ -40,24 +40,26 @@
#define LOCTEXT_NAMESPACE "K2Node_RaiseError"
// It simplifies everything if we can identify pins by name, but to do this
// we need for pin names to be unique. To ensure that there's no overlap
// between the hardwired names and the scripter's names, we add a single
// whitespace to any pin name specified in the format string.
static const FName FormatPinName(TEXT("Format"));
static const FName ResultPinName(TEXT("Result"));
static bool IsFormatPin(const UEdGraphPin *Pin) {
return (Pin->PinName == FormatPinName);
}
static bool IsResultPin(const UEdGraphPin *Pin) {
return (Pin->PinName == ResultPinName);
}
// All argument pins will have Names that start with "A:"
static bool IsArgumentPin(const UEdGraphPin *Pin) {
return ((Pin->PinName != FormatPinName) && (Pin->Direction == EGPD_Input));
TCHAR pname[FName::StringBufferSize];
Pin->PinName.ToString(pname);
return pname[0] == 'A' && pname[1] == ':';
}
static FName ArgumentNameAddPrefix(const FString &name) {
FString Prefixed = FString("A:") + name;
return FName(*Prefixed);
}
static FString ArgumentNameRemovePrefix(const FName &name) {
return name.ToString().Mid(2, FName::StringBufferSize);
}
static const FName FormatPinName(TEXT("Format"));
static bool IsFormatPin(const UEdGraphPin *Pin) {
return (Pin->PinName == FormatPinName);
}
UK2Node_RaiseError::UK2Node_RaiseError(const FObjectInitializer& ObjectInitializer)
@@ -74,14 +76,16 @@ void UK2Node_RaiseError::AllocateDefaultPins()
void UK2Node_RaiseError::CreateCorrectPins()
{
// Create the Format Pin if it doesn't already exist.
if (FindPin(FormatPinName, EGPD_Input) == nullptr) {
CreatePin(EGPD_Input, UEdGraphSchema_K2::PC_Text, FormatPinName);
if (FindPin(UEdGraphSchema_K2::PN_Execute) == nullptr) {
UEdGraphPin *P = CreatePin(EGPD_Input, UEdGraphSchema_K2::PC_Exec, UEdGraphSchema_K2::PN_Execute);
}
// Create the Result Pin if it doesn't already exist.
if (FindPin(ResultPinName, EGPD_Output) == nullptr) {
CreatePin(EGPD_Output, UEdGraphSchema_K2::PC_Text, ResultPinName);
if (FindPin(UEdGraphSchema_K2::PN_Then) == nullptr) {
UEdGraphPin *P = CreatePin(EGPD_Output, UEdGraphSchema_K2::PC_Exec, UEdGraphSchema_K2::PN_Then);
}
if (FindPin(FormatPinName, EGPD_Input) == nullptr) {
UEdGraphPin *P = CreatePin(EGPD_Input, UEdGraphSchema_K2::PC_Text, FormatPinName);
}
// Transfer all Existing Argument pins to the Old Pins Map.
@@ -91,20 +95,21 @@ void UK2Node_RaiseError::CreateCorrectPins()
UEdGraphPin* CheckPin = *It;
if (IsArgumentPin(CheckPin))
{
OldPins.Add(CheckPin->PinName.ToString(), CheckPin);
OldPins.Add(ArgumentNameRemovePrefix(CheckPin->PinName), CheckPin);
It.RemoveCurrent();
}
}
// Create Argument pins in the correct order, reusing old pins where possible.
for (const FName& PinName : PinNames)
for (const FString& Name : PinNames)
{
UEdGraphPin **OldPin = OldPins.Find(PinName.ToString());
UEdGraphPin **OldPin = OldPins.Find(Name);
if (OldPin != nullptr) {
Pins.Emplace(*OldPin);
OldPins.Remove(PinName.ToString());
OldPins.Remove(Name);
} else {
CreatePin(EGPD_Input, UEdGraphSchema_K2::PC_Wildcard, PinName);
FName PrefixedName = ArgumentNameAddPrefix(Name);
UEdGraphPin *P = CreatePin(EGPD_Input, UEdGraphSchema_K2::PC_Wildcard, PrefixedName);
}
}
@@ -169,6 +174,17 @@ FText UK2Node_RaiseError::GetNodeTitle(ENodeTitleType::Type TitleType) const
FText UK2Node_RaiseError::GetPinDisplayName(const UEdGraphPin* Pin) const
{
// These pins should be unlabeled.
if ((Pin->PinType.PinCategory == UEdGraphSchema_K2::PC_Exec) || (IsFormatPin(Pin))) {
return FText::GetEmpty();
}
// For argument pins, we must strip off the Argument Pin Prefix.
if (IsArgumentPin(Pin)) {
return FText::FromString(ArgumentNameRemovePrefix(Pin->PinName));
}
// Probably should never get here.
return FText::FromName(Pin->PinName);
}
@@ -193,15 +209,8 @@ void UK2Node_RaiseError::PinDefaultValueChanged(UEdGraphPin* Pin)
{
if(IsFormatPin(Pin))
{
TArray< FString > ArgumentParams;
FText::GetFormatPatternParameters(Pin->DefaultTextValue, ArgumentParams);
PinNames.Reset();
for (const FString& Param : ArgumentParams)
{
FString WithWhite = Param + TEXT(" ");
PinNames.Add(FName(*WithWhite));
}
PinNames.Empty();
FText::GetFormatPatternParameters(Pin->DefaultTextValue, PinNames);
CreateCorrectPins();
GetGraph()->NotifyNodeChanged(this);
}
@@ -265,29 +274,39 @@ void UK2Node_RaiseError::ExpandNode(class FKismetCompilerContext& CompilerContex
MakeArrayNode->AllocateDefaultPins();
CompilerContext.MessageLog.NotifyIntermediateObjectCreation(MakeArrayNode, this);
UEdGraphPin* ArrayOut = MakeArrayNode->GetOutputPin();
// This is the node that does all the Format work.
UK2Node_CallFunction* CallFormatFunction = CompilerContext.SpawnIntermediateNode<UK2Node_CallFunction>(this, SourceGraph);
CallFormatFunction->SetFromFunction(UKismetTextLibrary::StaticClass()->FindFunctionByName(GET_MEMBER_NAME_CHECKED(UKismetTextLibrary, Format)));
CallFormatFunction->AllocateDefaultPins();
CompilerContext.MessageLog.NotifyIntermediateObjectCreation(CallFormatFunction, this);
// This is the node that outputs the text.
UK2Node_CallFunction* CallPrintFunction = CompilerContext.SpawnIntermediateNode<UK2Node_CallFunction>(this, SourceGraph);
CallPrintFunction->SetFromFunction(UKismetSystemLibrary::StaticClass()->FindFunctionByName(GET_MEMBER_NAME_CHECKED(UKismetSystemLibrary, PrintText)));
CallPrintFunction->AllocateDefaultPins();
CompilerContext.MessageLog.NotifyIntermediateObjectCreation(CallPrintFunction, this);
// Connect the output of the "Make Array" pin to the function's "InArgs" pin
UEdGraphPin* ArrayOut = MakeArrayNode->GetOutputPin();
ArrayOut->MakeLinkTo(CallFormatFunction->FindPinChecked(TEXT("InArgs")));
// This will set the "Make Array" node's type, only works if one pin is connected.
MakeArrayNode->PinConnectionListChanged(ArrayOut);
// Connect the output of the "Format" node to the PrintText function's "InText" pin
UEdGraphPin* FormatOut = CallFormatFunction->GetReturnValuePin();
FormatOut->MakeLinkTo(CallPrintFunction->FindPinChecked(TEXT("InText")));
// Configure the Print function to keep the text onscreen for 30 seconds.
UEdGraphPin* DurationIn = CallPrintFunction->FindPinChecked(TEXT("Duration"));
CallPrintFunction->GetSchema()->TrySetDefaultValue(*DurationIn, "30");
// For each argument, we will need to add in a "Make Struct" node.
for(int32 ArgIdx = 0; ArgIdx < PinNames.Num(); ++ArgIdx)
{
UEdGraphPin* ArgumentPin = FindPin(PinNames[ArgIdx], EGPD_Input);
// All argument pins have a whitespace appended to their pin names.
// We need the original name before the whitespace was appended.
FString OriginalName = ArgumentPin->PinName.ToString().LeftChop(1);
FString OriginalName = PinNames[ArgIdx];
UEdGraphPin* ArgumentPin = FindPin(ArgumentNameAddPrefix(OriginalName), EGPD_Input);
static UScriptStruct* FormatArgumentDataStruct = FindObjectChecked<UScriptStruct>(FindObjectChecked<UPackage>(nullptr, TEXT("/Script/Engine")), TEXT("FormatArgumentData"));
// Spawn a "Make Struct" node to create the struct needed for formatting the text.
@@ -410,7 +429,7 @@ void UK2Node_RaiseError::ExpandNode(class FKismetCompilerContext& CompilerContex
else
{
// Unexpected pin type!
CompilerContext.MessageLog.Error(*FText::Format(LOCTEXT("Error_UnexpectedPinType", "Pin '{0}' has an unexpected type: {1}"), FText::FromName(PinNames[ArgIdx]), FText::FromName(ArgumentPinCategory)).ToString());
CompilerContext.MessageLog.Error(*FText::Format(LOCTEXT("Error_UnexpectedPinType", "Pin '{0}' has an unexpected type: {1}"), FText::FromString(OriginalName), FText::FromName(ArgumentPinCategory)).ToString());
}
}
else
@@ -434,11 +453,13 @@ void UK2Node_RaiseError::ExpandNode(class FKismetCompilerContext& CompilerContex
FindOutputStructPinChecked(MakeFormatArgumentDataStruct)->MakeLinkTo(InputPin);
}
// Move connection of RaiseError's "Result" pin to the call function's return value pin.
CompilerContext.MovePinLinksToIntermediate(*FindPinChecked(ResultPinName, EGPD_Output), *CallFormatFunction->GetReturnValuePin());
// Move connection of RaiseError's "Format" pin to the call function's "InPattern" pin
CompilerContext.MovePinLinksToIntermediate(*FindPinChecked(FormatPinName, EGPD_Input), *CallFormatFunction->FindPinChecked(TEXT("InPattern")));
CompilerContext.MovePinLinksToIntermediate(*FindPinChecked(FormatPinName), *CallFormatFunction->FindPinChecked(TEXT("InPattern")));
// Link up the Exec pins.
CompilerContext.MovePinLinksToIntermediate(*GetExecPin(), *CallPrintFunction->GetExecPin());
CompilerContext.MovePinLinksToIntermediate(*GetThenPin(), *CallPrintFunction->GetThenPin());
BreakAllNodeLinks();
}

View File

@@ -41,7 +41,7 @@ class UK2Node_RaiseError : public UK2Node
//~ End UEdGraphNode Interface.
//~ Begin UK2Node Interface.
virtual bool IsNodePure() const override { return true; }
virtual bool IsNodePure() const override { return false; }
virtual void PostReconstructNode() override;
virtual bool NodeCausesStructuralBlueprintChange() const override { return true; }
virtual void ExpandNode(class FKismetCompilerContext& CompilerContext, UEdGraph* SourceGraph) override;
@@ -62,7 +62,7 @@ private:
private:
/** When adding arguments to the node, their names are placed here and are generated as pins during construction */
UPROPERTY()
TArray<FName> PinNames;
TArray<FString> PinNames;
/** Tooltip text for this node. */
FText NodeTooltip;