From 6fb60e15a3ec2cae80ca48fba49af827a3109d6c Mon Sep 17 00:00:00 2001 From: Lars Date: Wed, 9 Sep 2026 17:41:43 +0200 Subject: [PATCH] added basic frost walker mechanic to boats --- .../frostWalkerBoat/BoatMoveListener.java | 52 +++++++++++++++++++ .../frostWalkerBoat/FrostWalkerBoat.java | 47 +++++++++++++++++ 2 files changed, 99 insertions(+) create mode 100644 craftattack/src/main/java/eu/mhsl/craftattack/spawn/craftattack/appliances/gameplay/frostWalkerBoat/BoatMoveListener.java create mode 100644 craftattack/src/main/java/eu/mhsl/craftattack/spawn/craftattack/appliances/gameplay/frostWalkerBoat/FrostWalkerBoat.java diff --git a/craftattack/src/main/java/eu/mhsl/craftattack/spawn/craftattack/appliances/gameplay/frostWalkerBoat/BoatMoveListener.java b/craftattack/src/main/java/eu/mhsl/craftattack/spawn/craftattack/appliances/gameplay/frostWalkerBoat/BoatMoveListener.java new file mode 100644 index 0000000..cc37eb0 --- /dev/null +++ b/craftattack/src/main/java/eu/mhsl/craftattack/spawn/craftattack/appliances/gameplay/frostWalkerBoat/BoatMoveListener.java @@ -0,0 +1,52 @@ +package eu.mhsl.craftattack.spawn.craftattack.appliances.gameplay.frostWalkerBoat; + +import eu.mhsl.craftattack.spawn.core.appliance.ApplianceListener; +import org.bukkit.Location; +import org.bukkit.Material; +import org.bukkit.block.Block; +import org.bukkit.block.BlockFace; +import org.bukkit.block.data.Levelled; +import org.bukkit.entity.Boat; +import org.bukkit.event.EventHandler; +import org.bukkit.event.vehicle.VehicleMoveEvent; +import org.bukkit.util.Vector; + +class BoatMoveListener extends ApplianceListener { + @EventHandler + public void onBoatMove(VehicleMoveEvent event) { + if(!(event.getVehicle() instanceof Boat boat)) return; + +// if(!event.getVehicle().getPersistentDataContainer().has( +// this.getAppliance().getNamespacedKey(), +// PersistentDataType.BOOLEAN) +// ) return; +// +// if(Boolean.FALSE.equals(event.getVehicle().getPersistentDataContainer().get( +// this.getAppliance().getNamespacedKey(), +// PersistentDataType.BOOLEAN +// ))) return; + + Block blockAtBoat = event.getTo().getBlock(); + + if(blockAtBoat.getType() == Material.WATER) { + if (!(blockAtBoat.getBlockData() instanceof Levelled waterData)) return; + if (waterData.getLevel() != 0) return; + if (!blockAtBoat.getRelative(BlockFace.UP).isEmpty()) return; + + Location teleportLocation = event.getTo().clone(); + teleportLocation.setY(blockAtBoat.getY()+1.1); + boat.teleport(teleportLocation); + } + + Vector velocity = event.getTo().toVector().subtract(event.getFrom().toVector()); + velocity.setY(0); + Block iceTargetBlock; + if(velocity.isZero()) { + iceTargetBlock = event.getTo().getBlock().getRelative(BlockFace.DOWN); + } else { + Location iceTargetLocation = blockAtBoat.getLocation().clone().add(velocity.clone().normalize().multiply(5)); + iceTargetBlock = iceTargetLocation.getBlock().getRelative(BlockFace.DOWN); + } + this.getAppliance().freezeWater(iceTargetBlock); + } +} diff --git a/craftattack/src/main/java/eu/mhsl/craftattack/spawn/craftattack/appliances/gameplay/frostWalkerBoat/FrostWalkerBoat.java b/craftattack/src/main/java/eu/mhsl/craftattack/spawn/craftattack/appliances/gameplay/frostWalkerBoat/FrostWalkerBoat.java new file mode 100644 index 0000000..5315cdd --- /dev/null +++ b/craftattack/src/main/java/eu/mhsl/craftattack/spawn/craftattack/appliances/gameplay/frostWalkerBoat/FrostWalkerBoat.java @@ -0,0 +1,47 @@ +package eu.mhsl.craftattack.spawn.craftattack.appliances.gameplay.frostWalkerBoat; + +import eu.mhsl.craftattack.spawn.core.appliance.Appliance; +import org.bukkit.Material; +import org.bukkit.NamespacedKey; +import org.bukkit.block.Block; +import org.bukkit.block.BlockFace; +import org.bukkit.block.data.Levelled; +import org.bukkit.event.Listener; +import org.jetbrains.annotations.NotNull; + +import java.util.List; + +public class FrostWalkerBoat extends Appliance { + public NamespacedKey getNamespacedKey() { + return new NamespacedKey(this.getClass().getSimpleName().toLowerCase(), "is_frostwalker_enchanted"); + } + + public void freezeWater(Block targetBlock) { + int radius = 4; + double circleRadiusSquared = Math.pow(radius + 0.5, 2); + + for(int xOffset = -radius; xOffset <= radius; xOffset++) { + for(int zOffset = -radius; zOffset <= radius; zOffset++) { + int distanceSquared = + xOffset * xOffset + zOffset * zOffset; + + if(distanceSquared > circleRadiusSquared) continue; + + Block block = targetBlock.getRelative(xOffset, 0, zOffset); + + if(block.getType() != Material.WATER) continue; + if(!(block.getBlockData() instanceof Levelled waterData)) continue; + if(waterData.getLevel() != 0) continue; + if(!block.getRelative(BlockFace.UP).isEmpty()) continue; + + block.setType(Material.FROSTED_ICE); + } + } + } + + @Override + @NotNull + protected List listeners() { + return List.of(new BoatMoveListener()); + } +}