Compare commits

..
Author SHA1 Message Date
YoyoNow b2b803aca6 Remove unused code from Laufbau 2026-06-12 12:24:46 +02:00
155 changed files with 1257 additions and 7974 deletions
-5
View File
@@ -15,11 +15,6 @@ bin/
.vscode
.settings
# Language Server
**/.project
**/.factorypath
**/.classpath
# Other
lib
/WebsiteBackend/data
@@ -35,7 +35,6 @@ dependencies {
compileOnly(libs.classindex)
annotationProcessor(libs.classindex)
compileOnly(project(":SpigotCore", "default"))
compileOnly(project(":KotlinCore", "default"))
compileOnly(libs.axiom)
compileOnly(libs.authlib)
@@ -25,14 +25,12 @@ import de.steamwar.bausystem.configplayer.ConfigConverter;
import de.steamwar.bausystem.features.gui.BauGUI;
import de.steamwar.bausystem.features.script.lua.SteamWarLuaPlugin;
import de.steamwar.bausystem.features.script.lua.libs.LuaLib;
import de.steamwar.bausystem.features.slaves.laufbau.BoundingBoxLoader;
import de.steamwar.bausystem.features.slaves.panzern.Panzern;
import de.steamwar.bausystem.features.slaves.panzern.PanzernAlgorithm;
import de.steamwar.bausystem.features.tracer.TraceManager;
import de.steamwar.bausystem.features.tracer.TraceRecorder;
import de.steamwar.bausystem.features.world.BauScoreboard;
import de.steamwar.bausystem.linkage.BauGuiItem;
import de.steamwar.bausystem.region.Region;
import de.steamwar.bausystem.region.RegionSystem;
import de.steamwar.bausystem.utils.ScoreboardElement;
import de.steamwar.bausystem.utils.TickManager;
@@ -41,9 +39,8 @@ import de.steamwar.command.AbstractValidator;
import de.steamwar.command.SWCommandUtils;
import de.steamwar.core.CRIUSleepEvent;
import de.steamwar.core.Core;
import de.steamwar.core.WorldEditRendererCUIEditor;
import de.steamwar.core.WorldIdentifier;
import de.steamwar.core.worldedit.SteamEdit;
import de.steamwar.core.worldedit.WorldEditRendererCUIEditor;
import de.steamwar.linkage.AbstractLinker;
import de.steamwar.linkage.SpigotLinker;
import de.steamwar.message.Message;
@@ -51,7 +48,6 @@ import de.steamwar.providers.BauServerInfo;
import lombok.Getter;
import org.bukkit.Bukkit;
import org.bukkit.GameRule;
import org.bukkit.Location;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
@@ -115,9 +111,6 @@ public class BauSystem extends JavaPlugin implements Listener {
if (any instanceof ConfigConverter) {
Config.addConfigConverter((ConfigConverter) any);
}
if (any instanceof BoundingBoxLoader) {
((BoundingBoxLoader) any).load();
}
}
};
try {
@@ -132,19 +125,7 @@ public class BauSystem extends JavaPlugin implements Listener {
TraceManager.instance.init();
TraceRecorder.instance.init();
SteamEdit.init();
SteamEdit.ADJACENT_FILTERS = location -> {
Region region = Region.getRegion(location);
Region.Area area;
if (region.getBuildArea().inRegion(location, true)) {
area = region.getBuildArea();
} else if (region.getTestblockArea().inRegion(location, true)) {
area = region.getTestblockArea();
} else {
return SteamEdit.AdjacentFilter.ALWAYS;
}
return (x, y, z) -> area.inRegion(new Location(null, x, y, z), true);
};
new WorldEditRendererCUIEditor();
Bukkit.getWorlds().get(0).setGameRule(GameRule.SEND_COMMAND_FEEDBACK, false);
@@ -290,7 +290,7 @@ public class KillcheckerVisualizer {
}
rEntities.get(point).die();
}
RBlockDisplay entity = new RBlockDisplay(outlinePoints.contains(point) ? outline : inner, point.toLocation(WORLD, 0, 0, 0));
RBlockDisplay entity = new RBlockDisplay(outlinePoints.contains(point) ? outline : inner, point.toLocation(WORLD, 0.5, 0, 0.5));
entity.setBlock(MATERIALS[Math.min(count - 1, MATERIALS.length) - 1].createBlockData());
rEntities.put(point, entity);
if (outlinePoints.contains(point)) outlinePointsCache.add(point);
@@ -185,16 +185,17 @@ public class TestblockCommand extends SWCommand {
return new TypeMapper<SchematicNode>() {
@Override
public List<String> tabCompletes(CommandSender commandSender, PreviousArguments previousArguments, String s) {
List<String> stringList = new ArrayList<>();
List<String> stringList = new ArrayList<>(SchematicNode.getNodeTabcomplete(SteamwarUser.get(((Player) commandSender).getUniqueId()), s));
stringList.addAll(SchematicNode.getNodeTabcomplete(SteamwarUser.byId(0), s));
stringList.addAll(SchematicNode.getNodeTabcomplete(SteamwarUser.get(((Player) commandSender).getUniqueId()), s));
return stringList;
}
@Override
public SchematicNode map(CommandSender commandSender, PreviousArguments previousArguments, String s) {
SchematicNode node = SchematicNode.getNodeFromPath(SteamwarUser.byId(0), s);
if (node == null) node = SchematicNode.getNodeFromPath(SteamwarUser.get(((Player) commandSender).getUniqueId()), s);
SchematicNode node = SchematicNode.getNodeFromPath(SteamwarUser.get(((Player) commandSender).getUniqueId()), s);
if (node == null) {
node = SchematicNode.getNodeFromPath(SteamwarUser.byId(0), s);
}
return node;
}
};
@@ -19,7 +19,6 @@
package de.steamwar.bausystem.features.simulator;
import com.destroystokyo.paper.event.server.ServerTickEndEvent;
import de.steamwar.bausystem.BauSystem;
import de.steamwar.bausystem.Permission;
import de.steamwar.bausystem.SWUtils;
@@ -78,16 +77,8 @@ public class SimulatorCursor implements Listener {
return isSimulatorItem(player.getInventory().getItemInMainHand()) || isSimulatorItem(player.getInventory().getItemInOffHand());
}
private static Set<Player> scheduledUpdates = new HashSet<>();
private static void scheduleCursorUpdate(Player player) {
scheduledUpdates.add(player);
}
@EventHandler
public void onServerTickEnd(ServerTickEndEvent event) {
scheduledUpdates.forEach(SimulatorCursor::calcCursor);
scheduledUpdates.clear();
BauSystem.runTaskLater(BauSystem.getInstance(), () -> calcCursor(player), 1);
}
@EventHandler
@@ -131,7 +122,6 @@ public class SimulatorCursor implements Listener {
public void onPlayerQuit(PlayerQuitEvent event) {
cursorType.remove(event.getPlayer());
removeCursor(event.getPlayer());
scheduledUpdates.remove(event.getPlayer());
}
private static final Map<Player, Long> LAST_SNEAKS = new HashMap<>();
@@ -19,28 +19,17 @@
package de.steamwar.bausystem.features.slaves.laufbau;
import com.sk89q.worldedit.blocks.SkullBlock;
import com.sk89q.worldedit.world.block.BaseBlock;
import de.steamwar.inventory.SWItem;
import lombok.Getter;
import lombok.ToString;
import org.bukkit.Material;
import org.bukkit.block.BlockFace;
import org.bukkit.block.data.Bisected;
import org.bukkit.block.data.BlockData;
import org.bukkit.block.data.Directional;
import org.bukkit.block.data.Waterlogged;
import org.bukkit.block.data.type.*;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Random;
import java.util.function.Consumer;
import static de.steamwar.bausystem.features.slaves.laufbau.LaufbauUtils.createItem;
import static de.steamwar.bausystem.features.slaves.laufbau.LaufbauUtils.pixelCuboid;
@ToString
@Getter
public class BlockBoundingBox {
@@ -92,197 +81,4 @@ public class BlockBoundingBox {
public double volume() {
return volume;
}
static {
addPixel(Material.AIR.createBlockData(), 0, 0, 0, 0, 0, 0, null);
// addPixel(Material.COBWEB.createBlockData(), 0, 0, 0, 0, 0, 0, createItem("LAUFBAU_BLOCK_COBWEB", Material.COBWEB));
addPixel(Material.END_STONE.createBlockData(), 0, 0, 0, 16, 16, 16, null);
addPixel(Material.DIRT_PATH.createBlockData(), 0, 0, 0, 16, 15, 16, createItem("LAUFBAU_BLOCK_GRASS_PATH", Material.DIRT_PATH));
addPixel(Material.MUD.createBlockData(), 0, 0, 0, 16, 14, 16, createItem("LAUFBAU_BLOCK_SOUL_SAND", Material.SOUL_SAND));
Cocoa cocoaNorth = (Cocoa) Material.COCOA.createBlockData();
cocoaNorth.setAge(2);
cocoaNorth.setFacing(BlockFace.NORTH);
addPixel(cocoaNorth, 4, 3, 1, 8, 9, 8, createItem("LAUFBAU_BLOCK_COCOA", Material.COCOA_BEANS, "LAUFBAU_FACING_NORTH"));
Cocoa cocoaSouth = (Cocoa) Material.COCOA.createBlockData();
cocoaSouth.setAge(2);
cocoaSouth.setFacing(BlockFace.SOUTH);
addPixel(cocoaSouth, 4, 3, 7, 8, 9, 8, createItem("LAUFBAU_BLOCK_COCOA", Material.COCOA_BEANS, "LAUFBAU_FACING_SOUTH"));
Cocoa cocoaWest = (Cocoa) Material.COCOA.createBlockData();
cocoaWest.setAge(2);
cocoaWest.setFacing(BlockFace.WEST);
addPixel(cocoaWest, 1, 3, 4, 8, 9, 8, createItem("LAUFBAU_BLOCK_COCOA", Material.COCOA_BEANS, "LAUFBAU_FACING_WEST"));
Cocoa cocoaEast = (Cocoa) Material.COCOA.createBlockData();
cocoaEast.setAge(2);
cocoaEast.setFacing(BlockFace.EAST);
addPixel(cocoaEast, 7, 3, 4, 8, 9, 8, createItem("LAUFBAU_BLOCK_COCOA", Material.COCOA_BEANS, "LAUFBAU_FACING_EAST"));
TurtleEgg singleTurtleEgg = (TurtleEgg) Material.TURTLE_EGG.createBlockData();
singleTurtleEgg.setEggs(1);
singleTurtleEgg.setHatch(0);
addPixel(singleTurtleEgg, 4, 0, 3, 9, 7, 9, createItem("LAUFBAU_BLOCK_TURTLE_EGG", Material.TURTLE_EGG, "LAUFBAU_COUNT_1"));
TurtleEgg doubleTurtleEgg = (TurtleEgg) Material.TURTLE_EGG.createBlockData();
doubleTurtleEgg.setEggs(2);
doubleTurtleEgg.setHatch(0);
addPixel(doubleTurtleEgg, 1, 0, 1, 14, 7, 14, createItem("LAUFBAU_BLOCK_TURTLE_EGG", Material.TURTLE_EGG, "LAUFBAU_COUNT_2"));
addPixel(Material.CHEST.createBlockData(), 1, 0, 1, 14, 14, 14, createItem("LAUFBAU_BLOCK_CHEST", Material.CHEST));
Snow snowLayers8 = (Snow) Material.SNOW.createBlockData();
snowLayers8.setLayers(8);
addPixel(snowLayers8, 0, 0, 0, 16, 14, 16, createItem("LAUFBAU_BLOCK_SNOW", Material.SNOW, "LAUFBAU_LAYERS_8"));
Directional headNorth = (Directional) Material.PLAYER_WALL_HEAD.createBlockData();
headNorth.setFacing(BlockFace.NORTH);
addPixel(headNorth, 4, 4, 8, 8, 8, 8, createItem("LAUFBAU_BLOCK_PLAYER_WALL_HEAD", Material.PLAYER_HEAD, "LAUFBAU_FACING_NORTH"), BlockBoundingBox::randomPlayerHead);
Directional headSouth = (Directional) Material.PLAYER_WALL_HEAD.createBlockData();
headSouth.setFacing(BlockFace.SOUTH);
addPixel(headSouth, 4, 4, 0, 8, 8, 8, createItem("LAUFBAU_BLOCK_PLAYER_WALL_HEAD", Material.PLAYER_HEAD, "LAUFBAU_FACING_SOUTH"), BlockBoundingBox::randomPlayerHead);
Directional headWest = (Directional) Material.PLAYER_WALL_HEAD.createBlockData();
headWest.setFacing(BlockFace.WEST);
addPixel(headWest, 8, 4, 4, 8, 8, 8, createItem("LAUFBAU_BLOCK_PLAYER_WALL_HEAD", Material.PLAYER_HEAD, "LAUFBAU_FACING_WEST"), BlockBoundingBox::randomPlayerHead);
Directional headEast = (Directional) Material.PLAYER_WALL_HEAD.createBlockData();
headEast.setFacing(BlockFace.EAST);
addPixel(headEast, 0, 4, 4, 8, 8, 8, createItem("LAUFBAU_BLOCK_PLAYER_WALL_HEAD", Material.PLAYER_HEAD, "LAUFBAU_FACING_EAST"), BlockBoundingBox::randomPlayerHead);
Snow snowLayers7 = (Snow) Material.SNOW.createBlockData();
snowLayers7.setLayers(7);
addPixel(snowLayers7, 0, 0, 0, 16, 12, 16, createItem("LAUFBAU_BLOCK_SNOW", Material.SNOW, "LAUFBAU_LAYERS_7"));
Snow snowLayers6 = (Snow) Material.SNOW.createBlockData();
snowLayers6.setLayers(6);
addPixel(snowLayers6, 0, 0, 0, 16, 10, 16, createItem("LAUFBAU_BLOCK_SNOW", Material.SNOW, "LAUFBAU_LAYERS_6"));
addPixel(Material.STONECUTTER.createBlockData(), 0, 0, 0, 16, 9, 16, createItem("LAUFBAU_BLOCK_STONECUTTER", Material.STONECUTTER));
addPixel(Material.PLAYER_HEAD.createBlockData(), 4, 0, 4, 8, 8, 8, createItem("LAUFBAU_BLOCK_PLAYER_HEAD", Material.PLAYER_HEAD), BlockBoundingBox::randomPlayerHead);
addPixel(Material.CAKE.createBlockData(), 1, 0, 1, 14, 8, 14, createItem("LAUFBAU_BLOCK_CAKE", Material.CAKE));
Slab bottomSlab = (Slab) Material.END_STONE_BRICK_SLAB.createBlockData();
bottomSlab.setType(Slab.Type.BOTTOM);
addPixel(bottomSlab, 0, 0, 0, 16, 8, 16, createItem("LAUFBAU_BLOCK_END_STONE_BRICK_SLAB", Material.END_STONE_BRICK_SLAB, "LAUFBAU_TYPE_BOTTOM"));
Slab topSlab = (Slab) Material.END_STONE_BRICK_SLAB.createBlockData();
topSlab.setType(Slab.Type.TOP);
addPixel(topSlab, 0, 8, 0, 16, 8, 16, createItem("LAUFBAU_BLOCK_END_STONE_BRICK_SLAB", Material.END_STONE_BRICK_SLAB, "LAUFBAU_TYPE_TOP"));
SeaPickle quadSeaPickle = (SeaPickle) Material.SEA_PICKLE.createBlockData();
quadSeaPickle.setWaterlogged(false);
quadSeaPickle.setPickles(4);
addPixel(quadSeaPickle, 2, 0, 2, 12, 7, 12, createItem("LAUFBAU_BLOCK_SEA_PICKLE", Material.SEA_PICKLE, "LAUFBAU_COUNT_4"));
Campfire campfire = (Campfire) Material.CAMPFIRE.createBlockData();
campfire.setSignalFire(false);
campfire.setLit(false);
addPixel(campfire, 0, 0, 0, 16, 7, 16, createItem("LAUFBAU_BLOCK_CAMPFIRE", Material.CAMPFIRE));
SeaPickle trippleSeaPickle = (SeaPickle) Material.SEA_PICKLE.createBlockData();
trippleSeaPickle.setWaterlogged(false);
trippleSeaPickle.setPickles(3);
addPixel(trippleSeaPickle, 2, 0, 2, 12, 6, 12, createItem("LAUFBAU_BLOCK_SEA_PICKLE", Material.SEA_PICKLE, "LAUFBAU_COUNT_3"));
SeaPickle doubleSeaPickle = (SeaPickle) Material.SEA_PICKLE.createBlockData();
doubleSeaPickle.setWaterlogged(false);
doubleSeaPickle.setPickles(2);
addPixel(doubleSeaPickle, 3, 0, 3, 10, 6, 10, createItem("LAUFBAU_BLOCK_SEA_PICKLE", Material.SEA_PICKLE, "LAUFBAU_COUNT_2"));
SeaPickle singleSeaPickle = (SeaPickle) Material.SEA_PICKLE.createBlockData();
singleSeaPickle.setWaterlogged(false);
singleSeaPickle.setPickles(1);
addPixel(singleSeaPickle, 6, 0, 6, 4, 6, 4, createItem("LAUFBAU_BLOCK_SEA_PICKLE", Material.SEA_PICKLE, "LAUFBAU_COUNT_1"));
addPixel(Material.FLOWER_POT.createBlockData(), 5, 0, 5, 6, 6, 6, createItem("LAUFBAU_BLOCK_FLOWER_POT", Material.FLOWER_POT));
Snow snowLayers3 = (Snow) Material.SNOW.createBlockData();
snowLayers3.setLayers(3);
addPixel(snowLayers3, 0, 0, 0, 16, 4, 16, createItem("LAUFBAU_BLOCK_SNOW", Material.SNOW, "LAUFBAU_LAYERS_3"));
TrapDoor bottomTrapDoor = (TrapDoor) Material.IRON_TRAPDOOR.createBlockData();
bottomTrapDoor.setHalf(Bisected.Half.BOTTOM);
addPixel(bottomTrapDoor, 0, 0, 0, 16, 3, 16, createItem("LAUFBAU_BLOCK_IRON_TRAPDOOR", Material.IRON_TRAPDOOR, "LAUFBAU_HALF_BOTTOM"));
TrapDoor topTrapDoor = (TrapDoor) Material.IRON_TRAPDOOR.createBlockData();
topTrapDoor.setHalf(Bisected.Half.TOP);
addPixel(topTrapDoor, 0, 13, 0, 16, 3, 16, createItem("LAUFBAU_BLOCK_IRON_TRAPDOOR", Material.IRON_TRAPDOOR, "LAUFBAU_HALF_TOP"));
Snow snowLayers2 = (Snow) Material.SNOW.createBlockData();
snowLayers2.setLayers(2);
addPixel(snowLayers2, 0, 0, 0, 16, 2, 16, createItem("LAUFBAU_BLOCK_SNOW", Material.SNOW, "LAUFBAU_LAYERS_2"));
addPixel(Material.LILY_PAD.createBlockData(), 1, 0, 1, 14, 1.5, 14, createItem("LAUFBAU_BLOCK_LILY_PAD", Material.LILY_PAD));
addPixel(Material.WHITE_CARPET.createBlockData(), 0, 0, 0, 16, 1, 16, createItem("LAUFBAU_BLOCK_WHITE_CARPET", Material.WHITE_CARPET));
Directional endRodBottomTop = (Directional) Material.END_ROD.createBlockData();
endRodBottomTop.setFacing(BlockFace.UP);
addPixel(endRodBottomTop, 6, 0, 6, 4, 16, 4, createItem("LAUFBAU_BLOCK_END_ROD", Material.END_ROD, "LAUFBAU_FACING_UP", "LAUFBAU_FACING_DOWN"));
Directional endRodNorthSouth = (Directional) Material.END_ROD.createBlockData();
endRodNorthSouth.setFacing(BlockFace.NORTH);
addPixel(endRodNorthSouth, 6, 6, 0, 4, 4, 16, createItem("LAUFBAU_BLOCK_END_ROD", Material.END_ROD, "LAUFBAU_FACING_NORTH", "LAUFBAU_FACING_SOUTH"));
Directional endRodEastWest = (Directional) Material.END_ROD.createBlockData();
endRodEastWest.setFacing(BlockFace.EAST);
addPixel(endRodEastWest, 0, 6, 6, 16, 4, 4, createItem("LAUFBAU_BLOCK_END_ROD", Material.END_ROD, "LAUFBAU_FACING_EAST", "LAUFBAU_FACING_WEST"));
Directional lightningRodBottomTop = (Directional) Material.LIGHTNING_ROD.createBlockData();
lightningRodBottomTop.setFacing(BlockFace.UP);
addPixel(lightningRodBottomTop, 6, 0, 6, 4, 16, 4, createItem("LAUFBAU_BLOCK_LIGHTNING_ROD", Material.LIGHTNING_ROD, "LAUFBAU_FACING_UP", "LAUFBAU_FACING_DOWN"));
Directional lightningRodNorthSouth = (Directional) Material.LIGHTNING_ROD.createBlockData();
lightningRodNorthSouth.setFacing(BlockFace.NORTH);
addPixel(lightningRodNorthSouth, 6, 6, 0, 4, 4, 16, createItem("LAUFBAU_BLOCK_LIGHTNING_ROD", Material.LIGHTNING_ROD, "LAUFBAU_FACING_NORTH", "LAUFBAU_FACING_SOUTH"));
Directional lightningRodEastWest = (Directional) Material.LIGHTNING_ROD.createBlockData();
lightningRodEastWest.setFacing(BlockFace.EAST);
addPixel(lightningRodEastWest, 0, 6, 6, 16, 4, 4, createItem("LAUFBAU_BLOCK_LIGHTNING_ROD", Material.LIGHTNING_ROD, "LAUFBAU_FACING_EAST", "LAUFBAU_FACING_WEST"));
Waterlogged conduit = (Waterlogged) Material.CONDUIT.createBlockData();
conduit.setWaterlogged(false);
addPixel(conduit, 5, 5, 5, 6, 6, 6, createItem("LAUFBAU_BLOCK_CONDUIT", Material.CONDUIT));
TrapDoor northTrapDoor = (TrapDoor) Material.IRON_TRAPDOOR.createBlockData();
northTrapDoor.setFacing(BlockFace.NORTH);
northTrapDoor.setOpen(true);
addPixel(northTrapDoor, 0, 0, 13, 16, 16, 3, createItem("LAUFBAU_BLOCK_IRON_TRAPDOOR", Material.IRON_TRAPDOOR, "LAUFBAU_FACING_NORTH", "LAUFBAU_OPEN"));
TrapDoor southTrapDoor = (TrapDoor) Material.IRON_TRAPDOOR.createBlockData();
southTrapDoor.setFacing(BlockFace.SOUTH);
southTrapDoor.setOpen(true);
addPixel(southTrapDoor, 0, 0, 0, 16, 16, 3, createItem("LAUFBAU_BLOCK_IRON_TRAPDOOR", Material.IRON_TRAPDOOR, "LAUFBAU_FACING_SOUTH", "LAUFBAU_OPEN"));
TrapDoor westTrapDoor = (TrapDoor) Material.IRON_TRAPDOOR.createBlockData();
westTrapDoor.setFacing(BlockFace.WEST);
westTrapDoor.setOpen(true);
addPixel(westTrapDoor, 13, 0, 0, 3, 16, 16, createItem("LAUFBAU_BLOCK_IRON_TRAPDOOR", Material.IRON_TRAPDOOR, "LAUFBAU_FACING_WEST", "LAUFBAU_OPEN"));
TrapDoor eastTrapDoor = (TrapDoor) Material.IRON_TRAPDOOR.createBlockData();
eastTrapDoor.setFacing(BlockFace.EAST);
eastTrapDoor.setOpen(true);
addPixel(eastTrapDoor, 0, 0, 0, 3, 16, 16, createItem("LAUFBAU_BLOCK_IRON_TRAPDOOR", Material.IRON_TRAPDOOR, "LAUFBAU_FACING_EAST", "LAUFBAU_OPEN"));
}
private static void addPixel(BlockData blockData, double xPixel, double yPixel, double zPixel, double dxPixel, double dyPixel, double dzPixel, SWItem swItem) {
new BlockBoundingBox(blockData, Arrays.asList(pixelCuboid(xPixel, yPixel, zPixel, dxPixel, dyPixel, dzPixel)), swItem);
}
private static void addPixel(BlockData blockData, double xPixel, double yPixel, double zPixel, double dxPixel, double dyPixel, double dzPixel, SWItem swItem, Consumer<BaseBlock> blockConsumer) {
new BlockBoundingBox(blockData, Arrays.asList(pixelCuboid(xPixel, yPixel, zPixel, dxPixel, dyPixel, dzPixel)), swItem, blockConsumer);
}
@SuppressWarnings("deprecation")
private static void randomPlayerHead(BaseBlock block) {
if (block instanceof SkullBlock) {
SkullBlock skullBlock = (SkullBlock) block;
skullBlock.setOwner(randomPlayerHead.get(random.nextInt(randomPlayerHead.size())).toString());
}
}
}
@@ -1,25 +0,0 @@
/*
* This file is a part of the SteamWar software.
*
* Copyright (C) 2025 SteamWar.de-Serverteam
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package de.steamwar.bausystem.features.slaves.laufbau;
public interface BoundingBoxLoader {
void load();
}
@@ -22,6 +22,7 @@ package de.steamwar.bausystem.features.slaves.laufbau;
import de.steamwar.bausystem.region.Point;
import lombok.AllArgsConstructor;
import lombok.Data;
import org.bukkit.util.BoundingBox;
@Data
@AllArgsConstructor
@@ -33,6 +34,15 @@ public class Cuboid {
private double dy;
private double dz;
public Cuboid(BoundingBox boundingBox) {
this.x = boundingBox.getMinX();
this.y = boundingBox.getMinY();
this.z = boundingBox.getMinZ();
this.dx = boundingBox.getWidthX();
this.dy = boundingBox.getHeight();
this.dz = boundingBox.getWidthZ();
}
public boolean intersects(Cuboid cuboid) {
double minx = x - cuboid.dx;
double miny = y - cuboid.dy;
@@ -24,15 +24,52 @@ import de.steamwar.bausystem.SWUtils;
import de.steamwar.bausystem.shared.Pair;
import de.steamwar.bausystem.utils.WorldEditUtils;
import de.steamwar.command.SWCommand;
import de.steamwar.inventory.SWItem;
import de.steamwar.linkage.Linked;
import net.minecraft.core.BlockPos;
import net.minecraft.world.level.EmptyBlockGetter;
import net.minecraft.world.level.block.Block;
import net.minecraft.world.phys.shapes.CollisionContext;
import org.bukkit.Bukkit;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.Registry;
import org.bukkit.craftbukkit.block.CraftBlockType;
import org.bukkit.craftbukkit.block.data.CraftBlockData;
import org.bukkit.craftbukkit.util.CraftVoxelShape;
import org.bukkit.entity.Player;
import org.bukkit.scheduler.BukkitRunnable;
import org.bukkit.util.VoxelShape;
import java.util.concurrent.atomic.AtomicLong;
import java.util.concurrent.atomic.AtomicReference;
import java.util.stream.Collectors;
@Linked
public class LaufbauCommand extends SWCommand {
static {
AtomicLong counter = new AtomicLong();
AtomicReference<VoxelShape> shape = new AtomicReference<>();
long time = System.currentTimeMillis();
Registry.BLOCK.forEach(blockType -> {
Block block = CraftBlockType.bukkitToMinecraftNew(blockType);
block.getStateDefinition().getPossibleStates().forEach(blockState -> {
VoxelShape voxelShape = new CraftVoxelShape(blockState.getCollisionShape(EmptyBlockGetter.INSTANCE, BlockPos.ZERO, CollisionContext.empty()));
shape.set(voxelShape);
Material material = blockType.asMaterial();
if (!material.isItem()) return;
new BlockBoundingBox(
CraftBlockData.createData(blockState),
voxelShape.getBoundingBoxes().stream().map(Cuboid::new).collect(Collectors.toList()),
new SWItem(material, "Item")
);
counter.incrementAndGet();
});
});
System.out.println(System.currentTimeMillis() - time + "ms " + shape.get() + " " + counter.get());
}
public LaufbauCommand() {
super("laufbau", "laufsklave");
}
@@ -1,261 +0,0 @@
/*
* This file is a part of the SteamWar software.
*
* Copyright (C) 2025 SteamWar.de-Serverteam
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package de.steamwar.bausystem.features.slaves.laufbau.boundingboxes;
import de.steamwar.bausystem.features.slaves.laufbau.BlockBoundingBox;
import de.steamwar.bausystem.features.slaves.laufbau.BoundingBoxLoader;
import de.steamwar.bausystem.features.slaves.laufbau.Cuboid;
import de.steamwar.linkage.Linked;
import org.bukkit.Material;
import org.bukkit.block.BlockFace;
import org.bukkit.block.data.type.AmethystCluster;
import java.util.ArrayList;
import java.util.List;
import static de.steamwar.bausystem.features.slaves.laufbau.LaufbauUtils.createItem;
import static de.steamwar.bausystem.features.slaves.laufbau.LaufbauUtils.pixelCuboid;
@Linked
public class AmethystBoundingBox implements BoundingBoxLoader {
@Override
public void load() {
floorSmallAmethystBud();
ceilingSmallAmethystBud();
northSmallAmethystBud();
southSmallAmethystBud();
eastSmallAmethystBud();
westSmallAmethystBud();
floorMediumAmethystBud();
ceilingMediumAmethystBud();
northMediumAmethystBud();
southMediumAmethystBud();
eastMediumAmethystBud();
westMediumAmethystBud();
floorLargeAmethystBud();
ceilingLargeAmethystBud();
northLargeAmethystBud();
southLargeAmethystBud();
eastLargeAmethystBud();
westLargeAmethystBud();
floorAmethystCluster();
ceilingAmethystCluster();
northAmethystCluster();
southAmethystCluster();
eastAmethystCluster();
westAmethystCluster();
}
private void floorSmallAmethystBud() {
AmethystCluster cluster = (AmethystCluster) Material.SMALL_AMETHYST_BUD.createBlockData();
cluster.setFacing(BlockFace.UP);
List<Cuboid> cuboidList = new ArrayList<>();
cuboidList.add(pixelCuboid(4, 0, 4, 8, 3, 8));
new BlockBoundingBox(cluster, cuboidList, createItem("LAUFBAU_BLOCK_SMALL_AMETHYST_BUD", Material.SMALL_AMETHYST_BUD, "LAUFBAU_FACING_UP"));
}
private void ceilingSmallAmethystBud() {
AmethystCluster cluster = (AmethystCluster) Material.SMALL_AMETHYST_BUD.createBlockData();
cluster.setFacing(BlockFace.DOWN);
List<Cuboid> cuboidList = new ArrayList<>();
cuboidList.add(pixelCuboid(4, 13, 4, 8, 3, 8));
new BlockBoundingBox(cluster, cuboidList, createItem("LAUFBAU_BLOCK_SMALL_AMETHYST_BUD", Material.SMALL_AMETHYST_BUD, "LAUFBAU_FACING_DOWN"));
}
private void northSmallAmethystBud() {
AmethystCluster cluster = (AmethystCluster) Material.SMALL_AMETHYST_BUD.createBlockData();
cluster.setFacing(BlockFace.NORTH);
List<Cuboid> cuboidList = new ArrayList<>();
cuboidList.add(pixelCuboid(4, 4, 13, 8, 8, 3));
new BlockBoundingBox(cluster, cuboidList, createItem("LAUFBAU_BLOCK_SMALL_AMETHYST_BUD", Material.SMALL_AMETHYST_BUD, "LAUFBAU_FACING_NORTH"));
}
private void southSmallAmethystBud() {
AmethystCluster cluster = (AmethystCluster) Material.SMALL_AMETHYST_BUD.createBlockData();
cluster.setFacing(BlockFace.SOUTH);
List<Cuboid> cuboidList = new ArrayList<>();
cuboidList.add(pixelCuboid(4, 4, 0, 8, 8, 3));
new BlockBoundingBox(cluster, cuboidList, createItem("LAUFBAU_BLOCK_SMALL_AMETHYST_BUD", Material.SMALL_AMETHYST_BUD, "LAUFBAU_FACING_SOUTH"));
}
private void eastSmallAmethystBud() {
AmethystCluster cluster = (AmethystCluster) Material.SMALL_AMETHYST_BUD.createBlockData();
cluster.setFacing(BlockFace.EAST);
List<Cuboid> cuboidList = new ArrayList<>();
cuboidList.add(pixelCuboid(0, 4, 4, 3, 8, 8));
new BlockBoundingBox(cluster, cuboidList, createItem("LAUFBAU_BLOCK_SMALL_AMETHYST_BUD", Material.SMALL_AMETHYST_BUD, "LAUFBAU_FACING_EAST"));
}
private void westSmallAmethystBud() {
AmethystCluster cluster = (AmethystCluster) Material.SMALL_AMETHYST_BUD.createBlockData();
cluster.setFacing(BlockFace.WEST);
List<Cuboid> cuboidList = new ArrayList<>();
cuboidList.add(pixelCuboid(13, 4, 4, 3, 8, 8));
new BlockBoundingBox(cluster, cuboidList, createItem("LAUFBAU_BLOCK_SMALL_AMETHYST_BUD", Material.SMALL_AMETHYST_BUD, "LAUFBAU_FACING_WEST"));
}
private void floorMediumAmethystBud() {
AmethystCluster cluster = (AmethystCluster) Material.MEDIUM_AMETHYST_BUD.createBlockData();
cluster.setFacing(BlockFace.UP);
List<Cuboid> cuboidList = new ArrayList<>();
cuboidList.add(pixelCuboid(3, 0, 3, 10, 4, 10));
new BlockBoundingBox(cluster, cuboidList, createItem("LAUFBAU_BLOCK_MEDIUM_AMETHYST_BUD", Material.MEDIUM_AMETHYST_BUD, "LAUFBAU_FACING_UP"));
}
private void ceilingMediumAmethystBud() {
AmethystCluster cluster = (AmethystCluster) Material.MEDIUM_AMETHYST_BUD.createBlockData();
cluster.setFacing(BlockFace.DOWN);
List<Cuboid> cuboidList = new ArrayList<>();
cuboidList.add(pixelCuboid(3, 12, 3, 10, 4, 10));
new BlockBoundingBox(cluster, cuboidList, createItem("LAUFBAU_BLOCK_MEDIUM_AMETHYST_BUD", Material.MEDIUM_AMETHYST_BUD, "LAUFBAU_FACING_DOWN"));
}
private void northMediumAmethystBud() {
AmethystCluster cluster = (AmethystCluster) Material.MEDIUM_AMETHYST_BUD.createBlockData();
cluster.setFacing(BlockFace.NORTH);
List<Cuboid> cuboidList = new ArrayList<>();
cuboidList.add(pixelCuboid(3, 3, 12, 10, 10, 4));
new BlockBoundingBox(cluster, cuboidList, createItem("LAUFBAU_BLOCK_MEDIUM_AMETHYST_BUD", Material.MEDIUM_AMETHYST_BUD, "LAUFBAU_FACING_NORTH"));
}
private void southMediumAmethystBud() {
AmethystCluster cluster = (AmethystCluster) Material.MEDIUM_AMETHYST_BUD.createBlockData();
cluster.setFacing(BlockFace.SOUTH);
List<Cuboid> cuboidList = new ArrayList<>();
cuboidList.add(pixelCuboid(3, 3, 0, 10, 10, 4));
new BlockBoundingBox(cluster, cuboidList, createItem("LAUFBAU_BLOCK_MEDIUM_AMETHYST_BUD", Material.MEDIUM_AMETHYST_BUD, "LAUFBAU_FACING_SOUTH"));
}
private void eastMediumAmethystBud() {
AmethystCluster cluster = (AmethystCluster) Material.MEDIUM_AMETHYST_BUD.createBlockData();
cluster.setFacing(BlockFace.EAST);
List<Cuboid> cuboidList = new ArrayList<>();
cuboidList.add(pixelCuboid(0, 3, 3, 4, 10, 10));
new BlockBoundingBox(cluster, cuboidList, createItem("LAUFBAU_BLOCK_MEDIUM_AMETHYST_BUD", Material.MEDIUM_AMETHYST_BUD, "LAUFBAU_FACING_EAST"));
}
private void westMediumAmethystBud() {
AmethystCluster cluster = (AmethystCluster) Material.MEDIUM_AMETHYST_BUD.createBlockData();
cluster.setFacing(BlockFace.WEST);
List<Cuboid> cuboidList = new ArrayList<>();
cuboidList.add(pixelCuboid(12, 3, 3, 4, 10, 10));
new BlockBoundingBox(cluster, cuboidList, createItem("LAUFBAU_BLOCK_MEDIUM_AMETHYST_BUD", Material.MEDIUM_AMETHYST_BUD, "LAUFBAU_FACING_WEST"));
}
private void floorLargeAmethystBud() {
AmethystCluster cluster = (AmethystCluster) Material.LARGE_AMETHYST_BUD.createBlockData();
cluster.setFacing(BlockFace.UP);
List<Cuboid> cuboidList = new ArrayList<>();
cuboidList.add(pixelCuboid(3, 0, 3, 10, 5, 10));
new BlockBoundingBox(cluster, cuboidList, createItem("LAUFBAU_BLOCK_LARGE_AMETHYST_BUD", Material.LARGE_AMETHYST_BUD, "LAUFBAU_FACING_UP"));
}
private void ceilingLargeAmethystBud() {
AmethystCluster cluster = (AmethystCluster) Material.LARGE_AMETHYST_BUD.createBlockData();
cluster.setFacing(BlockFace.DOWN);
List<Cuboid> cuboidList = new ArrayList<>();
cuboidList.add(pixelCuboid(3, 11, 3, 10, 5, 10));
new BlockBoundingBox(cluster, cuboidList, createItem("LAUFBAU_BLOCK_LARGE_AMETHYST_BUD", Material.LARGE_AMETHYST_BUD, "LAUFBAU_FACING_DOWN"));
}
private void northLargeAmethystBud() {
AmethystCluster cluster = (AmethystCluster) Material.LARGE_AMETHYST_BUD.createBlockData();
cluster.setFacing(BlockFace.NORTH);
List<Cuboid> cuboidList = new ArrayList<>();
cuboidList.add(pixelCuboid(3, 3, 11, 10, 10, 5));
new BlockBoundingBox(cluster, cuboidList, createItem("LAUFBAU_BLOCK_LARGE_AMETHYST_BUD", Material.LARGE_AMETHYST_BUD, "LAUFBAU_FACING_NORTH"));
}
private void southLargeAmethystBud() {
AmethystCluster cluster = (AmethystCluster) Material.LARGE_AMETHYST_BUD.createBlockData();
cluster.setFacing(BlockFace.SOUTH);
List<Cuboid> cuboidList = new ArrayList<>();
cuboidList.add(pixelCuboid(3, 3, 0, 10, 10, 5));
new BlockBoundingBox(cluster, cuboidList, createItem("LAUFBAU_BLOCK_LARGE_AMETHYST_BUD", Material.LARGE_AMETHYST_BUD, "LAUFBAU_FACING_SOUTH"));
}
private void eastLargeAmethystBud() {
AmethystCluster cluster = (AmethystCluster) Material.LARGE_AMETHYST_BUD.createBlockData();
cluster.setFacing(BlockFace.EAST);
List<Cuboid> cuboidList = new ArrayList<>();
cuboidList.add(pixelCuboid(0, 3, 3, 5, 10, 10));
new BlockBoundingBox(cluster, cuboidList, createItem("LAUFBAU_BLOCK_LARGE_AMETHYST_BUD", Material.LARGE_AMETHYST_BUD, "LAUFBAU_FACING_EAST"));
}
private void westLargeAmethystBud() {
AmethystCluster cluster = (AmethystCluster) Material.LARGE_AMETHYST_BUD.createBlockData();
cluster.setFacing(BlockFace.WEST);
List<Cuboid> cuboidList = new ArrayList<>();
cuboidList.add(pixelCuboid(11, 3, 3, 5, 10, 10));
new BlockBoundingBox(cluster, cuboidList, createItem("LAUFBAU_BLOCK_LARGE_AMETHYST_BUD", Material.LARGE_AMETHYST_BUD, "LAUFBAU_FACING_WEST"));
}
private void floorAmethystCluster() {
AmethystCluster cluster = (AmethystCluster) Material.AMETHYST_CLUSTER.createBlockData();
cluster.setFacing(BlockFace.UP);
List<Cuboid> cuboidList = new ArrayList<>();
cuboidList.add(pixelCuboid(3, 0, 3, 10, 7, 10));
new BlockBoundingBox(cluster, cuboidList, createItem("LAUFBAU_BLOCK_AMETHYST_CLUSTER", Material.AMETHYST_CLUSTER, "LAUFBAU_FACING_UP"));
}
private void ceilingAmethystCluster() {
AmethystCluster cluster = (AmethystCluster) Material.AMETHYST_CLUSTER.createBlockData();
cluster.setFacing(BlockFace.DOWN);
List<Cuboid> cuboidList = new ArrayList<>();
cuboidList.add(pixelCuboid(3, 9, 3, 10, 7, 10));
new BlockBoundingBox(cluster, cuboidList, createItem("LAUFBAU_BLOCK_AMETHYST_CLUSTER", Material.AMETHYST_CLUSTER, "LAUFBAU_FACING_DOWN"));
}
private void northAmethystCluster() {
AmethystCluster cluster = (AmethystCluster) Material.AMETHYST_CLUSTER.createBlockData();
cluster.setFacing(BlockFace.NORTH);
List<Cuboid> cuboidList = new ArrayList<>();
cuboidList.add(pixelCuboid(3, 3, 9, 10, 10, 7));
new BlockBoundingBox(cluster, cuboidList, createItem("LAUFBAU_BLOCK_AMETHYST_CLUSTER", Material.AMETHYST_CLUSTER, "LAUFBAU_FACING_NORTH"));
}
private void southAmethystCluster() {
AmethystCluster cluster = (AmethystCluster) Material.AMETHYST_CLUSTER.createBlockData();
cluster.setFacing(BlockFace.SOUTH);
List<Cuboid> cuboidList = new ArrayList<>();
cuboidList.add(pixelCuboid(3, 3, 0, 10, 10, 7));
new BlockBoundingBox(cluster, cuboidList, createItem("LAUFBAU_BLOCK_AMETHYST_CLUSTER", Material.AMETHYST_CLUSTER, "LAUFBAU_FACING_SOUTH"));
}
private void eastAmethystCluster() {
AmethystCluster cluster = (AmethystCluster) Material.AMETHYST_CLUSTER.createBlockData();
cluster.setFacing(BlockFace.EAST);
List<Cuboid> cuboidList = new ArrayList<>();
cuboidList.add(pixelCuboid(0, 3, 3, 7, 10, 10));
new BlockBoundingBox(cluster, cuboidList, createItem("LAUFBAU_BLOCK_AMETHYST_CLUSTER", Material.AMETHYST_CLUSTER, "LAUFBAU_FACING_EAST"));
}
private void westAmethystCluster() {
AmethystCluster cluster = (AmethystCluster) Material.AMETHYST_CLUSTER.createBlockData();
cluster.setFacing(BlockFace.WEST);
List<Cuboid> cuboidList = new ArrayList<>();
cuboidList.add(pixelCuboid(9, 3, 3, 7, 10, 10));
new BlockBoundingBox(cluster, cuboidList, createItem("LAUFBAU_BLOCK_AMETHYST_CLUSTER", Material.AMETHYST_CLUSTER, "LAUFBAU_FACING_WEST"));
}
}
@@ -1,46 +0,0 @@
/*
* This file is a part of the SteamWar software.
*
* Copyright (C) 2025 SteamWar.de-Serverteam
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package de.steamwar.bausystem.features.slaves.laufbau.boundingboxes;
import de.steamwar.bausystem.features.slaves.laufbau.BlockBoundingBox;
import de.steamwar.bausystem.features.slaves.laufbau.BoundingBoxLoader;
import de.steamwar.bausystem.features.slaves.laufbau.Cuboid;
import de.steamwar.linkage.Linked;
import org.bukkit.Material;
import org.bukkit.block.data.BlockData;
import java.util.ArrayList;
import java.util.List;
import static de.steamwar.bausystem.features.slaves.laufbau.LaufbauUtils.createItem;
import static de.steamwar.bausystem.features.slaves.laufbau.LaufbauUtils.pixelCuboid;
@Linked
public class AzaleaBoundingBox implements BoundingBoxLoader {
@Override
public void load() {
BlockData blockData = Material.FLOWERING_AZALEA.createBlockData();
List<Cuboid> cuboidList = new ArrayList<>();
cuboidList.add(pixelCuboid(0, 8, 0, 16, 8, 16));
cuboidList.add(pixelCuboid(6, 0, 6, 4, 8, 4));
new BlockBoundingBox(blockData, cuboidList, createItem("LAUFBAU_BLOCK_AZALEA", Material.FLOWERING_AZALEA));
}
}
@@ -1,149 +0,0 @@
/*
* This file is a part of the SteamWar software.
*
* Copyright (C) 2025 SteamWar.de-Serverteam
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package de.steamwar.bausystem.features.slaves.laufbau.boundingboxes;
import de.steamwar.bausystem.features.slaves.laufbau.BlockBoundingBox;
import de.steamwar.bausystem.features.slaves.laufbau.BoundingBoxLoader;
import de.steamwar.bausystem.features.slaves.laufbau.Cuboid;
import de.steamwar.linkage.Linked;
import org.bukkit.Material;
import org.bukkit.block.BlockFace;
import org.bukkit.block.data.type.Bell;
import java.util.ArrayList;
import java.util.List;
import static de.steamwar.bausystem.features.slaves.laufbau.LaufbauUtils.createItem;
import static de.steamwar.bausystem.features.slaves.laufbau.LaufbauUtils.pixelCuboid;
@Linked
public class BellBoundingBox implements BoundingBoxLoader {
@Override
public void load() {
ceilingBell();
floorNorthBell();
floorEastBell();
doubleWallNorthBell();
doubleWallEastBell();
singleWallNorthBell();
singleWallSouthBell();
singleWallEastBell();
singleWallWestBell();
}
public void ceilingBell() {
Bell bell = (Bell) Material.BELL.createBlockData();
bell.setAttachment(Bell.Attachment.CEILING);
bell.setFacing(BlockFace.NORTH);
List<Cuboid> cuboidList = new ArrayList<>();
cuboidList.add(pixelCuboid(4, 4, 4, 8, 2, 8));
cuboidList.add(pixelCuboid(5, 6, 5, 6, 8, 6));
cuboidList.add(pixelCuboid(7, 13, 7, 2, 3, 2));
new BlockBoundingBox(bell, cuboidList, createItem("LAUFBAU_BLOCK_BELL", Material.BELL, "LAUFBAU_ATTACHMENT_CEILING"));
}
public void floorNorthBell() {
Bell bell = (Bell) Material.BELL.createBlockData();
bell.setAttachment(Bell.Attachment.FLOOR);
bell.setFacing(BlockFace.NORTH);
List<Cuboid> cuboidList = new ArrayList<>();
cuboidList.add(pixelCuboid(0, 0, 4, 16, 16, 8));
new BlockBoundingBox(bell, cuboidList, createItem("LAUFBAU_BLOCK_BELL", Material.BELL, "LAUFBAU_ATTACHMENT_FLOOR", "LAUFBAU_FACING_NORTH", "LAUFBAU_FACING_SOUTH"));
}
public void floorEastBell() {
Bell bell = (Bell) Material.BELL.createBlockData();
bell.setAttachment(Bell.Attachment.FLOOR);
bell.setFacing(BlockFace.EAST);
List<Cuboid> cuboidList = new ArrayList<>();
cuboidList.add(pixelCuboid(4, 0, 0, 8, 16, 16));
new BlockBoundingBox(bell, cuboidList, createItem("LAUFBAU_BLOCK_BELL", Material.BELL, "LAUFBAU_ATTACHMENT_FLOOR", "LAUFBAU_FACING_EAST", "LAUFBAU_FACING_WEST"));
}
public void doubleWallNorthBell() {
Bell bell = (Bell) Material.BELL.createBlockData();
bell.setAttachment(Bell.Attachment.DOUBLE_WALL);
bell.setFacing(BlockFace.NORTH);
List<Cuboid> cuboidList = new ArrayList<>();
cuboidList.add(pixelCuboid(4, 4, 4, 8, 2, 8));
cuboidList.add(pixelCuboid(5, 6, 5, 6, 8, 6));
cuboidList.add(pixelCuboid(7, 13, 0, 2, 2, 16));
new BlockBoundingBox(bell, cuboidList, createItem("LAUFBAU_BLOCK_BELL", Material.BELL, "LAUFBAU_ATTACHMENT_DOUBLE_WALL", "LAUFBAU_FACING_NORTH"));
}
public void doubleWallEastBell() {
Bell bell = (Bell) Material.BELL.createBlockData();
bell.setAttachment(Bell.Attachment.DOUBLE_WALL);
bell.setFacing(BlockFace.EAST);
List<Cuboid> cuboidList = new ArrayList<>();
cuboidList.add(pixelCuboid(4, 4, 4, 8, 2, 8));
cuboidList.add(pixelCuboid(5, 6, 5, 6, 8, 6));
cuboidList.add(pixelCuboid(0, 13, 7, 16, 2, 2));
new BlockBoundingBox(bell, cuboidList, createItem("LAUFBAU_BLOCK_BELL", Material.BELL, "LAUFBAU_ATTACHMENT_DOUBLE_WALL", "LAUFBAU_FACING_EAST"));
}
public void singleWallNorthBell() {
Bell bell = (Bell) Material.BELL.createBlockData();
bell.setAttachment(Bell.Attachment.SINGLE_WALL);
bell.setFacing(BlockFace.NORTH);
List<Cuboid> cuboidList = new ArrayList<>();
cuboidList.add(pixelCuboid(4, 4, 4, 8, 2, 8));
cuboidList.add(pixelCuboid(5, 6, 5, 6, 8, 6));
cuboidList.add(pixelCuboid(7, 13, 0, 2, 2, 13));
new BlockBoundingBox(bell, cuboidList, createItem("LAUFBAU_BLOCK_BELL", Material.BELL, "LAUFBAU_ATTACHMENT_SINGLE_WALL", "LAUFBAU_FACING_NORTH"));
}
public void singleWallSouthBell() {
Bell bell = (Bell) Material.BELL.createBlockData();
bell.setAttachment(Bell.Attachment.SINGLE_WALL);
bell.setFacing(BlockFace.SOUTH);
List<Cuboid> cuboidList = new ArrayList<>();
cuboidList.add(pixelCuboid(4, 4, 4, 8, 2, 8));
cuboidList.add(pixelCuboid(5, 6, 5, 6, 8, 6));
cuboidList.add(pixelCuboid(7, 13, 3, 2, 2, 13));
new BlockBoundingBox(bell, cuboidList, createItem("LAUFBAU_BLOCK_BELL", Material.BELL, "LAUFBAU_ATTACHMENT_SINGLE_WALL", "LAUFBAU_FACING_SOUTH"));
}
public void singleWallEastBell() {
Bell bell = (Bell) Material.BELL.createBlockData();
bell.setAttachment(Bell.Attachment.SINGLE_WALL);
bell.setFacing(BlockFace.EAST);
List<Cuboid> cuboidList = new ArrayList<>();
cuboidList.add(pixelCuboid(4, 4, 4, 8, 2, 8));
cuboidList.add(pixelCuboid(5, 6, 5, 6, 8, 6));
cuboidList.add(pixelCuboid(3, 13, 7, 13, 2, 2));
new BlockBoundingBox(bell, cuboidList, createItem("LAUFBAU_BLOCK_BELL", Material.BELL, "LAUFBAU_ATTACHMENT_SINGLE_WALL", "LAUFBAU_FACING_EAST"));
}
public void singleWallWestBell() {
Bell bell = (Bell) Material.BELL.createBlockData();
bell.setAttachment(Bell.Attachment.SINGLE_WALL);
bell.setFacing(BlockFace.WEST);
List<Cuboid> cuboidList = new ArrayList<>();
cuboidList.add(pixelCuboid(4, 4, 4, 8, 2, 8));
cuboidList.add(pixelCuboid(5, 6, 5, 6, 8, 6));
cuboidList.add(pixelCuboid(0, 13, 7, 13, 2, 2));
new BlockBoundingBox(bell, cuboidList, createItem("LAUFBAU_BLOCK_BELL", Material.BELL, "LAUFBAU_ATTACHMENT_SINGLE_WALL", "LAUFBAU_FACING_WEST"));
}
}
@@ -1,46 +0,0 @@
/*
* This file is a part of the SteamWar software.
*
* Copyright (C) 2025 SteamWar.de-Serverteam
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package de.steamwar.bausystem.features.slaves.laufbau.boundingboxes;
import de.steamwar.bausystem.features.slaves.laufbau.BlockBoundingBox;
import de.steamwar.bausystem.features.slaves.laufbau.BoundingBoxLoader;
import de.steamwar.bausystem.features.slaves.laufbau.Cuboid;
import de.steamwar.linkage.Linked;
import org.bukkit.Material;
import org.bukkit.block.data.type.BrewingStand;
import java.util.ArrayList;
import java.util.List;
import static de.steamwar.bausystem.features.slaves.laufbau.LaufbauUtils.createItem;
import static de.steamwar.bausystem.features.slaves.laufbau.LaufbauUtils.pixelCuboid;
@Linked
public class BrewingStandBoundingBox implements BoundingBoxLoader {
@Override
public void load() {
BrewingStand brewingStand = (BrewingStand) Material.BREWING_STAND.createBlockData();
List<Cuboid> cuboids = new ArrayList<>();
cuboids.add(pixelCuboid(1, 0, 1, 14, 2, 14));
cuboids.add(pixelCuboid(7, 2, 7, 2, 12, 2));
new BlockBoundingBox(brewingStand, cuboids, createItem("LAUFBAU_BLOCK_BREWING_STAND", Material.BREWING_STAND));
}
}
@@ -1,62 +0,0 @@
/*
* This file is a part of the SteamWar software.
*
* Copyright (C) 2025 SteamWar.de-Serverteam
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package de.steamwar.bausystem.features.slaves.laufbau.boundingboxes;
import de.steamwar.bausystem.features.slaves.laufbau.BlockBoundingBox;
import de.steamwar.bausystem.features.slaves.laufbau.BoundingBoxLoader;
import de.steamwar.bausystem.features.slaves.laufbau.Cuboid;
import de.steamwar.linkage.Linked;
import org.bukkit.Material;
import org.bukkit.block.data.Lightable;
import org.bukkit.block.data.type.Candle;
import java.util.ArrayList;
import java.util.List;
import static de.steamwar.bausystem.features.slaves.laufbau.LaufbauUtils.createItem;
import static de.steamwar.bausystem.features.slaves.laufbau.LaufbauUtils.pixelCuboid;
@Linked
public class CandleBoundingBox implements BoundingBoxLoader {
@Override
public void load() {
caked();
single();
}
private void caked() {
Lightable candleCake = (Lightable) Material.CYAN_CANDLE_CAKE.createBlockData();
candleCake.setLit(true);
List<Cuboid> cuboidList = new ArrayList<>();
cuboidList.add(pixelCuboid(0, 0, 0, 16, 8, 16));
cuboidList.add(pixelCuboid(7, 8, 7, 2, 6, 2));
new BlockBoundingBox(candleCake, cuboidList, createItem("LAUFBAU_BLOCK_CANDLE_CAKE", Material.CAKE));
}
private void single() {
Candle candle = (Candle) Material.CYAN_CANDLE.createBlockData();
candle.setCandles(1);
List<Cuboid> cuboidList = new ArrayList<>();
cuboidList.add(pixelCuboid(7, 0, 7, 2, 6, 2));
new BlockBoundingBox(candle, cuboidList, createItem("LAUFBAU_BLOCK_CANDLE", Material.CYAN_CANDLE, "LAUFBAU_COUNT_1"));
}
}
@@ -1,69 +0,0 @@
/*
* This file is a part of the SteamWar software.
*
* Copyright (C) 2025 SteamWar.de-Serverteam
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package de.steamwar.bausystem.features.slaves.laufbau.boundingboxes;
import de.steamwar.bausystem.features.slaves.laufbau.BlockBoundingBox;
import de.steamwar.bausystem.features.slaves.laufbau.BoundingBoxLoader;
import de.steamwar.bausystem.features.slaves.laufbau.Cuboid;
import de.steamwar.linkage.Linked;
import org.bukkit.Axis;
import org.bukkit.Material;
import org.bukkit.block.data.Orientable;
import java.util.ArrayList;
import java.util.List;
import static de.steamwar.bausystem.features.slaves.laufbau.LaufbauUtils.createItem;
import static de.steamwar.bausystem.features.slaves.laufbau.LaufbauUtils.pixelCuboid;
@Linked
public class ChainBoundingBox implements BoundingBoxLoader {
@Override
public void load() {
bottomTopChain();
northSouthChain();
eastWestChain();
}
private void bottomTopChain() {
Orientable chainBottomTop = (Orientable) Material.CHAIN.createBlockData();
chainBottomTop.setAxis(Axis.Y);
List<Cuboid> cuboidList = new ArrayList<>();
cuboidList.add(pixelCuboid(6.5, 0, 6.5, 3, 16, 3));
new BlockBoundingBox(chainBottomTop, cuboidList, createItem("LAUFBAU_BLOCK_CHAIN", Material.CHAIN, "LAUFBAU_FACING_UP", "LAUFBAU_FACING_DOWN"));
}
private void northSouthChain() {
Orientable chainBottomTop = (Orientable) Material.CHAIN.createBlockData();
chainBottomTop.setAxis(Axis.Z);
List<Cuboid> cuboidList = new ArrayList<>();
cuboidList.add(pixelCuboid(6.5, 6.5, 0, 3, 3, 16));
new BlockBoundingBox(chainBottomTop, cuboidList, createItem("LAUFBAU_BLOCK_CHAIN", Material.CHAIN, "LAUFBAU_FACING_NORTH", "LAUFBAU_FACING_SOUTH"));
}
private void eastWestChain() {
Orientable chainBottomTop = (Orientable) Material.CHAIN.createBlockData();
chainBottomTop.setAxis(Axis.X);
List<Cuboid> cuboidList = new ArrayList<>();
cuboidList.add(pixelCuboid(0, 6.5, 6.5, 16, 3, 3));
new BlockBoundingBox(chainBottomTop, cuboidList, createItem("LAUFBAU_BLOCK_CHAIN", Material.CHAIN, "LAUFBAU_FACING_EAST", "LAUFBAU_FACING_WEST"));
}
}
@@ -1,89 +0,0 @@
/*
* This file is a part of the SteamWar software.
*
* Copyright (C) 2025 SteamWar.de-Serverteam
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package de.steamwar.bausystem.features.slaves.laufbau.boundingboxes;
import de.steamwar.bausystem.features.slaves.laufbau.BlockBoundingBox;
import de.steamwar.bausystem.features.slaves.laufbau.BoundingBoxLoader;
import de.steamwar.bausystem.features.slaves.laufbau.Cuboid;
import de.steamwar.linkage.Linked;
import org.bukkit.Material;
import org.bukkit.block.BlockFace;
import org.bukkit.block.data.MultipleFacing;
import java.util.ArrayList;
import java.util.List;
import static de.steamwar.bausystem.features.slaves.laufbau.LaufbauUtils.createItem;
import static de.steamwar.bausystem.features.slaves.laufbau.LaufbauUtils.pixelCuboid;
@Linked
public class ChorusPlantBoundingBox implements BoundingBoxLoader {
@Override
public void load() {
for (int nx = 0; nx < 2; nx++) {
for (int ny = 0; ny < 2; ny++) {
for (int nz = 0; nz < 2; nz++) {
for (int px = 0; px < 2; px++) {
for (int py = 0; py < 2; py++) {
for (int pz = 0; pz < 2; pz++) {
MultipleFacing chorusPlant = (MultipleFacing) Material.CHORUS_PLANT.createBlockData();
List<String> lore = new ArrayList<>();
List<Cuboid> cuboidList = new ArrayList<>();
cuboidList.add(pixelCuboid(3, 3, 3, 10, 10, 10));
if (nx == 1) {
lore.add("LAUFBAU_CONNECTION_WEST");
chorusPlant.setFace(BlockFace.WEST, true);
cuboidList.add(pixelCuboid(0, 3, 3, 3, 10, 10));
}
if (ny == 1) {
lore.add("LAUFBAU_CONNECTION_DOWN");
chorusPlant.setFace(BlockFace.DOWN, true);
cuboidList.add(pixelCuboid(3, 0, 3, 10, 3, 10));
}
if (nz == 1) {
lore.add("LAUFBAU_CONNECTION_NORTH");
chorusPlant.setFace(BlockFace.NORTH, true);
cuboidList.add(pixelCuboid(3, 3, 0, 10, 10, 3));
}
if (px == 1) {
lore.add("LAUFBAU_CONNECTION_EAST");
chorusPlant.setFace(BlockFace.EAST, true);
cuboidList.add(pixelCuboid(13, 3, 3, 3, 10, 10));
}
if (py == 1) {
lore.add("LAUFBAU_CONNECTION_UP");
chorusPlant.setFace(BlockFace.UP, true);
cuboidList.add(pixelCuboid(3, 13, 3, 10, 3, 10));
}
if (pz == 1) {
lore.add("LAUFBAU_CONNECTION_SOUTH");
chorusPlant.setFace(BlockFace.SOUTH, true);
cuboidList.add(pixelCuboid(3, 3, 13, 10, 10, 3));
}
new BlockBoundingBox(chorusPlant, cuboidList, createItem("LAUFBAU_BLOCK_CHORUS_PLANT", Material.CHORUS_PLANT, lore.toArray(new String[0])));
}
}
}
}
}
}
}
}
@@ -1,45 +0,0 @@
/*
* This file is a part of the SteamWar software.
*
* Copyright (C) 2025 SteamWar.de-Serverteam
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package de.steamwar.bausystem.features.slaves.laufbau.boundingboxes;
import de.steamwar.bausystem.features.slaves.laufbau.BlockBoundingBox;
import de.steamwar.bausystem.features.slaves.laufbau.BoundingBoxLoader;
import de.steamwar.bausystem.features.slaves.laufbau.Cuboid;
import de.steamwar.linkage.Linked;
import org.bukkit.Material;
import org.bukkit.block.data.BlockData;
import java.util.ArrayList;
import java.util.List;
import static de.steamwar.bausystem.features.slaves.laufbau.LaufbauUtils.createItem;
import static de.steamwar.bausystem.features.slaves.laufbau.LaufbauUtils.pixelCuboid;
@Linked
public class DragonEggBoundingBox implements BoundingBoxLoader {
@Override
public void load() {
BlockData blockData = Material.DRAGON_EGG.createBlockData();
List<Cuboid> cuboidList = new ArrayList<>();
cuboidList.add(pixelCuboid(1, 0, 1, 14, 16, 14));
new BlockBoundingBox(blockData, cuboidList, createItem("LAUFBAU_BLOCK_DRAGON_EGG", Material.DRAGON_EGG));
}
}
@@ -1,59 +0,0 @@
/*
* This file is a part of the SteamWar software.
*
* Copyright (C) 2025 SteamWar.de-Serverteam
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package de.steamwar.bausystem.features.slaves.laufbau.boundingboxes;
import de.steamwar.bausystem.features.slaves.laufbau.BlockBoundingBox;
import de.steamwar.bausystem.features.slaves.laufbau.BoundingBoxLoader;
import de.steamwar.bausystem.features.slaves.laufbau.Cuboid;
import de.steamwar.linkage.Linked;
import org.bukkit.Material;
import org.bukkit.block.data.type.BigDripleaf;
import java.util.ArrayList;
import java.util.List;
import static de.steamwar.bausystem.features.slaves.laufbau.LaufbauUtils.createItem;
import static de.steamwar.bausystem.features.slaves.laufbau.LaufbauUtils.pixelCuboid;
@Linked
public class DripLeafBoundingBox implements BoundingBoxLoader {
@Override
public void load() {
tiltNone();
tiltPartial();
}
private void tiltNone() {
BigDripleaf bigDripleaf = (BigDripleaf) Material.BIG_DRIPLEAF.createBlockData();
bigDripleaf.setTilt(BigDripleaf.Tilt.NONE);
List<Cuboid> cuboidList = new ArrayList<>();
cuboidList.add(pixelCuboid(0, 11, 0, 16, 4, 16));
new BlockBoundingBox(bigDripleaf, cuboidList, createItem("LAUFBAU_BLOCK_BIG_DRIP_LEAF", Material.BIG_DRIPLEAF, "LAUFBAU_TILT_NONE"));
}
private void tiltPartial() {
BigDripleaf bigDripleaf = (BigDripleaf) Material.BIG_DRIPLEAF.createBlockData();
bigDripleaf.setTilt(BigDripleaf.Tilt.PARTIAL);
List<Cuboid> cuboidList = new ArrayList<>();
cuboidList.add(pixelCuboid(0, 11, 0, 16, 2, 16));
new BlockBoundingBox(bigDripleaf, cuboidList, createItem("LAUFBAU_BLOCK_BIG_DRIP_LEAF", Material.BIG_DRIPLEAF, "LAUFBAU_TILT_PARTIAL"));
}
}
@@ -1,75 +0,0 @@
/*
* This file is a part of the SteamWar software.
*
* Copyright (C) 2025 SteamWar.de-Serverteam
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package de.steamwar.bausystem.features.slaves.laufbau.boundingboxes;
import de.steamwar.bausystem.features.slaves.laufbau.BlockBoundingBox;
import de.steamwar.bausystem.features.slaves.laufbau.BoundingBoxLoader;
import de.steamwar.bausystem.features.slaves.laufbau.Cuboid;
import de.steamwar.linkage.Linked;
import org.bukkit.Material;
import org.bukkit.block.BlockFace;
import org.bukkit.block.data.type.Fence;
import java.util.ArrayList;
import java.util.List;
import static de.steamwar.bausystem.features.slaves.laufbau.LaufbauUtils.createItem;
import static de.steamwar.bausystem.features.slaves.laufbau.LaufbauUtils.pixelCuboid;
@Linked
public class FencesBoundingBox implements BoundingBoxLoader {
@Override
public void load() {
for (int nx = 0; nx < 2; nx++) {
for (int nz = 0; nz < 2; nz++) {
for (int px = 0; px < 2; px++) {
for (int pz = 0; pz < 2; pz++) {
Fence fence = (Fence) Material.NETHER_BRICK_FENCE.createBlockData();
List<String> lore = new ArrayList<>();
List<Cuboid> cuboidList = new ArrayList<>();
cuboidList.add(pixelCuboid(6, 0, 6, 4, 24, 4));
if (nz == 1) {
lore.add("LAUFBAU_CONNECTION_NORTH");
fence.setFace(BlockFace.NORTH, true);
cuboidList.add(pixelCuboid(6, 0, 0, 4, 24, 6));
}
if (pz == 1) {
lore.add("LAUFBAU_CONNECTION_SOUTH");
fence.setFace(BlockFace.SOUTH, true);
cuboidList.add(pixelCuboid(6, 0, 10, 4, 24, 6));
}
if (nx == 1) {
lore.add("LAUFBAU_CONNECTION_WEST");
fence.setFace(BlockFace.WEST, true);
cuboidList.add(pixelCuboid(0, 0, 6, 6, 24, 4));
}
if (px == 1) {
lore.add("LAUFBAU_CONNECTION_EAST");
fence.setFace(BlockFace.EAST, true);
cuboidList.add(pixelCuboid(10, 0, 6, 6, 24, 4));
}
new BlockBoundingBox(fence, cuboidList, createItem("LAUFBAU_BLOCK_NETHER_BRICK_FENCE", Material.NETHER_BRICK_FENCE, lore.toArray(new String[0])));
}
}
}
}
}
}
@@ -1,157 +0,0 @@
/*
* This file is a part of the SteamWar software.
*
* Copyright (C) 2025 SteamWar.de-Serverteam
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package de.steamwar.bausystem.features.slaves.laufbau.boundingboxes;
import de.steamwar.bausystem.features.slaves.laufbau.BlockBoundingBox;
import de.steamwar.bausystem.features.slaves.laufbau.BoundingBoxLoader;
import de.steamwar.bausystem.features.slaves.laufbau.Cuboid;
import de.steamwar.linkage.Linked;
import org.bukkit.Material;
import org.bukkit.block.BlockFace;
import org.bukkit.block.data.FaceAttachable;
import org.bukkit.block.data.type.Grindstone;
import java.util.ArrayList;
import java.util.List;
import static de.steamwar.bausystem.features.slaves.laufbau.LaufbauUtils.createItem;
import static de.steamwar.bausystem.features.slaves.laufbau.LaufbauUtils.pixelCuboid;
@Linked
public class GrindstoneBoundingBox implements BoundingBoxLoader {
@Override
public void load() {
floorNorthGrindstone();
floorEastGrindstone();
ceilingNorthGrindstone();
ceilingEastGrindstone();
wallNorthGrindstone();
wallSouthGrindstone();
wallEastGrindstone();
wallWestGrindstone();
}
public void floorNorthGrindstone() {
Grindstone grindstone = (Grindstone) Material.GRINDSTONE.createBlockData();
grindstone.setAttachedFace(FaceAttachable.AttachedFace.FLOOR);
grindstone.setFacing(BlockFace.NORTH);
List<Cuboid> cuboidList = new ArrayList<>();
cuboidList.add(pixelCuboid(4, 4, 2, 8, 12, 12));
cuboidList.add(pixelCuboid(2, 0, 6, 2, 7, 4));
cuboidList.add(pixelCuboid(12, 0, 6, 2, 7, 4));
cuboidList.add(pixelCuboid(2, 7, 5, 2, 6, 6));
cuboidList.add(pixelCuboid(12, 7, 5, 2, 6, 6));
new BlockBoundingBox(grindstone, cuboidList, createItem("LAUFBAU_BLOCK_GRINDSTONE", Material.GRINDSTONE, "LAUFBAU_ATTACHMENT_FLOOR", "LAUFBAU_FACING_NORTH", "LAUFBAU_FACING_SOUTH"));
}
public void floorEastGrindstone() {
Grindstone grindstone = (Grindstone) Material.GRINDSTONE.createBlockData();
grindstone.setAttachedFace(FaceAttachable.AttachedFace.FLOOR);
grindstone.setFacing(BlockFace.EAST);
List<Cuboid> cuboidList = new ArrayList<>();
cuboidList.add(pixelCuboid(2, 4, 4, 12, 12, 8));
cuboidList.add(pixelCuboid(6, 0, 2, 4, 7, 2));
cuboidList.add(pixelCuboid(6, 0, 12, 4, 7, 2));
cuboidList.add(pixelCuboid(5, 7, 2, 6, 6, 2));
cuboidList.add(pixelCuboid(5, 7, 12, 6, 6, 2));
new BlockBoundingBox(grindstone, cuboidList, createItem("LAUFBAU_BLOCK_GRINDSTONE", Material.GRINDSTONE, "LAUFBAU_ATTACHMENT_FLOOR", "LAUFBAU_FACING_EAST", "LAUFBAU_FACING_WEST"));
}
public void ceilingNorthGrindstone() {
Grindstone grindstone = (Grindstone) Material.GRINDSTONE.createBlockData();
grindstone.setAttachedFace(FaceAttachable.AttachedFace.CEILING);
grindstone.setFacing(BlockFace.NORTH);
List<Cuboid> cuboidList = new ArrayList<>();
cuboidList.add(pixelCuboid(4, 0, 2, 8, 12, 12));
cuboidList.add(pixelCuboid(2, 9, 6, 2, 7, 4));
cuboidList.add(pixelCuboid(12, 9, 6, 2, 7, 4));
cuboidList.add(pixelCuboid(2, 3, 5, 2, 6, 6));
cuboidList.add(pixelCuboid(12, 3, 5, 2, 6, 6));
new BlockBoundingBox(grindstone, cuboidList, createItem("LAUFBAU_BLOCK_GRINDSTONE", Material.GRINDSTONE, "LAUFBAU_ATTACHMENT_CEILING", "LAUFBAU_FACING_NORTH", "LAUFBAU_FACING_SOUTH"));
}
public void ceilingEastGrindstone() {
Grindstone grindstone = (Grindstone) Material.GRINDSTONE.createBlockData();
grindstone.setAttachedFace(FaceAttachable.AttachedFace.CEILING);
grindstone.setFacing(BlockFace.EAST);
List<Cuboid> cuboidList = new ArrayList<>();
cuboidList.add(pixelCuboid(2, 0, 4, 12, 12, 8));
cuboidList.add(pixelCuboid(6, 9, 2, 4, 7, 2));
cuboidList.add(pixelCuboid(6, 9, 12, 4, 7, 2));
cuboidList.add(pixelCuboid(5, 3, 2, 6, 6, 2));
cuboidList.add(pixelCuboid(5, 3, 12, 6, 6, 2));
new BlockBoundingBox(grindstone, cuboidList, createItem("LAUFBAU_BLOCK_GRINDSTONE", Material.GRINDSTONE, "LAUFBAU_ATTACHMENT_CEILING", "LAUFBAU_FACING_EAST", "LAUFBAU_FACING_WEST"));
}
public void wallNorthGrindstone() {
Grindstone grindstone = (Grindstone) Material.GRINDSTONE.createBlockData();
grindstone.setAttachedFace(FaceAttachable.AttachedFace.WALL);
grindstone.setFacing(BlockFace.NORTH);
List<Cuboid> cuboidList = new ArrayList<>();
cuboidList.add(pixelCuboid(4, 2, 0, 8, 12, 12));
cuboidList.add(pixelCuboid(2, 6, 9, 2, 4, 7));
cuboidList.add(pixelCuboid(12, 6, 9, 2, 4, 7));
cuboidList.add(pixelCuboid(2, 5, 3, 2, 6, 6));
cuboidList.add(pixelCuboid(12, 5, 3, 2, 6, 6));
new BlockBoundingBox(grindstone, cuboidList, createItem("LAUFBAU_BLOCK_GRINDSTONE", Material.GRINDSTONE, "LAUFBAU_ATTACHMENT_WALL", "LAUFBAU_FACING_NORTH"));
}
public void wallSouthGrindstone() {
Grindstone grindstone = (Grindstone) Material.GRINDSTONE.createBlockData();
grindstone.setAttachedFace(FaceAttachable.AttachedFace.WALL);
grindstone.setFacing(BlockFace.SOUTH);
List<Cuboid> cuboidList = new ArrayList<>();
cuboidList.add(pixelCuboid(4, 2, 4, 8, 12, 12));
cuboidList.add(pixelCuboid(2, 6, 0, 2, 4, 7));
cuboidList.add(pixelCuboid(12, 6, 0, 2, 4, 7));
cuboidList.add(pixelCuboid(2, 5, 7, 2, 6, 6));
cuboidList.add(pixelCuboid(12, 5, 7, 2, 6, 6));
new BlockBoundingBox(grindstone, cuboidList, createItem("LAUFBAU_BLOCK_GRINDSTONE", Material.GRINDSTONE, "LAUFBAU_ATTACHMENT_WALL", "LAUFBAU_FACING_SOUTH"));
}
public void wallEastGrindstone() {
Grindstone grindstone = (Grindstone) Material.GRINDSTONE.createBlockData();
grindstone.setAttachedFace(FaceAttachable.AttachedFace.WALL);
grindstone.setFacing(BlockFace.EAST);
List<Cuboid> cuboidList = new ArrayList<>();
cuboidList.add(pixelCuboid(4, 2, 4, 12, 12, 8));
cuboidList.add(pixelCuboid(0, 6, 2, 7, 4, 2));
cuboidList.add(pixelCuboid(0, 6, 12, 7, 4, 2));
cuboidList.add(pixelCuboid(7, 5, 2, 6, 6, 2));
cuboidList.add(pixelCuboid(7, 5, 12, 6, 6, 2));
new BlockBoundingBox(grindstone, cuboidList, createItem("LAUFBAU_BLOCK_GRINDSTONE", Material.GRINDSTONE, "LAUFBAU_ATTACHMENT_WALL", "LAUFBAU_FACING_EAST"));
}
public void wallWestGrindstone() {
Grindstone grindstone = (Grindstone) Material.GRINDSTONE.createBlockData();
grindstone.setAttachedFace(FaceAttachable.AttachedFace.WALL);
grindstone.setFacing(BlockFace.WEST);
List<Cuboid> cuboidList = new ArrayList<>();
cuboidList.add(pixelCuboid(0, 2, 4, 12, 12, 8));
cuboidList.add(pixelCuboid(9, 6, 2, 7, 4, 2));
cuboidList.add(pixelCuboid(9, 6, 12, 7, 4, 2));
cuboidList.add(pixelCuboid(3, 5, 2, 6, 6, 2));
cuboidList.add(pixelCuboid(3, 5, 12, 6, 6, 2));
new BlockBoundingBox(grindstone, cuboidList, createItem("LAUFBAU_BLOCK_GRINDSTONE", Material.GRINDSTONE, "LAUFBAU_ATTACHMENT_WALL", "LAUFBAU_FACING_WEST"));
}
}
@@ -1,97 +0,0 @@
/*
* This file is a part of the SteamWar software.
*
* Copyright (C) 2025 SteamWar.de-Serverteam
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package de.steamwar.bausystem.features.slaves.laufbau.boundingboxes;
import de.steamwar.bausystem.features.slaves.laufbau.BlockBoundingBox;
import de.steamwar.bausystem.features.slaves.laufbau.BoundingBoxLoader;
import de.steamwar.bausystem.features.slaves.laufbau.Cuboid;
import de.steamwar.linkage.Linked;
import org.bukkit.Material;
import org.bukkit.block.BlockFace;
import org.bukkit.block.data.type.Hopper;
import java.util.ArrayList;
import java.util.List;
import static de.steamwar.bausystem.features.slaves.laufbau.LaufbauUtils.createItem;
import static de.steamwar.bausystem.features.slaves.laufbau.LaufbauUtils.pixelCuboid;
@Linked
public class HopperBoundingBox implements BoundingBoxLoader {
@Override
public void load() {
downHopper();
northHopper();
southHopper();
eastHopper();
westHopper();
}
public void downHopper() {
Hopper hopper = (Hopper) Material.HOPPER.createBlockData();
hopper.setFacing(BlockFace.DOWN);
List<Cuboid> cuboidList = new ArrayList<>();
cuboidList.add(pixelCuboid(0, 10, 0, 16, 6, 16));
cuboidList.add(pixelCuboid(4, 4, 4, 8, 6, 8));
cuboidList.add(pixelCuboid(6, 0, 6, 4, 4, 4));
new BlockBoundingBox(hopper, cuboidList, createItem("LAUFBAU_BLOCK_HOPPER", Material.HOPPER, "LAUFBAU_CONNECTION_FLOOR"));
}
public void northHopper() {
Hopper hopper = (Hopper) Material.HOPPER.createBlockData();
hopper.setFacing(BlockFace.NORTH);
List<Cuboid> cuboidList = new ArrayList<>();
cuboidList.add(pixelCuboid(0, 10, 0, 16, 6, 16));
cuboidList.add(pixelCuboid(4, 4, 4, 8, 6, 8));
cuboidList.add(pixelCuboid(6, 4, 0, 4, 4, 4));
new BlockBoundingBox(hopper, cuboidList, createItem("LAUFBAU_BLOCK_HOPPER", Material.HOPPER, "LAUFBAU_CONNECTION_NORTH"));
}
public void southHopper() {
Hopper hopper = (Hopper) Material.HOPPER.createBlockData();
hopper.setFacing(BlockFace.SOUTH);
List<Cuboid> cuboidList = new ArrayList<>();
cuboidList.add(pixelCuboid(0, 10, 0, 16, 6, 16));
cuboidList.add(pixelCuboid(4, 4, 4, 8, 6, 8));
cuboidList.add(pixelCuboid(6, 4, 12, 4, 4, 4));
new BlockBoundingBox(hopper, cuboidList, createItem("LAUFBAU_BLOCK_HOPPER", Material.HOPPER, "LAUFBAU_CONNECTION_SOUTH"));
}
public void eastHopper() {
Hopper hopper = (Hopper) Material.HOPPER.createBlockData();
hopper.setFacing(BlockFace.EAST);
List<Cuboid> cuboidList = new ArrayList<>();
cuboidList.add(pixelCuboid(0, 10, 0, 16, 6, 16));
cuboidList.add(pixelCuboid(4, 4, 4, 8, 6, 8));
cuboidList.add(pixelCuboid(12, 4, 6, 4, 4, 4));
new BlockBoundingBox(hopper, cuboidList, createItem("LAUFBAU_BLOCK_HOPPER", Material.HOPPER, "LAUFBAU_CONNECTION_EAST"));
}
public void westHopper() {
Hopper hopper = (Hopper) Material.HOPPER.createBlockData();
hopper.setFacing(BlockFace.WEST);
List<Cuboid> cuboidList = new ArrayList<>();
cuboidList.add(pixelCuboid(0, 10, 0, 16, 6, 16));
cuboidList.add(pixelCuboid(4, 4, 4, 8, 6, 8));
cuboidList.add(pixelCuboid(0, 4, 6, 4, 4, 4));
new BlockBoundingBox(hopper, cuboidList, createItem("LAUFBAU_BLOCK_HOPPER", Material.HOPPER, "LAUFBAU_CONNECTION_WEST"));
}
}
@@ -1,75 +0,0 @@
/*
* This file is a part of the SteamWar software.
*
* Copyright (C) 2025 SteamWar.de-Serverteam
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package de.steamwar.bausystem.features.slaves.laufbau.boundingboxes;
import de.steamwar.bausystem.features.slaves.laufbau.BlockBoundingBox;
import de.steamwar.bausystem.features.slaves.laufbau.BoundingBoxLoader;
import de.steamwar.bausystem.features.slaves.laufbau.Cuboid;
import de.steamwar.linkage.Linked;
import org.bukkit.Material;
import org.bukkit.block.BlockFace;
import org.bukkit.block.data.type.Fence;
import java.util.ArrayList;
import java.util.List;
import static de.steamwar.bausystem.features.slaves.laufbau.LaufbauUtils.createItem;
import static de.steamwar.bausystem.features.slaves.laufbau.LaufbauUtils.pixelCuboid;
@Linked
public class IronBarBoundingBox implements BoundingBoxLoader {
@Override
public void load() {
for (int nx = 0; nx < 2; nx++) {
for (int nz = 0; nz < 2; nz++) {
for (int px = 0; px < 2; px++) {
for (int pz = 0; pz < 2; pz++) {
Fence fence = (Fence) Material.IRON_BARS.createBlockData();
List<String> lore = new ArrayList<>();
List<Cuboid> cuboidList = new ArrayList<>();
cuboidList.add(pixelCuboid(7, 0, 7, 2, 16, 2));
if (nz == 1) {
lore.add("LAUFBAU_CONNECTION_NORTH");
fence.setFace(BlockFace.NORTH, true);
cuboidList.add(pixelCuboid(7, 0, 0, 2, 16, 7));
}
if (pz == 1) {
lore.add("LAUFBAU_CONNECTION_SOUTH");
fence.setFace(BlockFace.SOUTH, true);
cuboidList.add(pixelCuboid(7, 0, 9, 2, 16, 7));
}
if (nx == 1) {
lore.add("LAUFBAU_CONNECTION_WEST");
fence.setFace(BlockFace.WEST, true);
cuboidList.add(pixelCuboid(0, 0, 7, 7, 16, 2));
}
if (px == 1) {
lore.add("LAUFBAU_CONNECTION_EAST");
fence.setFace(BlockFace.EAST, true);
cuboidList.add(pixelCuboid(9, 0, 7, 7, 16, 2));
}
new BlockBoundingBox(fence, cuboidList, createItem("LAUFBAU_BLOCK_IRON_BARS", Material.IRON_BARS, lore.toArray(new String[0])));
}
}
}
}
}
}
@@ -1,61 +0,0 @@
/*
* This file is a part of the SteamWar software.
*
* Copyright (C) 2025 SteamWar.de-Serverteam
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package de.steamwar.bausystem.features.slaves.laufbau.boundingboxes;
import de.steamwar.bausystem.features.slaves.laufbau.BlockBoundingBox;
import de.steamwar.bausystem.features.slaves.laufbau.BoundingBoxLoader;
import de.steamwar.bausystem.features.slaves.laufbau.Cuboid;
import de.steamwar.linkage.Linked;
import org.bukkit.Material;
import org.bukkit.block.data.type.Lantern;
import java.util.ArrayList;
import java.util.List;
import static de.steamwar.bausystem.features.slaves.laufbau.LaufbauUtils.createItem;
import static de.steamwar.bausystem.features.slaves.laufbau.LaufbauUtils.pixelCuboid;
@Linked
public class LanternBoundingBox implements BoundingBoxLoader {
@Override
public void load() {
lantern();
hangingLantern();
}
public void lantern() {
Lantern lantern = (Lantern) Material.LANTERN.createBlockData();
lantern.setHanging(false);
List<Cuboid> cuboidList = new ArrayList<>();
cuboidList.add(pixelCuboid(5, 0, 5, 6, 7, 6));
cuboidList.add(pixelCuboid(6, 7, 6, 4, 2, 4));
new BlockBoundingBox(lantern, cuboidList, createItem("LAUFBAU_BLOCK_LANTERN", Material.LANTERN));
}
public void hangingLantern() {
Lantern lantern = (Lantern) Material.LANTERN.createBlockData();
lantern.setHanging(true);
List<Cuboid> cuboidList = new ArrayList<>();
cuboidList.add(pixelCuboid(5, 1, 5, 6, 7, 6));
cuboidList.add(pixelCuboid(6, 8, 6, 4, 2, 4));
new BlockBoundingBox(lantern, cuboidList, createItem("LAUFBAU_BLOCK_LANTERN", Material.LANTERN, "LAUFBAU_HANGING"));
}
}
@@ -1,46 +0,0 @@
/*
* This file is a part of the SteamWar software.
*
* Copyright (C) 2025 SteamWar.de-Serverteam
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package de.steamwar.bausystem.features.slaves.laufbau.boundingboxes;
import de.steamwar.bausystem.features.slaves.laufbau.BlockBoundingBox;
import de.steamwar.bausystem.features.slaves.laufbau.BoundingBoxLoader;
import de.steamwar.bausystem.features.slaves.laufbau.Cuboid;
import de.steamwar.linkage.Linked;
import org.bukkit.Material;
import org.bukkit.block.data.BlockData;
import java.util.ArrayList;
import java.util.List;
import static de.steamwar.bausystem.features.slaves.laufbau.LaufbauUtils.createItem;
import static de.steamwar.bausystem.features.slaves.laufbau.LaufbauUtils.pixelCuboid;
@Linked
public class LecternBoundingBox implements BoundingBoxLoader {
@Override
public void load() {
BlockData blockData = Material.LECTERN.createBlockData();
List<Cuboid> cuboidList = new ArrayList<>();
cuboidList.add(pixelCuboid(0, 0, 0, 16, 2, 16));
cuboidList.add(pixelCuboid(4, 2, 4, 8, 12, 8));
new BlockBoundingBox(blockData, cuboidList, createItem("LAUFBAU_BLOCK_LECTERN", Material.LECTERN));
}
}
@@ -1,343 +0,0 @@
/*
* This file is a part of the SteamWar software.
*
* Copyright (C) 2025 SteamWar.de-Serverteam
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package de.steamwar.bausystem.features.slaves.laufbau.boundingboxes;
import de.steamwar.bausystem.features.slaves.laufbau.BlockBoundingBox;
import de.steamwar.bausystem.features.slaves.laufbau.BoundingBoxLoader;
import de.steamwar.bausystem.features.slaves.laufbau.Cuboid;
import de.steamwar.linkage.Linked;
import org.bukkit.Material;
import org.bukkit.block.BlockFace;
import org.bukkit.block.data.type.Stairs;
import java.util.ArrayList;
import java.util.List;
import static de.steamwar.bausystem.features.slaves.laufbau.LaufbauUtils.createItem;
import static de.steamwar.bausystem.features.slaves.laufbau.LaufbauUtils.pixelCuboid;
@Linked
public class StairBoundingBox implements BoundingBoxLoader {
@Override
public void load() {
straightBottomNorthStair();
straightBottomSouthStair();
straightBottomEastStair();
straightBottomWestStair();
straightTopNorthStair();
straightTopSouthStair();
straightTopEastStair();
straightTopWestStair();
outerLeftBottomNorthStair();
outerLeftBottomSouthStair();
outerLeftBottomEastStair();
outerLeftBottomWestStair();
outerLeftTopNorthStair();
outerLeftTopSouthStair();
outerLeftTopEastStair();
outerLeftTopWestStair();
innerLeftBottomNorthStair();
innerLeftBottomSouthStair();
innerLeftBottomEastStair();
innerLeftBottomWestStair();
innerLeftTopNorthStair();
innerLeftTopSouthStair();
innerLeftTopEastStair();
innerLeftTopWestStair();
}
public void straightBottomNorthStair() {
Stairs stairs = (Stairs) Material.END_STONE_BRICK_STAIRS.createBlockData();
stairs.setShape(Stairs.Shape.STRAIGHT);
stairs.setHalf(Stairs.Half.BOTTOM);
stairs.setFacing(BlockFace.NORTH);
List<Cuboid> cuboidList = new ArrayList<>();
cuboidList.add(pixelCuboid(0, 0, 0, 16, 8, 16));
cuboidList.add(pixelCuboid(0, 8, 0, 16, 8, 8));
new BlockBoundingBox(stairs, cuboidList, createItem("LAUFBAU_BLOCK_END_STONE_BRICK_STAIRS", Material.END_STONE_BRICK_STAIRS, "LAUFBAU_SHAPE_STRAIGHT", "LAUFBAU_HALF_BOTTOM", "LAUFBAU_FACING_NORTH"));
}
public void straightBottomSouthStair() {
Stairs stairs = (Stairs) Material.END_STONE_BRICK_STAIRS.createBlockData();
stairs.setShape(Stairs.Shape.STRAIGHT);
stairs.setHalf(Stairs.Half.BOTTOM);
stairs.setFacing(BlockFace.SOUTH);
List<Cuboid> cuboidList = new ArrayList<>();
cuboidList.add(pixelCuboid(0, 0, 0, 16, 8, 16));
cuboidList.add(pixelCuboid(0, 8, 8, 16, 8, 8));
new BlockBoundingBox(stairs, cuboidList, createItem("LAUFBAU_BLOCK_END_STONE_BRICK_STAIRS", Material.END_STONE_BRICK_STAIRS, "LAUFBAU_SHAPE_STRAIGHT", "LAUFBAU_HALF_BOTTOM", "LAUFBAU_FACING_SOUTH"));
}
public void straightBottomEastStair() {
Stairs stairs = (Stairs) Material.END_STONE_BRICK_STAIRS.createBlockData();
stairs.setShape(Stairs.Shape.STRAIGHT);
stairs.setHalf(Stairs.Half.BOTTOM);
stairs.setFacing(BlockFace.EAST);
List<Cuboid> cuboidList = new ArrayList<>();
cuboidList.add(pixelCuboid(0, 0, 0, 16, 8, 16));
cuboidList.add(pixelCuboid(8, 8, 0, 8, 8, 16));
new BlockBoundingBox(stairs, cuboidList, createItem("LAUFBAU_BLOCK_END_STONE_BRICK_STAIRS", Material.END_STONE_BRICK_STAIRS, "LAUFBAU_SHAPE_STRAIGHT", "LAUFBAU_HALF_BOTTOM", "LAUFBAU_FACING_EAST"));
}
public void straightBottomWestStair() {
Stairs stairs = (Stairs) Material.END_STONE_BRICK_STAIRS.createBlockData();
stairs.setShape(Stairs.Shape.STRAIGHT);
stairs.setHalf(Stairs.Half.BOTTOM);
stairs.setFacing(BlockFace.WEST);
List<Cuboid> cuboidList = new ArrayList<>();
cuboidList.add(pixelCuboid(0, 0, 0, 16, 8, 16));
cuboidList.add(pixelCuboid(0, 8, 0, 8, 8, 16));
new BlockBoundingBox(stairs, cuboidList, createItem("LAUFBAU_BLOCK_END_STONE_BRICK_STAIRS", Material.END_STONE_BRICK_STAIRS, "LAUFBAU_SHAPE_STRAIGHT", "LAUFBAU_HALF_BOTTOM", "LAUFBAU_FACING_WEST"));
}
public void straightTopNorthStair() {
Stairs stairs = (Stairs) Material.END_STONE_BRICK_STAIRS.createBlockData();
stairs.setShape(Stairs.Shape.STRAIGHT);
stairs.setHalf(Stairs.Half.TOP);
stairs.setFacing(BlockFace.NORTH);
List<Cuboid> cuboidList = new ArrayList<>();
cuboidList.add(pixelCuboid(0, 8, 0, 16, 8, 16));
cuboidList.add(pixelCuboid(0, 0, 0, 16, 8, 8));
new BlockBoundingBox(stairs, cuboidList, createItem("LAUFBAU_BLOCK_END_STONE_BRICK_STAIRS", Material.END_STONE_BRICK_STAIRS, "LAUFBAU_SHAPE_STRAIGHT", "LAUFBAU_HALF_TOP", "LAUFBAU_FACING_NORTH"));
}
public void straightTopSouthStair() {
Stairs stairs = (Stairs) Material.END_STONE_BRICK_STAIRS.createBlockData();
stairs.setShape(Stairs.Shape.STRAIGHT);
stairs.setHalf(Stairs.Half.TOP);
stairs.setFacing(BlockFace.SOUTH);
List<Cuboid> cuboidList = new ArrayList<>();
cuboidList.add(pixelCuboid(0, 8, 0, 16, 8, 16));
cuboidList.add(pixelCuboid(0, 0, 8, 16, 8, 8));
new BlockBoundingBox(stairs, cuboidList, createItem("LAUFBAU_BLOCK_END_STONE_BRICK_STAIRS", Material.END_STONE_BRICK_STAIRS, "LAUFBAU_SHAPE_STRAIGHT", "LAUFBAU_HALF_TOP", "LAUFBAU_FACING_SOUTH"));
}
public void straightTopEastStair() {
Stairs stairs = (Stairs) Material.END_STONE_BRICK_STAIRS.createBlockData();
stairs.setShape(Stairs.Shape.STRAIGHT);
stairs.setHalf(Stairs.Half.TOP);
stairs.setFacing(BlockFace.EAST);
List<Cuboid> cuboidList = new ArrayList<>();
cuboidList.add(pixelCuboid(0, 8, 0, 16, 8, 16));
cuboidList.add(pixelCuboid(8, 0, 0, 8, 8, 16));
new BlockBoundingBox(stairs, cuboidList, createItem("LAUFBAU_BLOCK_END_STONE_BRICK_STAIRS", Material.END_STONE_BRICK_STAIRS, "LAUFBAU_SHAPE_STRAIGHT", "LAUFBAU_HALF_TOP", "LAUFBAU_FACING_EAST"));
}
public void straightTopWestStair() {
Stairs stairs = (Stairs) Material.END_STONE_BRICK_STAIRS.createBlockData();
stairs.setShape(Stairs.Shape.STRAIGHT);
stairs.setHalf(Stairs.Half.TOP);
stairs.setFacing(BlockFace.WEST);
List<Cuboid> cuboidList = new ArrayList<>();
cuboidList.add(pixelCuboid(0, 8, 0, 16, 8, 16));
cuboidList.add(pixelCuboid(0, 0, 0, 8, 8, 16));
new BlockBoundingBox(stairs, cuboidList, createItem("LAUFBAU_BLOCK_END_STONE_BRICK_STAIRS", Material.END_STONE_BRICK_STAIRS, "LAUFBAU_SHAPE_STRAIGHT", "LAUFBAU_HALF_TOP", "LAUFBAU_FACING_WEST"));
}
public void outerLeftBottomNorthStair() {
Stairs stairs = (Stairs) Material.END_STONE_BRICK_STAIRS.createBlockData();
stairs.setShape(Stairs.Shape.OUTER_LEFT);
stairs.setHalf(Stairs.Half.BOTTOM);
stairs.setFacing(BlockFace.NORTH);
List<Cuboid> cuboidList = new ArrayList<>();
cuboidList.add(pixelCuboid(0, 0, 0, 16, 8, 16));
cuboidList.add(pixelCuboid(0, 8, 0, 8, 8, 8));
new BlockBoundingBox(stairs, cuboidList, createItem("LAUFBAU_BLOCK_END_STONE_BRICK_STAIRS", Material.END_STONE_BRICK_STAIRS, "LAUFBAU_SHAPE_OUTER_LEFT", "LAUFBAU_HALF_BOTTOM", "LAUFBAU_FACING_NORTH"));
}
public void outerLeftBottomSouthStair() {
Stairs stairs = (Stairs) Material.END_STONE_BRICK_STAIRS.createBlockData();
stairs.setShape(Stairs.Shape.OUTER_LEFT);
stairs.setHalf(Stairs.Half.BOTTOM);
stairs.setFacing(BlockFace.SOUTH);
List<Cuboid> cuboidList = new ArrayList<>();
cuboidList.add(pixelCuboid(0, 0, 0, 16, 8, 16));
cuboidList.add(pixelCuboid(8, 8, 8, 8, 8, 8));
new BlockBoundingBox(stairs, cuboidList, createItem("LAUFBAU_BLOCK_END_STONE_BRICK_STAIRS", Material.END_STONE_BRICK_STAIRS, "LAUFBAU_SHAPE_OUTER_LEFT", "LAUFBAU_HALF_BOTTOM", "LAUFBAU_FACING_SOUTH"));
}
public void outerLeftBottomEastStair() {
Stairs stairs = (Stairs) Material.END_STONE_BRICK_STAIRS.createBlockData();
stairs.setShape(Stairs.Shape.OUTER_LEFT);
stairs.setHalf(Stairs.Half.BOTTOM);
stairs.setFacing(BlockFace.EAST);
List<Cuboid> cuboidList = new ArrayList<>();
cuboidList.add(pixelCuboid(0, 0, 0, 16, 8, 16));
cuboidList.add(pixelCuboid(8, 8, 0, 8, 8, 8));
new BlockBoundingBox(stairs, cuboidList, createItem("LAUFBAU_BLOCK_END_STONE_BRICK_STAIRS", Material.END_STONE_BRICK_STAIRS, "LAUFBAU_SHAPE_OUTER_LEFT", "LAUFBAU_HALF_BOTTOM", "LAUFBAU_FACING_EAST"));
}
public void outerLeftBottomWestStair() {
Stairs stairs = (Stairs) Material.END_STONE_BRICK_STAIRS.createBlockData();
stairs.setShape(Stairs.Shape.OUTER_LEFT);
stairs.setHalf(Stairs.Half.BOTTOM);
stairs.setFacing(BlockFace.WEST);
List<Cuboid> cuboidList = new ArrayList<>();
cuboidList.add(pixelCuboid(0, 0, 0, 16, 8, 16));
cuboidList.add(pixelCuboid(0, 8, 8, 8, 8, 8));
new BlockBoundingBox(stairs, cuboidList, createItem("LAUFBAU_BLOCK_END_STONE_BRICK_STAIRS", Material.END_STONE_BRICK_STAIRS, "LAUFBAU_SHAPE_OUTER_LEFT", "LAUFBAU_HALF_BOTTOM", "LAUFBAU_FACING_WEST"));
}
public void outerLeftTopNorthStair() {
Stairs stairs = (Stairs) Material.END_STONE_BRICK_STAIRS.createBlockData();
stairs.setShape(Stairs.Shape.OUTER_LEFT);
stairs.setHalf(Stairs.Half.TOP);
stairs.setFacing(BlockFace.NORTH);
List<Cuboid> cuboidList = new ArrayList<>();
cuboidList.add(pixelCuboid(0, 8, 0, 16, 8, 16));
cuboidList.add(pixelCuboid(0, 0, 0, 8, 8, 8));
new BlockBoundingBox(stairs, cuboidList, createItem("LAUFBAU_BLOCK_END_STONE_BRICK_STAIRS", Material.END_STONE_BRICK_STAIRS, "LAUFBAU_SHAPE_OUTER_LEFT", "LAUFBAU_HALF_TOP", "LAUFBAU_FACING_NORTH"));
}
public void outerLeftTopSouthStair() {
Stairs stairs = (Stairs) Material.END_STONE_BRICK_STAIRS.createBlockData();
stairs.setShape(Stairs.Shape.OUTER_LEFT);
stairs.setHalf(Stairs.Half.TOP);
stairs.setFacing(BlockFace.SOUTH);
List<Cuboid> cuboidList = new ArrayList<>();
cuboidList.add(pixelCuboid(0, 8, 0, 16, 8, 16));
cuboidList.add(pixelCuboid(8, 0, 8, 8, 8, 8));
new BlockBoundingBox(stairs, cuboidList, createItem("LAUFBAU_BLOCK_END_STONE_BRICK_STAIRS", Material.END_STONE_BRICK_STAIRS, "LAUFBAU_SHAPE_OUTER_LEFT", "LAUFBAU_HALF_TOP", "LAUFBAU_FACING_SOUTH"));
}
public void outerLeftTopEastStair() {
Stairs stairs = (Stairs) Material.END_STONE_BRICK_STAIRS.createBlockData();
stairs.setShape(Stairs.Shape.OUTER_LEFT);
stairs.setHalf(Stairs.Half.TOP);
stairs.setFacing(BlockFace.EAST);
List<Cuboid> cuboidList = new ArrayList<>();
cuboidList.add(pixelCuboid(0, 8, 0, 16, 8, 16));
cuboidList.add(pixelCuboid(8, 0, 0, 8, 8, 8));
new BlockBoundingBox(stairs, cuboidList, createItem("LAUFBAU_BLOCK_END_STONE_BRICK_STAIRS", Material.END_STONE_BRICK_STAIRS, "LAUFBAU_SHAPE_OUTER_LEFT", "LAUFBAU_HALF_TOP", "LAUFBAU_FACING_EAST"));
}
public void outerLeftTopWestStair() {
Stairs stairs = (Stairs) Material.END_STONE_BRICK_STAIRS.createBlockData();
stairs.setShape(Stairs.Shape.OUTER_LEFT);
stairs.setHalf(Stairs.Half.TOP);
stairs.setFacing(BlockFace.WEST);
List<Cuboid> cuboidList = new ArrayList<>();
cuboidList.add(pixelCuboid(0, 8, 0, 16, 8, 16));
cuboidList.add(pixelCuboid(0, 0, 8, 8, 8, 8));
new BlockBoundingBox(stairs, cuboidList, createItem("LAUFBAU_BLOCK_END_STONE_BRICK_STAIRS", Material.END_STONE_BRICK_STAIRS, "LAUFBAU_SHAPE_OUTER_LEFT", "LAUFBAU_HALF_TOP", "LAUFBAU_FACING_WEST"));
}
public void innerLeftBottomNorthStair() {
Stairs stairs = (Stairs) Material.END_STONE_BRICK_STAIRS.createBlockData();
stairs.setShape(Stairs.Shape.INNER_LEFT);
stairs.setHalf(Stairs.Half.BOTTOM);
stairs.setFacing(BlockFace.NORTH);
List<Cuboid> cuboidList = new ArrayList<>();
cuboidList.add(pixelCuboid(0, 0, 0, 16, 8, 16));
cuboidList.add(pixelCuboid(0, 8, 0, 16, 8, 8));
cuboidList.add(pixelCuboid(0, 8, 8, 8, 8, 8));
new BlockBoundingBox(stairs, cuboidList, createItem("LAUFBAU_BLOCK_END_STONE_BRICK_STAIRS", Material.END_STONE_BRICK_STAIRS, "LAUFBAU_SHAPE_INNER_LEFT", "LAUFBAU_HALF_BOTTOM", "LAUFBAU_FACING_NORTH"));
}
public void innerLeftBottomSouthStair() {
Stairs stairs = (Stairs) Material.END_STONE_BRICK_STAIRS.createBlockData();
stairs.setShape(Stairs.Shape.INNER_LEFT);
stairs.setHalf(Stairs.Half.BOTTOM);
stairs.setFacing(BlockFace.SOUTH);
List<Cuboid> cuboidList = new ArrayList<>();
cuboidList.add(pixelCuboid(0, 0, 0, 16, 8, 16));
cuboidList.add(pixelCuboid(0, 8, 8, 16, 8, 8));
cuboidList.add(pixelCuboid(8, 8, 0, 8, 8, 8));
new BlockBoundingBox(stairs, cuboidList, createItem("LAUFBAU_BLOCK_END_STONE_BRICK_STAIRS", Material.END_STONE_BRICK_STAIRS, "LAUFBAU_SHAPE_INNER_LEFT", "LAUFBAU_HALF_BOTTOM", "LAUFBAU_FACING_SOUTH"));
}
public void innerLeftBottomEastStair() {
Stairs stairs = (Stairs) Material.END_STONE_BRICK_STAIRS.createBlockData();
stairs.setShape(Stairs.Shape.INNER_LEFT);
stairs.setHalf(Stairs.Half.BOTTOM);
stairs.setFacing(BlockFace.EAST);
List<Cuboid> cuboidList = new ArrayList<>();
cuboidList.add(pixelCuboid(0, 0, 0, 16, 8, 16));
cuboidList.add(pixelCuboid(0, 8, 0, 16, 8, 8));
cuboidList.add(pixelCuboid(8, 8, 8, 8, 8, 8));
new BlockBoundingBox(stairs, cuboidList, createItem("LAUFBAU_BLOCK_END_STONE_BRICK_STAIRS", Material.END_STONE_BRICK_STAIRS, "LAUFBAU_SHAPE_INNER_LEFT", "LAUFBAU_HALF_BOTTOM", "LAUFBAU_FACING_EAST"));
}
public void innerLeftBottomWestStair() {
Stairs stairs = (Stairs) Material.END_STONE_BRICK_STAIRS.createBlockData();
stairs.setShape(Stairs.Shape.INNER_LEFT);
stairs.setHalf(Stairs.Half.BOTTOM);
stairs.setFacing(BlockFace.WEST);
List<Cuboid> cuboidList = new ArrayList<>();
cuboidList.add(pixelCuboid(0, 0, 0, 16, 8, 16));
cuboidList.add(pixelCuboid(0, 8, 8, 16, 8, 8));
cuboidList.add(pixelCuboid(0, 8, 0, 8, 8, 8));
new BlockBoundingBox(stairs, cuboidList, createItem("LAUFBAU_BLOCK_END_STONE_BRICK_STAIRS", Material.END_STONE_BRICK_STAIRS, "LAUFBAU_SHAPE_INNER_LEFT", "LAUFBAU_HALF_BOTTOM", "LAUFBAU_FACING_WEST"));
}
public void innerLeftTopNorthStair() {
Stairs stairs = (Stairs) Material.END_STONE_BRICK_STAIRS.createBlockData();
stairs.setShape(Stairs.Shape.INNER_LEFT);
stairs.setHalf(Stairs.Half.TOP);
stairs.setFacing(BlockFace.NORTH);
List<Cuboid> cuboidList = new ArrayList<>();
cuboidList.add(pixelCuboid(0, 8, 0, 16, 8, 16));
cuboidList.add(pixelCuboid(0, 0, 0, 16, 8, 8));
cuboidList.add(pixelCuboid(0, 0, 8, 8, 8, 8));
new BlockBoundingBox(stairs, cuboidList, createItem("LAUFBAU_BLOCK_END_STONE_BRICK_STAIRS", Material.END_STONE_BRICK_STAIRS, "LAUFBAU_SHAPE_INNER_LEFT", "LAUFBAU_HALF_TOP", "LAUFBAU_FACING_NORTH"));
}
public void innerLeftTopSouthStair() {
Stairs stairs = (Stairs) Material.END_STONE_BRICK_STAIRS.createBlockData();
stairs.setShape(Stairs.Shape.INNER_LEFT);
stairs.setHalf(Stairs.Half.TOP);
stairs.setFacing(BlockFace.SOUTH);
List<Cuboid> cuboidList = new ArrayList<>();
cuboidList.add(pixelCuboid(0, 8, 0, 16, 8, 16));
cuboidList.add(pixelCuboid(0, 0, 8, 16, 8, 8));
cuboidList.add(pixelCuboid(8, 0, 0, 8, 8, 8));
new BlockBoundingBox(stairs, cuboidList, createItem("LAUFBAU_BLOCK_END_STONE_BRICK_STAIRS", Material.END_STONE_BRICK_STAIRS, "LAUFBAU_SHAPE_INNER_LEFT", "LAUFBAU_HALF_TOP", "LAUFBAU_FACING_SOUTH"));
}
public void innerLeftTopEastStair() {
Stairs stairs = (Stairs) Material.END_STONE_BRICK_STAIRS.createBlockData();
stairs.setShape(Stairs.Shape.INNER_LEFT);
stairs.setHalf(Stairs.Half.TOP);
stairs.setFacing(BlockFace.EAST);
List<Cuboid> cuboidList = new ArrayList<>();
cuboidList.add(pixelCuboid(0, 8, 0, 16, 8, 16));
cuboidList.add(pixelCuboid(0, 0, 0, 16, 8, 8));
cuboidList.add(pixelCuboid(8, 0, 8, 8, 8, 8));
new BlockBoundingBox(stairs, cuboidList, createItem("LAUFBAU_BLOCK_END_STONE_BRICK_STAIRS", Material.END_STONE_BRICK_STAIRS, "LAUFBAU_SHAPE_INNER_LEFT", "LAUFBAU_HALF_TOP", "LAUFBAU_FACING_EAST"));
}
public void innerLeftTopWestStair() {
Stairs stairs = (Stairs) Material.END_STONE_BRICK_STAIRS.createBlockData();
stairs.setShape(Stairs.Shape.INNER_LEFT);
stairs.setHalf(Stairs.Half.TOP);
stairs.setFacing(BlockFace.WEST);
List<Cuboid> cuboidList = new ArrayList<>();
cuboidList.add(pixelCuboid(0, 8, 0, 16, 8, 16));
cuboidList.add(pixelCuboid(0, 0, 8, 16, 8, 8));
cuboidList.add(pixelCuboid(0, 0, 0, 8, 8, 8));
new BlockBoundingBox(stairs, cuboidList, createItem("LAUFBAU_BLOCK_END_STONE_BRICK_STAIRS", Material.END_STONE_BRICK_STAIRS, "LAUFBAU_SHAPE_INNER_LEFT", "LAUFBAU_HALF_TOP", "LAUFBAU_FACING_WEST"));
}
}
@@ -1,79 +0,0 @@
/*
* This file is a part of the SteamWar software.
*
* Copyright (C) 2025 SteamWar.de-Serverteam
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package de.steamwar.bausystem.features.slaves.laufbau.boundingboxes;
import de.steamwar.bausystem.features.slaves.laufbau.BlockBoundingBox;
import de.steamwar.bausystem.features.slaves.laufbau.BoundingBoxLoader;
import de.steamwar.bausystem.features.slaves.laufbau.Cuboid;
import de.steamwar.linkage.Linked;
import org.bukkit.Material;
import org.bukkit.block.BlockFace;
import org.bukkit.block.data.type.Wall;
import java.util.ArrayList;
import java.util.List;
import static de.steamwar.bausystem.features.slaves.laufbau.LaufbauUtils.createItem;
import static de.steamwar.bausystem.features.slaves.laufbau.LaufbauUtils.pixelCuboid;
@Linked
public class WallBoundingBox implements BoundingBoxLoader {
@Override
public void load() {
v18();
}
private void v18() {
for (int nx = 0; nx < 2; nx++) {
for (int nz = 0; nz < 2; nz++) {
for (int px = 0; px < 2; px++) {
for (int pz = 0; pz < 2; pz++) {
Wall fence = (Wall) Material.END_STONE_BRICK_WALL.createBlockData();
List<String> lore = new ArrayList<>();
List<Cuboid> cuboidList = new ArrayList<>();
cuboidList.add(pixelCuboid(4, 0, 4, 8, 24, 8));
if (nz == 1) {
lore.add("LAUFBAU_CONNECTION_NORTH");
fence.setHeight(BlockFace.NORTH, Wall.Height.LOW);
cuboidList.add(pixelCuboid(5, 0, 0, 6, 24, 4));
}
if (pz == 1) {
lore.add("LAUFBAU_CONNECTION_SOUTH");
fence.setHeight(BlockFace.SOUTH, Wall.Height.LOW);
cuboidList.add(pixelCuboid(5, 0, 12, 6, 24, 4));
}
if (nx == 1) {
lore.add("LAUFBAU_CONNECTION_WEST");
fence.setHeight(BlockFace.WEST, Wall.Height.LOW);
cuboidList.add(pixelCuboid(0, 0, 5, 4, 24, 6));
}
if (px == 1) {
lore.add("LAUFBAU_CONNECTION_EAST");
fence.setHeight(BlockFace.EAST, Wall.Height.LOW);
cuboidList.add(pixelCuboid(12, 0, 5, 4, 24, 6));
}
new BlockBoundingBox(fence, cuboidList, createItem("LAUFBAU_BLOCK_END_STONE_BRICK_WALL", Material.END_STONE_BRICK_WALL, lore.toArray(new String[0])));
}
}
}
}
}
}
@@ -165,7 +165,6 @@ public class TPSSystem implements Listener {
}
@Register(value = "default", description = "TPSLIMIT_DEFAULT_HELP")
@Register(value = "rate")
public void reset(@Validator Player player) {
TickManager.impl.setTickRate(20.0F);
sendTickRateChange();
@@ -188,18 +187,15 @@ public class TPSSystem implements Listener {
}
@Register(value = {"rate", "0"}, description = "TICK_FREEZE_HELP")
public void rate(@Validator Player player) {
@Register(value = "freeze", description = "TICK_FREEZE_HELP_2")
public void freeze(@Validator Player player) {
TickManager.impl.setFreeze(true);
sendTickRateChange();
}
@Register(value = "freeze", description = "TICK_FREEZE_HELP_2")
public void freezeToggle(@Validator Player player) {
if (TickManager.impl.isFrozen()) {
TickManager.impl.setTickRate(20.0F);
} else {
TickManager.impl.setFreeze(true);
}
@Register(value = "unfreeze", description = "TICK_UNFREEZE_HELP")
public void unfreeze(@Validator Player player) {
TickManager.impl.setTickRate(20.0F);
sendTickRateChange();
}
}
@@ -153,11 +153,7 @@ public class TraceCommand extends SWCommand {
@Register(value = "isolate", description = "TRACE_COMMAND_HELP_ISOLATE")
public void isolate(@Validator Player player, Trace trace, @ErrorMessage("TRACE_RECORD_ID_INVALID") TNTPoint... records) {
if (records.length == 0) {
TraceManager.instance.isolate(player, trace, trace.getRecords().toArray(TNTPoint[]::new));
} else {
TraceManager.instance.isolate(player, trace, records);
}
TraceManager.instance.isolate(player, records);
BauSystem.MESSAGE.send("TRACE_MESSAGE_ISOLATE", player);
}
@@ -347,10 +347,9 @@ public class TraceManager implements Listener {
* Toggles the isolated render for the given records and player
*
* @param player the player the trace is shown to
* @param ptrace the trace for whitch isolation is toggled
* @param records the records of the trace for which isolation is toggled
* @param records the record for which isolation is toggled
*/
public void isolate(Player player, Trace ptrace, TNTPoint... records) {
public void isolate(Player player, TNTPoint... records) {
unfollow(player);
Region region = Region.getRegion(player.getLocation());
@@ -375,20 +374,12 @@ public class TraceManager implements Listener {
isolateFlag.toggleId(record.getTntId());
}
if (isolateFlag.isEmpty() && playerTraceShowData.hasViewFlagOnly(IsolateFlag.class) && records.length != 0) {
playerTraceShowData.removeViewFlag(IsolateFlag.class);
}
PlayerTraceShowData finalPlayerTraceShowData = playerTraceShowData;
tracesByRegion.getOrDefault(region, Collections.emptyMap()).forEach((integer, trace) -> {
if (trace.getUuid() == ptrace.getUuid() || finalPlayerTraceShowData.hasNoViewFlags()) {
trace.render(player, finalPlayerTraceShowData);
followerMap.getOrDefault(player, Collections.emptySet()).forEach(follower -> {
trace.render(follower, finalPlayerTraceShowData);
});
} else {
trace.hide(player);
}
trace.render(player, finalPlayerTraceShowData);
followerMap.getOrDefault(player, Collections.emptySet()).forEach(follower -> {
trace.render(follower, finalPlayerTraceShowData);
});
});
}
@@ -135,13 +135,6 @@ public class TraceRecorder implements Listener {
Iterator<TNTPrimed> iter = trackedTNT.getOrDefault(region, Collections.emptyList()).iterator();
while (iter.hasNext()) {
TNTPrimed tnt = iter.next();
if (tnt.isDead()) {
iter.remove();
tntSpawnRegion.remove(tnt);
historyMap.remove(tnt);
tntSpawnRegion.remove(tnt);
continue;
}
if (tnt.getFuseTicks() == 80) continue;
TNTPoint record = record(tnt, wrappedTrace, Collections.emptyList());
if (record == null) {
@@ -95,8 +95,4 @@ public class PlayerTraceShowData {
public void addViewFlag(ViewFlag viewFlag) {
viewFlags.put(viewFlag.getClass(), viewFlag);
}
public <T extends ViewFlag> void removeViewFlag(Class<T> clazz) {
viewFlags.remove(clazz);
}
}
@@ -48,9 +48,9 @@ import static de.steamwar.bausystem.features.util.TNTClickListener.TNT_CLICK_DET
*/
public class TraceEntity extends RBlockDisplay {
public static final float TNT_VISUAL_SCALE = 0.98F;
public static final float TNT_VISUAL_OFFSET = -TNT_VISUAL_SCALE / 2.0F;
public static final Transformation TNT_VISUAL_TRANSFORM = new Transformation(
private static final float TNT_VISUAL_SCALE = 0.98F;
private static final float TNT_VISUAL_OFFSET = -TNT_VISUAL_SCALE / 2.0F;
private static final Transformation TNT_VISUAL_TRANSFORM = new Transformation(
new Vector3f(TNT_VISUAL_OFFSET, 0.0F, TNT_VISUAL_OFFSET),
new Quaternionf(0, 0, 0, 1),
new Vector3f(TNT_VISUAL_SCALE, TNT_VISUAL_SCALE, TNT_VISUAL_SCALE),
@@ -131,7 +131,6 @@ public abstract class ViewFlag {
if (yLocation.distanceSquared(representative.getLocation()) >= 1.0 / 256.0 && yLocation.distanceSquared(previous.getLocation()) >= 1.0 / 256.0) {
RBlockDisplay y = new RBlockDisplay(server, yLocation);
y.setBlock(Material.WHITE_STAINED_GLASS.createBlockData());
y.setTransform(TraceEntity.TNT_VISUAL_TRANSFORM);
}
Location secoundLocation;
@@ -144,7 +143,6 @@ public abstract class ViewFlag {
if (secoundLocation.distanceSquared(representative.getLocation()) >= 1.0 / 256.0 && secoundLocation.distanceSquared(previous.getLocation()) >= 1.0 / 256.0) {
RBlockDisplay second = new RBlockDisplay(server, secoundLocation);
second.setBlock(Material.WHITE_STAINED_GLASS.createBlockData());
second.setTransform(TraceEntity.TNT_VISUAL_TRANSFORM);
}
}
}
@@ -51,10 +51,6 @@ public class IsolateFlag extends ViewFlag {
}
}
public boolean isEmpty() {
return tntToIsolate.isEmpty();
}
@Override
public Stream<TNTPoint> filter(Stream<TNTPoint> records) {
if (tntToIsolate.isEmpty()) return records;
@@ -139,7 +139,6 @@ public class NoClipCommand extends SWCommand implements Listener {
@EventHandler(ignoreCancelled = true)
public void onBlock(BlockCanBuildEvent event) {
if (event.getPlayer() == null) return;
if (SWPlayer.of(event.getPlayer()).hasComponent(NoClipData.class)) {
event.setBuildable(true);
}
@@ -1,41 +0,0 @@
/*
* This file is a part of the SteamWar software.
*
* Copyright (C) 2026 SteamWar.de-Serverteam
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package de.steamwar.bausystem.features.world;
import de.steamwar.linkage.Linked;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.Listener;
import org.bukkit.event.player.PlayerJoinEvent;
import org.bukkit.scoreboard.Scoreboard;
import org.bukkit.scoreboard.Team;
@Linked
public class AntiPlayerCollision implements Listener {
@EventHandler(priority = EventPriority.MONITOR)
public void onPlayerJoin(PlayerJoinEvent event) {
Scoreboard board = event.getPlayer().getScoreboard();
Team team = board.getTeam("players");
if (team == null) team = board.registerNewTeam("players");
team.setOption(Team.Option.COLLISION_RULE, Team.OptionStatus.NEVER);
team.addPlayer(event.getPlayer());
}
}
@@ -57,7 +57,7 @@ public class WorldEditListener implements Listener {
private static final Set<String> commands = new HashSet<>();
private static final Set<String> commandExclusions = new HashSet<>();
private static final String[] shortcutCommands = {"//1", "//2", "//90", "//-90", "//180", "//p", "//c", "//flopy", "//floppy", "//flopyp", "//floppyp", "//u", "//r", "//download", "/download"};
private static final String[] shortcutCommands = {"//1", "//2", "//90", "//-90", "//180", "//p", "//c", "//flopy", "//floppy", "//flopyp", "//floppyp", "//u", "//r"};
public static boolean isWorldEditCommand(String command) {
for (String shortcut : shortcutCommands) {
-1
View File
@@ -18,7 +18,6 @@ dependencies {
implementation("com.github.ajalt.clikt:clikt:5.0.3")
implementation("com.github.ajalt.mordant:mordant:3.0.2")
implementation(libs.logback)
implementation("org.yaml:snakeyaml:2.2")
implementation("org.mariadb.jdbc:mariadb-java-client:3.3.1")
implementation(libs.exposedCore)
+5 -18
View File
@@ -7,7 +7,6 @@ import com.github.ajalt.mordant.rendering.TextColors
import com.github.ajalt.mordant.rendering.TextStyles
import de.steamwar.db.Database
import de.steamwar.db.execute
import de.steamwar.db.executeScript
import de.steamwar.db.useDb
import java.io.File
@@ -23,25 +22,13 @@ class ResetCommand : CliktCommand() {
val schema = schemaFile.readText()
execute("SET FOREIGN_KEY_CHECKS=0;") { }
val databaseObjects = execute("SHOW FULL TABLES;") { it.getString(1) to it.getString(2) }
for (view in databaseObjects.filter { it.second == "VIEW" }.map { it.first }) {
execute("DROP VIEW IF EXISTS `${view.replace("`", "``")}`;") { }
}
for (table in databaseObjects.filter { it.second == "BASE TABLE" }.map { it.first }) {
execute("DROP TABLE IF EXISTS `${table.replace("`", "``")}`;") { }
val tables = execute("SHOW TABLES;") { it.getString(1) }
for (table in tables) {
execute("DROP TABLE IF EXISTS $table;") { }
}
executeScript(schema)
val seed = javaClass.getResource("/db/reset-seed.sql")
?: throw CliktError("Reset seed file not found!")
executeScript(seed.readText())
execute("SET FOREIGN_KEY_CHECKS=1;") { }
execute(schema) { }
echo(TextColors.brightGreen(TextStyles.bold("Database reset!")))
}
}
}
+14 -90
View File
@@ -14,11 +14,9 @@ import com.github.ajalt.clikt.parameters.types.file
import com.github.ajalt.clikt.parameters.types.long
import com.github.ajalt.clikt.parameters.types.path
import com.sun.security.auth.module.UnixSystem
import org.yaml.snakeyaml.Yaml
import java.io.File
import kotlin.io.path.absolute
import kotlin.io.path.absolutePathString
import kotlin.random.Random
const val LOG4J_CONFIG = """<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="WARN" packages="com.mojang.util">
@@ -71,47 +69,35 @@ class DevCommand : CliktCommand("dev") {
override fun run() {
val args = mutableListOf<String>()
var serverDir = resolveServerDirectory(server)
val serverDirectory = File(workingDir, server)
val serverDir =
if (serverDirectory.exists() && serverDirectory.isDirectory) serverDirectory else File(workingDir, server)
if (isVelocity(server)) {
runServer(
args, jvmArgs, listOf(
jar?.absolutePath
?: File("/jars/Velocity.jar").absolutePath
?: File("/jar/Velocity.jar").absolutePath
), serverDir
)
} else {
setLogConfig(args)
val version = findVersion(server)
?: throw CliktError("Unknown Server Version")
val gameModeTemplate = if (serverDir.isDirectory) null else loadGameModeTemplate(server)
if (gameModeTemplate != null) {
serverDir = gameModeTemplate.serverDir
args += "-Dconfig=$server.yml"
}
val worldFile = world?.absolute()?.toFile()
?: File(workingDir, "devtempworld")
var jarFile = jar?.absolutePath
?: File(serverDir, "devtempworld")
val jarFile = jar?.absolutePath
?: additionalVersions[server]?.let { supportedVersionJars[it] }
?: supportedVersionJars[version]
?: throw CliktError("Unknown Server Version")
if (gameModeTemplate != null) {
jarFile = if (gameModeTemplate.spigot) {
jarFile.replace("paper", "spigot")
} else {
jarFile.replace("spigot", "paper")
}
}
if (!worldFile.exists()) {
val templateFile = gameModeTemplate?.worldTemplate ?: File(serverDir, "Bauwelt")
val templateFile = File(serverDir, "Bauwelt")
if (!templateFile.exists()) {
throw CliktError("Could not find world template: ${templateFile.absolutePath}")
throw CliktError("World Template not found!")
}
worldFile.parentFile?.mkdirs()
templateFile.copyRecursively(worldFile)
}
val worldDir = worldFile.parentFile ?: workingDir
val devFile = File("/configs/DevServer/${System.getProperty("user.name")}.$port.$version")
if (System.getProperty("user.name") != "minecraft") {
@@ -122,11 +108,10 @@ class DevCommand : CliktCommand("dev") {
args, jvmArgs, listOf(
jarFile,
*(if (forceUpgrade) arrayOf("-forceUpgrade") else arrayOf()),
"--log-strip-color",
"--port", port.toString(),
"--level-name", worldFile.name,
"--world-dir", worldDir.absolutePath,
"nogui",
"--world-dir", workingDir.absolutePath,
"--nogui",
*(if (plugins != null) arrayOf("--plugins", plugins!!.absolutePathString()) else arrayOf())
), serverDir
)
@@ -138,12 +123,6 @@ class DevCommand : CliktCommand("dev") {
}
}
data class GameModeTemplate(
val serverDir: File,
val worldTemplate: File,
val spigot: Boolean
)
val jvmDefaultParams = arrayOf(
"-Xmx1G",
"-Xgc:excessiveGCratio=80",
@@ -159,16 +138,6 @@ class DevCommand : CliktCommand("dev") {
val jvmArgOverrides = arrayOf("--add-opens", "java.base/jdk.internal.misc=ALL-UNNAMED")
val jvmNonJava8Params = arrayOf(
*jvmArgOverrides,
"-XX:-CRIUSecProvider"
)
val extendedStartupParams = arrayOf(
"-Dpaper.disablePluginRemapping=true",
"-javaagent:/jars/AccessWidener.jar=start"
)
val supportedVersionJars = mapOf(
8 to "/jars/paper-1.8.8.jar",
9 to "/jars/spigot-1.9.4.jar",
@@ -196,41 +165,6 @@ class DevCommand : CliktCommand("dev") {
fun isVelocity(server: String): Boolean =
server.endsWith("Velocity")
fun resolveServerDirectory(server: String): File {
val localServer = File(workingDir, server)
if (localServer.isDirectory) {
return localServer
}
return File("/servers", server)
}
fun loadGameModeTemplate(server: String): GameModeTemplate? {
val configFile = File("/configs/GameModes/$server.yml")
if (!configFile.exists()) {
throw CliktError("Server/GameMode not found")
}
val document = configFile.reader().use { reader ->
Yaml().load<Map<String, Any?>>(reader)
} ?: throw CliktError("GameMode config is empty: ${configFile.absolutePath}")
val serverConfig = document["Server"] as? Map<*, *>
?: throw CliktError("GameMode config is missing Server section: ${configFile.absolutePath}")
val folder = serverConfig["Folder"] as? String
?: throw CliktError("GameMode config is missing Server.Folder: ${configFile.absolutePath}")
val maps = (serverConfig["Maps"] as? List<*>)
?.filterIsInstance<String>()
?.takeIf { it.isNotEmpty() }
?: throw CliktError("GameMode config is missing Server.Maps: ${configFile.absolutePath}")
val serverDir = File("/servers", folder)
val worldTemplate = File(File(serverDir, "arenas"), maps[Random.nextInt(maps.size)])
return GameModeTemplate(
serverDir = serverDir,
worldTemplate = worldTemplate,
spigot = serverConfig["Spigot"] == true
)
}
fun setLogConfig(args: MutableList<String>) {
args += "-DlogPath=${workingDir.absolutePath}/logs"
args += "-Dlog4j.configurationFile=${log4jConfig.absolutePath}"
@@ -241,23 +175,13 @@ class DevCommand : CliktCommand("dev") {
}
fun runServer(args: List<String>, jvmArgs: List<String>, cmd: List<String>, serverDir: File) {
val effectiveJvmArgs = mutableListOf<String>()
effectiveJvmArgs += jvmArgs
if (!isVelocity(server)) {
extendedStartupParams.forEach { arg ->
if (effectiveJvmArgs.none { it == arg }) {
effectiveJvmArgs += arg
}
}
}
val process = ProcessBuilder(
jvm?.absolutePath
?: if (isJava8(server)) "/usr/lib/jvm/openj9-8/bin/java" else "/usr/lib/jvm/openj9-21/bin/java",
*effectiveJvmArgs.toTypedArray(),
?: if (isJava8(server)) "/usr/lib/jvm/openj9-8/bin/java" else "java",
*jvmArgs.toTypedArray(),
*args.toTypedArray(),
*jvmDefaultParams,
*(if (isJava8(server)) arrayOf() else jvmNonJava8Params),
*(if (isJava8(server)) arrayOf() else jvmArgOverrides),
*(if (profile) arrayOf("-javaagent:/jars/LixfelsProfiler.jar=start") else arrayOf()),
"-Xshareclasses:nonfatal,name=$server",
"-jar",
@@ -266,4 +190,4 @@ class DevCommand : CliktCommand("dev") {
Runtime.getRuntime().addShutdownHook(Thread { if (process.isAlive) process.destroyForcibly() })
process.waitFor()
}
}
}
+9 -120
View File
@@ -16,14 +16,15 @@ import java.sql.ResultSet
import java.util.*
object Database {
val host: String
val port: String
val database: String
val username: String
val password: String
lateinit var host: String
lateinit var port: String
lateinit var database: String
lateinit var db: Database
init {
fun ensureConnected() {
if (::db.isInitialized) {
return
}
val config = File(System.getProperty("user.home"), "mysql.properties")
if (!config.exists()) {
@@ -37,14 +38,9 @@ object Database {
host = props.getProperty("host")
port = props.getProperty("port")
database = props.getProperty("database")
username = props.getProperty("user")
password = props.getProperty("password")
}
fun ensureConnected() {
if (::db.isInitialized) {
return
}
val username = props.getProperty("user")
val password = props.getProperty("password")
val url = "jdbc:mariadb://$host:$port/$database"
@@ -83,113 +79,6 @@ fun <T> JdbcTransaction.executeSingle(sql: String, transform: (ResultSet) -> T):
}.single()
}
fun JdbcTransaction.executeScript(sql: String) {
for (statement in splitSqlScript(sql)) {
exec(statement) { }
}
}
private fun splitSqlScript(sql: String): List<String> {
val statements = mutableListOf<String>()
val current = StringBuilder()
var quote: Char? = null
var inLineComment = false
var inBlockComment = false
var index = 0
fun addStatement() {
val statement = current.toString().trim()
if (statement.isNotEmpty()) {
statements += statement
}
current.clear()
}
while (index < sql.length) {
val char = sql[index]
val next = sql.getOrNull(index + 1)
if (inLineComment) {
current.append(char)
if (char == '\n') {
inLineComment = false
}
index++
continue
}
if (inBlockComment) {
current.append(char)
if (char == '*' && next == '/') {
current.append(next)
inBlockComment = false
index += 2
} else {
index++
}
continue
}
if (quote != null) {
current.append(char)
if (char == '\\' && quote != '`' && next != null) {
current.append(next)
index += 2
continue
}
if (char == quote) {
if (next == quote) {
current.append(next)
index += 2
continue
}
quote = null
}
index++
continue
}
when {
char == '-' && next == '-' -> {
current.append(char).append(next)
inLineComment = true
index += 2
}
char == '#' -> {
current.append(char)
inLineComment = true
index++
}
char == '/' && next == '*' -> {
current.append(char).append(next)
inBlockComment = true
index += 2
}
char == '\'' || char == '"' || char == '`' -> {
current.append(char)
quote = char
index++
}
char == ';' -> {
addStatement()
index++
}
else -> {
current.append(char)
index++
}
}
}
addStatement()
return statements
}
fun useDb(statement: JdbcTransaction.() -> Unit) {
de.steamwar.db.Database.ensureConnected()
transaction(de.steamwar.db.Database.db, statement = statement)
File diff suppressed because one or more lines are too long
-5
View File
@@ -19,7 +19,6 @@
plugins {
steamwar.kotlin
kotlin("plugin.lombok")
}
kotlin {
@@ -41,8 +40,4 @@ dependencies {
compileOnlyApi(libs.exposedDao)
compileOnlyApi(libs.exposedJdbc)
compileOnlyApi(libs.exposedTime)
testImplementation(kotlin("test"))
}
repositories {
mavenCentral()
}
@@ -86,24 +86,6 @@ class CheckedSchematic(id: EntityID<CompositeID>) : CompositeEntity(id) {
useDb {
find { (CheckedSchematicTable.nodeOwner eq owner.id) and (CheckedSchematicTable.seen eq false) }.orderBy(CheckedSchematicTable.endTime to SortOrder.DESC).toList()
}
@JvmStatic
fun countAccepted(owner: SteamwarUser) =
useDb {
find { (CheckedSchematicTable.nodeOwner eq owner.id) and (CheckedSchematicTable.declineReason eq "freigegeben") }.count()
}
@JvmStatic
fun countAccepted(owner: SteamwarUser, type: String) =
useDb {
find { (CheckedSchematicTable.nodeOwner eq owner.id) and (CheckedSchematicTable.declineReason eq "freigegeben") and (CheckedSchematicTable.nodeType like "$type%") }.count()
}
@JvmStatic
fun countChecked(validator: SteamwarUser) =
useDb {
find { CheckedSchematicTable.validator eq validator.id }.count()
}
}
val node by CheckedSchematicTable.nodeId.transform({ it?.let { EntityID(it, SchematicNodeTable) } }, { it?.value })
@@ -130,43 +130,6 @@ class EventFight(id: EntityID<Int>) : IntEntity(id), Comparable<EventFight> {
}
)
}
@JvmStatic
fun countEventFights(fighter: SteamwarUser) =
useDb {
exec(
"SELECT COUNT(DISTINCT F.FightID) AS FightCount FROM FightPlayer INNER JOIN Fight F on FightPlayer.FightID = F.FightID INNER JOIN EventFight EF on F.FightID = EF.Fight WHERE UserID = ?",
args = listOf(IntegerColumnType() to fighter.id.value)
) {
if (it.next()) {
it.getLong("FightCount")
} else {
0
}
}
?: 0
}
@JvmStatic
fun countPlacement(fighter: SteamwarUser, placement: Int) =
useDb {
exec(
"""
SELECT COUNT(DISTINCT EventFight.EventID) AS PlacementCount FROM TeamTeilnahme
INNER JOIN EventFight ON EventFight.EventID = TeamTeilnahme.EventID
INNER JOIN FightPlayer ON FightPlayer.FightID = EventFight.Fight
WHERE (IF(FightPlayer.Team = 1, EventFight.TeamBlue, EventFight.TeamRed)) = TeamTeilnahme.TeamID AND UserID = ? AND Placement = ?
""".trimIndent(),
args = listOf(IntegerColumnType() to fighter.id.value, IntegerColumnType() to placement)
) {
if (it.next()) {
it.getInt("PlacementCount")
} else {
0
}
}
?: 0
}
}
val fightID by EventFightTable.id.transform({ EntityID(it, EventFightTable) }, { it.value })
@@ -237,7 +200,6 @@ class EventFight(id: EntityID<Int>) : IntEntity(id), Comparable<EventFight> {
override fun delete() =
useDb {
EventRelation.deleteRelations(this@EventFight)
super.delete()
}
}
}
@@ -159,13 +159,10 @@ class EventGroup(id: EntityID<Int>) : IntEntity(id) {
}
override fun delete() =
useDb {
EventRelation.deleteRelations(this@EventGroup)
super.delete()
}
useDb { super.delete() }
enum class EventGroupType {
GROUP_STAGE,
ELIMINATION_STAGE
}
}
}
@@ -24,10 +24,8 @@ import org.jetbrains.exposed.v1.core.and
import org.jetbrains.exposed.v1.core.dao.id.EntityID
import org.jetbrains.exposed.v1.core.dao.id.IntIdTable
import org.jetbrains.exposed.v1.core.eq
import org.jetbrains.exposed.v1.core.or
import org.jetbrains.exposed.v1.dao.IntEntity
import org.jetbrains.exposed.v1.dao.IntEntityClass
import org.jetbrains.exposed.v1.jdbc.deleteWhere
import org.jetbrains.exposed.v1.jdbc.select
object EventRelationTable : IntIdTable("EventRelation") {
@@ -61,23 +59,6 @@ class EventRelation(id: EntityID<Int>) : IntEntity(id) {
fun getGroupRelations(group: EventGroup) =
useDb { find { (EventRelationTable.fromId eq group.id.value) and (EventRelationTable.fromType eq FromType.GROUP) }.toList() }
@JvmStatic
fun deleteRelations(fight: EventFight) =
useDb {
EventRelationTable.deleteWhere {
(EventRelationTable.fightId eq fight.id) or
((EventRelationTable.fromId eq fight.id.value) and (EventRelationTable.fromType eq FromType.FIGHT))
}
}
@JvmStatic
fun deleteRelations(group: EventGroup) =
useDb {
EventRelationTable.deleteWhere {
(EventRelationTable.fromId eq group.id.value) and (EventRelationTable.fromType eq FromType.GROUP)
}
}
@JvmStatic
fun create(fight: EventFight, fightTeam: FightTeam, fromType: FromType, fromId: Int, fromPlace: Int) =
useDb {
@@ -178,4 +159,4 @@ class EventRelation(id: EntityID<Int>) : IntEntity(id) {
enum class FromType {
FIGHT, GROUP
}
}
}
@@ -20,12 +20,9 @@
package de.steamwar.sql
import de.steamwar.sql.internal.useDb
import org.jetbrains.exposed.v1.core.IntegerColumnType
import org.jetbrains.exposed.v1.core.VarCharColumnType
import org.jetbrains.exposed.v1.core.dao.id.CompositeID
import org.jetbrains.exposed.v1.core.dao.id.CompositeIdTable
import org.jetbrains.exposed.v1.core.dao.id.EntityID
import org.jetbrains.exposed.v1.core.eq
import org.jetbrains.exposed.v1.core.inList
import org.jetbrains.exposed.v1.dao.CompositeEntity
import org.jetbrains.exposed.v1.dao.CompositeEntityClass
@@ -72,28 +69,6 @@ class FightPlayer(id: EntityID<CompositeID>) : CompositeEntity(id) {
useDb {
find { FightPlayerTable.fightId inList fightIds.toList() }.toList()
}
@JvmStatic
fun countFights(userId: Int) =
useDb {
find { FightPlayerTable.userId eq userId }.count()
}
@JvmStatic
fun countFights(userId: Int, type: String) =
useDb {
exec(
"SELECT COUNT(*) AS FightCount FROM FightPlayer INNER JOIN Fight F on FightPlayer.FightID = F.FightID WHERE UserID = ? AND GameMode LIKE ?",
args = listOf(IntegerColumnType() to userId, VarCharColumnType() to "$type%")
) {
if (it.next()) {
it.getInt("FightCount")
} else {
0
}
}
?: 0
}
}
val fightID by FightPlayerTable.fightId.transform({ EntityID(it, FightTable) }, { it.value })
@@ -146,12 +146,12 @@ public final class GameModeConfig<M, W> {
public final List<String> CheckQuestions;
/**
* The allowed checkers to check this schematic type denoted by a list of SteamwarUser ids.
* The allowed checkers to check this schematic type denoted by a list of SteamWar ids.
* The people need the {@link UserPerm#CHECK} to be able to check though.
*
* @implSpec {@code []} by default -> denoting every person with {@link UserPerm#CHECK} can check it
*/
public final Set<Integer> Checkers;
public final List<Integer> Checkers;
/**
* Bundle for countdowns during the fight
@@ -246,7 +246,7 @@ public final class GameModeConfig<M, W> {
}
CheckQuestions = loader.getStringList("CheckQuestions");
Checkers = loader.getIntSet("Checkers");
Checkers = loader.getIntList("Checkers");
Times = new TimesConfig(loader.with("Times"));
// Arena would be here to be in config order but needs Schematic.Size and EnterStages loaded afterwards
Schematic = new SchematicConfig<>(loader.with("Schematic"));
@@ -488,41 +488,6 @@ public final class GameModeConfig<M, W> {
*/
public final boolean NoFloor;
/**
* Allows Wind Charges to cross the Middle.
*
* @implSpec {@code false} by default
*/
public final boolean WindchargesCanCrossMiddle;
/**
* Allows Wind Charge interaction with Blocks.
*
* @implSpec {@code true} by default
*/
public final boolean WindchargesInteractWithBlocks;
/**
* Allows Wind Charge to destroy Water.
*
* @implSpec {@code false} by default
*/
public final boolean WindchargesDestroyWater;
/**
* Allows Wind Charges to leave the Region.
*
* @implSpec {@code true} by default
*/
public final boolean WindchargesCanLeaveRegion;
/**
* Limits the amount of Wind Charges in each extended region. -1 is no limit
*
* @implSpec {@code -1} by default
*/
public final int WindchargeLimit;
private ArenaConfig(YMLWrapper<M, W> loader, SchematicConfig.SizeConfig Size, List<Integer> EnterStages) {
loaded = loader.canLoad();
WaterDepth = loader.getInt("WaterDepth", 0);
@@ -540,11 +505,6 @@ public final class GameModeConfig<M, W> {
Leaveable = loader.getBoolean("Leaveable", false);
AllowMissiles = loader.getBoolean("AllowMissiles", !EnterStages.isEmpty());
NoFloor = loader.getBoolean("NoFloor", false);
WindchargesCanCrossMiddle = loader.getBoolean("WindchargesCanCrossMiddle", false);
WindchargesInteractWithBlocks = loader.getBoolean("WindchargesInteractWithBlocks", true);
WindchargesDestroyWater = loader.getBoolean("WindchargesDestroyWater", false);
WindchargesCanLeaveRegion = loader.getBoolean("WindchargesCanLeaveRegion", true);
WindchargeLimit = loader.getInt("WindchargeLimit", -1);
}
@ToString
@@ -704,6 +664,13 @@ public final class GameModeConfig<M, W> {
*/
public final int MaxBlocks;
/**
* Maximal amount of items per dispenser
*
* @implSpec {@code 128} by default
*/
public final int MaxDispenserItems;
/**
* Maximal blast resistance for the blocks
*
@@ -719,12 +686,10 @@ public final class GameModeConfig<M, W> {
public final double MaxDesignBlastResistance;
/**
* List of limited block materials
*
* @implSpec {@link SQLWrapper#getInventoryMaterials)} are all disallowed by default to have any content but are unlimited in number.
* @implSpec Any Block that has more Blast Resistance than {@link #MaxBlastResistance} will be defaulted to 0.
* List of limited material (combinations)<br/>
* List contains tags Amount (integer) and Materials (List of material names in Spigot 1.12 AND Spigot 1.15 format)
*/
public final List<BlockRule<M>> Limited;
public final Map<Set<M>, Integer> Limited;
private SchematicConfig(YMLWrapper<M, ?> loader) {
loaded = loader.canLoad();
@@ -742,140 +707,32 @@ public final class GameModeConfig<M, W> {
IgnorePublicOnly = loader.getBoolean("IgnorePublicOnly", false);
UnlimitedPrepare = loader.getBoolean("UnlimitedPrepare", false);
MaxBlocks = loader.getInt("MaxBlocks", 0);
MaxDispenserItems = loader.getInt("MaxDispenserItems", 128);
MaxBlastResistance = loader.getDouble("MaxBlastResistance", Double.MAX_VALUE);
MaxDesignBlastResistance = loader.getDouble("MaxDesignBlastResistance", MaxBlastResistance);
List<BlockRule<M>> limited = new ArrayList<>();
Set<M> blocks = new HashSet<>();
for (YMLWrapper<M, ?> limitedLoader : loader.withAsList("Limited")) {
BlockRule<M> blockRule = new BlockRule<>(limitedLoader);
blocks.addAll(blockRule.Materials);
limited.add(blockRule);
Map<Set<M>, Integer> Limited = new HashMap<>();
for (Map<?, ?> entry : loader.getMapList("Limited")) {
int amount = (Integer) entry.get("Amount");
Set<String> materials = new HashSet<>((List<String>) entry.get("Materials"));
if (amount == 0) {
materials.forEach(material -> {
Limited.put(Collections.singleton(loader.materialMapper.apply(material.toUpperCase())), 0);
});
} else {
Limited.put(Collections.unmodifiableSet(materials.stream().map(String::toUpperCase).map(loader.materialMapper).collect(Collectors.toSet())), amount);
}
}
for (M material : (List<M>) SQLWrapper.impl.getMaterialWithGreaterBlastResistance(MaxBlastResistance)) {
if (material == null || !blocks.add(material)) continue;
limited.add(new BlockRule<>(material, 0));
}
for (M material : (Set<M>) SQLWrapper.impl.getInventoryMaterials()) {
if (material == null || !blocks.add(material)) continue;
limited.add(new BlockRule<>(material, Integer.MAX_VALUE));
}
this.Limited = Collections.unmodifiableList(limited);
SQLWrapper.impl.getMaterialWithGreaterBlastResistance(MaxBlastResistance).forEach(material -> {
if (Limited.entrySet().stream().anyMatch(entry -> entry.getKey().contains(material))) return;
Limited.put(Collections.singleton((M) material), 0);
});
this.Limited = Collections.unmodifiableMap(Limited);
this.ReplacementsWithoutBlockUpdates = loader.getMap("ReplacementsWithoutBlockUpdates", loader.materialMapper, loader.materialMapper);
this.ReplacementsWithBlockUpdates = loader.getMap("ReplacementsWithBlockUpdates", loader.materialMapper, loader.materialMapper);
}
public int getMaxCount(M material) {
return Limited.stream()
.filter(rule -> rule.Materials.contains(material))
.mapToInt(rule -> rule.Amount)
.max()
.orElse(Integer.MAX_VALUE);
}
public boolean isInventory(M material) {
return Limited.stream()
.filter(rule -> rule.Materials.contains(material))
.anyMatch(rule -> rule.Content.loaded);
}
public Integer getItemAmount(M material, M item) {
return Limited.stream()
.filter(rule -> rule.Materials.contains(material))
.filter(rule -> rule.Content.Items.contains(item))
.mapToInt(rule -> rule.Content.Amount)
.max()
.orElse(0);
}
@ToString
public static final class BlockRule<M> {
/**
* The block materials this rule applies to
*/
public final Set<M> Materials;
/**
* Maximal amount of Blocks allowed in the schematic
*
* @implSpec {@code 0} by default
*/
public final int Amount;
/**
* The item content filter for Blocks
*
* @implSpec no Items with {@code Amount 0} (denies any item) by default
*/
public final Content<M> Content;
/**
* Resolves one {@code Materials} entry to the concrete materials it denotes: {@code storage}
* for {@link SQLWrapper#getStorageMaterials()}, {@code inventory} for
* {@link SQLWrapper#getInventoryMaterials()}, or the material itself otherwise.
*/
private Set<M> expandInventoryGroup(YMLWrapper<M, ?> loader, String name) {
switch (name.toUpperCase()) {
case "STORAGE":
return (Set<M>) SQLWrapper.impl.getStorageMaterials();
case "INVENTORY":
return (Set<M>) SQLWrapper.impl.getInventoryMaterials();
default:
M material = loader.materialMapper.apply(name.toUpperCase());
return material != null ? Collections.singleton(material) : Collections.emptySet();
}
}
private BlockRule(YMLWrapper<M, ?> loader) {
Set<M> blocks = loader.getStringList("Materials")
.stream()
.flatMap(value -> expandInventoryGroup(loader, value).stream())
.collect(Collectors.toSet());
Materials = Collections.unmodifiableSet(blocks);
Amount = loader.getInt("Amount", 0);
Content = new Content<>(loader.with("Content"));
}
private BlockRule(M block, int amount) {
Materials = Collections.singleton(block);
Amount = amount;
Content = new Content<>();
}
@ToString
public static final class Content<M> {
public final boolean loaded;
/**
* Items allowed by this rule
*/
public final Set<M> Items;
/**
* Maximal amount of an allowed item per single block instance
*
* @implSpec {@code 0} by default
*/
public final int Amount;
private Content(YMLWrapper<M, ?> loader) {
loaded = loader.canLoad();
List<M> items = loader.getMaterialList("Items");
Items = Collections.unmodifiableSet(new HashSet<>(items));
Amount = loader.getInt("Amount", 0);
}
private Content() {
loaded = false;
Items = new HashSet<>();
Amount = 0;
}
}
}
@ToString
public static final class SizeConfig {
@@ -1072,13 +929,6 @@ public final class GameModeConfig<M, W> {
*/
public final boolean PersonalKits;
/**
* Maximal blast resistance for the blocks in the kit
*
* @implSpec {@code 9.0} by default
*/
public final double MaxBlastResistance;
/**
* Items (Valid spigot material values) that are not allowed in the personal kit
*/
@@ -1090,10 +940,7 @@ public final class GameModeConfig<M, W> {
MemberDefault = loader.getString("MemberDefault", "default");
LeaderDefault = loader.getString("LeaderDefault", "default");
PersonalKits = loader.getBoolean("PersonalKits", false);
MaxBlastResistance = loader.getDouble("MaxBlastResistance", 9.0);
List forbiddenItems = new ArrayList<>(loader.getMaterialList("ForbiddenItems"));
forbiddenItems.addAll(SQLWrapper.impl.getMaterialWithGreaterBlastResistance(MaxBlastResistance));
ForbiddenItems = Collections.unmodifiableList(forbiddenItems);
ForbiddenItems = loader.getMaterialList("ForbiddenItems");
}
}
@@ -183,6 +183,14 @@ class Punishment(id: EntityID<Int>) : IntEntity(id) {
"UNNOFIGHTSERVER",
UserPerm.MODERATION
),
NoTeamServer(
"NOTEAMSERVER_TEAM",
"NOTEAMSERVER_PERMA",
"NOTEAMSERVER_UNTIL",
"UNNOTEAMSERVER_ERROR",
"UNNOTEAMSERVER",
UserPerm.MODERATION
),
Note("NOTE_TEAM", null, null, null, null, UserPerm.PUNISHMENTS, true);
fun isMulti() =
@@ -24,7 +24,6 @@ import de.steamwar.ImplementationProvider;
import java.io.File;
import java.util.Collections;
import java.util.List;
import java.util.Set;
public interface SQLWrapper<M> {
SQLWrapper<?> impl = ImplementationProvider.getImpl("de.steamwar.sql.SQLWrapperImpl");
@@ -37,21 +36,5 @@ public interface SQLWrapper<M> {
return Collections.emptyList();
}
/**
* Storage-type inventory materials (chests, barrels, shulker boxes of any color) - the
* {@code storage} group usable in {@code GameModeConfig}'s {@code Limited}.
*/
default Set<M> getStorageMaterials() {
return Collections.emptySet();
}
/**
* Every inventory material - the {@code all} group usable in {@code GameModeConfig}'s
* {@code Limited}. Expected to be a superset of {@link #getStorageMaterials()}.
*/
default Set<M> getInventoryMaterials() {
return Collections.emptySet();
}
void additionalExceptionMetadata(StringBuilder builder);
}
@@ -76,25 +76,6 @@ final class YMLWrapper<M, W> {
return new YMLWrapper<>(false, Collections.emptyMap(), materialMapper, winconditionMapper);
}
public List<YMLWrapper<M, W>> withAsList(String path) {
if (document.containsKey(path)) {
Object value = document.get(path);
if (value instanceof List) {
List<?> list = (List<?>) value;
List<Map> maps = list.stream()
.filter(Map.class::isInstance)
.map(Map.class::cast)
.collect(Collectors.toList());
if (maps.size() == list.size()) {
return (List) maps.stream()
.map(map -> new YMLWrapper(true, map, materialMapper, winconditionMapper))
.collect(Collectors.toList());
}
}
}
return Collections.emptyList();
}
public <T> T get(String path, T defaultValue, Function<Object, T> mapper) {
Object value = this.document.get(path);
if (value == null) return defaultValue;
@@ -158,12 +139,6 @@ final class YMLWrapper<M, W> {
return get(path, o -> (List<Integer>) o);
}
public Set<Integer> getIntSet(String path) {
List<Integer> list = get(path, o -> (List<Integer>) o);
if (list.isEmpty()) return Collections.emptySet();
return Collections.unmodifiableSet(new HashSet<>(list));
}
public List<SchematicType> getSchematicTypeList(String path) {
List<String> list = getStringList(path);
if (list.isEmpty()) {
+6 -22
View File
@@ -64,14 +64,6 @@ Arena:
AllowMissiles: false # defaults to true if EnterStages are present otherwise 'false'
# Denotes that there is no floor for this GameMode
NoFloor: false # defaults to false if missing
# Allows Wind Charges to cross the Middle.
WindchargesCanCrossMiddle: false # defaults to false if missing
# Allows Wind Charge interaction with Blocks.
WindchargesInteractWithBlocks: false # defaults to false if missing
# Allows Wind Charges to leave the extended region.
WindchargesCanLeaveRegion: true # defaults to true
# Limits the amount of Wind Charges in each extended region. -1 is no limit
WindchargeLimit: -1 # defaults to -1
Schematic:
# The size of the schematics
@@ -111,23 +103,15 @@ Schematic:
UnlimitedPrepare: false # defaults to false if missing
# Maximal amount of blocks allowed in the schematic
MaxBlocks: 0 # defaults to 0 (ignored) if missing
# Maximal amount of items per dispenser
MaxDispenserItems: 128 # defaults to 128 if missing
# Maximal blast resistance for the design blocks
MaxDesignBlastResistance: 100000000 # defaults to Double.MAX_VALUE if missing
# List of limited block materials
# InventoryMaterials are all disallowed by default to have any content but are unlimited in number
# Any Block that has more Blast Resistance than MaxBlastResistance will be defaulted to 0.
# List of limited material (combinations)
# List contains tags Amount (integer) and Materials (List of material names in Spigot 1.12 AND Spigot 1.15 format)
Limited:
- Blocks: [ DISPENSER ]
MaxCount: 64
- Blocks: [ DISPENSER ]
MaxCount: 16
Content:
Items: [ ARROW, FIRE_CHARGE ]
Amount: 128
- Blocks: [ storage ]
Content:
Items: [ TNT ]
Amount: 1728
- Materials: [ ]
Amount: 0
# The name of the game mode presented to the players
GameName: WarGear # defaults to WarGear if missing
@@ -39,7 +39,6 @@ public enum ArenaMode {
public static final Set<ArenaMode> Test = Collections.unmodifiableSet(EnumSet.of(TEST, CHECK));
public static final Set<ArenaMode> Prepare = Collections.unmodifiableSet(EnumSet.of(PREPARE));
public static final Set<ArenaMode> Replay = Collections.unmodifiableSet(EnumSet.of(REPLAY, TEST));
public static final Set<ArenaMode> TestOrReferee = Collections.unmodifiableSet(EnumSet.of(TEST, CHECK, EVENT));
public static final Set<ArenaMode> AntiReplay = Collections.unmodifiableSet(EnumSet.complementOf(EnumSet.of(REPLAY)));
public static final Set<ArenaMode> AntiTest = Collections.unmodifiableSet(EnumSet.complementOf(EnumSet.of(TEST, CHECK)));
@@ -21,8 +21,8 @@ package de.steamwar.fightsystem;
import com.comphenix.tinyprotocol.TinyProtocol;
import de.steamwar.core.Core;
import de.steamwar.core.worldedit.SteamEdit;
import de.steamwar.core.worldedit.WorldEditRendererCUIEditor;
import de.steamwar.core.WorldEditRendererCUIEditor;
import de.steamwar.fightsystem.commands.TechareaCommand;
import de.steamwar.fightsystem.fight.Fight;
import de.steamwar.fightsystem.fight.FightTeam;
import de.steamwar.fightsystem.listener.ClickAnalyzer;
@@ -108,7 +108,7 @@ public class FightSystem extends JavaPlugin {
}
});
new OneShotStateDependent(ArenaMode.All, FightState.PreSchemSetup, () -> Fight.playSound(SWSound.BLOCK_NOTE_PLING.getSound(), 100.0f, 2.0f));
new OneShotStateDependent(ArenaMode.Test, FightState.All, SteamEdit::init);
new OneShotStateDependent(ArenaMode.Test, FightState.All, WorldEditRendererCUIEditor::new);
Config.world.setGameRule(GameRule.REDUCED_DEBUG_INFO, ArenaMode.AntiTest.contains(Config.mode));
hullHider = new HullHider();
@@ -127,6 +127,8 @@ public class FightSystem extends JavaPlugin {
if (checkSchematicNode.isPrepared()) {
Fight.getRedTeam().setSchem(checkSchematicNode, NodeData.getRevisions(checkSchematicNode) - 1);
}
new TechareaCommand();
} else if (Config.mode == ArenaMode.PREPARE) {
Fight.getUnrotated().setSchem(SchematicNode.getSchematicNode(Config.PrepareSchemID));
}
@@ -24,25 +24,35 @@ import de.steamwar.fightsystem.ArenaMode;
import de.steamwar.fightsystem.FightSystem;
import de.steamwar.fightsystem.fight.Kit;
import de.steamwar.fightsystem.states.FightState;
import de.steamwar.fightsystem.states.StateDependentCommand;
import de.steamwar.linkage.Linked;
import de.steamwar.sql.SteamwarUser;
import de.steamwar.sql.UserPerm;
import org.bukkit.command.Command;
import org.bukkit.command.CommandExecutor;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
@Linked
public class AkCommand extends FightSWCommand {
public class AkCommand implements CommandExecutor {
public AkCommand() {
super(ArenaMode.Test, FightState.All, "ak");
new StateDependentCommand(ArenaMode.Test, FightState.All, "ak", this);
}
@Override
protected boolean hasPerm(Player player, SteamwarUser user) {
return player.isOp() && user.hasPerm(UserPerm.ADMINISTRATION) && Core.getInstance() != FightSystem.getPlugin();
}
public boolean onCommand(CommandSender sender, Command command, String label, String[] args) {
if (!(sender instanceof Player)) {
return false;
}
Player player = (Player) sender;
if (!player.isOp()) return false;
@Register
public void run(@Validator Player player, String name) {
Kit.createKit(name, player);
if (!SteamwarUser.get(player.getUniqueId()).hasPerm(UserPerm.ADMINISTRATION) && Core.getInstance() != FightSystem.getPlugin()) {
return false;
}
Kit.createKit(args[0], player);
return false;
}
}
@@ -1,95 +0,0 @@
/*
* This file is a part of the SteamWar software.
*
* Copyright (C) 2026 SteamWar.de-Serverteam
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package de.steamwar.fightsystem.commands;
import de.steamwar.command.SWCommand;
import de.steamwar.command.TypeValidator;
import de.steamwar.fightsystem.ArenaMode;
import de.steamwar.fightsystem.states.FightState;
import de.steamwar.fightsystem.states.StateDependent;
import de.steamwar.sql.SteamwarUser;
import org.bukkit.Bukkit;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.player.PlayerCommandSendEvent;
import java.util.Set;
public abstract class FightSWCommand extends SWCommand implements Listener {
private final String command;
private final String[] aliases;
protected FightSWCommand(Set<ArenaMode> mode, Set<FightState> states, String command) {
super(command);
this.command = command;
this.aliases = new String[0];
stateDependant(mode, states);
}
protected FightSWCommand(Set<ArenaMode> mode, Set<FightState> states, String command, String... aliases) {
super(command, aliases);
this.command = command;
this.aliases = aliases;
stateDependant(mode, states);
}
private void stateDependant(Set<ArenaMode> mode, Set<FightState> states) {
FightSWCommand.this.unregister();
new StateDependent(mode, states) {
@Override
public void enable() {
System.out.println("--- Enable: " + command);
FightSWCommand.this.register();
}
@Override
public void disable() {
System.out.println("--- Disable: " + command);
FightSWCommand.this.unregister();
}
}.register();
}
public static void postFightStateChange() {
for (Player player : Bukkit.getOnlinePlayers()) {
player.updateCommands();
}
}
protected boolean hasPerm(Player player, SteamwarUser user) {
return true;
}
@EventHandler(ignoreCancelled = true)
public final void onPlayerCommandSend(PlayerCommandSendEvent event) {
if (hasPerm(event.getPlayer(), SteamwarUser.get(event.getPlayer().getUniqueId()))) return;
event.getCommands().remove(command);
for (String alias : aliases) {
event.getCommands().remove(alias);
}
}
@ClassValidator(value = Player.class, local = true)
public final TypeValidator<Player> permissionCheck() {
return (sender, value, messageSender) -> hasPerm(value, SteamwarUser.get(value.getUniqueId()));
}
}
@@ -19,28 +19,92 @@
package de.steamwar.fightsystem.commands;
import de.steamwar.fightsystem.ArenaMode;
import com.google.common.collect.ImmutableList;
import de.steamwar.fightsystem.Config;
import de.steamwar.fightsystem.states.FightState;
import de.steamwar.fightsystem.FightSystem;
import de.steamwar.linkage.Linked;
import de.steamwar.sql.SteamwarUser;
import net.md_5.bungee.api.ChatMessageType;
import org.bukkit.Bukkit;
import org.bukkit.GameMode;
import org.bukkit.command.Command;
import org.bukkit.command.CommandSender;
import org.bukkit.command.defaults.BukkitCommand;
import org.bukkit.craftbukkit.CraftServer;
import org.bukkit.entity.Player;
import org.bukkit.util.StringUtil;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
@Linked
public class GamemodeCommand extends FightSWCommand {
public class GamemodeCommand extends BukkitCommand {
private static final List<String> GAMEMODE_NAMES = ImmutableList.of("adventure", "creative", "survival",
"spectator");
public GamemodeCommand() {
super(ArenaMode.TestOrReferee, FightState.All, "gamemode", "gm");
super("gamemode");
List<String> aliases = new ArrayList<>();
aliases.add("gm");
this.setAliases(aliases);
Map<String, Command> knownCommands = ((CraftServer) Bukkit.getServer()).getCommandMap().getKnownCommands();
knownCommands.remove("gamemode");
Commands.injectCommand(this);
}
@Override
protected boolean hasPerm(Player player, SteamwarUser user) {
return Config.test() || Config.isReferee(player);
public boolean execute(CommandSender sender, String currentAlias, String[] args) {
if (!(sender instanceof Player)) {
return false;
} else if (args.length == 0) {
FightSystem.getMessage().sendPrefixless("GAMEMODE_HELP", sender);
return false;
}
Player p = (Player) sender;
if (!(Config.test() || Config.isReferee(p))) {
FightSystem.getMessage().sendPrefixless("GAMEMODE_NOT_ALLOWED", p, ChatMessageType.ACTION_BAR);
return false;
}
GameMode mode = createMode(args[0]);
if (mode == null) {
FightSystem.getMessage().sendPrefixless("GAMEMODE_UNKNOWN", p, ChatMessageType.ACTION_BAR, args[0]);
return false;
}
p.setGameMode(mode);
return true;
}
@Register(description = "GAMEMODE_HELP")
public void execute(@Validator Player player, GameMode gameMode) {
player.setGameMode(gameMode);
@SuppressWarnings("deprecation")
private GameMode createMode(String modeArg) {
try {
return GameMode.getByValue(Integer.parseInt(modeArg));
} catch (NumberFormatException ignored) {
if ((modeArg.equalsIgnoreCase("creative")) || (modeArg.equalsIgnoreCase("c"))) {
return GameMode.CREATIVE;
} else if ((modeArg.equalsIgnoreCase("adventure")) || (modeArg.equalsIgnoreCase("a"))) {
return GameMode.ADVENTURE;
} else if ((modeArg.equalsIgnoreCase("spectator")) || (modeArg.equalsIgnoreCase("sp"))) {
return GameMode.SPECTATOR;
} else if ((modeArg.equalsIgnoreCase("survival")) || (modeArg.equalsIgnoreCase("s"))) {
return GameMode.SURVIVAL;
}
}
return null;
}
@Override
public List<String> tabComplete(CommandSender sender, String alias, String[] args) {
if (args.length == 1) {
return StringUtil.copyPartialMatches(args[0], GAMEMODE_NAMES, new ArrayList<>(GAMEMODE_NAMES.size()));
}
return ImmutableList.of();
}
}
@@ -20,31 +20,34 @@
package de.steamwar.fightsystem.commands;
import de.steamwar.fightsystem.ArenaMode;
import de.steamwar.fightsystem.Config;
import de.steamwar.fightsystem.FightSystem;
import de.steamwar.fightsystem.fight.Fight;
import de.steamwar.fightsystem.fight.FightTeam;
import de.steamwar.fightsystem.listener.Check;
import de.steamwar.fightsystem.states.FightState;
import de.steamwar.fightsystem.states.StateDependentCommand;
import de.steamwar.linkage.Linked;
import de.steamwar.sql.SchematicNode;
import de.steamwar.sql.SteamwarUser;
import de.steamwar.sql.UserPerm;
import org.bukkit.command.Command;
import org.bukkit.command.CommandExecutor;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
@Linked
public class InfoCommand extends FightSWCommand {
public class InfoCommand implements CommandExecutor {
public InfoCommand() {
super(ArenaMode.All, FightState.All, "fightinfo");
new StateDependentCommand(ArenaMode.All, FightState.All, "fightinfo", this);
}
@Override
protected boolean hasPerm(Player player, SteamwarUser user) {
return Check.checkPermission(user, Config.GameModeConfig);
}
public boolean onCommand(CommandSender sender, Command command, String label, String[] args) {
if (!(sender instanceof Player)) return false;
Player player = (Player) sender;
if (!SteamwarUser.get(player.getUniqueId()).hasPerm(UserPerm.CHECK)) return false;
@Register
public void run(@Validator Player player) {
for (FightTeam team : Fight.teams()) {
if (!team.isLeaderless()) {
FightSystem.getMessage().send("INFO_LEADER", player, team.getColoredName(), team.getLeader().getEntity().getName());
@@ -55,5 +58,6 @@ public class InfoCommand extends FightSWCommand {
FightSystem.getMessage().send("INFO_SCHEMATIC", player, team.getColoredName(), schematic.getName(), SteamwarUser.byId(schematic.getOwner()).getUserName(), schematic.getRank());
}
}
return false;
}
}
@@ -21,23 +21,32 @@ package de.steamwar.fightsystem.commands;
import de.steamwar.fightsystem.ArenaMode;
import de.steamwar.fightsystem.states.FightState;
import de.steamwar.fightsystem.states.StateDependentCommand;
import de.steamwar.linkage.Linked;
import org.bukkit.command.Command;
import org.bukkit.command.CommandExecutor;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
@Linked
public class KitCommand extends FightSWCommand {
public class KitCommand implements CommandExecutor {
public KitCommand() {
super(ArenaMode.AntiReplay, FightState.Setup, "kit");
new StateDependentCommand(ArenaMode.AntiReplay, FightState.Setup, "kit", this);
}
@Register
public void execute(Player player) {
GUI.kitSelection(player, "");
}
@Override
public boolean onCommand(CommandSender sender, Command command, String label, String[] args) {
if (!(sender instanceof Player)) {
return false;
}
Player player = (Player) sender;
@Register
public void execute(Player player, String query) { // TODO: TabCompletion of Kit Names!
GUI.kitSelection(player, query);
if (args.length != 1) {
GUI.kitSelection(player, "");
} else {
Commands.kit(player, args[0]);
}
return false;
}
}
@@ -21,18 +21,28 @@ package de.steamwar.fightsystem.commands;
import de.steamwar.fightsystem.ArenaMode;
import de.steamwar.fightsystem.states.FightState;
import de.steamwar.fightsystem.states.StateDependentCommand;
import de.steamwar.linkage.Linked;
import org.bukkit.command.Command;
import org.bukkit.command.CommandExecutor;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
@Linked
public class LeaveCommand extends FightSWCommand {
public class LeaveCommand implements CommandExecutor {
public LeaveCommand() {
super(ArenaMode.AntiReplay, FightState.Setup, "leave");
new StateDependentCommand(ArenaMode.AntiReplay, FightState.Setup, "leave", this);
}
@Register
public void execute(Player player) {
@Override
public boolean onCommand(CommandSender sender, Command command, String label, String[] args) {
if (!(sender instanceof Player)) {
return false;
}
Player player = (Player) sender;
Commands.leaveTeam(player);
return false;
}
}
@@ -20,42 +20,52 @@
package de.steamwar.fightsystem.commands;
import de.steamwar.fightsystem.ArenaMode;
import de.steamwar.fightsystem.Config;
import de.steamwar.fightsystem.FightSystem;
import de.steamwar.fightsystem.fight.Fight;
import de.steamwar.fightsystem.fight.FightTeam;
import de.steamwar.fightsystem.listener.Check;
import de.steamwar.fightsystem.states.FightState;
import de.steamwar.fightsystem.states.StateDependentCommand;
import de.steamwar.linkage.Linked;
import de.steamwar.sql.SchematicNode;
import de.steamwar.sql.SchematicType;
import de.steamwar.sql.SteamwarUser;
import de.steamwar.sql.UserPerm;
import net.md_5.bungee.api.ChatMessageType;
import org.bukkit.command.Command;
import org.bukkit.command.CommandExecutor;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
@Linked
public class LockschemCommand extends FightSWCommand {
public class LockschemCommand implements CommandExecutor {
public LockschemCommand() {
super(ArenaMode.All, FightState.Schem, "lockschem");
new StateDependentCommand(ArenaMode.All, FightState.Schem, "lockschem", this);
}
@Override
protected boolean hasPerm(Player player, SteamwarUser user) {
return Check.checkPermission(user, Config.GameModeConfig);
}
public boolean onCommand(CommandSender sender, Command command, String label, String[] args) {
if (!(sender instanceof Player)) return false;
Player player = (Player) sender;
@Register(description = "LOCKSCHEM_HELP")
public void execute(@Validator Player player, String teamName) {
if (!SteamwarUser.get(player.getUniqueId()).hasPerm(UserPerm.CHECK)) return false;
if (args.length != 1) {
FightSystem.getMessage().sendPrefixless("LOCKSCHEM_HELP", player);
return false;
}
String teamName = args[0];
FightTeam fightTeam = Fight.getTeamByName(teamName);
if (fightTeam == null) {
FightSystem.getMessage().sendPrefixless("UNKNOWN_TEAM", player, ChatMessageType.ACTION_BAR);
return;
return false;
}
SchematicNode.getSchematicNode(fightTeam.getSchematic()).setSchemtype(SchematicType.Normal);
FightSystem.getMessage().sendPrefixless("LOCKSCHEM_LOCKED", player, ChatMessageType.ACTION_BAR);
fightTeam.broadcastSystem("LOCKSCHEM_LOCKED_BY", player.getName());
return false;
}
}
@@ -21,18 +21,28 @@ package de.steamwar.fightsystem.commands;
import de.steamwar.fightsystem.ArenaMode;
import de.steamwar.fightsystem.states.FightState;
import de.steamwar.fightsystem.states.StateDependentCommand;
import de.steamwar.linkage.Linked;
import org.bukkit.command.Command;
import org.bukkit.command.CommandExecutor;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
@Linked
public class ReadyCommand extends FightSWCommand {
public class ReadyCommand implements CommandExecutor {
public ReadyCommand() {
super(ArenaMode.AntiPrepare, FightState.PostSchemSetup, "ready");
new StateDependentCommand(ArenaMode.AntiPrepare, FightState.PostSchemSetup, "ready", this);
}
@Register
public void execute(Player player) {
@Override
public boolean onCommand(CommandSender sender, Command command, String label, String[] args) {
if (!(sender instanceof Player)) {
return false;
}
Player player = (Player) sender;
Commands.toggleReady(player);
return false;
}
}
@@ -20,19 +20,35 @@
package de.steamwar.fightsystem.commands;
import de.steamwar.fightsystem.ArenaMode;
import de.steamwar.fightsystem.FightSystem;
import de.steamwar.fightsystem.states.FightState;
import de.steamwar.fightsystem.states.StateDependentCommand;
import de.steamwar.linkage.Linked;
import org.bukkit.command.Command;
import org.bukkit.command.CommandExecutor;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
@Linked
public class RemoveCommand extends FightSWCommand {
public class RemoveCommand implements CommandExecutor {
public RemoveCommand() {
super(ArenaMode.VariableTeams, FightState.Setup, "remove");
new StateDependentCommand(ArenaMode.VariableTeams, FightState.Setup, "remove", this);
}
@Register(description = "REMOVE_HELP")
public void execute(Player player, Player teamMember) {
Commands.kick(player, teamMember.getName());
@Override
public boolean onCommand(CommandSender sender, Command command, String label, String[] args) {
if (!(sender instanceof Player)) {
return false;
}
Player player = (Player) sender;
if (args.length != 1) {
FightSystem.getMessage().sendPrefixless("REMOVE_HELP", player);
return false;
}
Commands.kick(player, args[0]);
return false;
}
}
@@ -26,28 +26,37 @@ import de.steamwar.fightsystem.fight.FightPlayer;
import de.steamwar.fightsystem.fight.FightTeam;
import de.steamwar.fightsystem.fight.JoinRequest;
import de.steamwar.fightsystem.states.FightState;
import de.steamwar.fightsystem.states.StateDependentCommand;
import de.steamwar.linkage.Linked;
import org.bukkit.command.Command;
import org.bukkit.command.CommandExecutor;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import java.util.function.BiConsumer;
@Linked
public class RequestsCommand extends FightSWCommand {
public class RequestsCommand implements CommandExecutor {
public RequestsCommand() {
super(ArenaMode.VariableTeams, FightState.AntiSpectate, "request", "requests");
new StateDependentCommand(ArenaMode.VariableTeams, FightState.AntiSpectate, "request", this);
new StateDependentCommand(ArenaMode.VariableTeams, FightState.AntiSpectate, "requests", this);
}
@Register
public void execute(Player player) {
@Override
public boolean onCommand(CommandSender sender, Command command, String label, String[] args) {
if (!(sender instanceof Player)) return false;
Player player = (Player) sender;
FightPlayer fp = Fight.getFightPlayer(player);
if (fp == null || !(fp.isLeader() || fp.isLiving())) {
GUI.joinRequest(player);
return;
return false;
}
if (Commands.checkGetLeader(player) == null) return;
if (Commands.checkGetLeader(player) == null) return false;
GUI.chooseJoinRequests(player);
return false;
}
public static void onJoinRequest(Player player, JoinRequest request, BiConsumer<JoinRequest, FightTeam> handleJoinRequest) {
@@ -24,22 +24,32 @@ import de.steamwar.fightsystem.Config;
import de.steamwar.fightsystem.fight.Fight;
import de.steamwar.fightsystem.record.PacketProcessor;
import de.steamwar.fightsystem.states.FightState;
import de.steamwar.fightsystem.states.StateDependentCommand;
import de.steamwar.linkage.Linked;
import org.bukkit.command.Command;
import org.bukkit.command.CommandExecutor;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
@Linked
public class SkipCommand extends FightSWCommand {
public class SkipCommand implements CommandExecutor {
public SkipCommand() {
super(ArenaMode.AntiPrepare, ArenaMode.Replay.contains(Config.mode) ? FightState.All : FightState.TeamFix, "skip");
new StateDependentCommand(ArenaMode.AntiPrepare, ArenaMode.Replay.contains(Config.mode) ? FightState.All : FightState.TeamFix, "skip", this);
}
@Register
public void execute(Player player) {
@Override
public boolean onCommand(CommandSender sender, Command command, String label, String[] args) {
if (!(sender instanceof Player)) {
return false;
}
Player player = (Player) sender;
if (PacketProcessor.isReplaying() && player.getUniqueId().equals(Fight.getBlueTeam().getDesignatedLeader())) {
PacketProcessor.currentReplay().skipToSubtitle();
} else {
Commands.toggleSkip(player);
}
return false;
}
}
@@ -21,18 +21,27 @@ package de.steamwar.fightsystem.commands;
import de.steamwar.fightsystem.ArenaMode;
import de.steamwar.fightsystem.states.FightState;
import de.steamwar.fightsystem.states.StateDependentCommand;
import de.steamwar.linkage.Linked;
import org.bukkit.command.Command;
import org.bukkit.command.CommandExecutor;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
@Linked
public class StateCommand extends FightSWCommand {
public class StateCommand implements CommandExecutor {
public StateCommand() {
super(ArenaMode.Test, FightState.All, "state");
new StateDependentCommand(ArenaMode.Test, FightState.All, "state", this);
}
@Register
public void execute(Player player) {
GUI.state(player);
@Override
public boolean onCommand(CommandSender sender, Command command, String label, String[] args) {
if (!(sender instanceof Player)) {
return false;
}
GUI.state((Player) sender);
return false;
}
}
@@ -22,18 +22,26 @@ package de.steamwar.fightsystem.commands;
import de.steamwar.fightsystem.ArenaMode;
import de.steamwar.fightsystem.fight.Fight;
import de.steamwar.fightsystem.states.FightState;
import de.steamwar.fightsystem.states.StateDependentCommand;
import de.steamwar.linkage.Linked;
import org.bukkit.command.Command;
import org.bukkit.command.CommandExecutor;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
@Linked
public class TBCommand extends FightSWCommand {
public class TBCommand implements CommandExecutor {
public TBCommand() {
super(ArenaMode.Check, FightState.All, "resettb");
new StateDependentCommand(ArenaMode.Check, FightState.All, "resettb", this);
}
@Register
public void execute(Player player) {
@Override
public boolean onCommand(CommandSender sender, Command command, String label, String[] args) {
if (!(sender instanceof Player)) {
return false;
}
Fight.getRedTeam().pasteSchem();
return false;
}
}
@@ -20,20 +20,34 @@ package de.steamwar.fightsystem.commands;
import de.steamwar.fightsystem.ArenaMode;
import de.steamwar.fightsystem.FightSystem;
import de.steamwar.fightsystem.states.FightState;
import de.steamwar.fightsystem.states.StateDependentCommand;
import de.steamwar.linkage.Linked;
import net.minecraft.server.MinecraftServer;
import org.bukkit.entity.Player;
import org.bukkit.command.Command;
import org.bukkit.command.CommandExecutor;
import org.bukkit.command.CommandSender;
@Linked
public class TPSWarpCommand extends FightSWCommand {
public class TPSWarpCommand implements CommandExecutor {
public TPSWarpCommand() {
super(ArenaMode.Prepare, FightState.PostSchemSetup, "tpswarp", "tpslimit");
new StateDependentCommand(ArenaMode.Prepare, FightState.PostSchemSetup, "tpswarp", this);
new StateDependentCommand(ArenaMode.Prepare, FightState.PostSchemSetup, "tpslimit", this);
}
@Register(description = "TPSWARP_HELP")
public void execute(Player player, float tps) {
@Override
public boolean onCommand(CommandSender sender, Command command, String label, String[] args) {
float tps;
try {
tps = Float.parseFloat(args[0]);
} catch (NumberFormatException | ArrayIndexOutOfBoundsException e) {
FightSystem.getMessage().send("TPSWARP_HELP", sender);
return false;
}
MinecraftServer.getServer().tickRateManager().setTickRate(tps);
FightSystem.getMessage().broadcastActionbar("TPSWARP_SET", tps);
return false;
}
}
@@ -19,39 +19,42 @@
package de.steamwar.fightsystem.commands;
import de.steamwar.command.SWCommand;
import de.steamwar.entity.CWireframe;
import de.steamwar.entity.REntityServer;
import de.steamwar.fightsystem.ArenaMode;
import de.steamwar.fightsystem.Config;
import de.steamwar.fightsystem.states.FightState;
import de.steamwar.fightsystem.states.OneShotStateDependent;
import de.steamwar.linkage.Linked;
import de.steamwar.fightsystem.FightSystem;
import org.bukkit.Bukkit;
import org.bukkit.Material;
import org.bukkit.entity.Player;
@Linked
public class TechareaCommand extends FightSWCommand {
private REntityServer entityServer = new REntityServer();
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;
public class TechareaCommand extends SWCommand {
private final Map<UUID, REntityServer> servers = new HashMap<>();
public TechareaCommand() {
super(ArenaMode.Check, FightState.All, "techarea");
new OneShotStateDependent(ArenaMode.Check, FightState.All, () -> {
if (!entityServer.getEntities().isEmpty()) return;
super("techarea");
Bukkit.getScheduler().runTaskTimer(FightSystem.getPlugin(), () -> servers.forEach((uuid, rEntityServer) -> rEntityServer.tick()), 2, 2);
}
@Register
public void genericCommand(Player player) {
if (servers.containsKey(player.getUniqueId())) {
servers.get(player.getUniqueId()).close();
} else {
REntityServer server = new REntityServer();
CWireframe wireframe = new CWireframe(server);
wireframe.setPos1(Config.BlueInsetRegion.getMinLocation(Config.world));
wireframe.setPos2(Config.BlueInsetRegion.getMaxLocation(Config.world).subtract(1, 1, 1));
wireframe.setBlock(Material.RED_CONCRETE.createBlockData());
});
}
@Register
public void genericCommand(Player player) {
if (entityServer.getPlayers().contains(player)) {
entityServer.removePlayer(player);
} else {
entityServer.addPlayer(player);
server.addPlayer(player);
servers.put(player.getUniqueId(), server);
}
}
}
@@ -25,24 +25,27 @@ import de.steamwar.fightsystem.Config;
import de.steamwar.fightsystem.FightSystem;
import de.steamwar.fightsystem.fight.Fight;
import de.steamwar.fightsystem.states.FightState;
import de.steamwar.fightsystem.states.StateDependentCommand;
import de.steamwar.linkage.Linked;
import de.steamwar.sql.SWException;
import org.bukkit.Bukkit;
import org.bukkit.entity.Player;
import org.bukkit.command.Command;
import org.bukkit.command.CommandExecutor;
import org.bukkit.command.CommandSender;
import java.io.StringWriter;
import java.util.Arrays;
import java.util.logging.Level;
@Linked
public class TechhiderbugCommand extends FightSWCommand {
public class TechhiderbugCommand implements CommandExecutor {
public TechhiderbugCommand() {
super(ArenaMode.All, FightState.All, "techhiderbug");
new StateDependentCommand(ArenaMode.All, FightState.All, "techhiderbug", this);
}
@Register
public void execute(Player player, String... args) {
@Override
public boolean onCommand(CommandSender sender, Command cmd, String alias, String[] args) {
StringWriter writer = new StringWriter();
try {
@@ -73,6 +76,7 @@ public class TechhiderbugCommand extends FightSWCommand {
Bukkit.getLogger().log(Level.SEVERE, "Error while generating bug report", e);
}
SWException.log("Techhider-Bug reported by " + player.getName() + ": " + Arrays.toString(args), writer.toString());
SWException.log("Techhider-Bug reported by " + sender.getName() + ": " + Arrays.toString(args), writer.toString());
return false;
}
}
@@ -23,20 +23,28 @@ import de.steamwar.fightsystem.ArenaMode;
import de.steamwar.fightsystem.fight.Fight;
import de.steamwar.fightsystem.fight.FightWorld;
import de.steamwar.fightsystem.states.FightState;
import de.steamwar.fightsystem.states.StateDependentCommand;
import de.steamwar.linkage.Linked;
import org.bukkit.command.Command;
import org.bukkit.command.CommandExecutor;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
@Linked
public class WGCommand extends FightSWCommand {
public class WGCommand implements CommandExecutor {
public WGCommand() {
super(ArenaMode.Check, FightState.All, "resetwg");
new StateDependentCommand(ArenaMode.Check, FightState.All, "resetwg", this);
}
@Register
public void execute(Player player) {
@Override
public boolean onCommand(CommandSender sender, Command command, String label, String[] args) {
if (!(sender instanceof Player)) {
return false;
}
FightWorld.resetWorld();
Fight.getBlueTeam().pasteSchem();
Fight.getRedTeam().pasteSchem();
return false;
}
}
@@ -25,34 +25,49 @@ import de.steamwar.fightsystem.FightSystem;
import de.steamwar.fightsystem.fight.Fight;
import de.steamwar.fightsystem.fight.FightTeam;
import de.steamwar.fightsystem.states.FightState;
import de.steamwar.fightsystem.states.StateDependentCommand;
import de.steamwar.linkage.Linked;
import de.steamwar.sql.SteamwarUser;
import net.md_5.bungee.api.ChatMessageType;
import org.bukkit.command.Command;
import org.bukkit.command.CommandExecutor;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
@Linked
public class WinCommand extends FightSWCommand {
public class WinCommand implements CommandExecutor {
public WinCommand() {
super(ArenaMode.Event, FightState.Ingame, "win");
new StateDependentCommand(ArenaMode.Event, FightState.Ingame, "win", this);
}
@Override
protected boolean hasPerm(Player player, SteamwarUser user) {
return Config.isReferee(player);
}
public boolean onCommand(CommandSender sender, Command command, String label, String[] args) {
if (!(sender instanceof Player)) {
return false;
}
Player p = (Player) sender;
@Register
public void execute(@Validator Player player, String teamName) {
if (teamName.equalsIgnoreCase("tie")) {
if (!Config.isReferee(p)) {
FightSystem.getMessage().sendPrefixless("NOT_FIGHTLEADER", p, ChatMessageType.ACTION_BAR);
return false;
}
if (args.length == 0) {
FightSystem.getMessage().sendPrefixless("WIN_HELP", p);
return false;
}
if (args[0].equalsIgnoreCase("tie")) {
FightSystem.setSpectateState(null, "Referee", "WIN_FIGHTLEADER");
return;
return false;
}
for (FightTeam team : Fight.teams()) {
if (teamName.equalsIgnoreCase(team.getName())) {
if (args[0].equalsIgnoreCase(team.getName())) {
FightSystem.setSpectateState(team, "Referee", "WIN_FIGHTLEADER");
return;
return false;
}
}
return false;
}
}
@@ -25,7 +25,6 @@ import de.steamwar.fightsystem.FightSystem;
import de.steamwar.fightsystem.states.FightState;
import de.steamwar.fightsystem.states.StateDependentListener;
import de.steamwar.linkage.Linked;
import de.steamwar.sql.GameModeConfig;
import de.steamwar.sql.SchematicNode;
import de.steamwar.sql.SteamwarUser;
import de.steamwar.sql.UserPerm;
@@ -45,28 +44,14 @@ public class Check implements Listener {
new StateDependentListener(ArenaMode.Check, FightState.All, this);
}
private boolean checkPermission(SteamwarUser user, SchematicNode schematic) {
GameModeConfig<Object, String> gameModeConfig = GameModeConfig.getAll().stream()
.filter(gmc -> gmc.Schematic.Type != null && gmc.Schematic.Type.checkType() != null && schematic.getSchemtype().name().equals(gmc.Schematic.Type.checkType().name()))
.findFirst()
.orElse(null);
if (gameModeConfig == null) gameModeConfig = GameModeConfig.getDefaults();
return checkPermission(user, gameModeConfig);
}
public static boolean checkPermission(SteamwarUser user, GameModeConfig gameModeConfig) {
if (user.hasPerm(UserPerm.ADMINISTRATION)) return true;
if (gameModeConfig.Checkers.isEmpty() && user.hasPerm(UserPerm.CHECK)) return true;
return gameModeConfig.Checkers.contains(user.getId());
}
@EventHandler
public void onJoin(PlayerJoinEvent e) {
Player player = e.getPlayer();
SteamwarUser user = SteamwarUser.get(player.getUniqueId());
if (user.hasPerm(UserPerm.CHECK)) return;
SchematicNode schem = SchematicNode.getSchematicNode(Config.CheckSchemID);
if (checkPermission(user, schem)) return;
if (user.getId() == schem.getOwner()) return;
FightSystem.getMessage().send("CHECK_JOIN_DENIED", player);
@@ -1,7 +1,7 @@
/*
* This file is a part of the SteamWar software.
*
* Copyright (C) 2026 SteamWar.de-Serverteam
* Copyright (C) 2025 SteamWar.de-Serverteam
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
@@ -31,16 +31,17 @@ import de.steamwar.linkage.Linked;
import net.md_5.bungee.api.ChatMessageType;
import org.bukkit.GameMode;
import org.bukkit.Material;
import org.bukkit.Tag;
import org.bukkit.block.Block;
import org.bukkit.block.data.type.Dispenser;
import org.bukkit.block.data.type.DriedGhast;
import org.bukkit.entity.Player;
import org.bukkit.entity.TNTPrimed;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.Listener;
import org.bukkit.event.block.*;
import org.bukkit.event.block.BlockBreakEvent;
import org.bukkit.event.block.BlockDispenseEvent;
import org.bukkit.event.block.BlockFromToEvent;
import org.bukkit.event.block.BlockPlaceEvent;
import org.bukkit.event.entity.EntityExplodeEvent;
import org.bukkit.event.entity.FoodLevelChangeEvent;
import org.bukkit.event.entity.PlayerDeathEvent;
@@ -257,16 +258,4 @@ public class Permanent implements Listener {
event.setCancelled(true);
FightSystem.getMessage().sendPrefixless("NO_BLOCK_BREAK", event.getPlayer(), ChatMessageType.ACTION_BAR);
}
/**
* Prevents Dried Ghast from spawning and plants from growing
*/
@EventHandler
public void onBlockGrow(BlockGrowEvent event) {
var type = event.getBlock().getType();
if (event.getBlock().getBlockData() instanceof DriedGhast || Tag.CROPS.isTagged(type) || Tag.SAPLINGS.isTagged(type)) {
event.setCancelled(true);
}
}
}
@@ -72,9 +72,6 @@ public class WaterRemover implements Listener {
@EventHandler
public void handleEntityExplode(EntityExplodeEvent event) {
if (event.getEntityType() == EntityType.WIND_CHARGE && !Config.GameModeConfig.Arena.WindchargesDestroyWater) {
return;
}
event.setYield(0); //No drops (additionally to world config)
FightTeam spawn = tnt.remove(event.getEntity().getEntityId());
@@ -1,44 +0,0 @@
/*
* This file is a part of the SteamWar software.
*
* Copyright (C) 2026 SteamWar.de-Serverteam
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package de.steamwar.fightsystem.listener;
import de.steamwar.fightsystem.Config;
import de.steamwar.fightsystem.states.FightState;
import de.steamwar.fightsystem.states.StateDependentListener;
import de.steamwar.linkage.Linked;
import org.bukkit.entity.EntityType;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.Listener;
import org.bukkit.event.entity.EntityExplodeEvent;
@Linked
public class WindchargeInteractionDisabler implements Listener {
public WindchargeInteractionDisabler() {
new StateDependentListener(!Config.GameModeConfig.Arena.WindchargesInteractWithBlocks, FightState.Running, this);
}
@EventHandler(priority = EventPriority.HIGHEST)
public void handleEntityExplode(EntityExplodeEvent event) {
if (event.getEntityType() != EntityType.WIND_CHARGE) return;
event.blockList().clear();
}
}
@@ -22,71 +22,31 @@ package de.steamwar.fightsystem.listener;
import de.steamwar.fightsystem.Config;
import de.steamwar.fightsystem.states.FightState;
import de.steamwar.fightsystem.states.StateDependentTask;
import de.steamwar.fightsystem.utils.Region;
import de.steamwar.linkage.Linked;
import net.minecraft.world.entity.projectile.windcharge.WindCharge;
import org.bukkit.Location;
import org.bukkit.entity.WindCharge;
@Linked
public class WindchargeStopper {
public WindchargeStopper() {
canCrossMiddle = Config.GameModeConfig.Arena.WindchargesCanCrossMiddle;
canLeaveRegion = Config.GameModeConfig.Arena.WindchargesCanLeaveRegion;
limit = Config.GameModeConfig.Arena.WindchargeLimit;
boolean enabled = limit >= 0 || !canCrossMiddle || !canLeaveRegion;
new StateDependentTask(enabled, FightState.Running, this::run, 1, 1);
new StateDependentTask(true, FightState.Running, this::run, 1, 1);
}
private static final int middleLine = Config.SpecSpawn.getBlockZ();
private static final Class<?> windChargeClass = WindCharge.class;
private final boolean canCrossMiddle;
private final boolean canLeaveRegion;
private final int limit;
private int blueCount;
private int redCount;
private void run() {
redCount = 0;
blueCount = 0;
Recording.iterateOverEntities(windChargeClass::isInstance, entity -> {
Location location = entity.getLocation();
Location nextlocation = location.clone().add(entity.getVelocity());
Location prevLocation = location.clone().subtract(entity.getVelocity());
if (!canCrossMiddle) {
boolean passedMiddle = nextlocation.getBlockZ() >= middleLine && location.getBlockZ() <= middleLine ||
nextlocation.getBlockZ() <= middleLine && location.getBlockZ() >= middleLine;
if (passedMiddle) {
entity.remove();
return;
}
}
boolean passedMiddle = location.getBlockZ() > middleLine && prevLocation.getBlockZ() > middleLine ||
location.getBlockZ() < middleLine && prevLocation.getBlockZ() < middleLine;
Region region = Config.BlueExtendRegion.inRegion(location) ? Config.BlueExtendRegion
: Config.RedExtendRegion.inRegion(location) ? Config.RedExtendRegion
: null;
if (!canLeaveRegion) {
if (region == null) {
entity.remove();
return;
}
if (!region.inRegion(nextlocation)) {
entity.remove();
return;
}
}
if (limit >= 0 && region != null) {
if (region == Config.BlueExtendRegion) {
if (++blueCount > limit) entity.remove();
} else {
if (++redCount > limit) entity.remove();
}
if (!passedMiddle) {
entity.remove();
}
});
}
@@ -20,7 +20,7 @@
package de.steamwar.fightsystem.record;
import com.sk89q.worldedit.extent.clipboard.Clipboard;
import de.steamwar.core.worldedit.WorldEditWrapper;
import de.steamwar.core.WorldEditWrapper;
import de.steamwar.entity.REntity;
import de.steamwar.entity.REntityServer;
import de.steamwar.entity.RPlayer;
@@ -19,7 +19,6 @@
package de.steamwar.fightsystem.states;
import de.steamwar.fightsystem.commands.FightSWCommand;
import lombok.Getter;
import java.util.*;
@@ -63,7 +62,6 @@ public enum FightState {
}
public static void setFightState(FightState state) {
if (fightState.equals(state)) return;
fightState = state;
for (Map.Entry<IStateDependent, Boolean> feature : stateDependentFeatures.entrySet()) {
@@ -79,7 +77,6 @@ public enum FightState {
feature.setValue(false);
}
}
FightSWCommand.postFightStateChange();
}
public static boolean setup() {
@@ -0,0 +1,58 @@
/*
* This file is a part of the SteamWar software.
*
* Copyright (C) 2025 SteamWar.de-Serverteam
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package de.steamwar.fightsystem.states;
import de.steamwar.fightsystem.ArenaMode;
import de.steamwar.fightsystem.FightSystem;
import net.md_5.bungee.api.ChatMessageType;
import org.bukkit.command.CommandExecutor;
import org.bukkit.command.PluginCommand;
import java.util.Set;
public class StateDependentCommand extends StateDependent {
private static final CommandExecutor unavailable = (sender, cmd, s, strings) -> {
FightSystem.getMessage().sendPrefixless("COMMAND_CURRENTLY_UNAVAILABLE", sender, ChatMessageType.ACTION_BAR);
return false;
};
private final PluginCommand command;
private final CommandExecutor executor;
public StateDependentCommand(Set<ArenaMode> mode, Set<FightState> states, String name, CommandExecutor executor) {
super(mode, states);
this.executor = executor;
this.command = FightSystem.getPlugin().getCommand(name);
assert command != null;
disable();
register();
}
@Override
public void enable() {
command.setExecutor(executor);
}
@Override
public void disable() {
command.setExecutor(unavailable);
}
}
+19 -1
View File
@@ -10,4 +10,22 @@ depend:
- WorldEdit
api-version: "1.13"
commands:
commands:
ak:
request:
requests:
fightinfo:
leave:
ready:
kit:
remove:
lockschem:
state:
skip:
win:
resetwg:
resettb:
tpslimit:
tpswarp:
techhiderbug:
unrank:
-12
View File
@@ -53,15 +53,3 @@ tasks.register<FightServer>("WarGear21") {
config = "WarGear21.yml"
jar = "/jars/paper-1.21.6.jar"
}
tasks.register<FightServer>("WarShip21") {
group = "run"
description = "Run a WarShip 1.21 Fight Server"
dependsOn(":SpigotCore:shadowJar")
dependsOn(":FightSystem:shadowJar")
dependsOn(":KotlinCore:shadowJar")
template = "WarShip21"
worldName = "arenas/Artic"
config = "WarShip21.yml"
jar = "/jars/paper-1.21.6.jar"
}
-8
View File
@@ -1,5 +1,3 @@
import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
/*
* This file is a part of the SteamWar software.
*
@@ -36,7 +34,6 @@ dependencies {
compileOnly(libs.paperapi)
compileOnly(project(":SpigotCore"))
implementation(libs.coroutinesCore)
implementation(libs.exposedCore)
implementation(libs.exposedDao)
implementation(libs.exposedJdbc)
@@ -44,8 +41,3 @@ dependencies {
implementation(libs.mysql)
implementation("org.slf4j:slf4j-simple:2.0.17")
}
val compileKotlin: KotlinCompile by tasks
compileKotlin.compilerOptions {
freeCompilerArgs.set(listOf("-XXLanguage:+ContextParameters"))
}
@@ -1,23 +0,0 @@
/*
* This file is a part of the SteamWar software.
*
* Copyright (C) 2026 SteamWar.de-Serverteam
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package de.steamwar.kotlin.ui
@DslMarker
annotation class RenderMarker()
@@ -1,26 +0,0 @@
/*
* This file is a part of the SteamWar software.
*
* Copyright (C) 2026 SteamWar.de-Serverteam
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package de.steamwar.kotlin.ui
interface RenderObject {
fun destroy()
fun render()
}
@@ -1,90 +0,0 @@
/*
* This file is a part of the SteamWar software.
*
* Copyright (C) 2026 SteamWar.de-Serverteam
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package de.steamwar.kotlin.ui
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.ExperimentalForInheritanceCoroutinesApi
import kotlinx.coroutines.SupervisorJob
import kotlinx.coroutines.flow.FlowCollector
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.drop
import kotlinx.coroutines.flow.launchIn
import kotlinx.coroutines.flow.onEach
import kotlin.reflect.KProperty
private val uiStateScope = CoroutineScope(SupervisorJob() + Dispatchers.Unconfined)
context(render: StateFlowListener)
fun <T> StateFlow<T>.listen(): StateFlow<T> {
render.track(this) {
drop(1).onEach { render.update() }.launchIn(uiStateScope)
}
return this
}
context(render: StateFlowListener)
fun <T> MutableStateFlow<T>.listen(): MutableStateFlow<T> {
render.track(this) {
drop(1).onEach { render.update() }.launchIn(uiStateScope)
}
return this
}
fun <T> StateFlow<T>.listen(callback: (T) -> Unit): () -> Unit {
callback(value)
val job = drop(1).onEach { callback(it) }.launchIn(uiStateScope)
return { job.cancel() }
}
operator fun <T> StateFlow<T>.getValue(thisRef: Any?, property: KProperty<*>): T = value
operator fun <T> MutableStateFlow<T>.setValue(thisRef: Any?, property: KProperty<*>, value: T) {
this.value = value
}
fun <T, R> StateFlow<T>.map(mapper: (T) -> R): StateFlow<R> = MappedStateFlow(this, mapper)
@OptIn(ExperimentalForInheritanceCoroutinesApi::class)
private class MappedStateFlow<T, R>(
private val parent: StateFlow<T>,
private val mapper: (T) -> R,
): StateFlow<R> {
override val replayCache: List<R>
get() = listOf(value)
override val value: R
get() = mapper(parent.value)
override suspend fun collect(collector: FlowCollector<R>): Nothing {
var initialized = false
var previous: Any? = null
parent.collect {
val mapped = mapper(it)
if (!initialized || previous != mapped) {
initialized = true
previous = mapped
collector.emit(mapped)
}
}
}
}
@@ -1,41 +0,0 @@
/*
* This file is a part of the SteamWar software.
*
* Copyright (C) 2026 SteamWar.de-Serverteam
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package de.steamwar.kotlin.ui
import kotlinx.coroutines.Job
abstract class StateFlowListener {
private val jobs = mutableMapOf<Any, Job>()
internal fun track(key: Any, createJob: () -> Job) {
if (key in jobs) return
val job = createJob()
jobs[key] = job
job.invokeOnCompletion { jobs.remove(key) }
}
abstract fun update()
open fun destroy() {
jobs.values.toList().forEach { it.cancel() }
jobs.clear()
}
}
@@ -1,46 +0,0 @@
/*
* This file is a part of the SteamWar software.
*
* Copyright (C) 2026 SteamWar.de-Serverteam
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package de.steamwar.kotlin.ui
import de.steamwar.kotlin.ui.components.item
import de.steamwar.kotlin.util.count
import kotlinx.coroutines.flow.MutableStateFlow
import org.bukkit.Material
import org.bukkit.entity.Player
import org.bukkit.inventory.ItemStack
val Counter = MutableStateFlow(0)
class TestInv(player: Player): UIInventory(player) {
override fun view() {
inventory(3, "") {
item {
val amount by Counter.map { it + 1 }.listen()
item = ItemStack.of(Material.STONE)
.count(amount)
x = 0
y = 0
onClick {
Counter.value += 1
}
}
}
}
}
@@ -1,55 +0,0 @@
/*
* This file is a part of the SteamWar software.
*
* Copyright (C) 2026 SteamWar.de-Serverteam
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package de.steamwar.kotlin.ui
import de.steamwar.kotlin.ui.context.WindowContext
import org.bukkit.entity.Player
import org.bukkit.event.inventory.InventoryType
abstract class UIInventory(val player: Player): StateFlowListener() {
var window: UIWindow? = null
abstract fun view()
fun open() {
if (window == null) {
view()
assert(window != null) { "View method must create a inventory" }
}
window!!.open()
}
fun render() {
window?.onClose()
window = null
open()
}
override fun update() = render()
protected fun inventory(size: Int, title: String, init: WindowContext.() -> Unit) {
window = UIWindow(size, title, player, init)
}
protected fun inventory(type: InventoryType, title: String, init: WindowContext.() -> Unit) {
window = UIWindow(type, title, player, init)
}
}
@@ -1,91 +0,0 @@
/*
* This file is a part of the SteamWar software.
*
* Copyright (C) 2026 SteamWar.de-Serverteam
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package de.steamwar.kotlin.ui
import de.steamwar.kotlin.KotlinCore
import de.steamwar.kotlin.ui.context.WindowContext
import net.kyori.adventure.text.Component
import org.bukkit.Bukkit
import org.bukkit.entity.Player
import org.bukkit.event.EventHandler
import org.bukkit.event.Listener
import org.bukkit.event.inventory.ClickType
import org.bukkit.event.inventory.InventoryClickEvent
import org.bukkit.event.inventory.InventoryCloseEvent
import org.bukkit.event.inventory.InventoryType
import org.bukkit.inventory.Inventory
import org.bukkit.inventory.InventoryHolder
import org.bukkit.inventory.InventoryView
class UIWindow(val player: Player, val render: WindowContext.() -> Unit): InventoryHolder {
val onClicks = mutableMapOf<Int, (event: InventoryClickEvent) -> Unit>()
private var updating = false
lateinit var bukkitInv: Inventory
private set
val context by lazy { WindowContext(this) }
constructor(size: Int, title: String, player: Player, render: WindowContext.() -> Unit): this(player, render) {
bukkitInv = KotlinCore.plugin.server.createInventory(this, size * 9, Component.translatable(title))
}
constructor(type: InventoryType, title: String, player: Player, render: WindowContext.() -> Unit): this(player, render) {
assert(type != InventoryType.CHEST) { "Chest inventories should use the constructor with size" }
bukkitInv = KotlinCore.plugin.server.createInventory(this, type, Component.translatable(title))
}
fun open() {
render(context)
player.openInventory(bukkitInv)
}
fun onClose() {
if (updating) return
onClicks.clear()
context.destroy()
}
override fun getInventory() = bukkitInv
companion object : Listener {
init {
Bukkit.getPluginManager().registerEvents(this, KotlinCore.plugin)
}
@EventHandler
fun onInventoryClick(event: InventoryClickEvent) {
val window = event.inventory.holder
if (window is UIWindow) {
event.isCancelled = true
if (window.context.skipDoubleClick && event.click == ClickType.DOUBLE_CLICK) return
window.onClicks[event.slot]?.invoke(event)
}
}
@EventHandler
fun onInventoryClose(event: InventoryCloseEvent) {
val window = event.inventory.holder
if (window is UIWindow) {
window.onClose()
}
}
}
}
@@ -1,66 +0,0 @@
/*
* This file is a part of the SteamWar software.
*
* Copyright (C) 2026 SteamWar.de-Serverteam
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package de.steamwar.kotlin.ui.components
import de.steamwar.kotlin.ui.StateFlowListener
import de.steamwar.kotlin.ui.RenderMarker
import de.steamwar.kotlin.ui.RenderObject
import de.steamwar.kotlin.ui.context.GroupContext
import de.steamwar.kotlin.ui.context.RenderParent
import org.bukkit.Material
import org.bukkit.event.inventory.InventoryClickEvent
import org.bukkit.inventory.ItemStack
@RenderMarker
class ItemContext(val parent: RenderParent, val renderFunc: ItemContext.() -> Unit): RenderObject, StateFlowListener() {
override fun update() {
val oldX = x
val oldY = y
render()
if (oldX != x || oldY != y) {
parent.resetSlot(oldX, oldY)
}
}
override fun destroy() {
super.destroy()
parent.resetSlot(x, y)
}
override fun render() {
renderFunc(this)
parent.renderItem(x, y, item, onClick)
}
init {
render()
}
var item: ItemStack = ItemStack.of(Material.AIR)
var onClick: (event: InventoryClickEvent) -> Unit = {}
var x: Int = 0
var y: Int = 0
fun onClick(func: (event: InventoryClickEvent) -> Unit) {
onClick = func
}
}
fun GroupContext.item(init: ItemContext.() -> Unit) = children.add(ItemContext(this, init))
@@ -1,65 +0,0 @@
/*
* This file is a part of the SteamWar software.
*
* Copyright (C) 2026 SteamWar.de-Serverteam
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package de.steamwar.kotlin.ui.context
import de.steamwar.kotlin.ui.StateFlowListener
import de.steamwar.kotlin.ui.RenderMarker
import de.steamwar.kotlin.ui.RenderObject
import org.bukkit.event.inventory.InventoryClickEvent
import org.bukkit.inventory.ItemStack
@RenderMarker
open class GroupContext(val parent: RenderParent?, val init: GroupContext.() -> Unit): StateFlowListener(), RenderObject, RenderParent {
val children = mutableListOf<RenderObject>()
val updatedSlots = mutableSetOf<Pair<Int, Int>>()
override fun update() = render()
override fun destroy() {
children.forEach { it.destroy() }
super.destroy()
}
init {
init(this)
}
override fun renderItem(x: Int, y: Int, item: ItemStack, onClick: (event: InventoryClickEvent) -> Unit) {
updatedSlots.add(x to y)
parent?.renderItem(x, y, item, onClick)
}
override fun resetSlot(x: Int, y: Int) {
parent?.resetSlot(x, y)
}
fun group(init: GroupContext.() -> Unit) {
children.add(GroupContext(this, init))
}
override fun render() {
children.forEach { it.destroy() }
children.clear()
val oldUpdatedSlots = updatedSlots.toList()
updatedSlots.clear()
init(this)
(oldUpdatedSlots - updatedSlots).forEach { resetSlot(it.first, it.second) }
}
}
@@ -1,29 +0,0 @@
/*
* This file is a part of the SteamWar software.
*
* Copyright (C) 2026 SteamWar.de-Serverteam
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package de.steamwar.kotlin.ui.context
import org.bukkit.event.inventory.InventoryClickEvent
import org.bukkit.inventory.ItemStack
interface RenderParent {
fun renderItem(x: Int, y: Int, item: ItemStack, onClick: (event: InventoryClickEvent) -> Unit)
fun resetSlot(x: Int, y: Int)
}
@@ -1,54 +0,0 @@
/*
* This file is a part of the SteamWar software.
*
* Copyright (C) 2026 SteamWar.de-Serverteam
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package de.steamwar.kotlin.ui.context
import de.steamwar.kotlin.ui.RenderMarker
import de.steamwar.kotlin.ui.UIWindow
import org.bukkit.Material
import org.bukkit.event.inventory.InventoryClickEvent
import org.bukkit.event.inventory.InventoryType
import org.bukkit.inventory.ItemStack
@RenderMarker
class WindowContext(val window: UIWindow): GroupContext(null, {}) {
override fun renderItem(x: Int, y: Int, item: ItemStack, onClick: (event: InventoryClickEvent) -> Unit) {
val slot = calculateSlot(x, y)
window.bukkitInv.setItem(slot, item)
window.onClicks[slot] = onClick
}
override fun resetSlot(x: Int, y: Int) {
val slot = calculateSlot(x, y)
window.bukkitInv.setItem(slot, ItemStack.of(Material.AIR))
window.onClicks.remove(slot)
}
private fun calculateSlot(x: Int, y: Int) = when (window.inventory.type) {
InventoryType.DROPPER, InventoryType.DISPENSER -> x + y * 3
InventoryType.HOPPER -> x
else -> x + y * 9
}
fun outsideClick(click: (event: InventoryClickEvent) -> Unit) {
window.onClicks[-999] = click
}
var skipDoubleClick = true
}
@@ -1,50 +0,0 @@
/*
* This file is a part of the SteamWar software.
*
* Copyright (C) 2026 SteamWar.de-Serverteam
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package de.steamwar.kotlin.util
import net.kyori.adventure.text.Component
import org.bukkit.Bukkit
import org.bukkit.Material
import org.bukkit.enchantments.Enchantment
import org.bukkit.inventory.ItemFlag
import org.bukkit.inventory.ItemStack
import org.bukkit.inventory.meta.SkullMeta
import org.bukkit.inventory.meta.components.CustomModelDataComponent
fun ItemStack.count(count: Int) = apply { amount = count }
fun ItemStack.name(name: Component) = apply { itemMeta = itemMeta.also { it.displayName(name) } }
fun ItemStack.lored(lore: List<Component>) = apply { itemMeta = itemMeta.also { it.lore(lore) } }
fun String.asMaterial(): Material = Material.matchMaterial(this) ?: Material.BARRIER
fun skull(owner: String): ItemStack = ItemStack(Material.PLAYER_HEAD)
.also {
it.editMeta(SkullMeta::class.java) {
it.playerProfile = Bukkit.getOfflinePlayer(owner.trimStart('.')).playerProfile.also { pp -> pp.complete() }
}
}
fun ItemStack.hideAttributes() = apply { itemMeta = itemMeta.also { it.addItemFlags(*ItemFlag.entries.toTypedArray()) } }
fun ItemStack.enchanted() = apply { itemMeta = itemMeta.also { it.addEnchant(Enchantment.UNBREAKING, 10, true) } }
fun ItemStack.customModelData(model: CustomModelDataComponent) = apply { itemMeta = itemMeta.also { it.setCustomModelDataComponent(model) } }
+3 -4
View File
@@ -38,12 +38,11 @@ widener {
fromCatalog(libs.paperapi)
}
tasks.register<DevServer>("DevLobby") {
tasks.register<DevServer>("DevLobby20") {
group = "run"
description = "Run a Dev Lobby"
description = "Run a 1.20 Dev Lobby"
dependsOn(":SpigotCore:shadowJar")
dependsOn(":KotlinCore:shadowJar")
dependsOn(":LobbySystem:jar")
template = "Lobby21"
template = "Lobby20"
worldName = "Lobby"
}
@@ -20,6 +20,7 @@
package de.steamwar.lobby.boatrace;
import de.steamwar.entity.REntity;
import de.steamwar.entity.REntityAction;
import de.steamwar.entity.REntityServer;
import de.steamwar.entity.RInteraction;
import de.steamwar.lobby.LobbySystem;
@@ -35,7 +36,6 @@ import org.bukkit.entity.Boat;
import org.bukkit.entity.Entity;
import org.bukkit.entity.EntityType;
import org.bukkit.entity.Player;
import org.bukkit.entity.boat.*;
import org.bukkit.event.EventHandler;
import org.bukkit.event.HandlerList;
import org.bukkit.event.Listener;
@@ -44,7 +44,6 @@ import org.bukkit.event.vehicle.VehicleMoveEvent;
import org.bukkit.scheduler.BukkitTask;
import java.util.EventListener;
import java.util.Random;
import static de.steamwar.lobby.util.LeaderboardManager.renderTime;
@@ -62,11 +61,11 @@ public class BoatRace implements EventListener, Listener {
static {
boatNpcServer = new REntityServer();
new REntity(boatNpcServer, EntityType.VILLAGER, BoatRacePositions.NPC);
RInteraction interaction = new RInteraction(boatNpcServer, BoatRacePositions.NPC.clone());
RInteraction interaction = new RInteraction(boatNpcServer, BoatRacePositions.NPC.clone().subtract(0.5, 0, 0.5));
interaction.setInteractionHeight(1.95f);
interaction.setCallback((player, entity, action) -> {
Bukkit.getWorlds().get(0).getEntities().stream().filter(e -> e.getType() == EntityType.END_CRYSTAL).forEach(Entity::remove);
if (!oneNotStarted) {
if (action == REntityAction.INTERACT && !oneNotStarted) {
oneNotStarted = true;
new BoatRace(player);
}
@@ -154,24 +153,10 @@ public class BoatRace implements EventListener, Listener {
oneNotStarted = false;
}
private final Class<? extends Boat>[] boatClasses = new Class[]{
AcaciaBoat.class,
BambooRaft.class,
BirchBoat.class,
CherryBoat.class,
DarkOakBoat.class,
JungleBoat.class,
MangroveBoat.class,
OakBoat.class,
PaleOakBoat.class,
SpruceBoat.class,
};
private final Random random = new Random();
public BoatRace(Player player) {
this.player = player;
boat = Bukkit.getWorlds().get(0).spawn(BoatRacePositions.START, boatClasses[random.nextInt(boatClasses.length)]);
boat = Bukkit.getWorlds().get(0).spawn(BoatRacePositions.START, Boat.class);
// boat.setBoatType(Boat.Type.values()[new Random().nextInt(Boat.Type.values().length)]);
boat.addPassenger(player);
bossBar = Bukkit.createBossBar("", BarColor.BLUE, BarStyle.SOLID);
task = Bukkit.getScheduler().runTaskTimer(LobbySystem.getInstance(), () -> {
@@ -42,10 +42,7 @@ import java.awt.image.BufferedImage;
import java.awt.image.WritableRaster;
import java.io.File;
import java.io.IOException;
import java.time.LocalDateTime;
import java.time.Month;
import java.util.*;
import java.util.concurrent.atomic.AtomicReference;
public class CustomMap implements Listener {
@@ -59,7 +56,7 @@ public class CustomMap implements Listener {
new Vector(2346, 45, 1297), new Vector(2345, 45, 1297), new Vector(2344, 45, 1297), new Vector(2343, 45, 1297), new Vector(2342, 45, 1297), new Vector(2341, 45, 1297), new Vector(2340, 45, 1297)
);
private static final CustomMap RIGHT = new CustomMap(new File(System.getProperty("user.home") + "/lobbyBanner/right/"),
private static final CustomMap RIGHT = new CustomMap(new File(System.getProperty("user.home") + "/lobbyBanner/right.png"),
new Vector(2330, 48, 1297), new Vector(2329, 48, 1297), new Vector(2328, 48, 1297), new Vector(2327, 48, 1297), new Vector(2326, 48, 1297), new Vector(2325, 48, 1297), new Vector(2324, 48, 1297),
new Vector(2330, 47, 1297), new Vector(2329, 47, 1297), new Vector(2328, 47, 1297), new Vector(2327, 47, 1297), new Vector(2326, 47, 1297), new Vector(2325, 47, 1297), new Vector(2324, 47, 1297),
new Vector(2330, 46, 1297), new Vector(2329, 46, 1297), new Vector(2328, 46, 1297), new Vector(2327, 46, 1297), new Vector(2326, 46, 1297), new Vector(2325, 46, 1297), new Vector(2324, 46, 1297),
@@ -69,52 +66,30 @@ public class CustomMap implements Listener {
private File mapFile;
private Map<Vector, Integer> itemFrameIndex = new HashMap<>();
private ItemFrame[] itemFrames;
private boolean update = true;
private long lastModified = Long.MAX_VALUE;
public CustomMap(File mapFileOrDirectory, Vector... itemFrames) {
this.mapFile = mapFileOrDirectory;
public CustomMap(File mapFile, Vector... itemFrames) {
this.mapFile = mapFile;
this.itemFrames = new ItemFrame[itemFrames.length];
for (int i = 0; i < itemFrames.length; i++) {
itemFrameIndex.put(itemFrames[i], i);
}
if (mapFileOrDirectory.isDirectory()) {
AtomicReference<Month> lastMonth = new AtomicReference<>(LocalDateTime.now().getMonth());
AtomicReference<Long> lastModified = new AtomicReference<>(Long.MAX_VALUE);
Bukkit.getScheduler().runTaskTimer(LobbySystem.getInstance(), () -> {
long modified = mapFileOrDirectory.lastModified();
Month current = LocalDateTime.now().getMonth();
if (modified > lastModified.get() || !current.equals(lastMonth.get()) || update) {
lastModified.set(modified);
lastMonth.set(current);
update = false;
this.mapFile = new File(mapFileOrDirectory, current.getValue() + ".png");
update();
}
}, 200L, 1200L);
} else {
AtomicReference<Long> lastModified = new AtomicReference<>(Long.MAX_VALUE);
Bukkit.getScheduler().runTaskTimer(LobbySystem.getInstance(), () -> {
long modified = mapFileOrDirectory.lastModified();
if (modified > lastModified.get() || update) {
lastModified.set(modified);
update = false;
update();
}
}, 200L, 200L);
}
Bukkit.getPluginManager().registerEvents(this, LobbySystem.getInstance());
}
private void update() {
System.out.println("Updating Banner: " + mapFile.getName());
Bukkit.getScheduler().runTaskAsynchronously(LobbySystem.getInstance(), () -> {
try {
run();
} catch (IOException e) {
// Ignore
Bukkit.getScheduler().runTaskTimer(LobbySystem.getInstance(), () -> {
long modified = mapFile.lastModified();
if (modified > lastModified) {
lastModified = modified;
System.out.println("Updating Banner: " + mapFile.getName());
Bukkit.getScheduler().runTaskAsynchronously(LobbySystem.getInstance(), () -> {
try {
run();
} catch (IOException e) {
// Ignore
}
});
}
});
}, 200L, 200L);
Bukkit.getPluginManager().registerEvents(this, LobbySystem.getInstance());
}
@EventHandler
@@ -126,7 +101,7 @@ public class CustomMap implements Listener {
if (itemFrameIndex.containsKey(vector)) {
if (itemFrames[itemFrameIndex.get(vector)] != null) continue;
itemFrames[itemFrameIndex.get(vector)] = itemFrame;
update = true;
lastModified = 0;
ItemStack itemStack = new ItemStack(Material.FILLED_MAP, 1);
MapMeta mapMeta = (MapMeta) itemStack.getItemMeta();

Some files were not shown because too many files have changed in this diff Show More