Fix Export paths name adjustments

This commit is contained in:
barsdeveloper
2025-01-20 23:58:57 +02:00
parent e40e6ba52b
commit 6403fec906
16 changed files with 320 additions and 171 deletions

176
dist/ueblueprint.js vendored
View File

@@ -47,7 +47,7 @@ class Configuration {
static colorWindowName = "Color Picker"
static defaultCommentHeight = 96
static defaultCommentWidth = 400
static distanceThreshold = 5 // px
static distanceThreshold = 20 // px
static dragEventName = "ueb-drag"
static dragGeneralEventName = "ueb-drag-general"
static edgeScrollThreshold = 50
@@ -5965,7 +5965,7 @@ class PinEntity extends IEntity {
}
isLinked() {
return this.LinkedTo?.length > 0 ?? false
return this.LinkedTo?.length > 0
}
/**
@@ -6640,45 +6640,7 @@ class ObjectEntity extends IEntity {
? outputIndex++
: i;
});
// Mirror name part of the object in ExportPath
const originalName = this.Name?.toString();
const exportPath = this.ExportPath?.valueOf();
if (originalName && exportPath?.path.endsWith(originalName)) {
const mirroredEntity = /** @type {typeof ObjectEntity} */(this.constructor).attributes.ExportPath;
this.ExportPath = new mirroredEntity(
() => new (mirroredEntity.type)(
exportPath.type,
exportPath.path.replace(originalName, (this.Name ?? "")?.toString()),
exportPath.full
)
);
}
// Mirror name part of the nested object in ExportPath
if (originalName) {
const values = Object.values(this);
for (let i = 0; i < values.length; ++i) {
const value = values[i];
if (value instanceof ObjectEntity) {
values.push(...Object.values(value));
if (!value.ExportPath?.valueOf(this).path.includes(originalName)) {
continue
}
} else {
continue
}
const mirroredEntity = /** @type {typeof ObjectEntity} */(value.constructor).attributes.ExportPath;
const exportPath = value.ExportPath?.valueOf();
value.ExportPath = new mirroredEntity(
(self = this) => new (mirroredEntity.type)(
exportPath.type,
exportPath.path.replace(originalName, (this.Name ?? "")?.toString()),
exportPath.full
)
);
}
}
this.mirrorNameInExportPaths();
}
/** @returns {P<ObjectEntity>} */
@@ -6724,6 +6686,40 @@ class ObjectEntity extends IEntity {
)
}
/**
* @protected
* Mirror then name part of the objects contained in this one in ExportPath
*/
mirrorNameInExportPaths(originalName = this.Name?.toString()) {
if (!originalName) {
return
}
const values = [this];
for (let i = 0; i < values.length; ++i) {
const value = values[i];
if (value instanceof ObjectEntity) {
values.push(...Object.values(value));
if (!value.ExportPath?.valueOf().path.includes(originalName)) {
continue
}
} else {
continue
}
const mirroredEntity = /** @type {typeof ObjectEntity} */(value.constructor).attributes.ExportPath;
let originalExportPath = value.ExportPath;
value.ExportPath = new mirroredEntity(
() => {
const exportPath = originalExportPath.valueOf();
return new (mirroredEntity.type)(
exportPath.type,
exportPath.path.replace(originalName, this.Name?.toString() ?? ""),
exportPath.full
)
}
);
}
}
/** @type {String} */
#class
getClass() {
@@ -7729,22 +7725,20 @@ class LinkTemplate extends IFromToPositionedTemplate {
if (changedProperties.has("fromX") || changedProperties.has("toX")) {
const from = this.element.fromX;
const to = this.element.toX;
const isSourceAKnot = sourcePin?.nodeElement.getType() == Configuration.paths.knot;
const isDestinationAKnot = destinationPin?.nodeElement.getType() == Configuration.paths.knot;
const isSourceAKnot = sourcePin?.isKnot();
const isDestinationAKnot = destinationPin?.isKnot();
if (isSourceAKnot && (!destinationPin || isDestinationAKnot)) {
if (sourcePin?.isInput() && to > from + Configuration.distanceThreshold) {
this.element.source = /** @type {KnotNodeTemplate} */(sourcePin.nodeElement.template).outputPin;
} else if (sourcePin?.isOutput() && to < from - Configuration.distanceThreshold) {
this.element.source = /** @type {KnotNodeTemplate} */(sourcePin.nodeElement.template).inputPin;
if (sourcePin?.isInputLoossly() && to > from + Configuration.distanceThreshold) {
this.element.source = /** @type {KnotPinTemplate} */(sourcePin.template).oppositePin();
} else if (sourcePin?.isOutputLoosely() && to < from - Configuration.distanceThreshold) {
this.element.source = /** @type {KnotPinTemplate} */(sourcePin.template).oppositePin();
}
}
if (isDestinationAKnot && (!sourcePin || isSourceAKnot)) {
if (destinationPin?.isInput() && to < from - Configuration.distanceThreshold) {
this.element.destination =
/** @type {KnotNodeTemplate} */(destinationPin.nodeElement.template).outputPin;
} else if (destinationPin?.isOutput() && to > from + Configuration.distanceThreshold) {
this.element.destination =
/** @type {KnotNodeTemplate} */(destinationPin.nodeElement.template).inputPin;
if (destinationPin?.isInputLoossly() && to < from - Configuration.distanceThreshold) {
this.element.destination = /** @type {KnotPinTemplate} */(destinationPin.template).oppositePin();
} else if (destinationPin?.isOutputLoosely() && to > from + Configuration.distanceThreshold) {
this.element.destination = /** @type {KnotPinTemplate} */(destinationPin.template).oppositePin();
}
}
}
@@ -9253,10 +9247,7 @@ class MouseCreateLink extends IMouseClickDrag {
const a = this.link.source ?? this.target; // Remember target might have change
const b = this.enteredPin;
const outputPin = a.isOutput() ? a : b;
if (
a.nodeElement.getType() === Configuration.paths.knot
|| b.nodeElement.getType() === Configuration.paths.knot
) {
if (a.isKnot() || b.isKnot()) {
// A knot can be linked to any pin, it doesn't matter the type or input/output direction
this.link.setMessageCorrect();
this.linkValid = true;
@@ -9311,7 +9302,7 @@ class MouseCreateLink extends IMouseClickDrag {
}
startDrag(location) {
if (this.target.nodeElement.getType() == Configuration.paths.knot) {
if (this.target.isKnot()) {
this.#knotPin = this.target;
}
/** @type {LinkElement} */
@@ -9346,18 +9337,18 @@ class MouseCreateLink extends IMouseClickDrag {
const otherPin = this.#knotPin !== this.link.source ? this.link.source : this.enteredPin;
// Knot pin direction correction
if (this.#knotPin.isInput() && otherPin.isInput() || this.#knotPin.isOutput() && otherPin.isOutput()) {
const oppositePin = /** @type {KnotPinTemplate} */(this.#knotPin.template).getOppositePin();
const oppositePin = /** @type {KnotPinTemplate} */(this.#knotPin.template).oppositePin();
if (this.#knotPin === this.link.source) {
this.link.source = oppositePin;
} else {
this.enteredPin = oppositePin;
}
}
} else if (this.enteredPin.nodeElement.getType() === Configuration.paths.knot) {
} else if (this.enteredPin.isKnot()) {
this.#knotPin = this.enteredPin;
if (this.link.source.isOutput()) {
// Knot uses by default the output pin, let's switch to keep it coherent with the source node we have
this.enteredPin = /** @type {KnotPinTemplate} */(this.enteredPin.template).getOppositePin();
this.enteredPin = /** @type {KnotPinTemplate} */(this.enteredPin.template).oppositePin();
}
}
if (!this.link.source.getLinks().find(ref => ref.equals(this.enteredPin.createPinReference()))) {
@@ -9373,6 +9364,7 @@ class MouseCreateLink extends IMouseClickDrag {
this.link.removeMessage();
this.link.finishDragging();
this.link = null;
this.#knotPin = null;
}
}
@@ -9708,7 +9700,7 @@ class KnotPinTemplate extends MinimalPinTemplate {
return this.element.isOutput() ? super.render() : x``
}
getOppositePin() {
oppositePin() {
const nodeTemplate = /** @type {KnotNodeTemplate} */(this.element.nodeElement.template);
return this.element.isOutput() ? nodeTemplate.inputPin : nodeTemplate.outputPin
}
@@ -9754,10 +9746,7 @@ class KnotNodeTemplate extends NodeTemplate {
/** @param {PinElement} startingPin */
findDirectionaPin(startingPin) {
if (
startingPin.nodeElement.getType() !== Configuration.paths.knot
|| KnotNodeTemplate.#traversedPin.has(startingPin)
) {
if (startingPin.isKnot() || KnotNodeTemplate.#traversedPin.has(startingPin)) {
KnotNodeTemplate.#traversedPin.clear();
return true
}
@@ -10436,6 +10425,7 @@ class BlueprintEntity extends ObjectEntity {
["ScriptVariables", new (blueprintEntity.attributes.ScriptVariables)(scriptVariables.reverse())]
);
const result = new BlueprintEntity(Object.fromEntries(entries));
result.mirrorNameInExportPaths(entity.Name?.toString());
result.#objectEntitiesNameCounter = this.#objectEntitiesNameCounter;
result.#objectEntities = this.#objectEntities;
return result
@@ -13284,12 +13274,49 @@ class PinElement extends IElement {
return this.entity.pinColor()
}
isInput() {
return this.entity.isInput()
/** @param {PinElement} pin */
#traverseKnots(pin) {
while (pin?.isKnot()) {
const pins = pin.nodeElement.getPinElements();
pin = pin === pins[0] ? pins[1] : pins[0];
pin = pin.isLinked ? this.blueprint.getPin(pin.getLinks()[0]) : null;
}
return pin?.isKnot() ? undefined : pin
}
isOutput() {
return this.entity.isOutput()
isInput(ignoreKnots = false) {
/** @type {PinElement} */
let result = this;
if (ignoreKnots) {
return this.#traverseKnots(result)?.isInput()
}
return result.entity.isInput()
}
/** @returns {boolean} True when the pin is the input part of a knot that can switch direction */
isInputLoossly() {
return this.isInput(false) && this.isInput(true) === undefined
}
isOutput(ignoreKnots = false) {
/** @type {PinElement} */
let result = this;
if (ignoreKnots) {
if (ignoreKnots) {
return this.#traverseKnots(result)?.isOutput()
}
}
return result.entity.isOutput()
}
/** @returns {boolean} True when the pin is the output part of a knot that can switch direction */
isOutputLoosely() {
return this.isOutput(false) && this.isOutput(true) === undefined
}
/** @returns {value is InstanceType<PinElement<>>} */
isKnot() {
return this.nodeElement?.getType() == Configuration.paths.knot
}
getLinkLocation() {
@@ -13344,9 +13371,12 @@ class PinElement extends IElement {
const pinReference = this.createPinReference();
if (
this.isLinked
&& this.isOutput()
&& (this.pinType === "exec" || targetPinElement.pinType === "exec")
&& !this.getLinks().some(ref => pinReference.equals(ref))) {
&& (
this.isInput(true)
|| this.isOutput(true) && (this.entity.isExecution() || targetPinElement.entity.isExecution())
)
&& !this.getLinks().some(ref => pinReference.equals(ref))
) {
this.unlinkFromAll();
}
if (this.entity.linkTo(targetPinElement.getNodeElement().getNodeName(), targetPinElement.entity)) {

File diff suppressed because one or more lines are too long

View File

@@ -23,7 +23,7 @@ export default class Configuration {
static colorWindowName = "Color Picker"
static defaultCommentHeight = 96
static defaultCommentWidth = 400
static distanceThreshold = 5 // px
static distanceThreshold = 20 // px
static dragEventName = "ueb-drag"
static dragGeneralEventName = "ueb-drag-general"
static edgeScrollThreshold = 50

View File

@@ -1,5 +1,5 @@
import Configuration from "../Configuration.js"
import pinTemplate from "../decoding/pinTemplate.js"
import ArrayEntity from "../entity/ArrayEntity.js"
import BooleanEntity from "../entity/BooleanEntity.js"
import GuidEntity from "../entity/GuidEntity.js"
import LinearColorEntity from "../entity/LinearColorEntity.js"
@@ -128,12 +128,49 @@ export default class PinElement extends IElement {
return this.entity.pinColor()
}
isInput() {
return this.entity.isInput()
/** @param {PinElement} pin */
#traverseKnots(pin) {
while (pin?.isKnot()) {
const pins = pin.nodeElement.getPinElements()
pin = pin === pins[0] ? pins[1] : pins[0]
pin = pin.isLinked ? this.blueprint.getPin(pin.getLinks()[0]) : null
}
return pin?.isKnot() ? undefined : pin
}
isOutput() {
return this.entity.isOutput()
isInput(ignoreKnots = false) {
/** @type {PinElement} */
let result = this
if (ignoreKnots) {
return this.#traverseKnots(result)?.isInput()
}
return result.entity.isInput()
}
/** @returns {boolean} True when the pin is the input part of a knot that can switch direction */
isInputLoossly() {
return this.isInput(false) && this.isInput(true) === undefined
}
isOutput(ignoreKnots = false) {
/** @type {PinElement} */
let result = this
if (ignoreKnots) {
if (ignoreKnots) {
return this.#traverseKnots(result)?.isOutput()
}
}
return result.entity.isOutput()
}
/** @returns {boolean} True when the pin is the output part of a knot that can switch direction */
isOutputLoosely() {
return this.isOutput(false) && this.isOutput(true) === undefined
}
/** @returns {value is InstanceType<PinElement<>>} */
isKnot() {
return this.nodeElement?.getType() == Configuration.paths.knot
}
getLinkLocation() {
@@ -188,9 +225,12 @@ export default class PinElement extends IElement {
const pinReference = this.createPinReference()
if (
this.isLinked
&& this.isOutput()
&& (this.pinType === "exec" || targetPinElement.pinType === "exec")
&& !this.getLinks().some(ref => pinReference.equals(ref))) {
&& (
this.isInput(true)
|| this.isOutput(true) && (this.entity.isExecution() || targetPinElement.entity.isExecution())
)
&& !this.getLinks().some(ref => pinReference.equals(ref))
) {
this.unlinkFromAll()
}
if (this.entity.linkTo(targetPinElement.getNodeElement().getNodeName(), targetPinElement.entity)) {

View File

@@ -160,6 +160,7 @@ export default class BlueprintEntity extends ObjectEntity {
["ScriptVariables", new (blueprintEntity.attributes.ScriptVariables)(scriptVariables.reverse())]
)
const result = new BlueprintEntity(Object.fromEntries(entries))
result.mirrorNameInExportPaths(entity.Name?.toString())
result.#objectEntitiesNameCounter = this.#objectEntitiesNameCounter
result.#objectEntities = this.#objectEntities
return result

View File

@@ -370,45 +370,7 @@ export default class ObjectEntity extends IEntity {
? outputIndex++
: i
})
// Mirror name part of the object in ExportPath
const originalName = this.Name?.toString()
const exportPath = this.ExportPath?.valueOf()
if (originalName && exportPath?.path.endsWith(originalName)) {
const mirroredEntity = /** @type {typeof ObjectEntity} */(this.constructor).attributes.ExportPath
this.ExportPath = new mirroredEntity(
() => new (mirroredEntity.type)(
exportPath.type,
exportPath.path.replace(originalName, (this.Name ?? "")?.toString()),
exportPath.full
)
)
}
// Mirror name part of the nested object in ExportPath
if (originalName) {
const values = Object.values(this)
for (let i = 0; i < values.length; ++i) {
const value = values[i]
if (value instanceof ObjectEntity) {
values.push(...Object.values(value))
if (!value.ExportPath?.valueOf(this).path.includes(originalName)) {
continue
}
} else {
continue
}
const mirroredEntity = /** @type {typeof ObjectEntity} */(value.constructor).attributes.ExportPath
const exportPath = value.ExportPath?.valueOf()
value.ExportPath = new mirroredEntity(
(self = this) => new (mirroredEntity.type)(
exportPath.type,
exportPath.path.replace(originalName, (this.Name ?? "")?.toString()),
exportPath.full
)
)
}
}
this.mirrorNameInExportPaths()
}
/** @returns {P<ObjectEntity>} */
@@ -454,6 +416,40 @@ export default class ObjectEntity extends IEntity {
)
}
/**
* @protected
* Mirror then name part of the objects contained in this one in ExportPath
*/
mirrorNameInExportPaths(originalName = this.Name?.toString()) {
if (!originalName) {
return
}
const values = [this]
for (let i = 0; i < values.length; ++i) {
const value = values[i]
if (value instanceof ObjectEntity) {
values.push(...Object.values(value))
if (!value.ExportPath?.valueOf().path.includes(originalName)) {
continue
}
} else {
continue
}
const mirroredEntity = /** @type {typeof ObjectEntity} */(value.constructor).attributes.ExportPath
let originalExportPath = value.ExportPath
value.ExportPath = new mirroredEntity(
() => {
const exportPath = originalExportPath.valueOf()
return new (mirroredEntity.type)(
exportPath.type,
exportPath.path.replace(originalName, this.Name?.toString() ?? ""),
exportPath.full
)
}
)
}
}
/** @type {String} */
#class
getClass() {

View File

@@ -277,7 +277,7 @@ export default class PinEntity extends IEntity {
}
isLinked() {
return this.LinkedTo?.length > 0 ?? false
return this.LinkedTo?.length > 0
}
/**

View File

@@ -25,10 +25,7 @@ export default class MouseCreateLink extends IMouseClickDrag {
const a = this.link.source ?? this.target // Remember target might have change
const b = this.enteredPin
const outputPin = a.isOutput() ? a : b
if (
a.nodeElement.getType() === Configuration.paths.knot
|| b.nodeElement.getType() === Configuration.paths.knot
) {
if (a.isKnot() || b.isKnot()) {
// A knot can be linked to any pin, it doesn't matter the type or input/output direction
this.link.setMessageCorrect()
this.linkValid = true
@@ -83,7 +80,7 @@ export default class MouseCreateLink extends IMouseClickDrag {
}
startDrag(location) {
if (this.target.nodeElement.getType() == Configuration.paths.knot) {
if (this.target.isKnot()) {
this.#knotPin = this.target
}
/** @type {LinkElement} */
@@ -118,18 +115,18 @@ export default class MouseCreateLink extends IMouseClickDrag {
const otherPin = this.#knotPin !== this.link.source ? this.link.source : this.enteredPin
// Knot pin direction correction
if (this.#knotPin.isInput() && otherPin.isInput() || this.#knotPin.isOutput() && otherPin.isOutput()) {
const oppositePin = /** @type {KnotPinTemplate} */(this.#knotPin.template).getOppositePin()
const oppositePin = /** @type {KnotPinTemplate} */(this.#knotPin.template).oppositePin()
if (this.#knotPin === this.link.source) {
this.link.source = oppositePin
} else {
this.enteredPin = oppositePin
}
}
} else if (this.enteredPin.nodeElement.getType() === Configuration.paths.knot) {
} else if (this.enteredPin.isKnot()) {
this.#knotPin = this.enteredPin
if (this.link.source.isOutput()) {
// Knot uses by default the output pin, let's switch to keep it coherent with the source node we have
this.enteredPin = /** @type {KnotPinTemplate} */(this.enteredPin.template).getOppositePin()
this.enteredPin = /** @type {KnotPinTemplate} */(this.enteredPin.template).oppositePin()
}
}
if (!this.link.source.getLinks().find(ref => ref.equals(this.enteredPin.createPinReference()))) {
@@ -145,5 +142,6 @@ export default class MouseCreateLink extends IMouseClickDrag {
this.link.removeMessage()
this.link.finishDragging()
this.link = null
this.#knotPin = null
}
}

View File

@@ -122,22 +122,20 @@ export default class LinkTemplate extends IFromToPositionedTemplate {
if (changedProperties.has("fromX") || changedProperties.has("toX")) {
const from = this.element.fromX
const to = this.element.toX
const isSourceAKnot = sourcePin?.nodeElement.getType() == Configuration.paths.knot
const isDestinationAKnot = destinationPin?.nodeElement.getType() == Configuration.paths.knot
const isSourceAKnot = sourcePin?.isKnot()
const isDestinationAKnot = destinationPin?.isKnot()
if (isSourceAKnot && (!destinationPin || isDestinationAKnot)) {
if (sourcePin?.isInput() && to > from + Configuration.distanceThreshold) {
this.element.source = /** @type {KnotNodeTemplate} */(sourcePin.nodeElement.template).outputPin
} else if (sourcePin?.isOutput() && to < from - Configuration.distanceThreshold) {
this.element.source = /** @type {KnotNodeTemplate} */(sourcePin.nodeElement.template).inputPin
if (sourcePin?.isInputLoossly() && to > from + Configuration.distanceThreshold) {
this.element.source = /** @type {KnotPinTemplate} */(sourcePin.template).oppositePin()
} else if (sourcePin?.isOutputLoosely() && to < from - Configuration.distanceThreshold) {
this.element.source = /** @type {KnotPinTemplate} */(sourcePin.template).oppositePin()
}
}
if (isDestinationAKnot && (!sourcePin || isSourceAKnot)) {
if (destinationPin?.isInput() && to < from - Configuration.distanceThreshold) {
this.element.destination =
/** @type {KnotNodeTemplate} */(destinationPin.nodeElement.template).outputPin
} else if (destinationPin?.isOutput() && to > from + Configuration.distanceThreshold) {
this.element.destination =
/** @type {KnotNodeTemplate} */(destinationPin.nodeElement.template).inputPin
if (destinationPin?.isInputLoossly() && to < from - Configuration.distanceThreshold) {
this.element.destination = /** @type {KnotPinTemplate} */(destinationPin.template).oppositePin()
} else if (destinationPin?.isOutputLoosely() && to > from + Configuration.distanceThreshold) {
this.element.destination = /** @type {KnotPinTemplate} */(destinationPin.template).oppositePin()
}
}
}

View File

@@ -31,10 +31,7 @@ export default class KnotNodeTemplate extends NodeTemplate {
/** @param {PinElement} startingPin */
findDirectionaPin(startingPin) {
if (
startingPin.nodeElement.getType() !== Configuration.paths.knot
|| KnotNodeTemplate.#traversedPin.has(startingPin)
) {
if (startingPin.isKnot() || KnotNodeTemplate.#traversedPin.has(startingPin)) {
KnotNodeTemplate.#traversedPin.clear()
return true
}

View File

@@ -9,7 +9,7 @@ export default class KnotPinTemplate extends MinimalPinTemplate {
return this.element.isOutput() ? super.render() : html``
}
getOppositePin() {
oppositePin() {
const nodeTemplate = /** @type {KnotNodeTemplate} */(this.element.nodeElement.template)
return this.element.isOutput() ? nodeTemplate.inputPin : nodeTemplate.outputPin
}

View File

@@ -38,15 +38,15 @@ defineConfig({
use: { ...devices['Desktop Chrome'] },
},
{
name: 'firefox',
use: { ...devices['Desktop Firefox'] },
},
// {
// name: 'firefox',
// use: { ...devices['Desktop Firefox'] },
// },
{
name: 'webkit',
use: { ...devices['Desktop Safari'] },
},
// {
// name: 'webkit',
// use: { ...devices['Desktop Safari'] },
// },
/* Test against mobile viewports. */
// {

View File

@@ -38,6 +38,8 @@ export const test = /**
const blueprintPage = new BlueprintFixture(page)
await blueprintPage.setup()
await use(blueprintPage)
await blueprintPage.cleanup()
await page.close()
}, { scope: "worker" }]
}
)

View File

@@ -0,0 +1,84 @@
import { expect, test } from "./fixtures/test.js"
test.describe.configure({ mode: "parallel" })
test("Linked knots direction", async ({ blueprintPage }) => {
await blueprintPage.paste(String.raw`
Begin Object Class=/Script/BlueprintGraph.K2Node_CallFunction Name="K2Node_CallFunction_2" ExportPath="/Script/BlueprintGraph.K2Node_CallFunction'/Game/NewWorld.NewWorld:PersistentLevel.NewWorld.EventGraph.K2Node_CallFunction_2'"
FunctionReference=(MemberParent="/Script/CoreUObject.Class'/Script/Engine.KismetSystemLibrary'",MemberName="PrintString")
NodePosX=-688
NodePosY=-480
AdvancedPinDisplay=Hidden
EnabledState=DevelopmentOnly
NodeGuid=C799F457FC974BE39AB9DFDB06B147CC
CustomProperties Pin (PinId=50BB0275555A476DAB6E032CEC8DCB8D,PinName="execute",PinToolTip="\nExec",PinType.PinCategory="exec",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,)
CustomProperties Pin (PinId=3329E83DBF9142F1ADED050DE676AAC8,PinName="then",PinToolTip="\nExec",Direction="EGPD_Output",PinType.PinCategory="exec",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_Knot_1 A35C55E791824F0191083ADDC60B9254,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,)
CustomProperties Pin (PinId=2780BC41A1984038AD716F4B57D62AD4,PinName="self",PinFriendlyName=NSLOCTEXT("K2Node", "Target", "Target"),PinToolTip="Target\nKismet System Library Riferimento Oggetto",PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject="/Script/CoreUObject.Class'/Script/Engine.KismetSystemLibrary'",PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,DefaultObject="/Script/Engine.Default__KismetSystemLibrary",PersistentGuid=00000000000000000000000000000000,bHidden=True,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,)
CustomProperties Pin (PinId=DCF3983679684A848212FC27B6423EEA,PinName="WorldContextObject",PinToolTip="World Context Object\nRiferimento Oggetto",PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject="/Script/CoreUObject.Class'/Script/CoreUObject.Object'",PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=True,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,PersistentGuid=00000000000000000000000000000000,bHidden=True,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,)
CustomProperties Pin (PinId=21B1587740814579A3BC176A388DFB27,PinName="InString",PinToolTip="In String\nStringa\n\nLa stringa per il logout",PinType.PinCategory="string",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,DefaultValue="Hello",AutogeneratedDefaultValue="Hello",PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,)
CustomProperties Pin (PinId=7F32726B6E2D4568B4E0811500A4AB87,PinName="bPrintToScreen",PinToolTip="Print to Screen\nBooleano\n\nDetermina se stampare o meno l\'output sullo schermo",PinType.PinCategory="bool",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,DefaultValue="true",AutogeneratedDefaultValue="true",PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=True,bOrphanedPin=False,)
CustomProperties Pin (PinId=FC4CF2634AC04418B6CD018200F40DAD,PinName="bPrintToLog",PinToolTip="Print to Log\nBooleano\n\nDetermina se stampare o meno l\'output nel registro",PinType.PinCategory="bool",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,DefaultValue="true",AutogeneratedDefaultValue="true",PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=True,bOrphanedPin=False,)
CustomProperties Pin (PinId=BE821BA0834B482A90DF017A1734B56A,PinName="TextColor",PinToolTip="Text Color\nLinear Color Struttura\n\nIl colore del testo da visualizzare",PinType.PinCategory="struct",PinType.PinSubCategory="",PinType.PinSubCategoryObject="/Script/CoreUObject.ScriptStruct'/Script/CoreUObject.LinearColor'",PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,DefaultValue="(R=0.000000,G=0.660000,B=1.000000,A=1.000000)",AutogeneratedDefaultValue="(R=0.000000,G=0.660000,B=1.000000,A=1.000000)",PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=True,bOrphanedPin=False,)
CustomProperties Pin (PinId=619EDE83100D4623862F2230152495A8,PinName="Duration",PinToolTip="Duration\nFloat (precisione singola)",PinType.PinCategory="real",PinType.PinSubCategory="float",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,DefaultValue="2.000000",AutogeneratedDefaultValue="2.000000",PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=True,bOrphanedPin=False,)
CustomProperties Pin (PinId=C1F3CDAE2AF6447D8590BD571379B513,PinName="Key",PinToolTip="Key\nNome",PinType.PinCategory="name",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=True,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,DefaultValue="None",AutogeneratedDefaultValue="None",PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=True,bOrphanedPin=False,)
End Object
Begin Object Class=/Script/BlueprintGraph.K2Node_Knot Name="K2Node_Knot_2" ExportPath="/Script/BlueprintGraph.K2Node_Knot'/Game/NewWorld.NewWorld:PersistentLevel.NewWorld.EventGraph.K2Node_Knot_2'"
NodePosX=-32
NodePosY=-448
NodeGuid=4142F276B8B742FFAF51B6CEDC0714E2
CustomProperties Pin (PinId=0E00FF0E15AC4F62A0BB73ABC3790946,PinName="InputPin",PinType.PinCategory="exec",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_Knot_3 0AE5CBEFA57A4D4E8264ED1DC9A6F0A7,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=True,bAdvancedView=False,bOrphanedPin=False,)
CustomProperties Pin (PinId=E87E272E9A5A43E8AD2DBA1953C48B7A,PinName="OutputPin",Direction="EGPD_Output",PinType.PinCategory="exec",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,)
End Object
Begin Object Class=/Script/BlueprintGraph.K2Node_Knot Name="K2Node_Knot_1" ExportPath="/Script/BlueprintGraph.K2Node_Knot'/Game/NewWorld.NewWorld:PersistentLevel.NewWorld.EventGraph.K2Node_Knot_1'"
NodePosX=-304
NodePosY=-448
NodeGuid=22B23583558A4BA9824A7A9133F0F4ED
CustomProperties Pin (PinId=A35C55E791824F0191083ADDC60B9254,PinName="InputPin",PinType.PinCategory="exec",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_CallFunction_2 3329E83DBF9142F1ADED050DE676AAC8,K2Node_Knot_4 B323C11F77EF430CB3AE50CE0DD0AC33,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=True,bAdvancedView=False,bOrphanedPin=False,)
CustomProperties Pin (PinId=689F0EA87F0B4B7484251AD1A30B191B,PinName="OutputPin",Direction="EGPD_Output",PinType.PinCategory="exec",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_Knot_3 AA76283BC9FE4FD2A5B51BA15487E851,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,)
End Object
Begin Object Class=/Script/BlueprintGraph.K2Node_CallFunction Name="K2Node_CallFunction_1" ExportPath="/Script/BlueprintGraph.K2Node_CallFunction'/Game/NewWorld.NewWorld:PersistentLevel.NewWorld.EventGraph.K2Node_CallFunction_1'"
FunctionReference=(MemberParent="/Script/CoreUObject.Class'/Script/Engine.KismetSystemLibrary'",MemberName="PrintString")
NodePosX=-688
NodePosY=-224
AdvancedPinDisplay=Hidden
EnabledState=DevelopmentOnly
NodeGuid=AB1E1BA7A8794D20AB0D495D7241AE95
CustomProperties Pin (PinId=50BB0275555A476DAB6E032CEC8DCB8D,PinName="execute",PinToolTip="\nExec",PinType.PinCategory="exec",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,)
CustomProperties Pin (PinId=3329E83DBF9142F1ADED050DE676AAC8,PinName="then",PinToolTip="\nExec",Direction="EGPD_Output",PinType.PinCategory="exec",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_Knot_4 3591D0F670F347A2A2C9A3CADE28DDB1,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,)
CustomProperties Pin (PinId=2780BC41A1984038AD716F4B57D62AD4,PinName="self",PinFriendlyName=NSLOCTEXT("K2Node", "Target", "Target"),PinToolTip="Target\nKismet System Library Riferimento Oggetto",PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject="/Script/CoreUObject.Class'/Script/Engine.KismetSystemLibrary'",PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,DefaultObject="/Script/Engine.Default__KismetSystemLibrary",PersistentGuid=00000000000000000000000000000000,bHidden=True,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,)
CustomProperties Pin (PinId=DCF3983679684A848212FC27B6423EEA,PinName="WorldContextObject",PinToolTip="World Context Object\nRiferimento Oggetto",PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject="/Script/CoreUObject.Class'/Script/CoreUObject.Object'",PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=True,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,PersistentGuid=00000000000000000000000000000000,bHidden=True,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,)
CustomProperties Pin (PinId=21B1587740814579A3BC176A388DFB27,PinName="InString",PinToolTip="In String\nStringa\n\nLa stringa per il logout",PinType.PinCategory="string",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,DefaultValue="Hello",AutogeneratedDefaultValue="Hello",PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,)
CustomProperties Pin (PinId=7F32726B6E2D4568B4E0811500A4AB87,PinName="bPrintToScreen",PinToolTip="Print to Screen\nBooleano\n\nDetermina se stampare o meno l\'output sullo schermo",PinType.PinCategory="bool",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,DefaultValue="true",AutogeneratedDefaultValue="true",PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=True,bOrphanedPin=False,)
CustomProperties Pin (PinId=FC4CF2634AC04418B6CD018200F40DAD,PinName="bPrintToLog",PinToolTip="Print to Log\nBooleano\n\nDetermina se stampare o meno l\'output nel registro",PinType.PinCategory="bool",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,DefaultValue="true",AutogeneratedDefaultValue="true",PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=True,bOrphanedPin=False,)
CustomProperties Pin (PinId=BE821BA0834B482A90DF017A1734B56A,PinName="TextColor",PinToolTip="Text Color\nLinear Color Struttura\n\nIl colore del testo da visualizzare",PinType.PinCategory="struct",PinType.PinSubCategory="",PinType.PinSubCategoryObject="/Script/CoreUObject.ScriptStruct'/Script/CoreUObject.LinearColor'",PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,DefaultValue="(R=0.000000,G=0.660000,B=1.000000,A=1.000000)",AutogeneratedDefaultValue="(R=0.000000,G=0.660000,B=1.000000,A=1.000000)",PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=True,bOrphanedPin=False,)
CustomProperties Pin (PinId=619EDE83100D4623862F2230152495A8,PinName="Duration",PinToolTip="Duration\nFloat (precisione singola)",PinType.PinCategory="real",PinType.PinSubCategory="float",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,DefaultValue="2.000000",AutogeneratedDefaultValue="2.000000",PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=True,bOrphanedPin=False,)
CustomProperties Pin (PinId=C1F3CDAE2AF6447D8590BD571379B513,PinName="Key",PinToolTip="Key\nNome",PinType.PinCategory="name",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=True,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,DefaultValue="None",AutogeneratedDefaultValue="None",PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=True,bOrphanedPin=False,)
End Object
Begin Object Class=/Script/BlueprintGraph.K2Node_Knot Name="K2Node_Knot_3" ExportPath="/Script/BlueprintGraph.K2Node_Knot'/Game/NewWorld.NewWorld:PersistentLevel.NewWorld.EventGraph.K2Node_Knot_3'"
NodePosX=-192
NodePosY=-448
NodeGuid=8ACF9A163F4B43CFB78DDC8F71B35EF0
CustomProperties Pin (PinId=AA76283BC9FE4FD2A5B51BA15487E851,PinName="InputPin",PinType.PinCategory="exec",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_Knot_1 689F0EA87F0B4B7484251AD1A30B191B,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=True,bAdvancedView=False,bOrphanedPin=False,)
CustomProperties Pin (PinId=0AE5CBEFA57A4D4E8264ED1DC9A6F0A7,PinName="OutputPin",Direction="EGPD_Output",PinType.PinCategory="exec",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_Knot_2 0E00FF0E15AC4F62A0BB73ABC3790946,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,)
End Object
Begin Object Class=/Script/BlueprintGraph.K2Node_Knot Name="K2Node_Knot_4" ExportPath="/Script/BlueprintGraph.K2Node_Knot'/Game/NewWorld.NewWorld:PersistentLevel.NewWorld.EventGraph.K2Node_Knot_4'"
NodePosX=-432
NodePosY=-336
NodeGuid=A6DAC4D17B254618A2251D0707836CC8
CustomProperties Pin (PinId=3591D0F670F347A2A2C9A3CADE28DDB1,PinName="InputPin",PinType.PinCategory="exec",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_CallFunction_1 3329E83DBF9142F1ADED050DE676AAC8,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=True,bAdvancedView=False,bOrphanedPin=False,)
CustomProperties Pin (PinId=B323C11F77EF430CB3AE50CE0DD0AC33,PinName="OutputPin",Direction="EGPD_Output",PinType.PinCategory="exec",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_Knot_1 A35C55E791824F0191083ADDC60B9254,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,)
End Object
`)
/** @type {Locator<PinElement>} */
let pinLocator = blueprintPage.blueprintLocator.locator("ueb-node").nth(2).locator("ueb-pin").nth(0)
expect(await pinLocator.evaluate(pin => pin.isInput())).toStrictEqual(true)
expect(await pinLocator.evaluate(pin => pin.isInput(true))).toBeUndefined()
expect(await pinLocator.evaluate(pin => pin.isOutput())).toStrictEqual(false)
expect(await pinLocator.evaluate(pin => pin.isOutput(true))).toBeUndefined()
pinLocator = blueprintPage.blueprintLocator.locator("ueb-node").nth(2).locator("ueb-pin").nth(1)
expect(await pinLocator.evaluate(pin => pin.isInput())).toStrictEqual(false)
expect(await pinLocator.evaluate(pin => pin.isInput(true))).toStrictEqual(false)
expect(await pinLocator.evaluate(pin => pin.isOutput())).toStrictEqual(true)
expect(await pinLocator.evaluate(pin => pin.isOutput(true))).toStrictEqual(true)
})

View File

@@ -2,6 +2,8 @@ import { expect, test } from "./fixtures/test.js"
const firstRowOnly = v => v.replaceAll(/^\s+|\n.+/gs, "")
test.describe.configure({ mode: "parallel" })
test("Renaming", async ({ blueprintPage }) => {
let source = String.raw`
Begin Object Class=/Script/UnrealEd.MaterialGraphNode Name="MaterialGraphNode_40" ExportPath=/Script/UnrealEd.MaterialGraphNode'"/Engine/Transient.M_Brick_Cut_Stone:MaterialGraph_0.MaterialGraphNode_40"'
@@ -11,7 +13,6 @@ test("Renaming", async ({ blueprintPage }) => {
expect(firstRowOnly(await blueprintPage.getSerializedNodes())).toEqual(
`Begin Object Class=/Script/UnrealEd.MaterialGraphNode Name="MaterialGraphNode_40" ExportPath=/Script/UnrealEd.MaterialGraphNode'"/Engine/Transient.M_Brick_Cut_Stone:MaterialGraph_0.MaterialGraphNode_40"'`
)
await blueprintPage.node.evaluate(n => n = "new name")
await blueprintPage.node.evaluate(n => n.entity.Name.value = "new name")
expect(firstRowOnly(await blueprintPage.getSerializedNodes())).toEqual(
`Begin Object Class=/Script/UnrealEd.MaterialGraphNode Name="new name" ExportPath=/Script/UnrealEd.MaterialGraphNode'"/Engine/Transient.M_Brick_Cut_Stone:MaterialGraph_0.new name"'`
@@ -198,7 +199,3 @@ test("Inner renaming", async ({ blueprintPage }) => {
`Begin Object Name="PCGBlueprintSettings_0" ExportPath=/Script/PCG.PCGBlueprintSettings'"/Game/NewPCGGraph.NewPCGGraph:PCGEditorGraph_1..ExecuteBlueprint_7.PCGBlueprintSettings_0"'`
)
})
test("Adopted renaming", async ({ blueprintPage }) => {
})

View File

@@ -7,7 +7,7 @@ import { expect, test } from "./fixtures/test.js"
*/
const serialized = (source, rename = "Blueprint") => {
let name = source.match(/.+?Name="([^"]+)"/)[1]
return source
let result = source
.replaceAll(/^\n|^ {12}| +$/gm, "")
.replaceAll(
new RegExp(
@@ -24,7 +24,10 @@ const serialized = (source, rename = "Blueprint") => {
""
)
.replaceAll(" ", " ")
.replaceAll(name, rename)
if (rename) {
result = result.replaceAll(name, rename)
}
return result
}
test.describe("Niagara ScriptVariables", () => {
@@ -33,11 +36,11 @@ test.describe("Niagara ScriptVariables", () => {
await blueprintPage.removeNodes()
})
test("Deserialization", async ({ blueprintPage }) => {
test.describe.configure({ mode: "parallel" })
test("Deserialization", async ({ blueprintPage }) => {
expect(await blueprintPage.blueprintLocator.evaluate(blueprint => blueprint.entity.serialize()))
.toEqual('Begin Object Name="Blueprint"\nEnd Object\n')
const source = String.raw`
Begin Object Class=/Script/NiagaraEditor.NiagaraClipboardContent Name="NiagaraClipboardContent_6" ExportPath="/Script/NiagaraEditor.NiagaraClipboardContent'/Engine/Transient.NiagaraClipboardContent_6'"
Begin Object Class=/Script/NiagaraEditor.NiagaraScriptVariable Name="NiagaraScriptVariable_2" ExportPath="/Script/NiagaraEditor.NiagaraScriptVariable'/Engine/Transient.NiagaraClipboardContent_6:NiagaraScriptVariable_2'"
@@ -73,12 +76,16 @@ test.describe("Niagara ScriptVariables", () => {
End Object
`
await blueprintPage.paste(source)
expect(await blueprintPage.blueprintLocator.evaluate(blueprint => blueprint.entity.serialize()))
.toEqual(serialized(source))
// await blueprintPage.blueprintLocator.evaluate(blueprint => blueprint.entity.Name.value = "NiagaraClipboardContent_6")
expect(await blueprintPage.blueprintLocator.evaluate(blueprint => {
const entity = blueprint.entity
entity.Name.value = "###########"
return entity.serialize()
}))
.toEqual(serialized(source, "###########"))
})
test("Merging", async ({ blueprintPage }) => {
// Var: Local.Module.Input, Local.Module.Input001, Local.Module.NewOutput
let source = String.raw`
Begin Object Class=/Script/NiagaraEditor.NiagaraClipboardContent Name="NiagaraClipboardContent_6" ExportPath="/Script/NiagaraEditor.NiagaraClipboardContent'/Engine/Transient.NiagaraClipboardContent_6'"
@@ -117,7 +124,6 @@ test.describe("Niagara ScriptVariables", () => {
await blueprintPage.paste(source)
expect(await blueprintPage.blueprintLocator.evaluate(blueprint => blueprint.entity.serialize()))
.toEqual(serialized(source))
// Var: Local.Module.Input, Local.Module.Input001, Local.Module.Camera Relative Position, Local.Module.X
// Add: Local.Module.Camera Relative Position (3), Local.Module.X (4)
// Has: Local.Module.Input (0), Local.Module.Input001 (1)