From 7f505f96155f124ad09e57c16f26bba3af7d0f94 Mon Sep 17 00:00:00 2001 From: Tqlted <78366008+Tqlted@users.noreply.github.com> Date: Mon, 4 Aug 2025 01:57:14 +0200 Subject: [PATCH 1/4] 15 new nodes, bossbar system --- .../fireflow/code/CodeEvaluator.java | 2 + .../fireflow/code/node/NodeList.java | 26 +++++++ .../code/node/impl/number/CosineNode.java | 47 +++++++++++ .../impl/number/GaussianDistributionNode.java | 38 +++++++++ .../code/node/impl/number/SineNode.java | 49 ++++++++++++ .../code/node/impl/number/TangentNode.java | 47 +++++++++++ .../impl/number/constants/EulersNode.java | 21 +++++ .../number/constants/GoldenRatioNode.java | 21 +++++ .../node/impl/number/constants/PiNode.java | 21 +++++ .../node/impl/number/constants/TauNode.java | 21 +++++ .../player/inventory/SetPlayerArmorNode.java | 52 +++++++++++++ .../visual/bossbar/ClearBossbarsNode.java | 37 +++++++++ .../visual/bossbar/RemoveBossbarNode.java | 44 +++++++++++ .../player/visual/bossbar/SetBossbarNode.java | 78 +++++++++++++++++++ .../code/node/impl/vector/DotProductNode.java | 26 +++++++ .../node/impl/vector/GetVectorLengthNode.java | 37 +++++++++ .../code/node/impl/world/TimestampNode.java | 21 +++++ .../fireflow/code/widget/NodeMenuWidget.java | 2 +- .../fireflow/space/BossBarManager.java | 62 +++++++++++++++ .../de/blazemcworld/fireflow/space/Space.java | 4 + 20 files changed, 655 insertions(+), 1 deletion(-) create mode 100644 src/main/java/de/blazemcworld/fireflow/code/node/impl/number/CosineNode.java create mode 100644 src/main/java/de/blazemcworld/fireflow/code/node/impl/number/GaussianDistributionNode.java create mode 100644 src/main/java/de/blazemcworld/fireflow/code/node/impl/number/SineNode.java create mode 100644 src/main/java/de/blazemcworld/fireflow/code/node/impl/number/TangentNode.java create mode 100644 src/main/java/de/blazemcworld/fireflow/code/node/impl/number/constants/EulersNode.java create mode 100644 src/main/java/de/blazemcworld/fireflow/code/node/impl/number/constants/GoldenRatioNode.java create mode 100644 src/main/java/de/blazemcworld/fireflow/code/node/impl/number/constants/PiNode.java create mode 100644 src/main/java/de/blazemcworld/fireflow/code/node/impl/number/constants/TauNode.java create mode 100644 src/main/java/de/blazemcworld/fireflow/code/node/impl/player/inventory/SetPlayerArmorNode.java create mode 100644 src/main/java/de/blazemcworld/fireflow/code/node/impl/player/visual/bossbar/ClearBossbarsNode.java create mode 100644 src/main/java/de/blazemcworld/fireflow/code/node/impl/player/visual/bossbar/RemoveBossbarNode.java create mode 100644 src/main/java/de/blazemcworld/fireflow/code/node/impl/player/visual/bossbar/SetBossbarNode.java create mode 100644 src/main/java/de/blazemcworld/fireflow/code/node/impl/vector/DotProductNode.java create mode 100644 src/main/java/de/blazemcworld/fireflow/code/node/impl/vector/GetVectorLengthNode.java create mode 100644 src/main/java/de/blazemcworld/fireflow/code/node/impl/world/TimestampNode.java create mode 100644 src/main/java/de/blazemcworld/fireflow/space/BossBarManager.java diff --git a/src/main/java/de/blazemcworld/fireflow/code/CodeEvaluator.java b/src/main/java/de/blazemcworld/fireflow/code/CodeEvaluator.java index 530e441..da50c6b 100644 --- a/src/main/java/de/blazemcworld/fireflow/code/CodeEvaluator.java +++ b/src/main/java/de/blazemcworld/fireflow/code/CodeEvaluator.java @@ -18,6 +18,7 @@ import de.blazemcworld.fireflow.code.widget.WidgetVec; import de.blazemcworld.fireflow.space.PlayWorld; import de.blazemcworld.fireflow.space.Space; +import de.blazemcworld.fireflow.space.SpaceManager; import de.blazemcworld.fireflow.util.DummyPlayer; import net.minecraft.entity.LivingEntity; import net.minecraft.entity.damage.DamageSource; @@ -206,6 +207,7 @@ public boolean onUseItem(ServerPlayerEntity player, ItemStack stack, Hand hand) } public void exitPlay(ServerPlayerEntity player) { + SpaceManager.getSpaceForPlayer(player).bossBarManager.clearBossBars(player); for (Node node : nodes) { if (node instanceof OnPlayerLeaveNode n) { n.onLeave(this, player); diff --git a/src/main/java/de/blazemcworld/fireflow/code/node/NodeList.java b/src/main/java/de/blazemcworld/fireflow/code/node/NodeList.java index 22e648d..cc33244 100644 --- a/src/main/java/de/blazemcworld/fireflow/code/node/NodeList.java +++ b/src/main/java/de/blazemcworld/fireflow/code/node/NodeList.java @@ -3,6 +3,10 @@ import de.blazemcworld.fireflow.FireFlow; import de.blazemcworld.fireflow.code.CodeEditor; import de.blazemcworld.fireflow.code.node.impl.condition.*; +import de.blazemcworld.fireflow.code.node.impl.number.constants.EulersNode; +import de.blazemcworld.fireflow.code.node.impl.number.constants.GoldenRatioNode; +import de.blazemcworld.fireflow.code.node.impl.number.constants.PiNode; +import de.blazemcworld.fireflow.code.node.impl.number.constants.TauNode; import de.blazemcworld.fireflow.code.node.impl.control.*; import de.blazemcworld.fireflow.code.node.impl.dictionary.*; import de.blazemcworld.fireflow.code.node.impl.entity.*; @@ -25,6 +29,9 @@ import de.blazemcworld.fireflow.code.node.impl.player.movement.*; import de.blazemcworld.fireflow.code.node.impl.player.statistic.*; import de.blazemcworld.fireflow.code.node.impl.player.visual.*; +import de.blazemcworld.fireflow.code.node.impl.player.visual.bossbar.ClearBossbarsNode; +import de.blazemcworld.fireflow.code.node.impl.player.visual.bossbar.RemoveBossbarNode; +import de.blazemcworld.fireflow.code.node.impl.player.visual.bossbar.SetBossbarNode; import de.blazemcworld.fireflow.code.node.impl.position.*; import de.blazemcworld.fireflow.code.node.impl.string.*; import de.blazemcworld.fireflow.code.node.impl.text.CombineTextsNode; @@ -170,11 +177,19 @@ public static void init() { .add(new TrimListNode<>(null)) ) .add(new Category("Number", Items.CLOCK) + .add(new Category("Math Constants", Items.TARGET) + .add(new EulersNode()) + .add(new GoldenRatioNode()) + .add(new PiNode()) + .add(new TauNode()) + ) .add(new AbsoluteNumberNode()) .add(new AddNumbersNode()) .add(new BasicNoiseNode()) .add(new ClampNumberNode()) + .add(new CosineNode()) .add(new DivideNumbersNode()) + .add(new GaussianDistributionNode()) .add(new GreaterEqualNode()) .add(new GreaterThanNode()) .add(new LessEqualNode()) @@ -186,8 +201,10 @@ public static void init() { .add(new RemainderNode()) .add(new RoundNumberNode()) .add(new SetToExponentialNode()) + .add(new SineNode()) .add(new SquareRootNode()) .add(new SubtractNumbersNode()) + .add(new TangentNode()) ) .add(new Category("Player", Items.PLAYER_HEAD) .add(new Category("Gameplay", Items.GRASS_BLOCK) @@ -213,6 +230,7 @@ public static void init() { .add(new PlayerHasItemNode()) .add(new PlayerItemHasCooldownNode()) .add(new SetHeldSlotNode()) + .add(new SetPlayerArmorNode()) .add(new SetPlayerInventoryNode()) .add(new SetPlayerInventorySlotNode()) .add(new SetPlayerItemCooldownNode()) @@ -254,6 +272,11 @@ public static void init() { .add(new SetPlayerSaturationNode()) ) .add(new Category("Visual", Items.ENDER_PEARL) + .add(new Category("Bossbar", Items.ENDER_DRAGON_SPAWN_EGG) + .add(new SetBossbarNode()) + .add(new RemoveBossbarNode()) + .add(new ClearBossbarsNode()) + ) .add(new BroadcastNode()) .add(new SendActionbarNode()) .add(new SendBlockChangeNode()) @@ -297,7 +320,9 @@ public static void init() { ) .add(new Category("Vector", Items.ARROW) .add(new AddVectorsNode()) + .add(new DotProductNode()) .add(new GetVectorComponentNode()) + .add(new GetVectorLengthNode()) .add(new PackVectorNode()) .add(new ReflectVectorNode()) .add(new RoundVectorAxesNode()) @@ -318,6 +343,7 @@ public static void init() { .add(new SetBlockNode()) .add(new SetBlockTagNode<>(null)) .add(new SetRegionNode()) + .add(new TimestampNode()) ) .add(new Category("Function", Items.COMMAND_BLOCK).markFunctions()) .finish(); diff --git a/src/main/java/de/blazemcworld/fireflow/code/node/impl/number/CosineNode.java b/src/main/java/de/blazemcworld/fireflow/code/node/impl/number/CosineNode.java new file mode 100644 index 0000000..7eba492 --- /dev/null +++ b/src/main/java/de/blazemcworld/fireflow/code/node/impl/number/CosineNode.java @@ -0,0 +1,47 @@ +package de.blazemcworld.fireflow.code.node.impl.number; + +import de.blazemcworld.fireflow.code.node.Node; +import de.blazemcworld.fireflow.code.type.NumberType; +import de.blazemcworld.fireflow.code.type.StringType; +import net.minecraft.item.Items; + +public class CosineNode extends Node { + public CosineNode() { + super("cosine", "Cosine", "Generates the trigonometric cosine function of a number.", Items.BUBBLE_CORAL_FAN); + Input value = new Input<>("value", "Value", NumberType.INSTANCE); + Input mode = new Input<>("mode", "Mode", StringType.INSTANCE).options("cos","cosh","acos"); + Input inputUnit = new Input<>("input_unit", "Input Unit", StringType.INSTANCE).options("Degrees","Radians"); + Output result = new Output<>("result", "Result", NumberType.INSTANCE); + + result.valueFrom((ctx) -> { + double valueInput = value.getValue(ctx); + switch (mode.getValue(ctx)) { + case "cos" -> { + if (inputUnit.getValue(ctx).equals("Degrees")) { + return Math.cos(Math.toRadians(valueInput)); + } else { + return Math.cos(valueInput); + } + } + case "acos" -> { + if (inputUnit.getValue(ctx).equals("Degrees")) { + return Math.toDegrees(Math.acos(valueInput)); + } else { + return Math.acos(valueInput); + } + } + case "cosh" -> { + return Math.cosh(valueInput); + } + default -> { + return 0.0; + } + } + }); + } + + @Override + public Node copy() { + return new CosineNode(); + } +} \ No newline at end of file diff --git a/src/main/java/de/blazemcworld/fireflow/code/node/impl/number/GaussianDistributionNode.java b/src/main/java/de/blazemcworld/fireflow/code/node/impl/number/GaussianDistributionNode.java new file mode 100644 index 0000000..ef2e2d8 --- /dev/null +++ b/src/main/java/de/blazemcworld/fireflow/code/node/impl/number/GaussianDistributionNode.java @@ -0,0 +1,38 @@ +package de.blazemcworld.fireflow.code.node.impl.number; + +import de.blazemcworld.fireflow.code.node.Node; +import de.blazemcworld.fireflow.code.type.NumberType; +import de.blazemcworld.fireflow.code.type.StringType; +import net.minecraft.item.Items; + +import java.util.Random; + +public class GaussianDistributionNode extends Node { + + public GaussianDistributionNode() { + super("gaussian_distribution", "Gaussian Distribution", "Generate a normally distributed random number", Items.POLAR_BEAR_SPAWN_EGG); + Input mode = new Input<>("mode", "Mode", StringType.INSTANCE) + .options("Normal", "Folded"); + Input mean = new Input<>("mean", "μ (Mean midpoint)", NumberType.INSTANCE); + Input deviation = new Input<>("max", "σ (Standard deviation)", NumberType.INSTANCE); + Output output = new Output<>("output", "Output", NumberType.INSTANCE); + + output.valueFrom((ctx -> { + Random random = new Random(); + double outputMean = mean.getValue(ctx); + double outputDeviation = deviation.getValue(ctx); + + return switch (mode.getValue(ctx)) { + case "Normal" -> outputMean + outputDeviation * random.nextGaussian(); + case "Folded" -> outputMean + outputDeviation * Math.abs(random.nextGaussian()); + + default -> 0.0; + }; + })); + } + + @Override + public Node copy() { + return new GaussianDistributionNode(); + } +} \ No newline at end of file diff --git a/src/main/java/de/blazemcworld/fireflow/code/node/impl/number/SineNode.java b/src/main/java/de/blazemcworld/fireflow/code/node/impl/number/SineNode.java new file mode 100644 index 0000000..588e30e --- /dev/null +++ b/src/main/java/de/blazemcworld/fireflow/code/node/impl/number/SineNode.java @@ -0,0 +1,49 @@ +package de.blazemcworld.fireflow.code.node.impl.number; + +import de.blazemcworld.fireflow.code.node.Node; +import de.blazemcworld.fireflow.code.type.NumberType; +import de.blazemcworld.fireflow.code.type.StringType; +import net.minecraft.item.Items; + +import java.util.Objects; + +public class SineNode extends Node { + public SineNode() { + super("sine", "Sine", "Generates the trigonometric sine function of a number.", Items.TUBE_CORAL_FAN); + Input value = new Input<>("value", "Value", NumberType.INSTANCE); + Input mode = new Input<>("mode", "Mode", StringType.INSTANCE).options("sin","sinh","asin"); + Input inputUnit = new Input<>("input_unit", "Input Unit", StringType.INSTANCE).options("Degrees","Radians"); + Output result = new Output<>("result", "Result", NumberType.INSTANCE); + + result.valueFrom((ctx) -> { + double valueInput = value.getValue(ctx); + switch (mode.getValue(ctx)) { + case "sin" -> { + if (inputUnit.getValue(ctx).equals("Degrees")) { + return Math.sin(Math.toRadians(valueInput)); + } else { + return Math.sin(valueInput); + } + } + case "asin" -> { + if (inputUnit.getValue(ctx).equals("Degrees")) { + return Math.toDegrees(Math.asin(valueInput)); + } else { + return Math.asin(valueInput); + } + } + case "sinh" -> { + return Math.sinh(valueInput); + } + default -> { + return 0.0; + } + } + }); + } + + @Override + public Node copy() { + return new SineNode(); + } +} \ No newline at end of file diff --git a/src/main/java/de/blazemcworld/fireflow/code/node/impl/number/TangentNode.java b/src/main/java/de/blazemcworld/fireflow/code/node/impl/number/TangentNode.java new file mode 100644 index 0000000..a459683 --- /dev/null +++ b/src/main/java/de/blazemcworld/fireflow/code/node/impl/number/TangentNode.java @@ -0,0 +1,47 @@ +package de.blazemcworld.fireflow.code.node.impl.number; + +import de.blazemcworld.fireflow.code.node.Node; +import de.blazemcworld.fireflow.code.type.NumberType; +import de.blazemcworld.fireflow.code.type.StringType; +import net.minecraft.item.Items; + +public class TangentNode extends Node { + public TangentNode() { + super("tangent", "Tangent", "Generates the trigonometric tangent function of a number.", Items.HORN_CORAL_FAN); + Input value = new Input<>("value", "Value", NumberType.INSTANCE); + Input mode = new Input<>("mode", "Mode", StringType.INSTANCE).options("tan","tanh","atan"); + Input inputUnit = new Input<>("input_unit", "Input Unit", StringType.INSTANCE).options("Degrees","Radians"); + Output result = new Output<>("result", "Result", NumberType.INSTANCE); + + result.valueFrom((ctx) -> { + double valueInput = value.getValue(ctx); + switch (mode.getValue(ctx)) { + case "tan" -> { + if (inputUnit.getValue(ctx).equals("Degrees")) { + return Math.tan(Math.toRadians(valueInput)); + } else { + return Math.tan(valueInput); + } + } + case "atan" -> { + if (inputUnit.getValue(ctx).equals("Degrees")) { + return Math.toDegrees(Math.atan(valueInput)); + } else { + return Math.atan(valueInput); + } + } + case "tanh" -> { + return Math.tanh(valueInput); + } + default -> { + return 0.0; + } + } + }); + } + + @Override + public Node copy() { + return new TangentNode(); + } +} \ No newline at end of file diff --git a/src/main/java/de/blazemcworld/fireflow/code/node/impl/number/constants/EulersNode.java b/src/main/java/de/blazemcworld/fireflow/code/node/impl/number/constants/EulersNode.java new file mode 100644 index 0000000..14eca5b --- /dev/null +++ b/src/main/java/de/blazemcworld/fireflow/code/node/impl/number/constants/EulersNode.java @@ -0,0 +1,21 @@ +package de.blazemcworld.fireflow.code.node.impl.number.constants; + +import de.blazemcworld.fireflow.code.node.Node; +import de.blazemcworld.fireflow.code.type.NumberType; +import net.minecraft.item.Items; + +public class EulersNode extends Node { + + public EulersNode() { + super("eulers", "Euler's (e)", "Returns Euler's number.", Items.SPECTRAL_ARROW); + + Output value = new Output<>("value", "Value", NumberType.INSTANCE); + value.valueFrom(ctx -> Math.E); + } + + @Override + public Node copy() { + return new EulersNode(); + } + +} diff --git a/src/main/java/de/blazemcworld/fireflow/code/node/impl/number/constants/GoldenRatioNode.java b/src/main/java/de/blazemcworld/fireflow/code/node/impl/number/constants/GoldenRatioNode.java new file mode 100644 index 0000000..e093e7f --- /dev/null +++ b/src/main/java/de/blazemcworld/fireflow/code/node/impl/number/constants/GoldenRatioNode.java @@ -0,0 +1,21 @@ +package de.blazemcworld.fireflow.code.node.impl.number.constants; + +import de.blazemcworld.fireflow.code.node.Node; +import de.blazemcworld.fireflow.code.type.NumberType; +import net.minecraft.item.Items; + +public class GoldenRatioNode extends Node { + + public GoldenRatioNode() { + super("golden_ratio", "Golden Ratio (Φ)", "Returns the Golden Ratio.", Items.GOLD_NUGGET); + + Output value = new Output<>("value", "Value", NumberType.INSTANCE); + value.valueFrom(ctx -> (1 + Math.sqrt(5)) / 2); + } + + @Override + public Node copy() { + return new GoldenRatioNode(); + } + +} diff --git a/src/main/java/de/blazemcworld/fireflow/code/node/impl/number/constants/PiNode.java b/src/main/java/de/blazemcworld/fireflow/code/node/impl/number/constants/PiNode.java new file mode 100644 index 0000000..78ef21e --- /dev/null +++ b/src/main/java/de/blazemcworld/fireflow/code/node/impl/number/constants/PiNode.java @@ -0,0 +1,21 @@ +package de.blazemcworld.fireflow.code.node.impl.number.constants; + +import de.blazemcworld.fireflow.code.node.Node; +import de.blazemcworld.fireflow.code.type.NumberType; +import net.minecraft.item.Items; + +public class PiNode extends Node { + + public PiNode() { + super("pi", "Pi (π)", "Returns PI.", Items.SNOWBALL); + + Output value = new Output<>("value", "Value", NumberType.INSTANCE); + value.valueFrom(ctx -> Math.PI); + } + + @Override + public Node copy() { + return new PiNode(); + } + +} diff --git a/src/main/java/de/blazemcworld/fireflow/code/node/impl/number/constants/TauNode.java b/src/main/java/de/blazemcworld/fireflow/code/node/impl/number/constants/TauNode.java new file mode 100644 index 0000000..678773b --- /dev/null +++ b/src/main/java/de/blazemcworld/fireflow/code/node/impl/number/constants/TauNode.java @@ -0,0 +1,21 @@ +package de.blazemcworld.fireflow.code.node.impl.number.constants; + +import de.blazemcworld.fireflow.code.node.Node; +import de.blazemcworld.fireflow.code.type.NumberType; +import net.minecraft.item.Items; + +public class TauNode extends Node { + + public TauNode() { + super("tau", "Tau (τ)", "Returns TAU.", Items.SNOW_BLOCK); + + Output value = new Output<>("value", "Value", NumberType.INSTANCE); + value.valueFrom(ctx -> Math.TAU); + } + + @Override + public Node copy() { + return new TauNode(); + } + +} diff --git a/src/main/java/de/blazemcworld/fireflow/code/node/impl/player/inventory/SetPlayerArmorNode.java b/src/main/java/de/blazemcworld/fireflow/code/node/impl/player/inventory/SetPlayerArmorNode.java new file mode 100644 index 0000000..c4556a1 --- /dev/null +++ b/src/main/java/de/blazemcworld/fireflow/code/node/impl/player/inventory/SetPlayerArmorNode.java @@ -0,0 +1,52 @@ +package de.blazemcworld.fireflow.code.node.impl.player.inventory; + +import de.blazemcworld.fireflow.code.node.Node; +import de.blazemcworld.fireflow.code.type.*; +import de.blazemcworld.fireflow.code.value.ListValue; +import de.blazemcworld.fireflow.code.value.PlayerValue; +import net.minecraft.entity.attribute.AttributeContainer; +import net.minecraft.entity.attribute.EntityAttributeModifier; +import net.minecraft.entity.attribute.EntityAttributes; +import net.minecraft.item.ItemStack; +import net.minecraft.item.Items; + +public class SetPlayerArmorNode extends Node { + + public SetPlayerArmorNode() { + super("set_player_armor", "Set Player Armor", "Changes the armor of a player", Items.DIAMOND_LEGGINGS); + + Input signal = new Input<>("signal", "Signal", SignalType.INSTANCE); + Input player = new Input<>("player", "Player", PlayerType.INSTANCE); + Input head = new Input<>("head", "Head", ItemType.INSTANCE); + Input chest = new Input<>("chest", "Chest", ItemType.INSTANCE); + Input legs = new Input<>("legs", "Legs", ItemType.INSTANCE); + Input feet = new Input<>("feet", "Feet", ItemType.INSTANCE); + Input behaviour = new Input<>("behaviour", "Behaviour", StringType.INSTANCE) + .options("Clear", "Merge"); + Output next = new Output<>("next", "Next", SignalType.INSTANCE); + + signal.onSignal((ctx) -> { + player.getValue(ctx).tryUse(ctx, p -> { + boolean clearInv = behaviour.getValue(ctx).equals("Clear"); + ItemStack headItem = head.getValue(ctx); + ItemStack chestItem = chest.getValue(ctx); + ItemStack legsItem = legs.getValue(ctx); + ItemStack feetItem = feet.getValue(ctx); + if (!headItem.isEmpty() || clearInv) p.getInventory().setStack(39, headItem); + if (!chestItem.isEmpty() || clearInv) p.getInventory().setStack(38, chestItem); + if (!legsItem.isEmpty() || clearInv) p.getInventory().setStack(37, legsItem); + if (!feetItem.isEmpty() || clearInv) p.getInventory().setStack(36, feetItem); + }); + ctx.sendSignal(next); + }); + + } + + @Override + public Node copy() { + return new SetPlayerArmorNode(); + } + +} + + diff --git a/src/main/java/de/blazemcworld/fireflow/code/node/impl/player/visual/bossbar/ClearBossbarsNode.java b/src/main/java/de/blazemcworld/fireflow/code/node/impl/player/visual/bossbar/ClearBossbarsNode.java new file mode 100644 index 0000000..02e8944 --- /dev/null +++ b/src/main/java/de/blazemcworld/fireflow/code/node/impl/player/visual/bossbar/ClearBossbarsNode.java @@ -0,0 +1,37 @@ +package de.blazemcworld.fireflow.code.node.impl.player.visual.bossbar; + +import de.blazemcworld.fireflow.code.node.Node; +import de.blazemcworld.fireflow.code.type.NumberType; +import de.blazemcworld.fireflow.code.type.PlayerType; +import de.blazemcworld.fireflow.code.type.SignalType; +import de.blazemcworld.fireflow.code.value.PlayerValue; +import de.blazemcworld.fireflow.space.BossBarManager; +import de.blazemcworld.fireflow.space.Space; +import de.blazemcworld.fireflow.space.SpaceManager; +import net.minecraft.item.Items; + +public class ClearBossbarsNode extends Node { + + public ClearBossbarsNode() { + super("clear_bossbars", "Clear Bossbars", "Removes all bossbars from a player", Items.STRUCTURE_VOID); + + Input signal = new Input<>("signal", "Signal", SignalType.INSTANCE); + Input player = new Input<>("player", "Player", PlayerType.INSTANCE); + + Output next = new Output<>("next", "Next", SignalType.INSTANCE); + + signal.onSignal((ctx) -> { + player.getValue(ctx).tryUse(ctx, p -> { + Space space = SpaceManager.getSpaceForPlayer(p); + BossBarManager bossBarManager = space.bossBarManager; + bossBarManager.clearBossBars(p); + }); + ctx.sendSignal(next); + }); + } + + @Override + public Node copy() { + return new ClearBossbarsNode(); + } +} diff --git a/src/main/java/de/blazemcworld/fireflow/code/node/impl/player/visual/bossbar/RemoveBossbarNode.java b/src/main/java/de/blazemcworld/fireflow/code/node/impl/player/visual/bossbar/RemoveBossbarNode.java new file mode 100644 index 0000000..ffc85dd --- /dev/null +++ b/src/main/java/de/blazemcworld/fireflow/code/node/impl/player/visual/bossbar/RemoveBossbarNode.java @@ -0,0 +1,44 @@ +package de.blazemcworld.fireflow.code.node.impl.player.visual.bossbar; + +import de.blazemcworld.fireflow.code.node.Node; +import de.blazemcworld.fireflow.code.type.NumberType; +import de.blazemcworld.fireflow.code.type.PlayerType; +import de.blazemcworld.fireflow.code.type.SignalType; +import de.blazemcworld.fireflow.code.type.TextType; +import de.blazemcworld.fireflow.code.value.PlayerValue; +import de.blazemcworld.fireflow.space.BossBarManager; +import de.blazemcworld.fireflow.space.Space; +import de.blazemcworld.fireflow.space.SpaceManager; +import net.minecraft.entity.boss.BossBar; +import net.minecraft.entity.boss.ServerBossBar; +import net.minecraft.item.Items; +import net.minecraft.text.Text; + +import java.util.List; + +public class RemoveBossbarNode extends Node { + + public RemoveBossbarNode() { + super("remove_bossbar", "Remove Bossbar", "Removes a bossbar from a player", Items.PALE_OAK_SIGN); + + Input signal = new Input<>("signal", "Signal", SignalType.INSTANCE); + Input player = new Input<>("player", "Player", PlayerType.INSTANCE); + Input position = new Input<>("position", "Position", NumberType.INSTANCE); + + Output next = new Output<>("next", "Next", SignalType.INSTANCE); + + signal.onSignal((ctx) -> { + player.getValue(ctx).tryUse(ctx, p -> { + Space space = SpaceManager.getSpaceForPlayer(p); + BossBarManager bossBarManager = space.bossBarManager; + bossBarManager.removeBossBarAtIndex(p,position.getValue(ctx).intValue()); + }); + ctx.sendSignal(next); + }); + } + + @Override + public Node copy() { + return new RemoveBossbarNode(); + } +} diff --git a/src/main/java/de/blazemcworld/fireflow/code/node/impl/player/visual/bossbar/SetBossbarNode.java b/src/main/java/de/blazemcworld/fireflow/code/node/impl/player/visual/bossbar/SetBossbarNode.java new file mode 100644 index 0000000..8d6c909 --- /dev/null +++ b/src/main/java/de/blazemcworld/fireflow/code/node/impl/player/visual/bossbar/SetBossbarNode.java @@ -0,0 +1,78 @@ +package de.blazemcworld.fireflow.code.node.impl.player.visual.bossbar; + +import de.blazemcworld.fireflow.code.node.Node; +import de.blazemcworld.fireflow.code.type.*; +import de.blazemcworld.fireflow.code.value.PlayerValue; +import de.blazemcworld.fireflow.space.BossBarManager; +import de.blazemcworld.fireflow.space.Space; +import de.blazemcworld.fireflow.space.SpaceManager; +import net.minecraft.entity.boss.BossBar; +import net.minecraft.entity.boss.ServerBossBar; +import net.minecraft.item.Items; +import net.minecraft.text.Text; + +import java.util.List; + +public class SetBossbarNode extends Node { + + public SetBossbarNode() { + super("set_bossbar", "Set Bossbar", "Sets a bossbar for a player", Items.BIRCH_SIGN); + + Input signal = new Input<>("signal", "Signal", SignalType.INSTANCE); + Input player = new Input<>("player", "Player", PlayerType.INSTANCE); + Input title = new Input<>("title", "Title", TextType.INSTANCE); + Input current_health = new Input<>("current_health", "Current Health", NumberType.INSTANCE); + Input max_health = new Input<>("max_health", "Maximum Health", NumberType.INSTANCE); + Input position = new Input<>("position", "Position", NumberType.INSTANCE); + Input barColor = new Input<>("bar_color", "Bar Color", StringType.INSTANCE).options("Red","Purple","Pink","Blue","Green","Yellow","White"); + Input barStyle = new Input<>("bar_style", "Bar Style", StringType.INSTANCE).options("Solid","6 Segments","10 Segments","12 Segments","20 Segments"); + Input skyEffect = new Input<>("sky_effect", "Sky Effect", StringType.INSTANCE).options("None","Thicken Fog","Darken Sky","Both"); + + Output next = new Output<>("next", "Next", SignalType.INSTANCE); + + signal.onSignal((ctx) -> { + player.getValue(ctx).tryUse(ctx, p -> { + Space space = SpaceManager.getSpaceForPlayer(p); + BossBarManager bossBarManager = space.bossBarManager; + BossBar.Color color = switch(barColor.getValue(ctx)) { + case "Red" -> BossBar.Color.RED; + case "Purple" -> BossBar.Color.PURPLE; + case "Pink" -> BossBar.Color.PINK; + case "Blue" -> BossBar.Color.BLUE; + case "Green" -> BossBar.Color.GREEN; + case "Yellow" -> BossBar.Color.YELLOW; + default -> BossBar.Color.WHITE; + }; + BossBar.Style style = switch(barStyle.getValue(ctx)) { + case "6 Segments" -> BossBar.Style.NOTCHED_6; + case "10 Segments" -> BossBar.Style.NOTCHED_10; + case "12 Segments" -> BossBar.Style.NOTCHED_12; + case "20 Segments" -> BossBar.Style.NOTCHED_20; + default -> BossBar.Style.PROGRESS; + }; + ServerBossBar bossBar = new ServerBossBar( + title.getValue(ctx), + color, + style + ); + switch(skyEffect.getValue(ctx)) { + case "Thicken Fog" -> bossBar.setThickenFog(true); + case "Darken Sky" -> bossBar.setDarkenSky(true); + case "Both" -> { + bossBar.setThickenFog(true); + bossBar.setDarkenSky(true); + } + } + bossBar.setPercent(current_health.getValue(ctx).floatValue()/max_health.getValue(ctx).floatValue()); + List bossBars = bossBarManager.getBossBars(p); + bossBarManager.setBossBarAtIndex(p,position.getValue(ctx).intValue(), bossBar); + }); + ctx.sendSignal(next); + }); + } + + @Override + public Node copy() { + return new SetBossbarNode(); + } +} diff --git a/src/main/java/de/blazemcworld/fireflow/code/node/impl/vector/DotProductNode.java b/src/main/java/de/blazemcworld/fireflow/code/node/impl/vector/DotProductNode.java new file mode 100644 index 0000000..57e986d --- /dev/null +++ b/src/main/java/de/blazemcworld/fireflow/code/node/impl/vector/DotProductNode.java @@ -0,0 +1,26 @@ +package de.blazemcworld.fireflow.code.node.impl.vector; + +import de.blazemcworld.fireflow.code.node.Node; +import de.blazemcworld.fireflow.code.type.NumberType; +import de.blazemcworld.fireflow.code.type.VectorType; +import net.minecraft.item.Items; +import net.minecraft.util.math.Vec3d; +import org.apache.logging.log4j.core.lookup.Interpolator; + +public class DotProductNode extends Node { + + public DotProductNode() { + super("dot_product", "Dot Product", "Gets the Dot Product of two vectors", Items.GUNPOWDER); + + Input first = new Input<>("first", "First", VectorType.INSTANCE); + Input second = new Input<>("second", "Second", VectorType.INSTANCE); + Output result = new Output<>("result", "Result", NumberType.INSTANCE); + + result.valueFrom(ctx -> first.getValue(ctx).dotProduct(second.getValue(ctx))); + } + + @Override + public Node copy() { + return new DotProductNode(); + } +} diff --git a/src/main/java/de/blazemcworld/fireflow/code/node/impl/vector/GetVectorLengthNode.java b/src/main/java/de/blazemcworld/fireflow/code/node/impl/vector/GetVectorLengthNode.java new file mode 100644 index 0000000..90dcfce --- /dev/null +++ b/src/main/java/de/blazemcworld/fireflow/code/node/impl/vector/GetVectorLengthNode.java @@ -0,0 +1,37 @@ +package de.blazemcworld.fireflow.code.node.impl.vector; + +import de.blazemcworld.fireflow.code.node.Node; +import de.blazemcworld.fireflow.code.type.NumberType; +import de.blazemcworld.fireflow.code.type.StringType; +import de.blazemcworld.fireflow.code.type.VectorType; +import net.minecraft.item.Items; +import net.minecraft.util.math.Vec3d; + +public class GetVectorLengthNode extends Node { + public GetVectorLengthNode() { + super("get_vector_length", "Get Vector Length", "Gets the length of a vector", Items.BREEZE_ROD); + Input vector = new Input<>("vector", "Vector", VectorType.INSTANCE); + Input lengthType = new Input<>("length_type", "Length Type", StringType.INSTANCE).options("Normal","Squared"); + Output length = new Output<>("length", "Length", NumberType.INSTANCE); + + length.valueFrom(ctx -> { + Vec3d v = vector.getValue(ctx); + switch(lengthType.getValue(ctx)) { + case "Normal" -> { + return v.length(); + } + case "Squared" -> { + return v.lengthSquared(); + } + default -> { + return 0.0; + } + } + }); + } + + @Override + public Node copy() { + return new GetVectorLengthNode(); + } +} diff --git a/src/main/java/de/blazemcworld/fireflow/code/node/impl/world/TimestampNode.java b/src/main/java/de/blazemcworld/fireflow/code/node/impl/world/TimestampNode.java new file mode 100644 index 0000000..1273c28 --- /dev/null +++ b/src/main/java/de/blazemcworld/fireflow/code/node/impl/world/TimestampNode.java @@ -0,0 +1,21 @@ +package de.blazemcworld.fireflow.code.node.impl.world; + +import de.blazemcworld.fireflow.code.node.Node; +import de.blazemcworld.fireflow.code.type.NumberType; +import net.minecraft.item.Items; + +public class TimestampNode extends Node { + + public TimestampNode() { + super("timestamp", "Timestamp", "Returns the elapsed seconds since the Unix epoch.", Items.CLOCK); + + Output usage = new Output<>("timestamp", "Timestamp", NumberType.INSTANCE); + usage.valueFrom(ctx -> (double) System.currentTimeMillis() / 1000); + } + + @Override + public Node copy() { + return new TimestampNode(); + } + +} diff --git a/src/main/java/de/blazemcworld/fireflow/code/widget/NodeMenuWidget.java b/src/main/java/de/blazemcworld/fireflow/code/widget/NodeMenuWidget.java index 8cfc36e..c7a4e86 100644 --- a/src/main/java/de/blazemcworld/fireflow/code/widget/NodeMenuWidget.java +++ b/src/main/java/de/blazemcworld/fireflow/code/widget/NodeMenuWidget.java @@ -61,7 +61,7 @@ public NodeMenuWidget(WidgetVec pos, NodeList.Category category, List { if (interaction.type() != CodeInteraction.Type.RIGHT_CLICK) return false; diff --git a/src/main/java/de/blazemcworld/fireflow/space/BossBarManager.java b/src/main/java/de/blazemcworld/fireflow/space/BossBarManager.java new file mode 100644 index 0000000..919fd07 --- /dev/null +++ b/src/main/java/de/blazemcworld/fireflow/space/BossBarManager.java @@ -0,0 +1,62 @@ +package de.blazemcworld.fireflow.space; + +import net.minecraft.entity.boss.ServerBossBar; +import net.minecraft.server.network.ServerPlayerEntity; +import java.util.*; + +public class BossBarManager { + private final Map> bossBars = new HashMap<>(); + + public void setBossBarAtIndex(ServerPlayerEntity player, int index, ServerBossBar newBossBar) { + List bars = bossBars.computeIfAbsent(player.getUuid(), k -> new ArrayList<>()); + + while (bars.size() <= index) { + bars.add(null); + } + + ServerBossBar existing = bars.get(index); + if (existing != null) { + existing.setName(newBossBar.getName()); + existing.setPercent(newBossBar.getPercent()); + existing.setColor(newBossBar.getColor()); + existing.setStyle(newBossBar.getStyle()); + existing.setDarkenSky(newBossBar.shouldDarkenSky()); + existing.setThickenFog(newBossBar.shouldThickenFog()); + existing.addPlayer(player); + } else { + bars.set(index, newBossBar); + for (ServerBossBar bar : bars) { + if(bar == null) continue; + bar.removePlayer(player); + bar.addPlayer(player); + } + } + } + + + + public void removeBossBarAtIndex(ServerPlayerEntity player, int index) { + List bars = getBossBars(player); + if (bars != null && index >= 0 && index < bars.size()) { + ServerBossBar bar = bars.get(index); + bar.removePlayer(player); + bars.remove(index); + } + } + + public void clearBossBars(ServerPlayerEntity player) { + for (ServerBossBar bar : getBossBars(player)) { + if(bar == null) continue; + bar.removePlayer(player); + } + bossBars.remove(player.getUuid()); + } + + public List getBossBars(ServerPlayerEntity player) { + return bossBars.getOrDefault(player.getUuid(), Collections.emptyList()); + } + + public void reset() { + bossBars.clear(); + } +} diff --git a/src/main/java/de/blazemcworld/fireflow/space/Space.java b/src/main/java/de/blazemcworld/fireflow/space/Space.java index c8569a0..81c82b3 100644 --- a/src/main/java/de/blazemcworld/fireflow/space/Space.java +++ b/src/main/java/de/blazemcworld/fireflow/space/Space.java @@ -28,6 +28,7 @@ public class Space { private int emptyTimer = 0; public CodeEvaluator evaluator; public final DummyManager dummyManager; + public final BossBarManager bossBarManager; public Space(SpaceInfo info) { this.info = info; @@ -51,6 +52,7 @@ public Space(SpaceInfo info) { editor.load(); evaluator = new CodeEvaluator(this); dummyManager = new DummyManager(this); + bossBarManager = new BossBarManager(); } public void save() { @@ -69,6 +71,7 @@ public boolean isInactive() { protected void unload(Runnable callback) { dummyManager.reset(); + bossBarManager.reset(); for (ServerPlayerEntity player : new ArrayList<>(playWorld.getPlayers())) { ModeManager.move(player, ModeManager.Mode.LOBBY, this); } @@ -117,6 +120,7 @@ public Path path() { public void reload() { dummyManager.reset(); + bossBarManager.reset(); for (ServerPlayerEntity player : new ArrayList<>(playWorld.getPlayers())) { if (info.isOwnerOrDeveloper(player.getUuid())) { ModeManager.move(player, ModeManager.Mode.CODE, this); From b7bbc9e160f5473f04ebb9eb5b3e000bf30d32db Mon Sep 17 00:00:00 2001 From: Tqlted <78366008+Tqlted@users.noreply.github.com> Date: Mon, 4 Aug 2025 20:21:06 +0200 Subject: [PATCH 2/4] fixed /reload not removing bossbars, 5 new nodes --- .../fireflow/code/node/NodeList.java | 5 ++++ .../node/impl/number/AverageNumberNode.java | 29 +++++++++++++++++++ .../node/impl/number/LerpNumbersNode.java | 29 +++++++++++++++++++ .../code/node/impl/number/MaxNumberNode.java | 28 ++++++++++++++++++ .../code/node/impl/number/MinNumberNode.java | 28 ++++++++++++++++++ .../impl/player/meta/GetPlayerPingNode.java | 24 +++++++++++++++ .../de/blazemcworld/fireflow/space/Space.java | 3 +- 7 files changed, 145 insertions(+), 1 deletion(-) create mode 100644 src/main/java/de/blazemcworld/fireflow/code/node/impl/number/AverageNumberNode.java create mode 100644 src/main/java/de/blazemcworld/fireflow/code/node/impl/number/LerpNumbersNode.java create mode 100644 src/main/java/de/blazemcworld/fireflow/code/node/impl/number/MaxNumberNode.java create mode 100644 src/main/java/de/blazemcworld/fireflow/code/node/impl/number/MinNumberNode.java create mode 100644 src/main/java/de/blazemcworld/fireflow/code/node/impl/player/meta/GetPlayerPingNode.java diff --git a/src/main/java/de/blazemcworld/fireflow/code/node/NodeList.java b/src/main/java/de/blazemcworld/fireflow/code/node/NodeList.java index cc33244..1b9dbdd 100644 --- a/src/main/java/de/blazemcworld/fireflow/code/node/NodeList.java +++ b/src/main/java/de/blazemcworld/fireflow/code/node/NodeList.java @@ -185,6 +185,7 @@ public static void init() { ) .add(new AbsoluteNumberNode()) .add(new AddNumbersNode()) + .add(new AverageNumberNode()) .add(new BasicNoiseNode()) .add(new ClampNumberNode()) .add(new CosineNode()) @@ -192,8 +193,11 @@ public static void init() { .add(new GaussianDistributionNode()) .add(new GreaterEqualNode()) .add(new GreaterThanNode()) + .add(new LerpNumbersNode()) .add(new LessEqualNode()) .add(new LessThanNode()) + .add(new MaxNumberNode()) + .add(new MinNumberNode()) .add(new ModuloNode()) .add(new MultiplyNumbersNode()) .add(new ParseNumberNode()) @@ -239,6 +243,7 @@ public static void init() { ) .add(new Category("Meta", Items.COMMAND_BLOCK) .add(new GetPlayerNameNode()) + .add(new GetPlayerPingNode()) .add(new GetPlayerUUIDNode()) .add(new IsPlayingNode()) .add(new KickPlayerNode()) diff --git a/src/main/java/de/blazemcworld/fireflow/code/node/impl/number/AverageNumberNode.java b/src/main/java/de/blazemcworld/fireflow/code/node/impl/number/AverageNumberNode.java new file mode 100644 index 0000000..bf60eed --- /dev/null +++ b/src/main/java/de/blazemcworld/fireflow/code/node/impl/number/AverageNumberNode.java @@ -0,0 +1,29 @@ +package de.blazemcworld.fireflow.code.node.impl.number; + +import de.blazemcworld.fireflow.code.node.Node; +import de.blazemcworld.fireflow.code.type.NumberType; +import net.minecraft.item.Items; + +public class AverageNumberNode extends Node { + + public AverageNumberNode() { + super("average_number", "Average Number", "Returns the average number of a set.", Items.RAW_COPPER); + + Varargs numbers = new Varargs<>("numbers", "Numbers", NumberType.INSTANCE); + Output result = new Output<>("result", "Result", NumberType.INSTANCE); + + result.valueFrom((ctx) -> { + return numbers.getVarargs(ctx) + .stream() + .mapToDouble(Double::doubleValue) + .average() + .orElse(0.0); + }); + } + + @Override + public Node copy() { + return new AverageNumberNode(); + } + +} diff --git a/src/main/java/de/blazemcworld/fireflow/code/node/impl/number/LerpNumbersNode.java b/src/main/java/de/blazemcworld/fireflow/code/node/impl/number/LerpNumbersNode.java new file mode 100644 index 0000000..46a3538 --- /dev/null +++ b/src/main/java/de/blazemcworld/fireflow/code/node/impl/number/LerpNumbersNode.java @@ -0,0 +1,29 @@ +package de.blazemcworld.fireflow.code.node.impl.number; + +import de.blazemcworld.fireflow.code.node.Node; +import de.blazemcworld.fireflow.code.type.NumberType; +import net.minecraft.item.Items; + +public class LerpNumbersNode extends Node { + + public LerpNumbersNode() { + super("lerp_numbers", "Lerp", "Calculates a value between two inputs by linearly interpolating based on a factor t, where t = 0 returns the start value, t = 1 returns the end value, and values in between produce a proportional blend.", Items.REPEATER); + + Input left = new Input<>("left", "Left", NumberType.INSTANCE); + Input right = new Input<>("right", "Right", NumberType.INSTANCE); + Input time = new Input<>("time", "Time (0-1)", NumberType.INSTANCE); + Output result = new Output<>("result", "Result", NumberType.INSTANCE); + + result.valueFrom((ctx) -> { + double leftValue = left.getValue(ctx); + double rightValue = right.getValue(ctx); + double timeValue = Math.clamp(time.getValue(ctx),0,1); + return leftValue + (rightValue - leftValue) * timeValue; + }); + } + + @Override + public Node copy() { + return new LerpNumbersNode(); + } +} diff --git a/src/main/java/de/blazemcworld/fireflow/code/node/impl/number/MaxNumberNode.java b/src/main/java/de/blazemcworld/fireflow/code/node/impl/number/MaxNumberNode.java new file mode 100644 index 0000000..f0be5f4 --- /dev/null +++ b/src/main/java/de/blazemcworld/fireflow/code/node/impl/number/MaxNumberNode.java @@ -0,0 +1,28 @@ +package de.blazemcworld.fireflow.code.node.impl.number; + +import de.blazemcworld.fireflow.code.node.Node; +import de.blazemcworld.fireflow.code.type.NumberType; +import net.minecraft.item.Items; + +public class MaxNumberNode extends Node { + + public MaxNumberNode() { + super("max_number", "Maximum Number", "Returns the highest number in a set.", Items.NETHERITE_SCRAP); + + Varargs numbers = new Varargs<>("numbers", "Numbers", NumberType.INSTANCE); + Output result = new Output<>("result", "Result", NumberType.INSTANCE); + + result.valueFrom((ctx) -> { + return numbers.getVarargs(ctx) + .stream() + .max(Double::compareTo) + .orElse(0.0); + }); + } + + @Override + public Node copy() { + return new MaxNumberNode(); + } + +} diff --git a/src/main/java/de/blazemcworld/fireflow/code/node/impl/number/MinNumberNode.java b/src/main/java/de/blazemcworld/fireflow/code/node/impl/number/MinNumberNode.java new file mode 100644 index 0000000..1e9bea4 --- /dev/null +++ b/src/main/java/de/blazemcworld/fireflow/code/node/impl/number/MinNumberNode.java @@ -0,0 +1,28 @@ +package de.blazemcworld.fireflow.code.node.impl.number; + +import de.blazemcworld.fireflow.code.node.Node; +import de.blazemcworld.fireflow.code.type.NumberType; +import net.minecraft.item.Items; + +public class MinNumberNode extends Node { + + public MinNumberNode() { + super("min_number", "Minimum Number", "Returns the lowest number in a set.", Items.DISC_FRAGMENT_5); + + Varargs numbers = new Varargs<>("numbers", "Numbers", NumberType.INSTANCE); + Output result = new Output<>("result", "Result", NumberType.INSTANCE); + + result.valueFrom((ctx) -> { + return numbers.getVarargs(ctx) + .stream() + .min(Double::compareTo) + .orElse(0.0); + }); + } + + @Override + public Node copy() { + return new MinNumberNode(); + } + +} diff --git a/src/main/java/de/blazemcworld/fireflow/code/node/impl/player/meta/GetPlayerPingNode.java b/src/main/java/de/blazemcworld/fireflow/code/node/impl/player/meta/GetPlayerPingNode.java new file mode 100644 index 0000000..c027d08 --- /dev/null +++ b/src/main/java/de/blazemcworld/fireflow/code/node/impl/player/meta/GetPlayerPingNode.java @@ -0,0 +1,24 @@ +package de.blazemcworld.fireflow.code.node.impl.player.meta; + +import de.blazemcworld.fireflow.code.node.Node; +import de.blazemcworld.fireflow.code.type.NumberType; +import de.blazemcworld.fireflow.code.type.PlayerType; +import de.blazemcworld.fireflow.code.type.StringType; +import de.blazemcworld.fireflow.code.value.PlayerValue; +import net.minecraft.item.Items; + +public class GetPlayerPingNode extends Node { + public GetPlayerPingNode() { + super("get_player_ping", "Get Player Ping", "Gets the ping of a player.", Items.SHAPER_ARMOR_TRIM_SMITHING_TEMPLATE); + + Input player = new Input<>("player", "Player", PlayerType.INSTANCE); + Output ping = new Output<>("ping", "Ping", NumberType.INSTANCE); + + ping.valueFrom(ctx -> (double) player.getValue(ctx).tryGet(ctx, p -> p.networkHandler.getLatency(), 0)); + } + + @Override + public Node copy() { + return new GetPlayerPingNode(); + } +} \ No newline at end of file diff --git a/src/main/java/de/blazemcworld/fireflow/space/Space.java b/src/main/java/de/blazemcworld/fireflow/space/Space.java index 81c82b3..61d2c4b 100644 --- a/src/main/java/de/blazemcworld/fireflow/space/Space.java +++ b/src/main/java/de/blazemcworld/fireflow/space/Space.java @@ -120,14 +120,15 @@ public Path path() { public void reload() { dummyManager.reset(); - bossBarManager.reset(); for (ServerPlayerEntity player : new ArrayList<>(playWorld.getPlayers())) { + bossBarManager.clearBossBars(player); if (info.isOwnerOrDeveloper(player.getUuid())) { ModeManager.move(player, ModeManager.Mode.CODE, this); } else { ModeManager.move(player, ModeManager.Mode.LOBBY, this); } } + bossBarManager.reset(); evaluator.stop(); playWorld.getChunkManager().chunkLoadingManager.unloadChunks(() -> true); evaluator = new CodeEvaluator(this); From 37b0bd0d5bb70087f2761b71cbc89ed9a2d3c56a Mon Sep 17 00:00:00 2001 From: Tqlted <78366008+Tqlted@users.noreply.github.com> Date: Tue, 5 Aug 2025 21:41:18 +0200 Subject: [PATCH 3/4] New nodes --- .../fireflow/code/node/NodeList.java | 24 ++++++ .../code/node/impl/number/ArcTan2Node.java | 31 ++++++++ .../node/impl/number/AverageNumberNode.java | 4 +- .../code/node/impl/number/CosineNode.java | 4 +- .../impl/number/GaussianDistributionNode.java | 4 +- .../node/impl/number/LerpNumbersNode.java | 4 +- .../code/node/impl/number/MaxNumberNode.java | 4 +- .../code/node/impl/number/MinNumberNode.java | 4 +- .../code/node/impl/number/SineNode.java | 6 +- .../code/node/impl/number/TangentNode.java | 4 +- .../impl/number/constants/EulersNode.java | 4 +- .../number/constants/GoldenRatioNode.java | 4 +- .../node/impl/number/constants/PiNode.java | 4 +- .../node/impl/number/constants/TauNode.java | 4 +- .../player/inventory/SetPlayerArmorNode.java | 19 ++--- .../impl/player/meta/GetPlayerPingNode.java | 8 +- .../impl/player/visual/SendActionbarNode.java | 2 +- .../impl/player/visual/SetTablistNode.java | 36 +++++++++ .../visual/bossbar/ClearBossbarsNode.java | 37 --------- .../visual/bossbar/RemoveBossbarNode.java | 44 ----------- .../player/visual/bossbar/SetBossbarNode.java | 78 ------------------- .../code/node/impl/vector/DotProductNode.java | 13 ++-- .../node/impl/vector/GetVectorLengthNode.java | 10 +-- .../code/node/impl/world/TimestampNode.java | 4 +- .../fireflow/space/BossBarManager.java | 62 --------------- .../fireflow/util/Statistics.java | 6 ++ 26 files changed, 147 insertions(+), 277 deletions(-) create mode 100644 src/main/java/de/blazemcworld/fireflow/code/node/impl/number/ArcTan2Node.java create mode 100644 src/main/java/de/blazemcworld/fireflow/code/node/impl/player/visual/SetTablistNode.java delete mode 100644 src/main/java/de/blazemcworld/fireflow/code/node/impl/player/visual/bossbar/ClearBossbarsNode.java delete mode 100644 src/main/java/de/blazemcworld/fireflow/code/node/impl/player/visual/bossbar/RemoveBossbarNode.java delete mode 100644 src/main/java/de/blazemcworld/fireflow/code/node/impl/player/visual/bossbar/SetBossbarNode.java delete mode 100644 src/main/java/de/blazemcworld/fireflow/space/BossBarManager.java diff --git a/src/main/java/de/blazemcworld/fireflow/code/node/NodeList.java b/src/main/java/de/blazemcworld/fireflow/code/node/NodeList.java index 5556f4b..8cb4f54 100644 --- a/src/main/java/de/blazemcworld/fireflow/code/node/NodeList.java +++ b/src/main/java/de/blazemcworld/fireflow/code/node/NodeList.java @@ -16,6 +16,10 @@ import de.blazemcworld.fireflow.code.node.impl.item.*; import de.blazemcworld.fireflow.code.node.impl.list.*; import de.blazemcworld.fireflow.code.node.impl.number.*; +import de.blazemcworld.fireflow.code.node.impl.number.constants.EulersNode; +import de.blazemcworld.fireflow.code.node.impl.number.constants.GoldenRatioNode; +import de.blazemcworld.fireflow.code.node.impl.number.constants.PiNode; +import de.blazemcworld.fireflow.code.node.impl.number.constants.TauNode; import de.blazemcworld.fireflow.code.node.impl.player.gameplay.*; import de.blazemcworld.fireflow.code.node.impl.player.inventory.*; import de.blazemcworld.fireflow.code.node.impl.player.meta.*; @@ -164,15 +168,28 @@ public static void init() { .add(new TrimListNode<>(null)) ) .add(new Category("Number", Material.CLOCK) + .add(new Category("Math Constants", Material.TARGET) + .add(new EulersNode()) + .add(new GoldenRatioNode()) + .add(new PiNode()) + .add(new TauNode()) + ) .add(new AbsoluteNumberNode()) .add(new AddNumbersNode()) + .add(new ArcTan2Node()) + .add(new AverageNumberNode()) .add(new BasicNoiseNode()) .add(new ClampNumberNode()) + .add(new CosineNode()) .add(new DivideNumbersNode()) + .add(new GaussianDistributionNode()) .add(new GreaterEqualNode()) .add(new GreaterThanNode()) + .add(new LerpNumbersNode()) .add(new LessEqualNode()) .add(new LessThanNode()) + .add(new MaxNumberNode()) + .add(new MinNumberNode()) .add(new ModuloNode()) .add(new MultiplyNumbersNode()) .add(new ParseNumberNode()) @@ -180,8 +197,10 @@ public static void init() { .add(new RemainderNode()) .add(new RoundNumberNode()) .add(new SetToExponentialNode()) + .add(new SineNode()) .add(new SquareRootNode()) .add(new SubtractNumbersNode()) + .add(new TangentNode()) ) .add(new Category("Player", Material.PLAYER_HEAD) .add(new Category("Gameplay", Material.GRASS_BLOCK) @@ -207,6 +226,7 @@ public static void init() { .add(new PlayerHasItemNode()) .add(new PlayerItemHasCooldownNode()) .add(new SetHeldSlotNode()) + .add(new SetPlayerArmorNode()) .add(new SetPlayerInventoryNode()) .add(new SetPlayerInventorySlotNode()) .add(new SetPlayerItemCooldownNode()) @@ -215,6 +235,7 @@ public static void init() { ) .add(new Category("Meta", Material.COMMAND_BLOCK) .add(new GetPlayerNameNode()) + .add(new GetPlayerPingNode()) .add(new GetPlayerUUIDNode()) .add(new IsPlayingNode()) .add(new KickPlayerNode()) @@ -254,6 +275,7 @@ public static void init() { .add(new SendMessageNode()) .add(new SendTitleNode()) .add(new SetPlayerSkinNode()) + .add(new SetTablistNode()) ) ) .add(new Category("Position", Material.COMPASS) @@ -291,7 +313,9 @@ public static void init() { ) .add(new Category("Vector", Material.ARROW) .add(new AddVectorsNode()) + .add(new DotProductNode()) .add(new GetVectorComponentNode()) + .add(new GetVectorLengthNode()) .add(new PackVectorNode()) .add(new ReflectVectorNode()) .add(new RoundVectorAxesNode()) diff --git a/src/main/java/de/blazemcworld/fireflow/code/node/impl/number/ArcTan2Node.java b/src/main/java/de/blazemcworld/fireflow/code/node/impl/number/ArcTan2Node.java new file mode 100644 index 0000000..3934a9b --- /dev/null +++ b/src/main/java/de/blazemcworld/fireflow/code/node/impl/number/ArcTan2Node.java @@ -0,0 +1,31 @@ +package de.blazemcworld.fireflow.code.node.impl.number; + +import de.blazemcworld.fireflow.code.node.Node; +import de.blazemcworld.fireflow.code.type.NumberType; +import de.blazemcworld.fireflow.code.type.StringType; +import org.bukkit.Material; + +public class ArcTan2Node extends Node { + public ArcTan2Node() { + super("arc_tan_2", "Arc Tangent 2", "Generates the arc tangent of 2 numbers.", Material.FIRE_CORAL_FAN); + Input left = new Input<>("left", "Left", NumberType.INSTANCE); + Input right = new Input<>("right", "Right", NumberType.INSTANCE); + Input inputUnit = new Input<>("input_unit", "Input Unit", StringType.INSTANCE).options("Degrees","Radians"); + Output result = new Output<>("result", "Result", NumberType.INSTANCE); + + result.valueFrom((ctx) -> { + double leftInput = left.getValue(ctx); + double rightInput = right.getValue(ctx); + if(inputUnit.getValue(ctx).equals("Degrees")) { + return Math.toDegrees(Math.atan2(leftInput, rightInput)); + } else { + return Math.atan2(leftInput, rightInput); + } + }); + } + + @Override + public Node copy() { + return new ArcTan2Node(); + } +} \ No newline at end of file diff --git a/src/main/java/de/blazemcworld/fireflow/code/node/impl/number/AverageNumberNode.java b/src/main/java/de/blazemcworld/fireflow/code/node/impl/number/AverageNumberNode.java index bf60eed..ed5412c 100644 --- a/src/main/java/de/blazemcworld/fireflow/code/node/impl/number/AverageNumberNode.java +++ b/src/main/java/de/blazemcworld/fireflow/code/node/impl/number/AverageNumberNode.java @@ -2,12 +2,12 @@ import de.blazemcworld.fireflow.code.node.Node; import de.blazemcworld.fireflow.code.type.NumberType; -import net.minecraft.item.Items; +import org.bukkit.Material; public class AverageNumberNode extends Node { public AverageNumberNode() { - super("average_number", "Average Number", "Returns the average number of a set.", Items.RAW_COPPER); + super("average_number", "Average Number", "Returns the average number of a set.", Material.RAW_COPPER); Varargs numbers = new Varargs<>("numbers", "Numbers", NumberType.INSTANCE); Output result = new Output<>("result", "Result", NumberType.INSTANCE); diff --git a/src/main/java/de/blazemcworld/fireflow/code/node/impl/number/CosineNode.java b/src/main/java/de/blazemcworld/fireflow/code/node/impl/number/CosineNode.java index 7eba492..c2d0d1e 100644 --- a/src/main/java/de/blazemcworld/fireflow/code/node/impl/number/CosineNode.java +++ b/src/main/java/de/blazemcworld/fireflow/code/node/impl/number/CosineNode.java @@ -3,11 +3,11 @@ import de.blazemcworld.fireflow.code.node.Node; import de.blazemcworld.fireflow.code.type.NumberType; import de.blazemcworld.fireflow.code.type.StringType; -import net.minecraft.item.Items; +import org.bukkit.Material; public class CosineNode extends Node { public CosineNode() { - super("cosine", "Cosine", "Generates the trigonometric cosine function of a number.", Items.BUBBLE_CORAL_FAN); + super("cosine", "Cosine", "Generates the trigonometric cosine function of a number.", Material.BUBBLE_CORAL_FAN); Input value = new Input<>("value", "Value", NumberType.INSTANCE); Input mode = new Input<>("mode", "Mode", StringType.INSTANCE).options("cos","cosh","acos"); Input inputUnit = new Input<>("input_unit", "Input Unit", StringType.INSTANCE).options("Degrees","Radians"); diff --git a/src/main/java/de/blazemcworld/fireflow/code/node/impl/number/GaussianDistributionNode.java b/src/main/java/de/blazemcworld/fireflow/code/node/impl/number/GaussianDistributionNode.java index ef2e2d8..1a2233c 100644 --- a/src/main/java/de/blazemcworld/fireflow/code/node/impl/number/GaussianDistributionNode.java +++ b/src/main/java/de/blazemcworld/fireflow/code/node/impl/number/GaussianDistributionNode.java @@ -3,14 +3,14 @@ import de.blazemcworld.fireflow.code.node.Node; import de.blazemcworld.fireflow.code.type.NumberType; import de.blazemcworld.fireflow.code.type.StringType; -import net.minecraft.item.Items; +import org.bukkit.Material; import java.util.Random; public class GaussianDistributionNode extends Node { public GaussianDistributionNode() { - super("gaussian_distribution", "Gaussian Distribution", "Generate a normally distributed random number", Items.POLAR_BEAR_SPAWN_EGG); + super("gaussian_distribution", "Gaussian Distribution", "Generate a normally distributed random number", Material.POLAR_BEAR_SPAWN_EGG); Input mode = new Input<>("mode", "Mode", StringType.INSTANCE) .options("Normal", "Folded"); Input mean = new Input<>("mean", "μ (Mean midpoint)", NumberType.INSTANCE); diff --git a/src/main/java/de/blazemcworld/fireflow/code/node/impl/number/LerpNumbersNode.java b/src/main/java/de/blazemcworld/fireflow/code/node/impl/number/LerpNumbersNode.java index 46a3538..3ae8382 100644 --- a/src/main/java/de/blazemcworld/fireflow/code/node/impl/number/LerpNumbersNode.java +++ b/src/main/java/de/blazemcworld/fireflow/code/node/impl/number/LerpNumbersNode.java @@ -2,12 +2,12 @@ import de.blazemcworld.fireflow.code.node.Node; import de.blazemcworld.fireflow.code.type.NumberType; -import net.minecraft.item.Items; +import org.bukkit.Material; public class LerpNumbersNode extends Node { public LerpNumbersNode() { - super("lerp_numbers", "Lerp", "Calculates a value between two inputs by linearly interpolating based on a factor t, where t = 0 returns the start value, t = 1 returns the end value, and values in between produce a proportional blend.", Items.REPEATER); + super("lerp_numbers", "Lerp", "Calculates a value between two inputs by linearly interpolating based on a factor t, where t = 0 returns the start value, t = 1 returns the end value, and values in between produce a proportional blend.", Material.REPEATER); Input left = new Input<>("left", "Left", NumberType.INSTANCE); Input right = new Input<>("right", "Right", NumberType.INSTANCE); diff --git a/src/main/java/de/blazemcworld/fireflow/code/node/impl/number/MaxNumberNode.java b/src/main/java/de/blazemcworld/fireflow/code/node/impl/number/MaxNumberNode.java index f0be5f4..7f207c5 100644 --- a/src/main/java/de/blazemcworld/fireflow/code/node/impl/number/MaxNumberNode.java +++ b/src/main/java/de/blazemcworld/fireflow/code/node/impl/number/MaxNumberNode.java @@ -2,12 +2,12 @@ import de.blazemcworld.fireflow.code.node.Node; import de.blazemcworld.fireflow.code.type.NumberType; -import net.minecraft.item.Items; +import org.bukkit.Material; public class MaxNumberNode extends Node { public MaxNumberNode() { - super("max_number", "Maximum Number", "Returns the highest number in a set.", Items.NETHERITE_SCRAP); + super("max_number", "Maximum Number", "Returns the highest number in a set.", Material.NETHERITE_SCRAP); Varargs numbers = new Varargs<>("numbers", "Numbers", NumberType.INSTANCE); Output result = new Output<>("result", "Result", NumberType.INSTANCE); diff --git a/src/main/java/de/blazemcworld/fireflow/code/node/impl/number/MinNumberNode.java b/src/main/java/de/blazemcworld/fireflow/code/node/impl/number/MinNumberNode.java index 1e9bea4..a5b89c0 100644 --- a/src/main/java/de/blazemcworld/fireflow/code/node/impl/number/MinNumberNode.java +++ b/src/main/java/de/blazemcworld/fireflow/code/node/impl/number/MinNumberNode.java @@ -2,12 +2,12 @@ import de.blazemcworld.fireflow.code.node.Node; import de.blazemcworld.fireflow.code.type.NumberType; -import net.minecraft.item.Items; +import org.bukkit.Material; public class MinNumberNode extends Node { public MinNumberNode() { - super("min_number", "Minimum Number", "Returns the lowest number in a set.", Items.DISC_FRAGMENT_5); + super("min_number", "Minimum Number", "Returns the lowest number in a set.", Material.DISC_FRAGMENT_5); Varargs numbers = new Varargs<>("numbers", "Numbers", NumberType.INSTANCE); Output result = new Output<>("result", "Result", NumberType.INSTANCE); diff --git a/src/main/java/de/blazemcworld/fireflow/code/node/impl/number/SineNode.java b/src/main/java/de/blazemcworld/fireflow/code/node/impl/number/SineNode.java index 588e30e..786e972 100644 --- a/src/main/java/de/blazemcworld/fireflow/code/node/impl/number/SineNode.java +++ b/src/main/java/de/blazemcworld/fireflow/code/node/impl/number/SineNode.java @@ -3,13 +3,11 @@ import de.blazemcworld.fireflow.code.node.Node; import de.blazemcworld.fireflow.code.type.NumberType; import de.blazemcworld.fireflow.code.type.StringType; -import net.minecraft.item.Items; - -import java.util.Objects; +import org.bukkit.Material; public class SineNode extends Node { public SineNode() { - super("sine", "Sine", "Generates the trigonometric sine function of a number.", Items.TUBE_CORAL_FAN); + super("sine", "Sine", "Generates the trigonometric sine function of a number.", Material.TUBE_CORAL_FAN); Input value = new Input<>("value", "Value", NumberType.INSTANCE); Input mode = new Input<>("mode", "Mode", StringType.INSTANCE).options("sin","sinh","asin"); Input inputUnit = new Input<>("input_unit", "Input Unit", StringType.INSTANCE).options("Degrees","Radians"); diff --git a/src/main/java/de/blazemcworld/fireflow/code/node/impl/number/TangentNode.java b/src/main/java/de/blazemcworld/fireflow/code/node/impl/number/TangentNode.java index a459683..1309e8a 100644 --- a/src/main/java/de/blazemcworld/fireflow/code/node/impl/number/TangentNode.java +++ b/src/main/java/de/blazemcworld/fireflow/code/node/impl/number/TangentNode.java @@ -3,11 +3,11 @@ import de.blazemcworld.fireflow.code.node.Node; import de.blazemcworld.fireflow.code.type.NumberType; import de.blazemcworld.fireflow.code.type.StringType; -import net.minecraft.item.Items; +import org.bukkit.Material; public class TangentNode extends Node { public TangentNode() { - super("tangent", "Tangent", "Generates the trigonometric tangent function of a number.", Items.HORN_CORAL_FAN); + super("tangent", "Tangent", "Generates the trigonometric tangent function of a number.", Material.HORN_CORAL_FAN); Input value = new Input<>("value", "Value", NumberType.INSTANCE); Input mode = new Input<>("mode", "Mode", StringType.INSTANCE).options("tan","tanh","atan"); Input inputUnit = new Input<>("input_unit", "Input Unit", StringType.INSTANCE).options("Degrees","Radians"); diff --git a/src/main/java/de/blazemcworld/fireflow/code/node/impl/number/constants/EulersNode.java b/src/main/java/de/blazemcworld/fireflow/code/node/impl/number/constants/EulersNode.java index 14eca5b..7884f4c 100644 --- a/src/main/java/de/blazemcworld/fireflow/code/node/impl/number/constants/EulersNode.java +++ b/src/main/java/de/blazemcworld/fireflow/code/node/impl/number/constants/EulersNode.java @@ -2,12 +2,12 @@ import de.blazemcworld.fireflow.code.node.Node; import de.blazemcworld.fireflow.code.type.NumberType; -import net.minecraft.item.Items; +import org.bukkit.Material; public class EulersNode extends Node { public EulersNode() { - super("eulers", "Euler's (e)", "Returns Euler's number.", Items.SPECTRAL_ARROW); + super("eulers", "Euler's (e)", "Returns Euler's number.", Material.SPECTRAL_ARROW); Output value = new Output<>("value", "Value", NumberType.INSTANCE); value.valueFrom(ctx -> Math.E); diff --git a/src/main/java/de/blazemcworld/fireflow/code/node/impl/number/constants/GoldenRatioNode.java b/src/main/java/de/blazemcworld/fireflow/code/node/impl/number/constants/GoldenRatioNode.java index e093e7f..f75f473 100644 --- a/src/main/java/de/blazemcworld/fireflow/code/node/impl/number/constants/GoldenRatioNode.java +++ b/src/main/java/de/blazemcworld/fireflow/code/node/impl/number/constants/GoldenRatioNode.java @@ -2,12 +2,12 @@ import de.blazemcworld.fireflow.code.node.Node; import de.blazemcworld.fireflow.code.type.NumberType; -import net.minecraft.item.Items; +import org.bukkit.Material; public class GoldenRatioNode extends Node { public GoldenRatioNode() { - super("golden_ratio", "Golden Ratio (Φ)", "Returns the Golden Ratio.", Items.GOLD_NUGGET); + super("golden_ratio", "Golden Ratio (Φ)", "Returns the Golden Ratio.", Material.GOLD_NUGGET); Output value = new Output<>("value", "Value", NumberType.INSTANCE); value.valueFrom(ctx -> (1 + Math.sqrt(5)) / 2); diff --git a/src/main/java/de/blazemcworld/fireflow/code/node/impl/number/constants/PiNode.java b/src/main/java/de/blazemcworld/fireflow/code/node/impl/number/constants/PiNode.java index 78ef21e..c09172f 100644 --- a/src/main/java/de/blazemcworld/fireflow/code/node/impl/number/constants/PiNode.java +++ b/src/main/java/de/blazemcworld/fireflow/code/node/impl/number/constants/PiNode.java @@ -2,12 +2,12 @@ import de.blazemcworld.fireflow.code.node.Node; import de.blazemcworld.fireflow.code.type.NumberType; -import net.minecraft.item.Items; +import org.bukkit.Material; public class PiNode extends Node { public PiNode() { - super("pi", "Pi (π)", "Returns PI.", Items.SNOWBALL); + super("pi", "Pi (π)", "Returns PI.", Material.SNOWBALL); Output value = new Output<>("value", "Value", NumberType.INSTANCE); value.valueFrom(ctx -> Math.PI); diff --git a/src/main/java/de/blazemcworld/fireflow/code/node/impl/number/constants/TauNode.java b/src/main/java/de/blazemcworld/fireflow/code/node/impl/number/constants/TauNode.java index 678773b..0a7c6d4 100644 --- a/src/main/java/de/blazemcworld/fireflow/code/node/impl/number/constants/TauNode.java +++ b/src/main/java/de/blazemcworld/fireflow/code/node/impl/number/constants/TauNode.java @@ -2,12 +2,12 @@ import de.blazemcworld.fireflow.code.node.Node; import de.blazemcworld.fireflow.code.type.NumberType; -import net.minecraft.item.Items; +import org.bukkit.Material; public class TauNode extends Node { public TauNode() { - super("tau", "Tau (τ)", "Returns TAU.", Items.SNOW_BLOCK); + super("tau", "Tau (τ)", "Returns TAU.", Material.SNOW_BLOCK); Output value = new Output<>("value", "Value", NumberType.INSTANCE); value.valueFrom(ctx -> Math.TAU); diff --git a/src/main/java/de/blazemcworld/fireflow/code/node/impl/player/inventory/SetPlayerArmorNode.java b/src/main/java/de/blazemcworld/fireflow/code/node/impl/player/inventory/SetPlayerArmorNode.java index c4556a1..f45e8ea 100644 --- a/src/main/java/de/blazemcworld/fireflow/code/node/impl/player/inventory/SetPlayerArmorNode.java +++ b/src/main/java/de/blazemcworld/fireflow/code/node/impl/player/inventory/SetPlayerArmorNode.java @@ -2,18 +2,15 @@ import de.blazemcworld.fireflow.code.node.Node; import de.blazemcworld.fireflow.code.type.*; -import de.blazemcworld.fireflow.code.value.ListValue; import de.blazemcworld.fireflow.code.value.PlayerValue; -import net.minecraft.entity.attribute.AttributeContainer; -import net.minecraft.entity.attribute.EntityAttributeModifier; -import net.minecraft.entity.attribute.EntityAttributes; -import net.minecraft.item.ItemStack; -import net.minecraft.item.Items; +import org.bukkit.Material; +import org.bukkit.inventory.ItemStack; + public class SetPlayerArmorNode extends Node { public SetPlayerArmorNode() { - super("set_player_armor", "Set Player Armor", "Changes the armor of a player", Items.DIAMOND_LEGGINGS); + super("set_player_armor", "Set Player Armor", "Changes the armor of a player", Material.DIAMOND_LEGGINGS); Input signal = new Input<>("signal", "Signal", SignalType.INSTANCE); Input player = new Input<>("player", "Player", PlayerType.INSTANCE); @@ -32,10 +29,10 @@ public SetPlayerArmorNode() { ItemStack chestItem = chest.getValue(ctx); ItemStack legsItem = legs.getValue(ctx); ItemStack feetItem = feet.getValue(ctx); - if (!headItem.isEmpty() || clearInv) p.getInventory().setStack(39, headItem); - if (!chestItem.isEmpty() || clearInv) p.getInventory().setStack(38, chestItem); - if (!legsItem.isEmpty() || clearInv) p.getInventory().setStack(37, legsItem); - if (!feetItem.isEmpty() || clearInv) p.getInventory().setStack(36, feetItem); + if (!headItem.isEmpty() || clearInv) p.getInventory().setItem(39, headItem); + if (!chestItem.isEmpty() || clearInv) p.getInventory().setItem(38, chestItem); + if (!legsItem.isEmpty() || clearInv) p.getInventory().setItem(37, legsItem); + if (!feetItem.isEmpty() || clearInv) p.getInventory().setItem(36, feetItem); }); ctx.sendSignal(next); }); diff --git a/src/main/java/de/blazemcworld/fireflow/code/node/impl/player/meta/GetPlayerPingNode.java b/src/main/java/de/blazemcworld/fireflow/code/node/impl/player/meta/GetPlayerPingNode.java index c027d08..239e71f 100644 --- a/src/main/java/de/blazemcworld/fireflow/code/node/impl/player/meta/GetPlayerPingNode.java +++ b/src/main/java/de/blazemcworld/fireflow/code/node/impl/player/meta/GetPlayerPingNode.java @@ -3,18 +3,18 @@ import de.blazemcworld.fireflow.code.node.Node; import de.blazemcworld.fireflow.code.type.NumberType; import de.blazemcworld.fireflow.code.type.PlayerType; -import de.blazemcworld.fireflow.code.type.StringType; import de.blazemcworld.fireflow.code.value.PlayerValue; -import net.minecraft.item.Items; +import org.bukkit.Material; +import org.bukkit.entity.Player; public class GetPlayerPingNode extends Node { public GetPlayerPingNode() { - super("get_player_ping", "Get Player Ping", "Gets the ping of a player.", Items.SHAPER_ARMOR_TRIM_SMITHING_TEMPLATE); + super("get_player_ping", "Get Player Ping", "Gets the ping of a player.", Material.SHAPER_ARMOR_TRIM_SMITHING_TEMPLATE); Input player = new Input<>("player", "Player", PlayerType.INSTANCE); Output ping = new Output<>("ping", "Ping", NumberType.INSTANCE); - ping.valueFrom(ctx -> (double) player.getValue(ctx).tryGet(ctx, p -> p.networkHandler.getLatency(), 0)); + ping.valueFrom(ctx -> (double) player.getValue(ctx).tryGet(ctx, Player::getPing, 0)); } @Override diff --git a/src/main/java/de/blazemcworld/fireflow/code/node/impl/player/visual/SendActionbarNode.java b/src/main/java/de/blazemcworld/fireflow/code/node/impl/player/visual/SendActionbarNode.java index 8e9845c..9e4f88d 100644 --- a/src/main/java/de/blazemcworld/fireflow/code/node/impl/player/visual/SendActionbarNode.java +++ b/src/main/java/de/blazemcworld/fireflow/code/node/impl/player/visual/SendActionbarNode.java @@ -20,7 +20,7 @@ public SendActionbarNode() { Output next = new Output<>("next", "Next", SignalType.INSTANCE); signal.onSignal((ctx) -> { - player.getValue(ctx).tryUse(ctx, p -> p.sendMessage(message.getValue(ctx))); + player.getValue(ctx).tryUse(ctx, p -> p.sendActionBar(message.getValue(ctx))); ctx.sendSignal(next); }); } diff --git a/src/main/java/de/blazemcworld/fireflow/code/node/impl/player/visual/SetTablistNode.java b/src/main/java/de/blazemcworld/fireflow/code/node/impl/player/visual/SetTablistNode.java new file mode 100644 index 0000000..c5b51cf --- /dev/null +++ b/src/main/java/de/blazemcworld/fireflow/code/node/impl/player/visual/SetTablistNode.java @@ -0,0 +1,36 @@ +package de.blazemcworld.fireflow.code.node.impl.player.visual; + +import de.blazemcworld.fireflow.code.node.Node; +import de.blazemcworld.fireflow.code.type.PlayerType; +import de.blazemcworld.fireflow.code.type.SignalType; +import de.blazemcworld.fireflow.code.type.TextType; +import de.blazemcworld.fireflow.code.value.PlayerValue; +import net.kyori.adventure.text.Component; +import org.bukkit.Material; + +public class SetTablistNode extends Node { + + public SetTablistNode() { + super("set_tablist", "Set Tablist", "Sets a tablist for a player", Material.OBSERVER); + + Input signal = new Input<>("signal", "Signal", SignalType.INSTANCE); + Input player = new Input<>("player", "Player", PlayerType.INSTANCE); + Input header = new Input<>("header", "Header", TextType.INSTANCE); + Input footer = new Input<>("footer", "Footer", TextType.INSTANCE); + + Output next = new Output<>("next", "Next", SignalType.INSTANCE); + + signal.onSignal((ctx) -> { + player.getValue(ctx).tryUse(ctx, p -> { + p.sendPlayerListHeader(header.getValue(ctx)); + p.sendPlayerListFooter(footer.getValue(ctx)); + }); + ctx.sendSignal(next); + }); + } + + @Override + public Node copy() { + return new SetTablistNode(); + } +} diff --git a/src/main/java/de/blazemcworld/fireflow/code/node/impl/player/visual/bossbar/ClearBossbarsNode.java b/src/main/java/de/blazemcworld/fireflow/code/node/impl/player/visual/bossbar/ClearBossbarsNode.java deleted file mode 100644 index 02e8944..0000000 --- a/src/main/java/de/blazemcworld/fireflow/code/node/impl/player/visual/bossbar/ClearBossbarsNode.java +++ /dev/null @@ -1,37 +0,0 @@ -package de.blazemcworld.fireflow.code.node.impl.player.visual.bossbar; - -import de.blazemcworld.fireflow.code.node.Node; -import de.blazemcworld.fireflow.code.type.NumberType; -import de.blazemcworld.fireflow.code.type.PlayerType; -import de.blazemcworld.fireflow.code.type.SignalType; -import de.blazemcworld.fireflow.code.value.PlayerValue; -import de.blazemcworld.fireflow.space.BossBarManager; -import de.blazemcworld.fireflow.space.Space; -import de.blazemcworld.fireflow.space.SpaceManager; -import net.minecraft.item.Items; - -public class ClearBossbarsNode extends Node { - - public ClearBossbarsNode() { - super("clear_bossbars", "Clear Bossbars", "Removes all bossbars from a player", Items.STRUCTURE_VOID); - - Input signal = new Input<>("signal", "Signal", SignalType.INSTANCE); - Input player = new Input<>("player", "Player", PlayerType.INSTANCE); - - Output next = new Output<>("next", "Next", SignalType.INSTANCE); - - signal.onSignal((ctx) -> { - player.getValue(ctx).tryUse(ctx, p -> { - Space space = SpaceManager.getSpaceForPlayer(p); - BossBarManager bossBarManager = space.bossBarManager; - bossBarManager.clearBossBars(p); - }); - ctx.sendSignal(next); - }); - } - - @Override - public Node copy() { - return new ClearBossbarsNode(); - } -} diff --git a/src/main/java/de/blazemcworld/fireflow/code/node/impl/player/visual/bossbar/RemoveBossbarNode.java b/src/main/java/de/blazemcworld/fireflow/code/node/impl/player/visual/bossbar/RemoveBossbarNode.java deleted file mode 100644 index ffc85dd..0000000 --- a/src/main/java/de/blazemcworld/fireflow/code/node/impl/player/visual/bossbar/RemoveBossbarNode.java +++ /dev/null @@ -1,44 +0,0 @@ -package de.blazemcworld.fireflow.code.node.impl.player.visual.bossbar; - -import de.blazemcworld.fireflow.code.node.Node; -import de.blazemcworld.fireflow.code.type.NumberType; -import de.blazemcworld.fireflow.code.type.PlayerType; -import de.blazemcworld.fireflow.code.type.SignalType; -import de.blazemcworld.fireflow.code.type.TextType; -import de.blazemcworld.fireflow.code.value.PlayerValue; -import de.blazemcworld.fireflow.space.BossBarManager; -import de.blazemcworld.fireflow.space.Space; -import de.blazemcworld.fireflow.space.SpaceManager; -import net.minecraft.entity.boss.BossBar; -import net.minecraft.entity.boss.ServerBossBar; -import net.minecraft.item.Items; -import net.minecraft.text.Text; - -import java.util.List; - -public class RemoveBossbarNode extends Node { - - public RemoveBossbarNode() { - super("remove_bossbar", "Remove Bossbar", "Removes a bossbar from a player", Items.PALE_OAK_SIGN); - - Input signal = new Input<>("signal", "Signal", SignalType.INSTANCE); - Input player = new Input<>("player", "Player", PlayerType.INSTANCE); - Input position = new Input<>("position", "Position", NumberType.INSTANCE); - - Output next = new Output<>("next", "Next", SignalType.INSTANCE); - - signal.onSignal((ctx) -> { - player.getValue(ctx).tryUse(ctx, p -> { - Space space = SpaceManager.getSpaceForPlayer(p); - BossBarManager bossBarManager = space.bossBarManager; - bossBarManager.removeBossBarAtIndex(p,position.getValue(ctx).intValue()); - }); - ctx.sendSignal(next); - }); - } - - @Override - public Node copy() { - return new RemoveBossbarNode(); - } -} diff --git a/src/main/java/de/blazemcworld/fireflow/code/node/impl/player/visual/bossbar/SetBossbarNode.java b/src/main/java/de/blazemcworld/fireflow/code/node/impl/player/visual/bossbar/SetBossbarNode.java deleted file mode 100644 index 8d6c909..0000000 --- a/src/main/java/de/blazemcworld/fireflow/code/node/impl/player/visual/bossbar/SetBossbarNode.java +++ /dev/null @@ -1,78 +0,0 @@ -package de.blazemcworld.fireflow.code.node.impl.player.visual.bossbar; - -import de.blazemcworld.fireflow.code.node.Node; -import de.blazemcworld.fireflow.code.type.*; -import de.blazemcworld.fireflow.code.value.PlayerValue; -import de.blazemcworld.fireflow.space.BossBarManager; -import de.blazemcworld.fireflow.space.Space; -import de.blazemcworld.fireflow.space.SpaceManager; -import net.minecraft.entity.boss.BossBar; -import net.minecraft.entity.boss.ServerBossBar; -import net.minecraft.item.Items; -import net.minecraft.text.Text; - -import java.util.List; - -public class SetBossbarNode extends Node { - - public SetBossbarNode() { - super("set_bossbar", "Set Bossbar", "Sets a bossbar for a player", Items.BIRCH_SIGN); - - Input signal = new Input<>("signal", "Signal", SignalType.INSTANCE); - Input player = new Input<>("player", "Player", PlayerType.INSTANCE); - Input title = new Input<>("title", "Title", TextType.INSTANCE); - Input current_health = new Input<>("current_health", "Current Health", NumberType.INSTANCE); - Input max_health = new Input<>("max_health", "Maximum Health", NumberType.INSTANCE); - Input position = new Input<>("position", "Position", NumberType.INSTANCE); - Input barColor = new Input<>("bar_color", "Bar Color", StringType.INSTANCE).options("Red","Purple","Pink","Blue","Green","Yellow","White"); - Input barStyle = new Input<>("bar_style", "Bar Style", StringType.INSTANCE).options("Solid","6 Segments","10 Segments","12 Segments","20 Segments"); - Input skyEffect = new Input<>("sky_effect", "Sky Effect", StringType.INSTANCE).options("None","Thicken Fog","Darken Sky","Both"); - - Output next = new Output<>("next", "Next", SignalType.INSTANCE); - - signal.onSignal((ctx) -> { - player.getValue(ctx).tryUse(ctx, p -> { - Space space = SpaceManager.getSpaceForPlayer(p); - BossBarManager bossBarManager = space.bossBarManager; - BossBar.Color color = switch(barColor.getValue(ctx)) { - case "Red" -> BossBar.Color.RED; - case "Purple" -> BossBar.Color.PURPLE; - case "Pink" -> BossBar.Color.PINK; - case "Blue" -> BossBar.Color.BLUE; - case "Green" -> BossBar.Color.GREEN; - case "Yellow" -> BossBar.Color.YELLOW; - default -> BossBar.Color.WHITE; - }; - BossBar.Style style = switch(barStyle.getValue(ctx)) { - case "6 Segments" -> BossBar.Style.NOTCHED_6; - case "10 Segments" -> BossBar.Style.NOTCHED_10; - case "12 Segments" -> BossBar.Style.NOTCHED_12; - case "20 Segments" -> BossBar.Style.NOTCHED_20; - default -> BossBar.Style.PROGRESS; - }; - ServerBossBar bossBar = new ServerBossBar( - title.getValue(ctx), - color, - style - ); - switch(skyEffect.getValue(ctx)) { - case "Thicken Fog" -> bossBar.setThickenFog(true); - case "Darken Sky" -> bossBar.setDarkenSky(true); - case "Both" -> { - bossBar.setThickenFog(true); - bossBar.setDarkenSky(true); - } - } - bossBar.setPercent(current_health.getValue(ctx).floatValue()/max_health.getValue(ctx).floatValue()); - List bossBars = bossBarManager.getBossBars(p); - bossBarManager.setBossBarAtIndex(p,position.getValue(ctx).intValue(), bossBar); - }); - ctx.sendSignal(next); - }); - } - - @Override - public Node copy() { - return new SetBossbarNode(); - } -} diff --git a/src/main/java/de/blazemcworld/fireflow/code/node/impl/vector/DotProductNode.java b/src/main/java/de/blazemcworld/fireflow/code/node/impl/vector/DotProductNode.java index 57e986d..9c60a32 100644 --- a/src/main/java/de/blazemcworld/fireflow/code/node/impl/vector/DotProductNode.java +++ b/src/main/java/de/blazemcworld/fireflow/code/node/impl/vector/DotProductNode.java @@ -3,20 +3,19 @@ import de.blazemcworld.fireflow.code.node.Node; import de.blazemcworld.fireflow.code.type.NumberType; import de.blazemcworld.fireflow.code.type.VectorType; -import net.minecraft.item.Items; -import net.minecraft.util.math.Vec3d; -import org.apache.logging.log4j.core.lookup.Interpolator; +import org.bukkit.Material; +import org.bukkit.util.Vector; public class DotProductNode extends Node { public DotProductNode() { - super("dot_product", "Dot Product", "Gets the Dot Product of two vectors", Items.GUNPOWDER); + super("dot_product", "Dot Product", "Gets the Dot Product of two vectors", Material.GUNPOWDER); - Input first = new Input<>("first", "First", VectorType.INSTANCE); - Input second = new Input<>("second", "Second", VectorType.INSTANCE); + Input first = new Input<>("first", "First", VectorType.INSTANCE); + Input second = new Input<>("second", "Second", VectorType.INSTANCE); Output result = new Output<>("result", "Result", NumberType.INSTANCE); - result.valueFrom(ctx -> first.getValue(ctx).dotProduct(second.getValue(ctx))); + result.valueFrom(ctx -> first.getValue(ctx).dot(second.getValue(ctx))); } @Override diff --git a/src/main/java/de/blazemcworld/fireflow/code/node/impl/vector/GetVectorLengthNode.java b/src/main/java/de/blazemcworld/fireflow/code/node/impl/vector/GetVectorLengthNode.java index 90dcfce..f5e4785 100644 --- a/src/main/java/de/blazemcworld/fireflow/code/node/impl/vector/GetVectorLengthNode.java +++ b/src/main/java/de/blazemcworld/fireflow/code/node/impl/vector/GetVectorLengthNode.java @@ -4,18 +4,18 @@ import de.blazemcworld.fireflow.code.type.NumberType; import de.blazemcworld.fireflow.code.type.StringType; import de.blazemcworld.fireflow.code.type.VectorType; -import net.minecraft.item.Items; -import net.minecraft.util.math.Vec3d; +import org.bukkit.Material; +import org.bukkit.util.Vector; public class GetVectorLengthNode extends Node { public GetVectorLengthNode() { - super("get_vector_length", "Get Vector Length", "Gets the length of a vector", Items.BREEZE_ROD); - Input vector = new Input<>("vector", "Vector", VectorType.INSTANCE); + super("get_vector_length", "Get Vector Length", "Gets the length of a vector", Material.BREEZE_ROD); + Input vector = new Input<>("vector", "Vector", VectorType.INSTANCE); Input lengthType = new Input<>("length_type", "Length Type", StringType.INSTANCE).options("Normal","Squared"); Output length = new Output<>("length", "Length", NumberType.INSTANCE); length.valueFrom(ctx -> { - Vec3d v = vector.getValue(ctx); + Vector v = vector.getValue(ctx); switch(lengthType.getValue(ctx)) { case "Normal" -> { return v.length(); diff --git a/src/main/java/de/blazemcworld/fireflow/code/node/impl/world/TimestampNode.java b/src/main/java/de/blazemcworld/fireflow/code/node/impl/world/TimestampNode.java index 1273c28..96db25f 100644 --- a/src/main/java/de/blazemcworld/fireflow/code/node/impl/world/TimestampNode.java +++ b/src/main/java/de/blazemcworld/fireflow/code/node/impl/world/TimestampNode.java @@ -2,12 +2,12 @@ import de.blazemcworld.fireflow.code.node.Node; import de.blazemcworld.fireflow.code.type.NumberType; -import net.minecraft.item.Items; +import org.bukkit.Material; public class TimestampNode extends Node { public TimestampNode() { - super("timestamp", "Timestamp", "Returns the elapsed seconds since the Unix epoch.", Items.CLOCK); + super("timestamp", "Timestamp", "Returns the elapsed seconds since the Unix epoch.", Material.CLOCK); Output usage = new Output<>("timestamp", "Timestamp", NumberType.INSTANCE); usage.valueFrom(ctx -> (double) System.currentTimeMillis() / 1000); diff --git a/src/main/java/de/blazemcworld/fireflow/space/BossBarManager.java b/src/main/java/de/blazemcworld/fireflow/space/BossBarManager.java deleted file mode 100644 index 919fd07..0000000 --- a/src/main/java/de/blazemcworld/fireflow/space/BossBarManager.java +++ /dev/null @@ -1,62 +0,0 @@ -package de.blazemcworld.fireflow.space; - -import net.minecraft.entity.boss.ServerBossBar; -import net.minecraft.server.network.ServerPlayerEntity; -import java.util.*; - -public class BossBarManager { - private final Map> bossBars = new HashMap<>(); - - public void setBossBarAtIndex(ServerPlayerEntity player, int index, ServerBossBar newBossBar) { - List bars = bossBars.computeIfAbsent(player.getUuid(), k -> new ArrayList<>()); - - while (bars.size() <= index) { - bars.add(null); - } - - ServerBossBar existing = bars.get(index); - if (existing != null) { - existing.setName(newBossBar.getName()); - existing.setPercent(newBossBar.getPercent()); - existing.setColor(newBossBar.getColor()); - existing.setStyle(newBossBar.getStyle()); - existing.setDarkenSky(newBossBar.shouldDarkenSky()); - existing.setThickenFog(newBossBar.shouldThickenFog()); - existing.addPlayer(player); - } else { - bars.set(index, newBossBar); - for (ServerBossBar bar : bars) { - if(bar == null) continue; - bar.removePlayer(player); - bar.addPlayer(player); - } - } - } - - - - public void removeBossBarAtIndex(ServerPlayerEntity player, int index) { - List bars = getBossBars(player); - if (bars != null && index >= 0 && index < bars.size()) { - ServerBossBar bar = bars.get(index); - bar.removePlayer(player); - bars.remove(index); - } - } - - public void clearBossBars(ServerPlayerEntity player) { - for (ServerBossBar bar : getBossBars(player)) { - if(bar == null) continue; - bar.removePlayer(player); - } - bossBars.remove(player.getUuid()); - } - - public List getBossBars(ServerPlayerEntity player) { - return bossBars.getOrDefault(player.getUuid(), Collections.emptyList()); - } - - public void reset() { - bossBars.clear(); - } -} diff --git a/src/main/java/de/blazemcworld/fireflow/util/Statistics.java b/src/main/java/de/blazemcworld/fireflow/util/Statistics.java index ace1d52..c035a43 100644 --- a/src/main/java/de/blazemcworld/fireflow/util/Statistics.java +++ b/src/main/java/de/blazemcworld/fireflow/util/Statistics.java @@ -1,9 +1,13 @@ package de.blazemcworld.fireflow.util; +import net.kyori.adventure.text.Component; +import org.bukkit.Bukkit; import org.bukkit.GameMode; import org.bukkit.entity.Player; import org.bukkit.event.inventory.InventoryType; +import java.util.Objects; + public class Statistics { public static void reset(Player player) { @@ -25,6 +29,8 @@ public static void reset(Player player) { player.setLastDeathLocation(null); player.setInvulnerable(false); player.setInvisible(false); + player.sendPlayerListHeader(Component.empty()); + player.sendPlayerListFooter(Component.empty()); } } From 99d93eefa3de6ddd8f4e2b8394f158eaa021cb31 Mon Sep 17 00:00:00 2001 From: Tqlted <78366008+Tqlted@users.noreply.github.com> Date: Tue, 5 Aug 2025 22:18:55 +0200 Subject: [PATCH 4/4] Get Player Input Node --- .../fireflow/code/node/NodeList.java | 1 + .../player/gameplay/GetPlayerInputNode.java | 41 +++++++++++++++++++ 2 files changed, 42 insertions(+) create mode 100644 src/main/java/de/blazemcworld/fireflow/code/node/impl/player/gameplay/GetPlayerInputNode.java diff --git a/src/main/java/de/blazemcworld/fireflow/code/node/NodeList.java b/src/main/java/de/blazemcworld/fireflow/code/node/NodeList.java index 8cb4f54..ab10b9f 100644 --- a/src/main/java/de/blazemcworld/fireflow/code/node/NodeList.java +++ b/src/main/java/de/blazemcworld/fireflow/code/node/NodeList.java @@ -206,6 +206,7 @@ public static void init() { .add(new Category("Gameplay", Material.GRASS_BLOCK) .add(new ClearPlayerEffectsNode()) .add(new DamagePlayerNode()) + .add(new GetPlayerInputNode()) .add(new GivePlayerEffectNode()) .add(new IsPlayerInvulnerableNode()) .add(new KillPlayerNode()) diff --git a/src/main/java/de/blazemcworld/fireflow/code/node/impl/player/gameplay/GetPlayerInputNode.java b/src/main/java/de/blazemcworld/fireflow/code/node/impl/player/gameplay/GetPlayerInputNode.java new file mode 100644 index 0000000..181f563 --- /dev/null +++ b/src/main/java/de/blazemcworld/fireflow/code/node/impl/player/gameplay/GetPlayerInputNode.java @@ -0,0 +1,41 @@ +package de.blazemcworld.fireflow.code.node.impl.player.gameplay; + +import de.blazemcworld.fireflow.code.node.Node; +import de.blazemcworld.fireflow.code.type.ConditionType; +import de.blazemcworld.fireflow.code.type.PlayerType; +import de.blazemcworld.fireflow.code.type.SignalType; +import de.blazemcworld.fireflow.code.type.StringType; +import de.blazemcworld.fireflow.code.value.PlayerValue; +import org.bukkit.GameMode; +import org.bukkit.Material; + +public class GetPlayerInputNode extends Node { + public GetPlayerInputNode() { + super("get_player_input", "Get Player Input", "Gets if a player is pressing a specific key", Material.OMINOUS_TRIAL_KEY); + + Input player = new Input<>("player", "Player", PlayerType.INSTANCE); + Input key = new Input<>("key", "Key", StringType.INSTANCE) + .options("Forward", "Backward", "Right", "Left", "Jump", "Sneak", "Sprint"); + Output pressed = new Output<>("pressed", "Pressed", ConditionType.INSTANCE); + + pressed.valueFrom(ctx -> player.getValue(ctx).tryGet(ctx, p -> { + return switch(key.getValue(ctx)) { + case "Forward" -> p.getCurrentInput().isForward(); + case "Backward" -> p.getCurrentInput().isBackward(); + case "Right" -> p.getCurrentInput().isRight(); + case "Left" -> p.getCurrentInput().isLeft(); + case "Jump" -> p.getCurrentInput().isJump(); + case "Sneak" -> p.getCurrentInput().isSneak(); + case "Sprint" -> p.getCurrentInput().isSprint(); + default -> false; + }; + }, false)); + + + } + + @Override + public Node copy() { + return new GetPlayerInputNode(); + } +} \ No newline at end of file