From 8e8da27f988b8884aa2115c3f4b912642c326ec7 Mon Sep 17 00:00:00 2001 From: tastybento Date: Sat, 22 Apr 2023 22:11:18 -0700 Subject: [PATCH 01/11] Store and trigger advancements for entering structures. --- .../boxed/listeners/AdvancementListener.java | 19 +++- .../boxed/listeners/NewAreaListener.java | 93 ++++++++++++++++++- .../boxed/objects/IslandStructures.java | 76 +++++++++++++++ 3 files changed, 181 insertions(+), 7 deletions(-) create mode 100644 src/main/java/world/bentobox/boxed/objects/IslandStructures.java diff --git a/src/main/java/world/bentobox/boxed/listeners/AdvancementListener.java b/src/main/java/world/bentobox/boxed/listeners/AdvancementListener.java index 444a761..651b4c9 100644 --- a/src/main/java/world/bentobox/boxed/listeners/AdvancementListener.java +++ b/src/main/java/world/bentobox/boxed/listeners/AdvancementListener.java @@ -30,6 +30,7 @@ import org.bukkit.event.player.PlayerMoveEvent; import org.bukkit.event.player.PlayerPortalEvent; import org.bukkit.event.player.PlayerTeleportEvent.TeleportCause; +import world.bentobox.bentobox.BentoBox; import world.bentobox.bentobox.api.events.island.IslandNewIslandEvent; import world.bentobox.bentobox.api.events.team.TeamJoinedEvent; import world.bentobox.bentobox.api.events.team.TeamLeaveEvent; @@ -66,7 +67,7 @@ public class AdvancementListener implements Listener { } - private Advancement getAdvancement(String string) { + public static Advancement getAdvancement(String string) { return StreamSupport.stream( Spliterators.spliteratorUnknownSize(Bukkit.advancementIterator(), Spliterator.ORDERED), false) .filter(a -> a.getKey().toString().equals(string)) @@ -191,14 +192,28 @@ public class AdvancementListener implements Listener { } - private void giveAdv(Player player, Advancement adv) { + public static void giveAdv(Player player, Advancement adv) { + //BentoBox.getInstance().logDebug("Give Adv " + adv.getKey() + " done status " + player.getAdvancementProgress(adv).isDone()); if (adv != null && !player.getAdvancementProgress(adv).isDone()) { + BentoBox.getInstance().logDebug("Awarding "); + //adv.getCriteria().forEach(c -> BentoBox.getInstance().logDebug("Criteria = " + c)); adv.getCriteria().forEach(player.getAdvancementProgress(adv)::awardCriteria); } } @EventHandler(priority = EventPriority.NORMAL, ignoreCancelled = true) public void onPlayerJoin(PlayerJoinEvent e) { + /* + StreamSupport.stream( + Spliterators.spliteratorUnknownSize(Bukkit.advancementIterator(), Spliterator.ORDERED), false).forEach(a-> { + AdvancementProgress progress = e.getPlayer().getAdvancementProgress(a); + BentoBox.getInstance().logDebug(a.getKey() + " " + progress.isDone()); + BentoBox.getInstance().logDebug("Awarded"); + progress.getAwardedCriteria().forEach(c -> BentoBox.getInstance().logDebug(c)); + BentoBox.getInstance().logDebug("Remaining"); + progress.getRemainingCriteria().forEach(c -> BentoBox.getInstance().logDebug(c)); + }); + */ User user = User.getInstance(e.getPlayer()); if (Util.sameWorld(addon.getOverWorld(), e.getPlayer().getWorld())) { // Set advancements to same as island diff --git a/src/main/java/world/bentobox/boxed/listeners/NewAreaListener.java b/src/main/java/world/bentobox/boxed/listeners/NewAreaListener.java index 77c3acd..eab9f94 100644 --- a/src/main/java/world/bentobox/boxed/listeners/NewAreaListener.java +++ b/src/main/java/world/bentobox/boxed/listeners/NewAreaListener.java @@ -2,10 +2,12 @@ package world.bentobox.boxed.listeners; import java.io.File; import java.lang.reflect.Field; +import java.util.HashMap; import java.util.LinkedList; import java.util.List; import java.util.Locale; import java.util.Map; +import java.util.Objects; import java.util.Queue; import java.util.Random; @@ -26,9 +28,11 @@ import org.bukkit.configuration.ConfigurationSection; import org.bukkit.configuration.file.YamlConfiguration; import org.bukkit.craftbukkit.v1_19_R3.CraftWorld; import org.bukkit.entity.EntityType; +import org.bukkit.entity.Player; import org.bukkit.event.EventHandler; import org.bukkit.event.EventPriority; import org.bukkit.event.Listener; +import org.bukkit.event.player.PlayerMoveEvent; import org.bukkit.loot.LootTables; import org.bukkit.structure.Structure; import org.bukkit.util.BoundingBox; @@ -45,12 +49,14 @@ import world.bentobox.bentobox.BentoBox; import world.bentobox.bentobox.api.events.BentoBoxReadyEvent; import world.bentobox.bentobox.api.events.island.IslandCreatedEvent; import world.bentobox.bentobox.api.events.island.IslandResettedEvent; +import world.bentobox.bentobox.database.Database; import world.bentobox.bentobox.database.objects.Island; import world.bentobox.bentobox.util.Pair; import world.bentobox.bentobox.util.Util; import world.bentobox.boxed.Boxed; import world.bentobox.boxed.objects.BoxedJigsawBlock; import world.bentobox.boxed.objects.BoxedStructureBlock; +import world.bentobox.boxed.objects.IslandStructures; /** * @author tastybento @@ -59,6 +65,14 @@ import world.bentobox.boxed.objects.BoxedStructureBlock; public class NewAreaListener implements Listener { private static final List CARDINALS = List.of(BlockFace.NORTH, BlockFace.SOUTH, BlockFace.EAST, BlockFace.WEST); + private static final List STRUCTURES = List.of("ancient_city", "bastion_remnant", "bastion", + "buried_treasure", "desert_pyramid", "end_city", + "fortress", "igloo", "jungle_pyramid", "mansion", "mineshaft", "mineshaft_mesa", + "monument", "nether_fossil", "ocean_ruin_cold", "ocean_ruin_warm", "pillager_outpost", + "ruined_portal_desert", "ruined_portal_jungle", "ruined_portal_mountain", "ruined_portal_nether", + "ruined_portal_ocean", "ruined_portal_swamp", "ruined_portal", "shipwreck_beached", + "shipwreck", "stronghold", "swamp_hut", "village_desert", "village_plains", + "village_savanna", "village_snowy", "village_taiga"); private final Boxed addon; private File structureFile; private Queue itemsToBuild = new LinkedList<>(); @@ -68,6 +82,10 @@ public class NewAreaListener implements Listener { private record Item(String name, Structure structure, Location location, StructureRotation rot, Mirror mirror) {}; Pair min = new Pair(0,0); Pair max = new Pair(0,0); + // Database handler for structure data + private final Database handler; + private Map islandStructureCache = new HashMap<>(); + /** @@ -78,7 +96,8 @@ public class NewAreaListener implements Listener { addon.saveResource("structures.yml", false); // Load the config structureFile = new File(addon.getDataFolder(), "structures.yml"); - + // Get database ready + handler = new Database<>(addon, IslandStructures.class); // Try to build something every second Bukkit.getScheduler().runTaskTimer(addon.getPlugin(), () -> BuildItem(), 20, 20); } @@ -96,7 +115,7 @@ public class NewAreaListener implements Listener { * Build a list of structures * @param event event */ - @EventHandler() + @EventHandler(priority = EventPriority.NORMAL, ignoreCancelled = true) public void onBentoBoxReady(BentoBoxReadyEvent event) { addon.saveResource("templates.yml", false); File templateFile = new File(addon.getDataFolder(), "templates.yml"); @@ -113,6 +132,58 @@ public class NewAreaListener implements Listener { } + @EventHandler(priority = EventPriority.NORMAL, ignoreCancelled = true) + public void onPlayerMove(PlayerMoveEvent e) { + // Ignore head movements + if (!addon.inWorld(e.getFrom().getWorld()) || e.getFrom().toVector().equals(e.getTo().toVector())) { + return; + } + // Check where the player is + addon.getIslands().getIslandAt(e.getTo()).ifPresent(island -> { + // See if island is in cache + final String islandId = island.getUniqueId(); + IslandStructures is = getIslandStructData(islandId); + // Check if player is in any of the structures + Map structures = e.getTo().getWorld().getEnvironment().equals(Environment.NETHER) ? + is.getNetherStructureBoundingBoxMap():is.getStructureBoundingBoxMap(); + for (Map.Entry en:structures.entrySet()) { + if (en.getKey().contains(e.getTo().toVector())) { + for (String s: STRUCTURES) { + if (en.getValue().startsWith(s)) { + giveAdvFromCriteria(e.getPlayer(), s); + } + } + //STRUCTURES.stream().filter(en.getValue()::startsWith).forEach(s -> giveAdvFromCriteria(e.getPlayer(), s)); + } + } + }); + } + + /** + * Gives a player all the advancements that have string as a named criteria + * @param player - player + * @param string - criteria + */ + private void giveAdvFromCriteria(Player player, String string) { + // Give every advancement that requires a bastion + Bukkit.advancementIterator().forEachRemaining(ad -> { + if (!player.getAdvancementProgress(ad).isDone()) { + for (String crit: ad.getCriteria()) { + if (crit.equals(string)) { + // Set the criteria (it may not complete the advancement completely + player.getAdvancementProgress(ad).awardCriteria(crit); + break; + } + } + } + }); + + } + + private IslandStructures getIslandStructData(String islandId) { + return this.islandStructureCache.computeIfAbsent(islandId, k -> Objects.requireNonNullElse(handler.loadObject(k), new IslandStructures(islandId))); + } + @EventHandler(priority = EventPriority.NORMAL, ignoreCancelled = true) public void onIslandCreated(IslandCreatedEvent event) { setUpIsland(event.getIsland()); @@ -185,7 +256,18 @@ public class NewAreaListener implements Listener { item.structure().place(item.location(), true, item.rot(), item.mirror(), -1, 1, rand); addon.log(item.name() + " placed at " + item.location().getWorld().getName() + " " + Util.xyz(item.location().toVector())); // Find it - removeJigsaw(item.location(), item.structure(), item.rot(), item.name()); + BoundingBox bb = removeJigsaw(item.location(), item.structure(), item.rot(), item.name()); + // Store it + addon.getIslands().getIslandAt(item.location()).map(Island::getUniqueId).ifPresent(id -> { + addon.log("Saved " + item.name()); + if (item.location().getWorld().getEnvironment().equals(Environment.NETHER)) { + getIslandStructData(id).addNetherStructure(bb, item.name()); + } else { + getIslandStructData(id).addStructure(bb, item.name()); + } + handler.saveObjectAsync(getIslandStructData(id)); + }); + pasting = false; } @@ -195,8 +277,9 @@ public class NewAreaListener implements Listener { * @param structure - structure that was placed * @param structureRotation - rotation of structure * @param key + * @return the resulting bounding box of the structure */ - public static void removeJigsaw(Location loc, Structure structure, StructureRotation structureRotation, String key) { + public static BoundingBox removeJigsaw(Location loc, Structure structure, StructureRotation structureRotation, String key) { Location otherCorner = switch (structureRotation) { case CLOCKWISE_180 -> loc.clone().add(new Vector(-structure.getSize().getX(), structure.getSize().getY(), -structure.getSize().getZ())); @@ -227,7 +310,7 @@ public class NewAreaListener implements Listener { } } } - + return bb; } diff --git a/src/main/java/world/bentobox/boxed/objects/IslandStructures.java b/src/main/java/world/bentobox/boxed/objects/IslandStructures.java new file mode 100644 index 0000000..a60203d --- /dev/null +++ b/src/main/java/world/bentobox/boxed/objects/IslandStructures.java @@ -0,0 +1,76 @@ +package world.bentobox.boxed.objects; + +import java.util.HashMap; +import java.util.Map; + +import org.bukkit.util.BoundingBox; + +import com.google.gson.annotations.Expose; + +import world.bentobox.bentobox.database.objects.DataObject; +import world.bentobox.bentobox.database.objects.Table; + +@Table(name = "IslandStructures") +public class IslandStructures implements DataObject { + + @Expose + String uniqueId; + @Expose + Map structureBoundingBoxMap = new HashMap<>(); + @Expose + Map netherStructureBoundingBoxMap = new HashMap<>(); + + public IslandStructures(String islandId) { + this.uniqueId = islandId; + } + + @Override + public String getUniqueId() { + return uniqueId; + } + + @Override + public void setUniqueId(String uniqueId) { + this.uniqueId = uniqueId; + } + + /** + * Add a structure for this island + * @param bb - bounding box of the structure + * @param key - structure namespace key + */ + public void addStructure(BoundingBox bb, String key) { + getStructureBoundingBoxMap().put(bb, key); + } + + public Map getStructureBoundingBoxMap() { + if (structureBoundingBoxMap == null) { + structureBoundingBoxMap = new HashMap<>(); + } + return structureBoundingBoxMap; + } + + public void setStructureBoundingBoxMap(Map structureBoundingBoxMap) { + this.structureBoundingBoxMap = structureBoundingBoxMap; + } + + /** + * Add a structure for this island + * @param bb - bounding box of the structure + * @param key - structure namespace key + */ + public void addNetherStructure(BoundingBox bb, String key) { + getNetherStructureBoundingBoxMap().put(bb, key); + } + + public Map getNetherStructureBoundingBoxMap() { + if (netherStructureBoundingBoxMap == null) { + netherStructureBoundingBoxMap = new HashMap<>(); + } + return netherStructureBoundingBoxMap; + } + + public void setNetherStructureBoundingBoxMap(Map netherStructureBoundingBoxMap) { + this.netherStructureBoundingBoxMap = netherStructureBoundingBoxMap; + } +} From 60999fc89ee104d948aa2bcce80be1e36ec6d4be Mon Sep 17 00:00:00 2001 From: tastybento Date: Sat, 29 Apr 2023 11:33:32 -0700 Subject: [PATCH 02/11] Version 2.0.4 --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 410f118..b67d651 100644 --- a/pom.xml +++ b/pom.xml @@ -65,7 +65,7 @@ -LOCAL - 2.0.3 + 2.0.4 BentoBoxWorld_Boxed bentobox-world From 20da0fd450181cc2c3cfdfe500aedf38c1643105 Mon Sep 17 00:00:00 2001 From: tastybento Date: Sat, 29 Apr 2023 11:33:49 -0700 Subject: [PATCH 03/11] Temporarily put in debug to track spawner issue --- .../bentobox/boxed/generators/chunks/BoxedBlockPopulator.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/main/java/world/bentobox/boxed/generators/chunks/BoxedBlockPopulator.java b/src/main/java/world/bentobox/boxed/generators/chunks/BoxedBlockPopulator.java index b36cb7f..d3c98a1 100644 --- a/src/main/java/world/bentobox/boxed/generators/chunks/BoxedBlockPopulator.java +++ b/src/main/java/world/bentobox/boxed/generators/chunks/BoxedBlockPopulator.java @@ -18,6 +18,7 @@ import org.bukkit.inventory.Inventory; import org.bukkit.inventory.InventoryHolder; import org.bukkit.util.Vector; +import world.bentobox.bentobox.BentoBox; import world.bentobox.bentobox.blueprints.dataobjects.BlueprintBlock; import world.bentobox.bentobox.blueprints.dataobjects.BlueprintCreatureSpawner; import world.bentobox.bentobox.util.Pair; @@ -117,6 +118,7 @@ public class BoxedBlockPopulator extends BlockPopulator { spawner.setDelay(s.getDelay()); spawner.setRequiredPlayerRange(s.getRequiredPlayerRange()); spawner.setSpawnRange(s.getSpawnRange()); + BentoBox.getInstance().logDebug("Set spawner at " + spawner.getLocation() + " to " + s.getSpawnedType()); spawner.update(true, false); } From 40ecdbdba66622acc54f3c3686defd3d02abf920 Mon Sep 17 00:00:00 2001 From: tastybento Date: Sat, 29 Apr 2023 12:10:55 -0700 Subject: [PATCH 04/11] Fix weird character in advancements.yml --- src/main/resources/advancements.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/resources/advancements.yml b/src/main/resources/advancements.yml index 71c1d1a..1b25253 100644 --- a/src/main/resources/advancements.yml +++ b/src/main/resources/advancements.yml @@ -9,7 +9,7 @@ advancements: 'exploration/jungle_in': 0 'exploration/write_book': 0 'forestry/sapling' : 0 -  'adventure/adventuring_time': 13 + 'adventure/adventuring_time': 13 'adventure/arbalistic': 11 'adventure/avoid_vibration': 13 'adventure/bullseye': 5 From 36162fe2935bdc8a4cf95f1f4852dada88f7ad69 Mon Sep 17 00:00:00 2001 From: tastybento Date: Sat, 29 Apr 2023 22:32:57 -0700 Subject: [PATCH 05/11] Fix bug with spawners not being set. --- pom.xml | 68 ++++++++++++++++--- src/main/java/world/bentobox/boxed/Boxed.java | 7 +- .../chunks/AbstractBoxedChunkGenerator.java | 8 ++- .../chunks/BoxedBlockPopulator.java | 15 ++-- .../chunks/BoxedChunkGenerator.java | 6 +- .../chunks/BoxedSeedChunkGenerator.java | 2 +- .../boxed/listeners/AdvancementListener.java | 3 - 7 files changed, 80 insertions(+), 29 deletions(-) diff --git a/pom.xml b/pom.xml index b67d651..e6fa1d7 100644 --- a/pom.xml +++ b/pom.xml @@ -150,7 +150,7 @@ org.mockito mockito-core - 4.8.0 + 3.11.1 test @@ -217,7 +217,7 @@ - + org.apache.maven.plugins maven-clean-plugin @@ -236,7 +236,7 @@ org.apache.maven.plugins maven-compiler-plugin - 3.7.0 + 3.8.1 ${java.version} @@ -247,15 +247,62 @@ 3.0.0-M5 - --illegal-access=permit + ${argLine} + --add-opens java.base/java.lang=ALL-UNNAMED + --add-opens java.base/java.math=ALL-UNNAMED + --add-opens java.base/java.io=ALL-UNNAMED + --add-opens java.base/java.util=ALL-UNNAMED + --add-opens + java.base/java.util.stream=ALL-UNNAMED + --add-opens java.base/java.text=ALL-UNNAMED + --add-opens + java.base/java.util.regex=ALL-UNNAMED + --add-opens + java.base/java.nio.channels.spi=ALL-UNNAMED + --add-opens java.base/sun.nio.ch=ALL-UNNAMED + --add-opens java.base/java.net=ALL-UNNAMED + --add-opens + java.base/java.util.concurrent=ALL-UNNAMED + --add-opens java.base/sun.nio.fs=ALL-UNNAMED + --add-opens java.base/sun.nio.cs=ALL-UNNAMED + --add-opens java.base/java.nio.file=ALL-UNNAMED + --add-opens + java.base/java.nio.charset=ALL-UNNAMED + --add-opens + java.base/java.lang.reflect=ALL-UNNAMED + --add-opens + java.logging/java.util.logging=ALL-UNNAMED + --add-opens java.base/java.lang.ref=ALL-UNNAMED + --add-opens java.base/java.util.jar=ALL-UNNAMED + --add-opens java.base/java.util.zip=ALL-UNNAMED - + org.apache.maven.plugins maven-jar-plugin 3.1.0 + + org.apache.maven.plugins + maven-javadoc-plugin + 3.3.0 + + false + -Xdoclint:none + + ${java.home}/bin/javadoc + + + + attach-javadocs + install + + jar + + + + org.apache.maven.plugins maven-source-plugin @@ -282,7 +329,7 @@ org.jacoco jacoco-maven-plugin - 0.8.3 + 0.8.7 true @@ -293,16 +340,21 @@ - pre-unit-test + prepare-agent prepare-agent - post-unit-test + report report + + + XML + + diff --git a/src/main/java/world/bentobox/boxed/Boxed.java b/src/main/java/world/bentobox/boxed/Boxed.java index bb6d325..352b966 100644 --- a/src/main/java/world/bentobox/boxed/Boxed.java +++ b/src/main/java/world/bentobox/boxed/Boxed.java @@ -280,7 +280,7 @@ public class Boxed extends GameModeAddon { int p = (int) (count / percent * 100); if (p % 10 == 0 && p != last) { last = p; - this.log("Storing seed chunks for " + world.getEnvironment() + " " + p + "% done"); + this.log("Pregenrating seed chunks for " + world.getName() + "'s " + world.getEnvironment() + " " + p + "% done"); } } @@ -293,10 +293,7 @@ public class Boxed extends GameModeAddon { * @return the chunkGenerator for the environment */ public AbstractBoxedChunkGenerator getChunkGenerator(Environment env) { - if (env.equals(Environment.NORMAL)) { - return chunkGenerator; - } - return netherChunkGenerator; + return env.equals(Environment.NORMAL) ? chunkGenerator : netherChunkGenerator; } /** diff --git a/src/main/java/world/bentobox/boxed/generators/chunks/AbstractBoxedChunkGenerator.java b/src/main/java/world/bentobox/boxed/generators/chunks/AbstractBoxedChunkGenerator.java index c5d6290..77d0407 100644 --- a/src/main/java/world/bentobox/boxed/generators/chunks/AbstractBoxedChunkGenerator.java +++ b/src/main/java/world/bentobox/boxed/generators/chunks/AbstractBoxedChunkGenerator.java @@ -53,12 +53,12 @@ public abstract class AbstractBoxedChunkGenerator extends ChunkGenerator { } } } - chunks.put(new Pair<>(x, z), new ChunkStore(chunk.getChunkSnapshot(), getEnts(chunk), getChests(chunk), chunkBiomes)); + chunks.put(new Pair<>(x, z), new ChunkStore(chunk.getChunkSnapshot(), getEnts(chunk), getTileEnts(chunk), chunkBiomes)); } protected abstract List getEnts(Chunk chunk); - protected abstract List getChests(Chunk chunk); + protected abstract List getTileEnts(Chunk chunk); /** * Get the chunk store for these chunk coords or null if there is none. @@ -84,13 +84,15 @@ public abstract class AbstractBoxedChunkGenerator extends ChunkGenerator { * @return mapped chunk coord */ public static int repeatCalc(int chunkCoord) { + return Math.floorMod(chunkCoord + size, size*2) - size; + /* int xx; if (chunkCoord > 0) { xx = Math.floorMod(chunkCoord + size, size*2) - size; } else { xx = Math.floorMod(chunkCoord - size, -size*2) + size; } - return xx; + return xx;*/ } /** diff --git a/src/main/java/world/bentobox/boxed/generators/chunks/BoxedBlockPopulator.java b/src/main/java/world/bentobox/boxed/generators/chunks/BoxedBlockPopulator.java index d3c98a1..811fd79 100644 --- a/src/main/java/world/bentobox/boxed/generators/chunks/BoxedBlockPopulator.java +++ b/src/main/java/world/bentobox/boxed/generators/chunks/BoxedBlockPopulator.java @@ -18,7 +18,6 @@ import org.bukkit.inventory.Inventory; import org.bukkit.inventory.InventoryHolder; import org.bukkit.util.Vector; -import world.bentobox.bentobox.BentoBox; import world.bentobox.bentobox.blueprints.dataobjects.BlueprintBlock; import world.bentobox.bentobox.blueprints.dataobjects.BlueprintCreatureSpawner; import world.bentobox.bentobox.util.Pair; @@ -53,7 +52,6 @@ public class BoxedBlockPopulator extends BlockPopulator { ChunkStore data = chunks.get(coords); // Paste entities data.bpEnts().forEach(e -> { - Location l = getLoc(world, e.relativeLoc().clone(), chunkX, chunkZ); if (limitedRegion.isInRegion(l)) { Entity ent = limitedRegion.spawnEntity(l, e.entity().getType()); @@ -62,10 +60,14 @@ public class BoxedBlockPopulator extends BlockPopulator { }); // Fill chests limitedRegion.getTileEntities().forEach(te -> { - for (ChestData cd : data.chests()) { - Location chestLoc = getLoc(world, cd.relativeLoc().clone(), chunkX, chunkZ); - if (limitedRegion.isInRegion(chestLoc) && te.getLocation().equals(chestLoc)) { - this.setBlockState(te, cd.chest()); + int teX = BoxedChunkGenerator.repeatCalc(te.getX() >> 4); + int teZ = BoxedChunkGenerator.repeatCalc(te.getZ() >> 4); + if (teX == xx && teZ == zz) { + for (ChestData cd : data.chests()) { + Location chestLoc = getLoc(world, cd.relativeLoc().clone(), chunkX, chunkZ); + if (limitedRegion.isInRegion(chestLoc) && te.getLocation().equals(chestLoc)) { + this.setBlockState(te, cd.chest()); + } } } }); @@ -118,7 +120,6 @@ public class BoxedBlockPopulator extends BlockPopulator { spawner.setDelay(s.getDelay()); spawner.setRequiredPlayerRange(s.getRequiredPlayerRange()); spawner.setSpawnRange(s.getSpawnRange()); - BentoBox.getInstance().logDebug("Set spawner at " + spawner.getLocation() + " to " + s.getSpawnedType()); spawner.update(true, false); } diff --git a/src/main/java/world/bentobox/boxed/generators/chunks/BoxedChunkGenerator.java b/src/main/java/world/bentobox/boxed/generators/chunks/BoxedChunkGenerator.java index c462e39..e4ca1f5 100644 --- a/src/main/java/world/bentobox/boxed/generators/chunks/BoxedChunkGenerator.java +++ b/src/main/java/world/bentobox/boxed/generators/chunks/BoxedChunkGenerator.java @@ -72,7 +72,7 @@ public class BoxedChunkGenerator extends AbstractBoxedChunkGenerator { } @Override - protected List getChests(Chunk chunk) { + protected List getTileEnts(Chunk chunk) { return Arrays.stream(chunk.getTileEntities()).map(t -> new ChestData(getLocInChunk(t.getLocation()), this.getBluePrintBlock(t.getBlock()))).toList(); } @@ -120,8 +120,10 @@ public class BoxedChunkGenerator extends AbstractBoxedChunkGenerator { return bpEnts; } + // Get the location in the chunk private Vector getLocInChunk(Location l) { - return new Vector(l.getBlockX() % 16, l.getBlockY(), l.getBlockZ() % 16); + // Have to use Math function because java % doesn't work correctly IMO with negatives + return new Vector(Math.floorMod(l.getBlockX(),16), l.getBlockY(), Math.floorMod(l.getBlockZ(), 16)); } diff --git a/src/main/java/world/bentobox/boxed/generators/chunks/BoxedSeedChunkGenerator.java b/src/main/java/world/bentobox/boxed/generators/chunks/BoxedSeedChunkGenerator.java index 81e40f2..6ba8dab 100644 --- a/src/main/java/world/bentobox/boxed/generators/chunks/BoxedSeedChunkGenerator.java +++ b/src/main/java/world/bentobox/boxed/generators/chunks/BoxedSeedChunkGenerator.java @@ -83,7 +83,7 @@ public class BoxedSeedChunkGenerator extends AbstractBoxedChunkGenerator { } @Override - protected List getChests(Chunk chunk) { + protected List getTileEnts(Chunk chunk) { // These won't be stored return null; } diff --git a/src/main/java/world/bentobox/boxed/listeners/AdvancementListener.java b/src/main/java/world/bentobox/boxed/listeners/AdvancementListener.java index 651b4c9..d65bf1a 100644 --- a/src/main/java/world/bentobox/boxed/listeners/AdvancementListener.java +++ b/src/main/java/world/bentobox/boxed/listeners/AdvancementListener.java @@ -30,7 +30,6 @@ import org.bukkit.event.player.PlayerMoveEvent; import org.bukkit.event.player.PlayerPortalEvent; import org.bukkit.event.player.PlayerTeleportEvent.TeleportCause; -import world.bentobox.bentobox.BentoBox; import world.bentobox.bentobox.api.events.island.IslandNewIslandEvent; import world.bentobox.bentobox.api.events.team.TeamJoinedEvent; import world.bentobox.bentobox.api.events.team.TeamLeaveEvent; @@ -195,8 +194,6 @@ public class AdvancementListener implements Listener { public static void giveAdv(Player player, Advancement adv) { //BentoBox.getInstance().logDebug("Give Adv " + adv.getKey() + " done status " + player.getAdvancementProgress(adv).isDone()); if (adv != null && !player.getAdvancementProgress(adv).isDone()) { - BentoBox.getInstance().logDebug("Awarding "); - //adv.getCriteria().forEach(c -> BentoBox.getInstance().logDebug("Criteria = " + c)); adv.getCriteria().forEach(player.getAdvancementProgress(adv)::awardCriteria); } } From 628068eb5d4e435e69f138244c14450450f9305d Mon Sep 17 00:00:00 2001 From: tastybento Date: Sun, 30 Apr 2023 09:39:26 -0700 Subject: [PATCH 06/11] Fixed bugs with structure placing and added more of them --- .../commands/AdminPlaceStructureCommand.java | 64 +++++++++++++++---- .../boxed/listeners/NewAreaListener.java | 54 +++++++++++----- src/main/resources/locales/en-US.yml | 12 ++++ src/main/resources/structures.yml | 16 ++++- 4 files changed, 114 insertions(+), 32 deletions(-) diff --git a/src/main/java/world/bentobox/boxed/commands/AdminPlaceStructureCommand.java b/src/main/java/world/bentobox/boxed/commands/AdminPlaceStructureCommand.java index 44b4fae..c27a5a5 100644 --- a/src/main/java/world/bentobox/boxed/commands/AdminPlaceStructureCommand.java +++ b/src/main/java/world/bentobox/boxed/commands/AdminPlaceStructureCommand.java @@ -21,19 +21,35 @@ import org.bukkit.structure.Structure; import com.google.common.base.Enums; import world.bentobox.bentobox.api.commands.CompositeCommand; +import world.bentobox.bentobox.api.localization.TextVariables; import world.bentobox.bentobox.api.user.User; import world.bentobox.bentobox.util.Util; import world.bentobox.boxed.Boxed; import world.bentobox.boxed.listeners.NewAreaListener; +import world.bentobox.boxed.listeners.NewAreaListener.Item; /** * @author tastybento * */ public class AdminPlaceStructureCommand extends CompositeCommand { - + + private static final String STRUCTURE_FILE = "structures.yml"; + + /** + * Integrity determines how damaged the building should look by randomly skipping blocks to place. + * This value can range from 0 to 1. With 0 removing all blocks and 1 spawning the structure in pristine condition. + */ + private static final float INTEGRITY = 1; + + /** + * The palette index of the structure to use, starting at 0, or -1 to pick a random palette. + */ + private static final int PALETTE = -1; + private StructureRotation sr = StructureRotation.NONE; private Mirror mirror = Mirror.NONE; + private boolean noMobs; public AdminPlaceStructureCommand(CompositeCommand parent) { super(parent, "place"); @@ -54,7 +70,7 @@ public class AdminPlaceStructureCommand extends CompositeCommand { // Initialize sr = StructureRotation.NONE; mirror = Mirror.NONE; - + // Check world if (!((Boxed)getAddon()).inWorld(getWorld())) { user.sendMessage("boxed.admin.place.wrong-world"); @@ -66,6 +82,7 @@ public class AdminPlaceStructureCommand extends CompositeCommand { * 4. place ~ ~ ~ * 5. place ~ ~ ~ ROTATION * 6. place ~ ~ ~ ROTATION MIRROR + * 7. place ~ ~ ~ ROTATION MIRROR NO_MOBS */ // Format is place ~ ~ ~ or coords if (args.isEmpty() || args.size() == 2 || args.size() == 3 || args.size() > 6) { @@ -110,6 +127,14 @@ public class AdminPlaceStructureCommand extends CompositeCommand { Arrays.stream(Mirror.values()).map(Mirror::name).forEach(user::sendRawMessage); return false; } + if (args.size() == 7) { + if (args.get(6).toUpperCase(Locale.ENGLISH).equals("NO_MOBS")) { + noMobs = true; + } else { + user.sendMessage("boxed.admin.place.unknown", TextVariables.LABEL, args.get(6).toUpperCase(Locale.ENGLISH)); + return false; + } + } // Syntax is okay return true; } @@ -122,28 +147,39 @@ public class AdminPlaceStructureCommand extends CompositeCommand { int y = args.size() == 1 || args.get(2).equals("~") ? user.getLocation().getBlockY() : Integer.valueOf(args.get(2).trim()); int z = args.size() == 1 || args.get(3).equals("~") ? user.getLocation().getBlockZ() : Integer.valueOf(args.get(3).trim()); Location spot = new Location(user.getWorld(), x, y, z); - s.place(spot, true, sr, mirror, -1, 1, new Random()); - NewAreaListener.removeJigsaw(spot, s, sr, tag.getKey()); - saveStructure(spot, tag, user, sr, mirror); - return true; + s.place(spot, true, sr, mirror, PALETTE, INTEGRITY, new Random()); + NewAreaListener.removeJigsaw(new Item(tag.getKey(), s, spot, sr, mirror, noMobs)); + boolean result = saveStructure(spot, tag, user, sr, mirror); + if (result) { + user.sendMessage("boxed.admin.place.saved"); + } else { + user.sendMessage("boxed.admin.place.failed"); + } + return result; } - private void saveStructure(Location spot, NamespacedKey tag, User user, StructureRotation sr2, Mirror mirror2) { - getAddon().getIslands().getIslandAt(spot).ifPresent(i -> { + private boolean saveStructure(Location spot, NamespacedKey tag, User user, StructureRotation sr2, Mirror mirror2) { + return getAddon().getIslands().getIslandAt(spot).map(i -> { int xx = spot.getBlockX() - i.getCenter().getBlockX(); int zz = spot.getBlockZ() - i.getCenter().getBlockZ(); - File structures = new File(getAddon().getDataFolder(), "structures.yml"); + File structures = new File(getAddon().getDataFolder(), STRUCTURE_FILE); YamlConfiguration config = new YamlConfiguration(); try { config.load(structures); - String value = tag.getKey() + "," + sr2.name() + "," + mirror2.name(); - config.set(spot.getWorld().getEnvironment().name().toLowerCase(Locale.ENGLISH) + "." + xx + "," + spot.getBlockY() + "," + zz, value); + StringBuilder v = new StringBuilder(); + v.append(tag.getKey() + "," + sr2.name() + "," + mirror2.name()); + if (noMobs) { + v.append(" NO_MOBS"); + } + config.set(spot.getWorld().getEnvironment().name().toLowerCase(Locale.ENGLISH) + "." + xx + "," + spot.getBlockY() + "," + zz, v.toString()); config.save(structures); } catch (IOException | InvalidConfigurationException e) { - // TODO Auto-generated catch block + // TODO Auto-generated catch block e.printStackTrace(); + return false; } - }); + return true; + }).orElse(false); } @@ -163,6 +199,8 @@ public class AdminPlaceStructureCommand extends CompositeCommand { return Optional.of(Arrays.stream(StructureRotation.values()).map(StructureRotation::name).toList()); } else if (args.size() == 7) { return Optional.of(Arrays.stream(Mirror.values()).map(Mirror::name).toList()); + }else if (args.size() == 8) { + return Optional.of(List.of("NO_MOBS")); } return Optional.of(Collections.emptyList()); } diff --git a/src/main/java/world/bentobox/boxed/listeners/NewAreaListener.java b/src/main/java/world/bentobox/boxed/listeners/NewAreaListener.java index eab9f94..893f9bf 100644 --- a/src/main/java/world/bentobox/boxed/listeners/NewAreaListener.java +++ b/src/main/java/world/bentobox/boxed/listeners/NewAreaListener.java @@ -79,7 +79,7 @@ public class NewAreaListener implements Listener { private static Random rand = new Random(); private boolean pasting; private static Gson gson = new Gson(); - private record Item(String name, Structure structure, Location location, StructureRotation rot, Mirror mirror) {}; + public record Item(String name, Structure structure, Location location, StructureRotation rot, Mirror mirror, Boolean noMobs) {}; Pair min = new Pair(0,0); Pair max = new Pair(0,0); // Database handler for structure data @@ -181,7 +181,14 @@ public class NewAreaListener implements Listener { } private IslandStructures getIslandStructData(String islandId) { - return this.islandStructureCache.computeIfAbsent(islandId, k -> Objects.requireNonNullElse(handler.loadObject(k), new IslandStructures(islandId))); + // Return from cache if it exists + if (islandStructureCache.containsKey(islandId)) { + return islandStructureCache.get(islandId); + } + // Get from database + IslandStructures struct = handler.objectExists(islandId) ? handler.loadObject(islandId) : new IslandStructures(islandId); + this.islandStructureCache.put(islandId, struct); + return struct; } @EventHandler(priority = EventPriority.NORMAL, ignoreCancelled = true) @@ -219,6 +226,7 @@ public class NewAreaListener implements Listener { for (String vector : section.getKeys(false)) { StructureRotation rot = StructureRotation.NONE; Mirror mirror = Mirror.NONE; + boolean noMobs = false; String name = section.getString(vector); // Check for rotation String[] split = name.split(","); @@ -229,7 +237,10 @@ public class NewAreaListener implements Listener { } if (split.length == 3) { // Mirror - mirror = Enums.getIfPresent(Mirror.class, split[1].strip().toUpperCase(Locale.ENGLISH)).or(Mirror.NONE); + mirror = Enums.getIfPresent(Mirror.class, split[2].strip().toUpperCase(Locale.ENGLISH)).or(Mirror.NONE); + } + if (split.length == 4) { + noMobs = split[3].strip().toUpperCase(Locale.ENGLISH).equals("NO_MOBS"); } // Load Structure Structure s = Bukkit.getStructureManager().loadStructure(NamespacedKey.fromString("minecraft:" + name)); @@ -244,7 +255,7 @@ public class NewAreaListener implements Listener { int y = Integer.valueOf(value[1].strip()); int z = Integer.valueOf(value[2].strip()) + center.getBlockZ(); Location l = new Location(world, x, y, z); - itemsToBuild.add(new Item(name, s, l, rot, mirror)); + itemsToBuild.add(new Item(name, s, l, rot, mirror, noMobs)); } else { addon.logError("Structure file syntax error: " + vector + ": " + value); } @@ -256,7 +267,7 @@ public class NewAreaListener implements Listener { item.structure().place(item.location(), true, item.rot(), item.mirror(), -1, 1, rand); addon.log(item.name() + " placed at " + item.location().getWorld().getName() + " " + Util.xyz(item.location().toVector())); // Find it - BoundingBox bb = removeJigsaw(item.location(), item.structure(), item.rot(), item.name()); + BoundingBox bb = removeJigsaw(item); // Store it addon.getIslands().getIslandAt(item.location()).map(Island::getUniqueId).ifPresent(id -> { addon.log("Saved " + item.name()); @@ -273,13 +284,15 @@ public class NewAreaListener implements Listener { /** * Removes Jigsaw blocks from a placed structure. Fills underwater ruins with water. - * @param loc - location where the structure was placed - * @param structure - structure that was placed - * @param structureRotation - rotation of structure - * @param key + * @param item - record of what's required * @return the resulting bounding box of the structure */ - public static BoundingBox removeJigsaw(Location loc, Structure structure, StructureRotation structureRotation, String key) { + public static BoundingBox removeJigsaw(Item item) { + Location loc = item.location(); + Structure structure = item.structure(); + StructureRotation structureRotation = item.rot(); + String key = item.name(); + Location otherCorner = switch (structureRotation) { case CLOCKWISE_180 -> loc.clone().add(new Vector(-structure.getSize().getX(), structure.getSize().getY(), -structure.getSize().getZ())); @@ -299,7 +312,7 @@ public class NewAreaListener implements Listener { Block b = loc.getWorld().getBlockAt(x, y, z); if (b.getType().equals(Material.JIGSAW)) { // I would like to read the data from the block and do something with it! - processJigsaw(b, structureRotation); + processJigsaw(b, structureRotation, !item.noMobs()); } else if (b.getType().equals(Material.STRUCTURE_BLOCK)) { processStructureBlock(b); } @@ -338,15 +351,19 @@ public class NewAreaListener implements Listener { } private static final Map BUTCHER_ANIMALS = Map.of(0, EntityType.COW, 1, EntityType.SHEEP, 2, EntityType.PIG); - private static void processJigsaw(Block b, StructureRotation structureRotation) { + private static void processJigsaw(Block b, StructureRotation structureRotation, boolean pasteMobs) { String data = nmsData(b); BoxedJigsawBlock bjb = gson.fromJson(data, BoxedJigsawBlock.class); - //BentoBox.getInstance().logDebug("Jigsaw: " + bjb); - //BentoBox.getInstance().logDebug("FinalState: " + bjb.getFinal_state()); String finalState = correctDirection(bjb.getFinal_state(), structureRotation); - //BentoBox.getInstance().logDebug("FinalState after rotation: " + finalState); BlockData bd = Bukkit.createBlockData(finalState); b.setBlockData(bd); + if (!bjb.getPool().equalsIgnoreCase("minecraft:empty") && pasteMobs) { + spawnMob(b, bjb); + } + } + + private static void spawnMob(Block b, BoxedJigsawBlock bjb) { + // bjb.getPool contains a lot more than just mobs, so we have to filter it to see if any mobs are in there. This list may need to grow in the future EntityType type = switch (bjb.getPool()) { case "minecraft:bastion/mobs/piglin" -> EntityType.PIGLIN; @@ -362,16 +379,19 @@ public class NewAreaListener implements Listener { case "minecraft:village/common/animals" -> BUTCHER_ANIMALS.get(rand.nextInt(3)); default -> null; }; + // Villagers if (bjb.getPool().contains("zombie/villagers")) { type = EntityType.ZOMBIE_VILLAGER; } else if (bjb.getPool().contains("villagers")) { type = EntityType.VILLAGER; } + if (type == null) { + BentoBox.getInstance().logDebug(bjb.getPool()); + } // Spawn it if (type != null && b.getWorld().spawnEntity(b.getRelative(BlockFace.UP).getLocation(), type) != null) { //BentoBox.getInstance().logDebug("Spawned a " + type + " at " + b.getRelative(BlockFace.UP).getLocation()); - } - + } } /** diff --git a/src/main/resources/locales/en-US.yml b/src/main/resources/locales/en-US.yml index 104a5c9..44f1c40 100755 --- a/src/main/resources/locales/en-US.yml +++ b/src/main/resources/locales/en-US.yml @@ -23,6 +23,18 @@ boxed: parameters: '[home number]' sethome: parameters: '[home number]' + admin: + place: + description: "Place an area structure" + parameters: " " + use-integers: "&c Coordinated must be integers" + wrong-world: "&c This command can only be used in a Boxed world" + unknown-structure: "&c Cannot place: Unknown structure" + unknown-rotation: "&c Cannot place: Unknown rotation type" + unknown-mirror: "&c Cannot place: Unknown mirror type" + saved: "&a Placed and saved to structures.yml" + failed: "&c Could not be saved to structures.yml. Check console for error" + unknown: "&c Unknown parameter: [label]" island: go: parameters: '[home number]' diff --git a/src/main/resources/structures.yml b/src/main/resources/structures.yml index ef77edd..3ab4c31 100644 --- a/src/main/resources/structures.yml +++ b/src/main/resources/structures.yml @@ -1,4 +1,5 @@ -normal: +# This file is written by the /boxadmin place command +ormal: 0,64,80: village/plains/houses/plains_masons_house_1,CLOCKWISE_90 -38,63,20: ruined_portal/portal_5 3,58,-60: shipwreck/rightsideup_backhalf @@ -15,6 +16,8 @@ normal: 34,69,-29: village/common/iron_golem 41,69,-26: village/common/animals/cat_calico 35,69,-22: village/common/animals/cat_calico + 32,70,65: village/savanna/houses/savanna_temple_1,NONE,NONE + 25,70,72: village/savanna/houses/savanna_small_house_7,COUNTERCLOCKWISE_90,NONE,NO_MOBS 99,72,118: pillager_outpost/feature_cage1 33,72,100: village/desert/houses/desert_farm_1 26,72,100: village/desert/houses/desert_medium_house_1 @@ -33,7 +36,16 @@ normal: -52,72,33: village/snowy/houses/snowy_farm_1,COUNTERCLOCKWISE_90,NONE -28,63,47: village/snowy/snowy_lamp_post_01,COUNTERCLOCKWISE_90,NONE -6,64,52: village/snowy/houses/snowy_small_house_3,COUNTERCLOCKWISE_90,NONE - 40,73,-3: village/savanna/houses/savanna_small_house_1,CLOCKWISE_180 + 60,81,88: village/desert/camel_spawn,NONE,NONE + 64,81,93: village/desert/houses/desert_animal_pen_1,NONE,NONE + 49,81,94: village/desert/houses/desert_large_farm_1,NONE,NONE + -106,45,68: underwater_ruin/big_brick_1,NONE,NONE + -117,45,88: underwater_ruin/big_brick_2,NONE,NONE + 64,78,49: village/common/animals/horses_1,NONE,NONE + 65,78,51: village/common/animals/horses_2,NONE,NONE + 67,78,52: village/common/animals/horses_3,NONE,NONE + 57,70,-90: village/common/animals/horses_5,NONE,NONE + 62,70,-88: village/common/animals/horses_5,NONE,NONE nether: 16,32,0: bastion/bridge/starting_pieces/entrance From 306df8b5fb592bb104e2c72e0c080450daf5bf85 Mon Sep 17 00:00:00 2001 From: tastybento Date: Sun, 30 Apr 2023 09:41:36 -0700 Subject: [PATCH 07/11] Fix copy and paste error. Remove debug --- .../world/bentobox/boxed/listeners/NewAreaListener.java | 6 +++--- src/main/resources/structures.yml | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/main/java/world/bentobox/boxed/listeners/NewAreaListener.java b/src/main/java/world/bentobox/boxed/listeners/NewAreaListener.java index 893f9bf..e88b288 100644 --- a/src/main/java/world/bentobox/boxed/listeners/NewAreaListener.java +++ b/src/main/java/world/bentobox/boxed/listeners/NewAreaListener.java @@ -385,9 +385,9 @@ public class NewAreaListener implements Listener { } else if (bjb.getPool().contains("villagers")) { type = EntityType.VILLAGER; } - if (type == null) { - BentoBox.getInstance().logDebug(bjb.getPool()); - } + //if (type == null) { + // BentoBox.getInstance().logDebug(bjb.getPool()); + //} // Spawn it if (type != null && b.getWorld().spawnEntity(b.getRelative(BlockFace.UP).getLocation(), type) != null) { //BentoBox.getInstance().logDebug("Spawned a " + type + " at " + b.getRelative(BlockFace.UP).getLocation()); diff --git a/src/main/resources/structures.yml b/src/main/resources/structures.yml index 3ab4c31..95ed448 100644 --- a/src/main/resources/structures.yml +++ b/src/main/resources/structures.yml @@ -1,5 +1,5 @@ # This file is written by the /boxadmin place command -ormal: +normal: 0,64,80: village/plains/houses/plains_masons_house_1,CLOCKWISE_90 -38,63,20: ruined_portal/portal_5 3,58,-60: shipwreck/rightsideup_backhalf From 7047565dca6a8362ff3654e2123f8781c07b5faa Mon Sep 17 00:00:00 2001 From: tastybento Date: Wed, 3 May 2023 21:31:25 -0700 Subject: [PATCH 08/11] Added custom structures for Boxed. Fixed missing texts and place bug --- pom.xml | 9 ++++++ .../commands/AdminPlaceStructureCommand.java | 22 +++++++------- .../boxed/listeners/NewAreaListener.java | 28 +++++++++++++++--- src/main/resources/locales/en-US.yml | 24 +++++++-------- src/main/resources/structures.yml | 20 +++++++++++++ src/main/resources/structures/allay.nbt | Bin 0 -> 222 bytes src/main/resources/structures/axolotl.nbt | Bin 0 -> 223 bytes src/main/resources/structures/bee.nbt | Bin 0 -> 220 bytes src/main/resources/structures/frog.nbt | Bin 0 -> 221 bytes src/main/resources/structures/parrot.nbt | Bin 0 -> 221 bytes src/main/resources/structures/pillager.nbt | Bin 0 -> 223 bytes src/main/resources/structures/polar_bear.nbt | Bin 0 -> 225 bytes src/main/resources/templates.yml | 7 +++++ 13 files changed, 83 insertions(+), 27 deletions(-) create mode 100644 src/main/resources/structures/allay.nbt create mode 100644 src/main/resources/structures/axolotl.nbt create mode 100644 src/main/resources/structures/bee.nbt create mode 100644 src/main/resources/structures/frog.nbt create mode 100644 src/main/resources/structures/parrot.nbt create mode 100644 src/main/resources/structures/pillager.nbt create mode 100644 src/main/resources/structures/polar_bear.nbt diff --git a/pom.xml b/pom.xml index e6fa1d7..1efdb21 100644 --- a/pom.xml +++ b/pom.xml @@ -199,6 +199,14 @@ src/main/resources true + + src/main/resources/structures + ./structures + false + + *.nbt + + src/main/resources/locales ./locales @@ -230,6 +238,7 @@ blu + nbt diff --git a/src/main/java/world/bentobox/boxed/commands/AdminPlaceStructureCommand.java b/src/main/java/world/bentobox/boxed/commands/AdminPlaceStructureCommand.java index c27a5a5..8a59f51 100644 --- a/src/main/java/world/bentobox/boxed/commands/AdminPlaceStructureCommand.java +++ b/src/main/java/world/bentobox/boxed/commands/AdminPlaceStructureCommand.java @@ -57,10 +57,10 @@ public class AdminPlaceStructureCommand extends CompositeCommand { @Override public void setup() { - this.setPermission("boxed.admin.place"); + this.setPermission("boxed.commands.boxadmin.place"); this.setOnlyPlayer(false); - this.setParametersHelp("boxed.admin.place.parameters"); - this.setDescription("boxed.admin.place.description"); + this.setParametersHelp("boxed.commands.boxadmin.place.parameters"); + this.setDescription("boxed.commands.boxadmin.place.description"); } @@ -73,7 +73,7 @@ public class AdminPlaceStructureCommand extends CompositeCommand { // Check world if (!((Boxed)getAddon()).inWorld(getWorld())) { - user.sendMessage("boxed.admin.place.wrong-world"); + user.sendMessage("boxed.commands.boxadmin.place.wrong-world"); return false; } /* @@ -92,7 +92,7 @@ public class AdminPlaceStructureCommand extends CompositeCommand { // First arg must always be the structure name List options = Bukkit.getStructureManager().getStructures().keySet().stream().map(k -> k.getKey()).toList(); if (!options.contains(args.get(0).toLowerCase(Locale.ENGLISH))) { - user.sendMessage("boxed.admin.place.unknown-structure"); + user.sendMessage("boxed.commands.boxadmin.place.unknown-structure"); return false; } // If that is all we have, we're done @@ -103,7 +103,7 @@ public class AdminPlaceStructureCommand extends CompositeCommand { if ((!args.get(1).equals("~") && !Util.isInteger(args.get(1), true)) || (!args.get(2).equals("~") && !Util.isInteger(args.get(2), true)) || (!args.get(3).equals("~") && !Util.isInteger(args.get(3), true))) { - user.sendMessage("boxed.admin.place.use-integers"); + user.sendMessage("boxed.commands.boxadmin.place.use-integers"); return false; } // If that is all we have, we're done @@ -113,7 +113,7 @@ public class AdminPlaceStructureCommand extends CompositeCommand { // But there is more! sr = Enums.getIfPresent(StructureRotation.class, args.get(4).toUpperCase(Locale.ENGLISH)).orNull(); if (sr == null) { - user.sendMessage("boxed.admin.place.unknown-rotation"); + user.sendMessage("boxed.commands.boxadmin.place.unknown-rotation"); Arrays.stream(StructureRotation.values()).map(StructureRotation::name).forEach(user::sendRawMessage); return false; } @@ -123,7 +123,7 @@ public class AdminPlaceStructureCommand extends CompositeCommand { // But there is more! mirror = Enums.getIfPresent(Mirror.class, args.get(5).toUpperCase(Locale.ENGLISH)).orNull(); if (mirror == null) { - user.sendMessage("boxed.admin.place.unknown-mirror"); + user.sendMessage("boxed.commands.boxadmin.place.unknown-mirror"); Arrays.stream(Mirror.values()).map(Mirror::name).forEach(user::sendRawMessage); return false; } @@ -131,7 +131,7 @@ public class AdminPlaceStructureCommand extends CompositeCommand { if (args.get(6).toUpperCase(Locale.ENGLISH).equals("NO_MOBS")) { noMobs = true; } else { - user.sendMessage("boxed.admin.place.unknown", TextVariables.LABEL, args.get(6).toUpperCase(Locale.ENGLISH)); + user.sendMessage("boxed.commands.boxadmin.place.unknown", TextVariables.LABEL, args.get(6).toUpperCase(Locale.ENGLISH)); return false; } } @@ -151,9 +151,9 @@ public class AdminPlaceStructureCommand extends CompositeCommand { NewAreaListener.removeJigsaw(new Item(tag.getKey(), s, spot, sr, mirror, noMobs)); boolean result = saveStructure(spot, tag, user, sr, mirror); if (result) { - user.sendMessage("boxed.admin.place.saved"); + user.sendMessage("boxed.commands.boxadmin.place.saved"); } else { - user.sendMessage("boxed.admin.place.failed"); + user.sendMessage("boxed.commands.boxadmin.place.failed"); } return result; } diff --git a/src/main/java/world/bentobox/boxed/listeners/NewAreaListener.java b/src/main/java/world/bentobox/boxed/listeners/NewAreaListener.java index e88b288..3220665 100644 --- a/src/main/java/world/bentobox/boxed/listeners/NewAreaListener.java +++ b/src/main/java/world/bentobox/boxed/listeners/NewAreaListener.java @@ -1,13 +1,15 @@ package world.bentobox.boxed.listeners; import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; +import java.io.InputStream; import java.lang.reflect.Field; import java.util.HashMap; import java.util.LinkedList; import java.util.List; import java.util.Locale; import java.util.Map; -import java.util.Objects; import java.util.Queue; import java.util.Random; @@ -65,6 +67,7 @@ import world.bentobox.boxed.objects.IslandStructures; public class NewAreaListener implements Listener { private static final List CARDINALS = List.of(BlockFace.NORTH, BlockFace.SOUTH, BlockFace.EAST, BlockFace.WEST); + private static final List JAR_STRUCTURES = List.of("bee", "pillager", "polar_bear", "axolotl", "allay", "parrot", "frog"); private static final List STRUCTURES = List.of("ancient_city", "bastion_remnant", "bastion", "buried_treasure", "desert_pyramid", "end_city", "fortress", "igloo", "jungle_pyramid", "mansion", "mineshaft", "mineshaft_mesa", @@ -100,6 +103,19 @@ public class NewAreaListener implements Listener { handler = new Database<>(addon, IslandStructures.class); // Try to build something every second Bukkit.getScheduler().runTaskTimer(addon.getPlugin(), () -> BuildItem(), 20, 20); + // Experiment: TODO: read all files in from the structure folder including the ones saved from the jar file + for (String js : JAR_STRUCTURES) { + addon.saveResource("structures/" + js + ".nbt", false); + File structureFile = new File(addon.getDataFolder(), "structures/" + js + ".nbt"); + try { + Bukkit.getStructureManager().loadStructure(structureFile); + addon.log("Loaded " + js + ".nbt"); + } catch (IOException e) { + addon.logError("Error trying to load " + structureFile.getAbsolutePath()); + e.printStackTrace(); + } + + } } private void BuildItem() { @@ -123,9 +139,8 @@ public class NewAreaListener implements Listener { YamlConfiguration loader = YamlConfiguration.loadConfiguration(templateFile); List list = loader.getStringList("templates"); for (String struct : list) { - Structure s = Bukkit.getStructureManager().loadStructure(NamespacedKey.fromString(struct)); - if (s == null) { - //addon.log("Now loading group from: " + struct); + if (!struct.endsWith("/")) { + Bukkit.getStructureManager().loadStructure(NamespacedKey.fromString(struct)); } } } @@ -379,6 +394,11 @@ public class NewAreaListener implements Listener { case "minecraft:village/common/animals" -> BUTCHER_ANIMALS.get(rand.nextInt(3)); default -> null; }; + // Boxed + if (type == null && bjb.getPool().startsWith("minecraft:boxed/")) { + String entString = bjb.getPool().toUpperCase(Locale.ENGLISH).substring(16, bjb.getPool().length()); + type = Enums.getIfPresent(EntityType.class, entString).orNull(); + } // Villagers if (bjb.getPool().contains("zombie/villagers")) { type = EntityType.ZOMBIE_VILLAGER; diff --git a/src/main/resources/locales/en-US.yml b/src/main/resources/locales/en-US.yml index 44f1c40..4c603c4 100755 --- a/src/main/resources/locales/en-US.yml +++ b/src/main/resources/locales/en-US.yml @@ -23,18 +23,18 @@ boxed: parameters: '[home number]' sethome: parameters: '[home number]' - admin: - place: - description: "Place an area structure" - parameters: " " - use-integers: "&c Coordinated must be integers" - wrong-world: "&c This command can only be used in a Boxed world" - unknown-structure: "&c Cannot place: Unknown structure" - unknown-rotation: "&c Cannot place: Unknown rotation type" - unknown-mirror: "&c Cannot place: Unknown mirror type" - saved: "&a Placed and saved to structures.yml" - failed: "&c Could not be saved to structures.yml. Check console for error" - unknown: "&c Unknown parameter: [label]" + boxadmin: + place: + description: Place an area structure + parameters: + use-integers: '&c Coordinated must be integers' + wrong-world: '&c This command can only be used in a Boxed world' + unknown-structure: '&c Cannot place: Unknown structure' + unknown-rotation: '&c Cannot place: Unknown rotation type' + unknown-mirror: '&c Cannot place: Unknown mirror type' + saved: '&a Placed and saved to structures.yml' + failed: '&c Could not be saved to structures.yml. Check console for error' + unknown: '&c Unknown parameter: [label]' island: go: parameters: '[home number]' diff --git a/src/main/resources/structures.yml b/src/main/resources/structures.yml index 95ed448..1e2fc65 100644 --- a/src/main/resources/structures.yml +++ b/src/main/resources/structures.yml @@ -46,6 +46,26 @@ normal: 67,78,52: village/common/animals/horses_3,NONE,NONE 57,70,-90: village/common/animals/horses_5,NONE,NONE 62,70,-88: village/common/animals/horses_5,NONE,NONE + -2,66,10: boxed/frog,NONE,NONE + 87,85,120: boxed/pillager,NONE,NONE + 85,85,122: boxed/pillager,NONE,NONE + 87,85,118: boxed/pillager,NONE,NONE + 87,85,123: boxed/pillager,NONE,NONE + 89,81,122: boxed/pillager,NONE,NONE + 87,77,120: boxed/pillager,NONE,NONE + 94,71,111: boxed/pillager,NONE,NONE + 90,71,111: boxed/pillager,NONE,NONE + 100,72,110: pillager_outpost/feature_tent1,NONE,NONE + -20,63,-24: boxed/parrot,NONE,NONE + -21,65,-21: boxed/parrot,NONE,NONE + 1,69,-12: boxed/frog,NONE,NONE + 2,67,10: boxed/parrot,NONE,NONE + -58,64,13: boxed/polar_bear,NONE,NONE + -90,63,57: boxed/polar_bear,NONE,NONE + -87,63,63: boxed/polar_bear,NONE,NONE + -33,69,58: boxed/polar_bear,NONE,NONE + 137,-8,11: boxed/axolotl,NONE,NONE + 137,-8,9: boxed/axolotl,NONE,NONE nether: 16,32,0: bastion/bridge/starting_pieces/entrance diff --git a/src/main/resources/structures/allay.nbt b/src/main/resources/structures/allay.nbt new file mode 100644 index 0000000000000000000000000000000000000000..a204ba2e3f22db49c82efbfa3ea9a5616fb8ff93 GIT binary patch literal 222 zcmV<403rV$iwFP!00000|8ILl7zl*q=lhdHfF7oWf2ae1mXm9Cuy{qs53<6V0G53Z^Feg;S>iaK6-TF9S4Nk$ zToHc}p-Y1Ym?k_CJe@ev#&G8^gPv*ojAs>f2{3oGJ^3BQ18-q#Ycb{gA!ydC%gLuaatX(b|+WW8$y3 z-NpGZ3;Pm=r|cN5yhu> zri=AZ3KyLM8Y%5yyu8vGa6nzW{|bIe@ht1jD8O*sIThx-&PO)TP2YiQ!Y$VrdWveJuZsc X&*qdW&XqRTq45njXH!R8WdQ&Hr*LO- literal 0 HcmV?d00001 diff --git a/src/main/resources/structures/parrot.nbt b/src/main/resources/structures/parrot.nbt new file mode 100644 index 0000000000000000000000000000000000000000..0556701bded3879e1f3c0e883292a6876d539a2e GIT binary patch literal 221 zcmV<303!b%iwFP!00000|8zJ`0(uEmvG$jr3L_Me%!Nx=?V?Eq?siG%-R;lU6B1H`(7VqL!(j`Mw2Ap z5s&cD#LgTHBVGySSB|t-Jle988yyx2Ri(&dLp_nbHw^dypHK13r;I-iMrYw@;8a4u zE>IbiM8bQ{^vDszu3vlhbRlcKVUjSA8U3GEVC%Z|%UlnBqmoFCDHo#Bo{^P XYxkWh&XqP-Q~!)Vwvc4?YXJZN^8sjt literal 0 HcmV?d00001 diff --git a/src/main/resources/structures/pillager.nbt b/src/main/resources/structures/pillager.nbt new file mode 100644 index 0000000000000000000000000000000000000000..f90628c7b1c71328318dcacaa2aecc5f2d3861ca GIT binary patch literal 223 zcmV<503iP#iwFP!00000|9z0bY63wFhSRRv*%85G-@?1+p2d?_$!c7q<7CLBRD618 zx>yed1A&nIe18%T(84J5jT!)``S!>LreA2dA4NOe*$?w^HZ&@AVKhnd z1MwFgn%J3xQN#z_a zfm4YQL!@e$MdD-De8&mnFh*G1mB`xiykv}IM!!)jaM=?4^Y-9ZDw))nN@a>NrAllM bb4k>`hVR^PuCBR>#>ZR%rNI*)cL4wZPKRm8 literal 0 HcmV?d00001 diff --git a/src/main/resources/templates.yml b/src/main/resources/templates.yml index 847844d..2745582 100644 --- a/src/main/resources/templates.yml +++ b/src/main/resources/templates.yml @@ -1,4 +1,11 @@ templates: +- boxed/frog +- boxed/allay +- boxed/bee +- boxed/axolotl +- boxed/pillager +- boxed/polar_bear +- boxed/parrot - ancient_city/city/entrance/entrance_connector - ancient_city/city/entrance/entrance_path_1 - ancient_city/city/entrance/entrance_path_2 From e4e710661342f2bad46924166a4fae64f482747c Mon Sep 17 00:00:00 2001 From: tastybento Date: Tue, 9 May 2023 17:33:49 -0700 Subject: [PATCH 09/11] Register custom structures --- src/.gitignore | 1 + .../java/world/bentobox/boxed/listeners/NewAreaListener.java | 5 ++--- 2 files changed, 3 insertions(+), 3 deletions(-) create mode 100644 src/.gitignore diff --git a/src/.gitignore b/src/.gitignore new file mode 100644 index 0000000..9bb88d3 --- /dev/null +++ b/src/.gitignore @@ -0,0 +1 @@ +/.DS_Store diff --git a/src/main/java/world/bentobox/boxed/listeners/NewAreaListener.java b/src/main/java/world/bentobox/boxed/listeners/NewAreaListener.java index 3220665..3fa3f07 100644 --- a/src/main/java/world/bentobox/boxed/listeners/NewAreaListener.java +++ b/src/main/java/world/bentobox/boxed/listeners/NewAreaListener.java @@ -1,9 +1,7 @@ package world.bentobox.boxed.listeners; import java.io.File; -import java.io.FileInputStream; import java.io.IOException; -import java.io.InputStream; import java.lang.reflect.Field; import java.util.HashMap; import java.util.LinkedList; @@ -108,7 +106,8 @@ public class NewAreaListener implements Listener { addon.saveResource("structures/" + js + ".nbt", false); File structureFile = new File(addon.getDataFolder(), "structures/" + js + ".nbt"); try { - Bukkit.getStructureManager().loadStructure(structureFile); + Structure s = Bukkit.getStructureManager().loadStructure(structureFile); + Bukkit.getStructureManager().registerStructure(NamespacedKey.fromString("minecraft:boxed/" + js), s); addon.log("Loaded " + js + ".nbt"); } catch (IOException e) { addon.logError("Error trying to load " + structureFile.getAbsolutePath()); From 387b86cbe8b0340a8a9401c443913a90554ea33d Mon Sep 17 00:00:00 2001 From: tastybento Date: Sun, 14 May 2023 15:37:55 -0700 Subject: [PATCH 10/11] Make initial mobs persistent. --- .../bentobox/boxed/listeners/NewAreaListener.java | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/src/main/java/world/bentobox/boxed/listeners/NewAreaListener.java b/src/main/java/world/bentobox/boxed/listeners/NewAreaListener.java index 3fa3f07..8280583 100644 --- a/src/main/java/world/bentobox/boxed/listeners/NewAreaListener.java +++ b/src/main/java/world/bentobox/boxed/listeners/NewAreaListener.java @@ -27,6 +27,7 @@ import org.bukkit.block.structure.StructureRotation; import org.bukkit.configuration.ConfigurationSection; import org.bukkit.configuration.file.YamlConfiguration; import org.bukkit.craftbukkit.v1_19_R3.CraftWorld; +import org.bukkit.entity.Entity; import org.bukkit.entity.EntityType; import org.bukkit.entity.Player; import org.bukkit.event.EventHandler; @@ -104,7 +105,7 @@ public class NewAreaListener implements Listener { // Experiment: TODO: read all files in from the structure folder including the ones saved from the jar file for (String js : JAR_STRUCTURES) { addon.saveResource("structures/" + js + ".nbt", false); - File structureFile = new File(addon.getDataFolder(), "structures/" + js + ".nbt"); + File structureFile = new File(addon.getDataFolder(), "structures/" + js + ".nbt"); try { Structure s = Bukkit.getStructureManager().loadStructure(structureFile); Bukkit.getStructureManager().registerStructure(NamespacedKey.fromString("minecraft:boxed/" + js), s); @@ -113,7 +114,7 @@ public class NewAreaListener implements Listener { addon.logError("Error trying to load " + structureFile.getAbsolutePath()); e.printStackTrace(); } - + } } @@ -201,7 +202,7 @@ public class NewAreaListener implements Listener { } // Get from database IslandStructures struct = handler.objectExists(islandId) ? handler.loadObject(islandId) : new IslandStructures(islandId); - this.islandStructureCache.put(islandId, struct); + this.islandStructureCache.put(islandId, struct); return struct; } @@ -408,9 +409,13 @@ public class NewAreaListener implements Listener { // BentoBox.getInstance().logDebug(bjb.getPool()); //} // Spawn it - if (type != null && b.getWorld().spawnEntity(b.getRelative(BlockFace.UP).getLocation(), type) != null) { + if (type != null) { + Entity e = b.getWorld().spawnEntity(b.getRelative(BlockFace.UP).getLocation(), type); + if (e != null) { + e.setPersistent(true); + } //BentoBox.getInstance().logDebug("Spawned a " + type + " at " + b.getRelative(BlockFace.UP).getLocation()); - } + } } /** From 9256b564e0bc8efcf64fd4c0dff146c62e1cb336 Mon Sep 17 00:00:00 2001 From: tastybento Date: Sun, 14 May 2023 15:38:25 -0700 Subject: [PATCH 11/11] Version 2.1.0 --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 1efdb21..10d06d3 100644 --- a/pom.xml +++ b/pom.xml @@ -65,7 +65,7 @@ -LOCAL - 2.0.4 + 2.1.0 BentoBoxWorld_Boxed bentobox-world