From 8217949fa297c829d9b77e5e8e52f204a22af6bb Mon Sep 17 00:00:00 2001 From: CocoTheOwner Date: Fri, 16 Jul 2021 17:28:28 +0200 Subject: [PATCH 01/41] Initial commit. Captures block place and sapling grow events and prints info to the console. Initial configuration options are in place, definitions will be added. --- build.gradle | 2 +- src/main/java/com/volmit/iris/Iris.java | 2 ++ .../com/volmit/iris/core/SaplingManager.java | 29 +++++++++++++++++++ .../volmit/iris/engine/object/IrisRegion.java | 6 ++++ .../iris/engine/object/IrisSaplings.java | 18 ++++++++++++ 5 files changed, 56 insertions(+), 1 deletion(-) create mode 100644 src/main/java/com/volmit/iris/core/SaplingManager.java create mode 100644 src/main/java/com/volmit/iris/engine/object/IrisSaplings.java diff --git a/build.gradle b/build.gradle index fada92362..31a793937 100644 --- a/build.gradle +++ b/build.gradle @@ -5,7 +5,7 @@ plugins { } group 'com.volmit.iris' -version '1.5' +version '1.5.1' def apiVersion = '1.17' def name = 'Iris' def main = 'com.volmit.iris.Iris' diff --git a/src/main/java/com/volmit/iris/Iris.java b/src/main/java/com/volmit/iris/Iris.java index 171e90833..8f1e6d04c 100644 --- a/src/main/java/com/volmit/iris/Iris.java +++ b/src/main/java/com/volmit/iris/Iris.java @@ -78,6 +78,7 @@ public class Iris extends VolmitPlugin implements Listener { public static BKLink linkBK; public static MultiverseCoreLink linkMultiverseCore; public static MythicMobsLink linkMythicMobs; + public static SaplingManager saplingManager; private static final Queue syncJobs = new ShurikenQueue<>(); public static boolean customModels = doesSupportCustomModels(); public static boolean awareEntities = doesSupportAwareness(); @@ -233,6 +234,7 @@ public class Iris extends VolmitPlugin implements Listener { linkMultiverseCore = new MultiverseCoreLink(); linkBK = new BKLink(); linkMythicMobs = new MythicMobsLink(); + saplingManager = new SaplingManager(); edit = new EditManager(); configWatcher = new FileWatcher(getDataFile("settings.json")); J.a(() -> IO.delete(getTemp())); diff --git a/src/main/java/com/volmit/iris/core/SaplingManager.java b/src/main/java/com/volmit/iris/core/SaplingManager.java new file mode 100644 index 000000000..3fc5f90f5 --- /dev/null +++ b/src/main/java/com/volmit/iris/core/SaplingManager.java @@ -0,0 +1,29 @@ +package com.volmit.iris.core; + +import com.volmit.iris.Iris; +import org.bukkit.TreeType; +import org.bukkit.block.data.type.Sapling; +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; +import org.bukkit.event.block.BlockPlaceEvent; +import org.bukkit.event.world.StructureGrowEvent; + +import java.util.Objects; + +public class SaplingManager implements Listener { + + public SaplingManager() { + Iris.instance.registerListener(this); + } + + @EventHandler + public void onStructureGrowEvent(StructureGrowEvent event) { + if (event.getSpecies() == TreeType.JUNGLE) + Iris.info("Sapling grew @ " + event.getLocation() + " for " + event.getSpecies().name() + " bonemealed is " + event.isFromBonemeal() + " by player " + Objects.requireNonNull(event.getPlayer()).getName()); + } + + @EventHandler + public void onBlockPlaceEvent(BlockPlaceEvent event) { + Iris.info("Placed " + event.getBlock().getBlockData().getMaterial().name() + " @ " + event.getBlock().getLocation()); + } +} diff --git a/src/main/java/com/volmit/iris/engine/object/IrisRegion.java b/src/main/java/com/volmit/iris/engine/object/IrisRegion.java index 47a587219..cbef49407 100644 --- a/src/main/java/com/volmit/iris/engine/object/IrisRegion.java +++ b/src/main/java/com/volmit/iris/engine/object/IrisRegion.java @@ -79,6 +79,12 @@ public class IrisRegion extends IrisRegistrant implements IRare { @ArrayType(min = 1, type = IrisEntityInitialSpawn.class) private KList entityInitialSpawns = new KList<>(); + @Desc("Sapling override settings") + private IrisSaplings saplings = new IrisSaplings(); + + @Desc("Enable sapling overrides") + private boolean useSaplings = false; + @MinNumber(1) @MaxNumber(128) @Desc("The rarity of the region") diff --git a/src/main/java/com/volmit/iris/engine/object/IrisSaplings.java b/src/main/java/com/volmit/iris/engine/object/IrisSaplings.java new file mode 100644 index 000000000..20211a651 --- /dev/null +++ b/src/main/java/com/volmit/iris/engine/object/IrisSaplings.java @@ -0,0 +1,18 @@ +package com.volmit.iris.engine.object; + +import com.volmit.iris.engine.object.annotations.Desc; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; +import lombok.experimental.Accessors; + +@Accessors(chain = true) +@NoArgsConstructor +@AllArgsConstructor +@Desc("Sapling override settings") +@Data +public class IrisSaplings { + + + +} From 16324e16c7a4041278ba4689b4b20625214b4ab1 Mon Sep 17 00:00:00 2001 From: CocoTheOwner Date: Fri, 16 Jul 2021 17:28:28 +0200 Subject: [PATCH 02/41] Initial commit. Captures block place and sapling grow events and prints info to the console. Initial configuration options are in place, definitions will be added. --- src/main/java/com/volmit/iris/Iris.java | 2 ++ .../com/volmit/iris/core/SaplingManager.java | 29 +++++++++++++++++++ .../volmit/iris/engine/object/IrisRegion.java | 6 ++++ .../iris/engine/object/IrisSaplings.java | 18 ++++++++++++ 4 files changed, 55 insertions(+) create mode 100644 src/main/java/com/volmit/iris/core/SaplingManager.java create mode 100644 src/main/java/com/volmit/iris/engine/object/IrisSaplings.java diff --git a/src/main/java/com/volmit/iris/Iris.java b/src/main/java/com/volmit/iris/Iris.java index 3c158e99f..a59f8a944 100644 --- a/src/main/java/com/volmit/iris/Iris.java +++ b/src/main/java/com/volmit/iris/Iris.java @@ -77,6 +77,7 @@ public class Iris extends VolmitPlugin implements Listener { public static BKLink linkBK; public static MultiverseCoreLink linkMultiverseCore; public static MythicMobsLink linkMythicMobs; + public static SaplingManager saplingManager; private static final Queue syncJobs = new ShurikenQueue<>(); public static boolean customModels = doesSupportCustomModels(); public static boolean awareEntities = doesSupportAwareness(); @@ -232,6 +233,7 @@ public class Iris extends VolmitPlugin implements Listener { linkMultiverseCore = new MultiverseCoreLink(); linkBK = new BKLink(); linkMythicMobs = new MythicMobsLink(); + saplingManager = new SaplingManager(); edit = new EditManager(); configWatcher = new FileWatcher(getDataFile("settings.json")); J.a(() -> IO.delete(getTemp())); diff --git a/src/main/java/com/volmit/iris/core/SaplingManager.java b/src/main/java/com/volmit/iris/core/SaplingManager.java new file mode 100644 index 000000000..3fc5f90f5 --- /dev/null +++ b/src/main/java/com/volmit/iris/core/SaplingManager.java @@ -0,0 +1,29 @@ +package com.volmit.iris.core; + +import com.volmit.iris.Iris; +import org.bukkit.TreeType; +import org.bukkit.block.data.type.Sapling; +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; +import org.bukkit.event.block.BlockPlaceEvent; +import org.bukkit.event.world.StructureGrowEvent; + +import java.util.Objects; + +public class SaplingManager implements Listener { + + public SaplingManager() { + Iris.instance.registerListener(this); + } + + @EventHandler + public void onStructureGrowEvent(StructureGrowEvent event) { + if (event.getSpecies() == TreeType.JUNGLE) + Iris.info("Sapling grew @ " + event.getLocation() + " for " + event.getSpecies().name() + " bonemealed is " + event.isFromBonemeal() + " by player " + Objects.requireNonNull(event.getPlayer()).getName()); + } + + @EventHandler + public void onBlockPlaceEvent(BlockPlaceEvent event) { + Iris.info("Placed " + event.getBlock().getBlockData().getMaterial().name() + " @ " + event.getBlock().getLocation()); + } +} diff --git a/src/main/java/com/volmit/iris/engine/object/IrisRegion.java b/src/main/java/com/volmit/iris/engine/object/IrisRegion.java index 47a587219..cbef49407 100644 --- a/src/main/java/com/volmit/iris/engine/object/IrisRegion.java +++ b/src/main/java/com/volmit/iris/engine/object/IrisRegion.java @@ -79,6 +79,12 @@ public class IrisRegion extends IrisRegistrant implements IRare { @ArrayType(min = 1, type = IrisEntityInitialSpawn.class) private KList entityInitialSpawns = new KList<>(); + @Desc("Sapling override settings") + private IrisSaplings saplings = new IrisSaplings(); + + @Desc("Enable sapling overrides") + private boolean useSaplings = false; + @MinNumber(1) @MaxNumber(128) @Desc("The rarity of the region") diff --git a/src/main/java/com/volmit/iris/engine/object/IrisSaplings.java b/src/main/java/com/volmit/iris/engine/object/IrisSaplings.java new file mode 100644 index 000000000..20211a651 --- /dev/null +++ b/src/main/java/com/volmit/iris/engine/object/IrisSaplings.java @@ -0,0 +1,18 @@ +package com.volmit.iris.engine.object; + +import com.volmit.iris.engine.object.annotations.Desc; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; +import lombok.experimental.Accessors; + +@Accessors(chain = true) +@NoArgsConstructor +@AllArgsConstructor +@Desc("Sapling override settings") +@Data +public class IrisSaplings { + + + +} From ea6937c0ac29a2a9c6ca414e9d0692934b83ccd7 Mon Sep 17 00:00:00 2001 From: CocoTheOwner Date: Sat, 17 Jul 2021 17:54:38 +0200 Subject: [PATCH 03/41] Add sapling configs to biome and dimension files --- src/main/java/com/volmit/iris/engine/object/IrisBiome.java | 6 ++++++ .../java/com/volmit/iris/engine/object/IrisDimension.java | 6 ++++++ 2 files changed, 12 insertions(+) diff --git a/src/main/java/com/volmit/iris/engine/object/IrisBiome.java b/src/main/java/com/volmit/iris/engine/object/IrisBiome.java index 6d098f33a..5140895ec 100644 --- a/src/main/java/com/volmit/iris/engine/object/IrisBiome.java +++ b/src/main/java/com/volmit/iris/engine/object/IrisBiome.java @@ -81,6 +81,12 @@ public class IrisBiome extends IrisRegistrant implements IRare { @ArrayType(min = 1, type = IrisEntityInitialSpawn.class) private KList entityInitialSpawns = new KList<>(); + @Desc("Sapling override settings") + private IrisSaplings saplings = new IrisSaplings(); + + @Desc("Enable sapling overrides") + private boolean useSaplings = false; + @ArrayType(min = 1, type = IrisEffect.class) @Desc("Effects are ambient effects such as potion effects, random sounds, or even particles around each player. All of these effects are played via packets so two players won't see/hear each others effects.\nDue to performance reasons, effects will play arround the player even if where the effect was played is no longer in the biome the player is in.") private KList effects = new KList<>(); diff --git a/src/main/java/com/volmit/iris/engine/object/IrisDimension.java b/src/main/java/com/volmit/iris/engine/object/IrisDimension.java index 9119c39c9..ed8424099 100644 --- a/src/main/java/com/volmit/iris/engine/object/IrisDimension.java +++ b/src/main/java/com/volmit/iris/engine/object/IrisDimension.java @@ -74,6 +74,12 @@ public class IrisDimension extends IrisRegistrant { @Desc("Improves the biome grid variation by shuffling the cell grid more depending on the seed. This makes biomes across multiple seeds look far different than before.") private boolean aggressiveBiomeReshuffle = false; + @Desc("Sapling override settings") + private IrisSaplings saplings = new IrisSaplings(); + + @Desc("Enable sapling overrides") + private boolean useSaplings = false; + @Desc("Instead of a flat bottom, applies a clamp (using this noise style) to the bottom instead of a flat bottom. Useful for carving out center-dimensions in a dimension composite world.") private IrisShapedGeneratorStyle undercarriage = null; From 80ede42191ddee842042f86d9c17a71a5a82ff89 Mon Sep 17 00:00:00 2001 From: CocoTheOwner Date: Sat, 17 Jul 2021 18:01:11 +0200 Subject: [PATCH 04/41] Remove toggle from biome/region sapling config & prevent non-iris world --- .../java/com/volmit/iris/core/SaplingManager.java | 12 ++++++------ .../com/volmit/iris/engine/object/IrisBiome.java | 3 --- .../com/volmit/iris/engine/object/IrisRegion.java | 3 --- 3 files changed, 6 insertions(+), 12 deletions(-) diff --git a/src/main/java/com/volmit/iris/core/SaplingManager.java b/src/main/java/com/volmit/iris/core/SaplingManager.java index 3fc5f90f5..a4f781c4d 100644 --- a/src/main/java/com/volmit/iris/core/SaplingManager.java +++ b/src/main/java/com/volmit/iris/core/SaplingManager.java @@ -1,6 +1,8 @@ package com.volmit.iris.core; import com.volmit.iris.Iris; +import com.volmit.iris.engine.IrisWorldManager; +import com.volmit.iris.engine.IrisWorlds; import org.bukkit.TreeType; import org.bukkit.block.data.type.Sapling; import org.bukkit.event.EventHandler; @@ -18,12 +20,10 @@ public class SaplingManager implements Listener { @EventHandler public void onStructureGrowEvent(StructureGrowEvent event) { - if (event.getSpecies() == TreeType.JUNGLE) - Iris.info("Sapling grew @ " + event.getLocation() + " for " + event.getSpecies().name() + " bonemealed is " + event.isFromBonemeal() + " by player " + Objects.requireNonNull(event.getPlayer()).getName()); - } + if (!IrisWorlds.isIrisWorld(event.getWorld())) return; + + // TODO: Remove this line + Iris.info("Sapling grew @ " + event.getLocation() + " for " + event.getSpecies().name() + " bonemealed is " + event.isFromBonemeal() + " by player " + Objects.requireNonNull(event.getPlayer()).getName()); - @EventHandler - public void onBlockPlaceEvent(BlockPlaceEvent event) { - Iris.info("Placed " + event.getBlock().getBlockData().getMaterial().name() + " @ " + event.getBlock().getLocation()); } } diff --git a/src/main/java/com/volmit/iris/engine/object/IrisBiome.java b/src/main/java/com/volmit/iris/engine/object/IrisBiome.java index 5140895ec..fb3baadca 100644 --- a/src/main/java/com/volmit/iris/engine/object/IrisBiome.java +++ b/src/main/java/com/volmit/iris/engine/object/IrisBiome.java @@ -84,9 +84,6 @@ public class IrisBiome extends IrisRegistrant implements IRare { @Desc("Sapling override settings") private IrisSaplings saplings = new IrisSaplings(); - @Desc("Enable sapling overrides") - private boolean useSaplings = false; - @ArrayType(min = 1, type = IrisEffect.class) @Desc("Effects are ambient effects such as potion effects, random sounds, or even particles around each player. All of these effects are played via packets so two players won't see/hear each others effects.\nDue to performance reasons, effects will play arround the player even if where the effect was played is no longer in the biome the player is in.") private KList effects = new KList<>(); diff --git a/src/main/java/com/volmit/iris/engine/object/IrisRegion.java b/src/main/java/com/volmit/iris/engine/object/IrisRegion.java index cbef49407..f821a9be7 100644 --- a/src/main/java/com/volmit/iris/engine/object/IrisRegion.java +++ b/src/main/java/com/volmit/iris/engine/object/IrisRegion.java @@ -82,9 +82,6 @@ public class IrisRegion extends IrisRegistrant implements IRare { @Desc("Sapling override settings") private IrisSaplings saplings = new IrisSaplings(); - @Desc("Enable sapling overrides") - private boolean useSaplings = false; - @MinNumber(1) @MaxNumber(128) @Desc("The rarity of the region") From b4602c1e48d90d142e499fa8d197a4a0f9083707 Mon Sep 17 00:00:00 2001 From: CocoTheOwner Date: Sat, 17 Jul 2021 18:42:30 +0200 Subject: [PATCH 05/41] Create IrisSapling, Make sapling lists, rename toggles, add objects --- .../volmit/iris/engine/object/IrisSapling.java | 2 ++ .../iris/engine/object/IrisSaplings.java | 18 ------------------ 2 files changed, 2 insertions(+), 18 deletions(-) create mode 100644 src/main/java/com/volmit/iris/engine/object/IrisSapling.java delete mode 100644 src/main/java/com/volmit/iris/engine/object/IrisSaplings.java diff --git a/src/main/java/com/volmit/iris/engine/object/IrisSapling.java b/src/main/java/com/volmit/iris/engine/object/IrisSapling.java new file mode 100644 index 000000000..09734c3fc --- /dev/null +++ b/src/main/java/com/volmit/iris/engine/object/IrisSapling.java @@ -0,0 +1,2 @@ +package com.volmit.iris.engine.object;public class IrisSapling { +} diff --git a/src/main/java/com/volmit/iris/engine/object/IrisSaplings.java b/src/main/java/com/volmit/iris/engine/object/IrisSaplings.java deleted file mode 100644 index 20211a651..000000000 --- a/src/main/java/com/volmit/iris/engine/object/IrisSaplings.java +++ /dev/null @@ -1,18 +0,0 @@ -package com.volmit.iris.engine.object; - -import com.volmit.iris.engine.object.annotations.Desc; -import lombok.AllArgsConstructor; -import lombok.Data; -import lombok.NoArgsConstructor; -import lombok.experimental.Accessors; - -@Accessors(chain = true) -@NoArgsConstructor -@AllArgsConstructor -@Desc("Sapling override settings") -@Data -public class IrisSaplings { - - - -} From 4eb111765973e409477634cb8f3565694a305d89 Mon Sep 17 00:00:00 2001 From: CocoTheOwner Date: Sat, 17 Jul 2021 18:45:11 +0200 Subject: [PATCH 06/41] Ok? --- .../com/volmit/iris/core/SaplingManager.java | 1 + .../volmit/iris/engine/object/IrisBiome.java | 3 +- .../iris/engine/object/IrisDimension.java | 6 ++-- .../volmit/iris/engine/object/IrisRegion.java | 3 +- .../iris/engine/object/IrisSapling.java | 34 ++++++++++++++++++- 5 files changed, 41 insertions(+), 6 deletions(-) diff --git a/src/main/java/com/volmit/iris/core/SaplingManager.java b/src/main/java/com/volmit/iris/core/SaplingManager.java index a4f781c4d..e23e779c3 100644 --- a/src/main/java/com/volmit/iris/core/SaplingManager.java +++ b/src/main/java/com/volmit/iris/core/SaplingManager.java @@ -25,5 +25,6 @@ public class SaplingManager implements Listener { // TODO: Remove this line Iris.info("Sapling grew @ " + event.getLocation() + " for " + event.getSpecies().name() + " bonemealed is " + event.isFromBonemeal() + " by player " + Objects.requireNonNull(event.getPlayer()).getName()); + } } diff --git a/src/main/java/com/volmit/iris/engine/object/IrisBiome.java b/src/main/java/com/volmit/iris/engine/object/IrisBiome.java index fb3baadca..a7872f6ec 100644 --- a/src/main/java/com/volmit/iris/engine/object/IrisBiome.java +++ b/src/main/java/com/volmit/iris/engine/object/IrisBiome.java @@ -82,7 +82,8 @@ public class IrisBiome extends IrisRegistrant implements IRare { private KList entityInitialSpawns = new KList<>(); @Desc("Sapling override settings") - private IrisSaplings saplings = new IrisSaplings(); + @ArrayType(min = 1, type = IrisSapling.class) + private KList saplings = new KList<>(); @ArrayType(min = 1, type = IrisEffect.class) @Desc("Effects are ambient effects such as potion effects, random sounds, or even particles around each player. All of these effects are played via packets so two players won't see/hear each others effects.\nDue to performance reasons, effects will play arround the player even if where the effect was played is no longer in the biome the player is in.") diff --git a/src/main/java/com/volmit/iris/engine/object/IrisDimension.java b/src/main/java/com/volmit/iris/engine/object/IrisDimension.java index ed8424099..61b0c2efe 100644 --- a/src/main/java/com/volmit/iris/engine/object/IrisDimension.java +++ b/src/main/java/com/volmit/iris/engine/object/IrisDimension.java @@ -66,7 +66,6 @@ public class IrisDimension extends IrisRegistrant { private IrisDimension sky = null; @RegistryListJigsaw - @Desc("If defined, Iris will place the given jigsaw structure where minecraft should place the overworld stronghold.") private String stronghold; @@ -75,10 +74,11 @@ public class IrisDimension extends IrisRegistrant { private boolean aggressiveBiomeReshuffle = false; @Desc("Sapling override settings") - private IrisSaplings saplings = new IrisSaplings(); + @ArrayType(min = 1, type = IrisSapling.class) + private KList saplings = new KList<>(); @Desc("Enable sapling overrides") - private boolean useSaplings = false; + private boolean overrideSaplings = false; @Desc("Instead of a flat bottom, applies a clamp (using this noise style) to the bottom instead of a flat bottom. Useful for carving out center-dimensions in a dimension composite world.") diff --git a/src/main/java/com/volmit/iris/engine/object/IrisRegion.java b/src/main/java/com/volmit/iris/engine/object/IrisRegion.java index f821a9be7..43f8ad114 100644 --- a/src/main/java/com/volmit/iris/engine/object/IrisRegion.java +++ b/src/main/java/com/volmit/iris/engine/object/IrisRegion.java @@ -80,7 +80,8 @@ public class IrisRegion extends IrisRegistrant implements IRare { private KList entityInitialSpawns = new KList<>(); @Desc("Sapling override settings") - private IrisSaplings saplings = new IrisSaplings(); + @ArrayType(min = 1, type = IrisSapling.class) + private KList saplings = new KList<>(); @MinNumber(1) @MaxNumber(128) diff --git a/src/main/java/com/volmit/iris/engine/object/IrisSapling.java b/src/main/java/com/volmit/iris/engine/object/IrisSapling.java index 09734c3fc..76e4861c7 100644 --- a/src/main/java/com/volmit/iris/engine/object/IrisSapling.java +++ b/src/main/java/com/volmit/iris/engine/object/IrisSapling.java @@ -1,2 +1,34 @@ -package com.volmit.iris.engine.object;public class IrisSapling { +package com.volmit.iris.engine.object; + +import com.volmit.iris.engine.object.annotations.*; +import com.volmit.iris.util.collection.KList; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; +import lombok.experimental.Accessors; +import org.bukkit.TreeType; + +@Accessors(chain = true) +@AllArgsConstructor +@NoArgsConstructor +@Desc("Sapling override settings") +@Data +public class IrisSapling { + + @Required + @Desc("The types of saplings overwritten") + @ArrayType(min = 1, type = TreeType.class) + private KList types; + + @RegistryListObject + @Required + @ArrayType(min = 1, type = String.class) + @Desc("List of objects to overwrite saplings with") + private KList replace = new KList<>(); + + @Desc("The size of the square of saplings this applies to (two means a 2 by 2 sapling area") + @MinNumber(1) + @MaxNumber(4) + private int size = 1; + } From ffc8a5188df3cc7db4a3e398277156644d8ebd7f Mon Sep 17 00:00:00 2001 From: CocoTheOwner Date: Sat, 17 Jul 2021 20:38:05 +0200 Subject: [PATCH 07/41] Descriptions --- src/main/java/com/volmit/iris/engine/object/IrisSapling.java | 2 +- .../java/com/volmit/iris/engine/object/IrisTerrainMode.java | 5 +++++ src/main/java/com/volmit/iris/engine/object/LootMode.java | 2 +- 3 files changed, 7 insertions(+), 2 deletions(-) diff --git a/src/main/java/com/volmit/iris/engine/object/IrisSapling.java b/src/main/java/com/volmit/iris/engine/object/IrisSapling.java index 76e4861c7..cccea648e 100644 --- a/src/main/java/com/volmit/iris/engine/object/IrisSapling.java +++ b/src/main/java/com/volmit/iris/engine/object/IrisSapling.java @@ -26,7 +26,7 @@ public class IrisSapling { @Desc("List of objects to overwrite saplings with") private KList replace = new KList<>(); - @Desc("The size of the square of saplings this applies to (two means a 2 by 2 sapling area") + @Desc("The size of the square of saplings this applies to (two means a 2 by 2 sapling area)") @MinNumber(1) @MaxNumber(4) private int size = 1; diff --git a/src/main/java/com/volmit/iris/engine/object/IrisTerrainMode.java b/src/main/java/com/volmit/iris/engine/object/IrisTerrainMode.java index fed827bee..7eadf9f18 100644 --- a/src/main/java/com/volmit/iris/engine/object/IrisTerrainMode.java +++ b/src/main/java/com/volmit/iris/engine/object/IrisTerrainMode.java @@ -18,7 +18,12 @@ package com.volmit.iris.engine.object; +import com.volmit.iris.engine.object.annotations.Desc; + +@Desc("Terrain modes are used to decide the generator type currently used") public enum IrisTerrainMode { + @Desc("Normal terrain, similar to the vanilla overworld") NORMAL, + @Desc("Island terrain, more similar to the end, but endless possibilities!") ISLANDS } diff --git a/src/main/java/com/volmit/iris/engine/object/LootMode.java b/src/main/java/com/volmit/iris/engine/object/LootMode.java index fa4f205c4..36b48995a 100644 --- a/src/main/java/com/volmit/iris/engine/object/LootMode.java +++ b/src/main/java/com/volmit/iris/engine/object/LootMode.java @@ -20,7 +20,7 @@ package com.volmit.iris.engine.object; import com.volmit.iris.engine.object.annotations.Desc; -@Desc("A loot mode is used to descrive what to do with the existing loot layers before adding this loot. Using ADD will simply add this table to the building list of tables (i.e. add dimension tables, region tables then biome tables). By using clear or replace, you remove the parent tables before and add just your tables.") +@Desc("A loot mode is used to describe what to do with the existing loot layers before adding this loot. Using ADD will simply add this table to the building list of tables (i.e. add dimension tables, region tables then biome tables). By using clear or replace, you remove the parent tables before and add just your tables.") public enum LootMode { @Desc("Add to the existing parent loot tables") From 8da9156bb5d90be616f98efdf5492d19dfb3779d Mon Sep 17 00:00:00 2001 From: CocoTheOwner Date: Sat, 17 Jul 2021 20:38:12 +0200 Subject: [PATCH 08/41] Saplings --- .../com/volmit/iris/core/SaplingManager.java | 20 ++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/src/main/java/com/volmit/iris/core/SaplingManager.java b/src/main/java/com/volmit/iris/core/SaplingManager.java index e23e779c3..46ffa7891 100644 --- a/src/main/java/com/volmit/iris/core/SaplingManager.java +++ b/src/main/java/com/volmit/iris/core/SaplingManager.java @@ -1,8 +1,12 @@ package com.volmit.iris.core; import com.volmit.iris.Iris; +import com.volmit.iris.engine.IrisEngine; import com.volmit.iris.engine.IrisWorldManager; import com.volmit.iris.engine.IrisWorlds; +import com.volmit.iris.engine.framework.IrisAccess; +import com.volmit.iris.engine.object.IrisBiome; +import com.volmit.iris.engine.object.IrisDimension; import org.bukkit.TreeType; import org.bukkit.block.data.type.Sapling; import org.bukkit.event.EventHandler; @@ -20,11 +24,25 @@ public class SaplingManager implements Listener { @EventHandler public void onStructureGrowEvent(StructureGrowEvent event) { + + // Must be iris world if (!IrisWorlds.isIrisWorld(event.getWorld())) return; + IrisAccess worldAccess; + try { + worldAccess = Objects.requireNonNull(IrisWorlds.access(event.getWorld())); + } catch (Throwable e){ + Iris.reportError(e); + return; + } + IrisDimension dim = worldAccess.getCompound().getDefaultEngine().getDimension(); + + // Must have override enabled + if (!dim.isOverrideSaplings()) return; + // TODO: Remove this line Iris.info("Sapling grew @ " + event.getLocation() + " for " + event.getSpecies().name() + " bonemealed is " + event.isFromBonemeal() + " by player " + Objects.requireNonNull(event.getPlayer()).getName()); - + Iris.info("Should replace sapling now!"); } } From 8d6a2e8882a1ea45067db1bbf429aedde1711f7f Mon Sep 17 00:00:00 2001 From: CocoTheOwner Date: Sat, 17 Jul 2021 21:41:30 +0200 Subject: [PATCH 09/41] Basic sapling manager logic. Needs polishing --- .../com/volmit/iris/core/SaplingManager.java | 109 +++++++++++++++--- .../iris/engine/object/IrisSapling.java | 3 +- 2 files changed, 95 insertions(+), 17 deletions(-) diff --git a/src/main/java/com/volmit/iris/core/SaplingManager.java b/src/main/java/com/volmit/iris/core/SaplingManager.java index 46ffa7891..6a45944d4 100644 --- a/src/main/java/com/volmit/iris/core/SaplingManager.java +++ b/src/main/java/com/volmit/iris/core/SaplingManager.java @@ -5,8 +5,9 @@ import com.volmit.iris.engine.IrisEngine; import com.volmit.iris.engine.IrisWorldManager; import com.volmit.iris.engine.IrisWorlds; import com.volmit.iris.engine.framework.IrisAccess; -import com.volmit.iris.engine.object.IrisBiome; -import com.volmit.iris.engine.object.IrisDimension; +import com.volmit.iris.engine.object.*; +import com.volmit.iris.util.collection.KList; +import com.volmit.iris.util.math.RNG; import org.bukkit.TreeType; import org.bukkit.block.data.type.Sapling; import org.bukkit.event.EventHandler; @@ -20,29 +21,107 @@ public class SaplingManager implements Listener { public SaplingManager() { Iris.instance.registerListener(this); + Iris.info("Loading Sapling Manager"); } + /** + * This function does the following: + * 1. Is the sapling growing in an Iris world? No -> exit + * 2. Is the sapling overwriting setting on in that dimension? No -> exit + * 3. Check biome for overrides for that sapling type -> Found -> use + * 4. Check region ... + * 5. Check dimension ... + * 6. Exit if none are found + * @param event Checks the given event for sapling overrides + */ @EventHandler public void onStructureGrowEvent(StructureGrowEvent event) { - // Must be iris world - if (!IrisWorlds.isIrisWorld(event.getWorld())) return; + // TODO: Remove this line + Iris.info("Sapling grew @ " + event.getLocation() + " for " + event.getSpecies().name() + " bonemealed is " + event.isFromBonemeal()); - IrisAccess worldAccess; - try { - worldAccess = Objects.requireNonNull(IrisWorlds.access(event.getWorld())); - } catch (Throwable e){ - Iris.reportError(e); - return; + + // TODO: Remove if statement here once Iris worlds are creatable again + boolean debug = true; + + if (!debug) { + // Must be iris world + if (!IrisWorlds.isIrisWorld(event.getWorld())) return; + + IrisAccess worldAccess; + try { + worldAccess = Objects.requireNonNull(IrisWorlds.access(event.getWorld())); + } catch (Throwable e) { + Iris.reportError(e); + return; + } + + IrisDimension dim = worldAccess.getCompound().getRootDimension(); } - IrisDimension dim = worldAccess.getCompound().getDefaultEngine().getDimension(); - - // Must have override enabled - if (!dim.isOverrideSaplings()) return; // TODO: Remove this line - Iris.info("Sapling grew @ " + event.getLocation() + " for " + event.getSpecies().name() + " bonemealed is " + event.isFromBonemeal() + " by player " + Objects.requireNonNull(event.getPlayer()).getName()); + IrisDimension dimension = IrisDataManager.loadAnyDimension("overworld"); + + // Must have override enabled + if (!dimension.isOverrideSaplings()) return; + + // TODO: Remove this line Iris.info("Should replace sapling now!"); + + IrisAccess worldAccess = IrisWorlds.access(event.getWorld()); + assert worldAccess != null; + KList replace = null; + + // Check biome + IrisBiome biome = worldAccess.getBiome(event.getLocation().getBlockX(), event.getLocation().getBlockZ()); + for (IrisSapling sapling : biome.getSaplings()){ + for (TreeType type : sapling.getTypes()){ + if (type == event.getSpecies()){ + replace = sapling.getReplace(); + // If we decide to do some sort of addition (biome + region + dim for options) we can do that here + } + } + } + + // Check region + if (replace == null) { + IrisRegion region = worldAccess.getCompound().getDefaultEngine().getRegion(event.getLocation().getBlockX(), event.getLocation().getBlockZ()); + for (IrisSapling sapling : region.getSaplings()) { + for (TreeType type : sapling.getTypes()) { + if (type == event.getSpecies()) { + replace = sapling.getReplace(); + // If we decide to do some sort of addition (biome + region + dim for options) we can do that here + } + } + } + } + + // Check dimension + if (replace == null) { + for (IrisSapling sapling : dimension.getSaplings()) { + for (TreeType type : sapling.getTypes()) { + if (type == event.getSpecies()) { + replace = sapling.getReplace(); + // If we decide to do some sort of addition (biome + region + dim for options) we can do that here + } + } + } + } + + // Check to make sure something was found + if (replace == null || replace.size() == 0) return; + + // Pick a random object from the list of objects found + String object = replace.get(RNG.r.i(0, replace.size() - 1)); + + // Cancel vanilla event + event.setCancelled(true); + + // Retrieve & place the object + // TODO: Make this specific for this pack + Iris.info("Placing tree object instead of vanilla tree: " + object); + IrisObject obj = IrisDataManager.loadAnyObject(object); + obj.place(event.getLocation()); } } diff --git a/src/main/java/com/volmit/iris/engine/object/IrisSapling.java b/src/main/java/com/volmit/iris/engine/object/IrisSapling.java index cccea648e..cc80a38ba 100644 --- a/src/main/java/com/volmit/iris/engine/object/IrisSapling.java +++ b/src/main/java/com/volmit/iris/engine/object/IrisSapling.java @@ -30,5 +30,4 @@ public class IrisSapling { @MinNumber(1) @MaxNumber(4) private int size = 1; - -} +} \ No newline at end of file From 944ef838054ad1d370377294057ad31af76e78e3 Mon Sep 17 00:00:00 2001 From: CocoTheOwner Date: Sun, 18 Jul 2021 17:21:29 +0200 Subject: [PATCH 10/41] everything reworked --- .../com/volmit/iris/core/SaplingManager.java | 173 ++++++++++-------- .../volmit/iris/core/edit/DustRevealer.java | 1 + .../volmit/iris/engine/object/IrisBiome.java | 4 +- .../iris/engine/object/IrisDimension.java | 6 +- .../volmit/iris/engine/object/IrisRegion.java | 4 +- .../{IrisSapling.java => IrisTree.java} | 16 +- .../iris/engine/object/IrisTreeModes.java | 12 ++ .../iris/engine/object/IrisTreeSettings.java | 29 +++ .../iris/engine/object/IrisTreeType.java | 75 ++++++++ 9 files changed, 227 insertions(+), 93 deletions(-) rename src/main/java/com/volmit/iris/engine/object/{IrisSapling.java => IrisTree.java} (62%) create mode 100644 src/main/java/com/volmit/iris/engine/object/IrisTreeModes.java create mode 100644 src/main/java/com/volmit/iris/engine/object/IrisTreeSettings.java create mode 100644 src/main/java/com/volmit/iris/engine/object/IrisTreeType.java diff --git a/src/main/java/com/volmit/iris/core/SaplingManager.java b/src/main/java/com/volmit/iris/core/SaplingManager.java index 6a45944d4..85927584a 100644 --- a/src/main/java/com/volmit/iris/core/SaplingManager.java +++ b/src/main/java/com/volmit/iris/core/SaplingManager.java @@ -1,127 +1,148 @@ package com.volmit.iris.core; import com.volmit.iris.Iris; -import com.volmit.iris.engine.IrisEngine; -import com.volmit.iris.engine.IrisWorldManager; import com.volmit.iris.engine.IrisWorlds; import com.volmit.iris.engine.framework.IrisAccess; import com.volmit.iris.engine.object.*; import com.volmit.iris.util.collection.KList; import com.volmit.iris.util.math.RNG; +import org.bukkit.Location; +import org.bukkit.Material; import org.bukkit.TreeType; -import org.bukkit.block.data.type.Sapling; import org.bukkit.event.EventHandler; import org.bukkit.event.Listener; -import org.bukkit.event.block.BlockPlaceEvent; import org.bukkit.event.world.StructureGrowEvent; +import org.jetbrains.annotations.NotNull; import java.util.Objects; public class SaplingManager implements Listener { + private static final boolean debugMe = false; + public SaplingManager() { Iris.instance.registerListener(this); Iris.info("Loading Sapling Manager"); } - /** - * This function does the following: - * 1. Is the sapling growing in an Iris world? No -> exit - * 2. Is the sapling overwriting setting on in that dimension? No -> exit - * 3. Check biome for overrides for that sapling type -> Found -> use - * 4. Check region ... - * 5. Check dimension ... - * 6. Exit if none are found + /**This function does the following + *
1. Is the sapling growing in an Iris world? No -> exit
+ *
2. Is the sapling overwriting setting on in that dimension? No -> exit
+ *
3. Check biome for overrides for that sapling type -> Found -> use
+ *
4. Check region ...
+ *
5. Check dimension ...
+ *
6. Exit if none are found
* @param event Checks the given event for sapling overrides */ @EventHandler public void onStructureGrowEvent(StructureGrowEvent event) { - // TODO: Remove this line - Iris.info("Sapling grew @ " + event.getLocation() + " for " + event.getSpecies().name() + " bonemealed is " + event.isFromBonemeal()); + if (debugMe) + Iris.info("Sapling grew @ " + event.getLocation() + " for " + event.getSpecies().name() + " usedBoneMeal is " + event.isFromBonemeal()); + // Must be iris world + if (!IrisWorlds.isIrisWorld(event.getWorld())) return; - // TODO: Remove if statement here once Iris worlds are creatable again - boolean debug = true; - - if (!debug) { - // Must be iris world - if (!IrisWorlds.isIrisWorld(event.getWorld())) return; - - IrisAccess worldAccess; - try { - worldAccess = Objects.requireNonNull(IrisWorlds.access(event.getWorld())); - } catch (Throwable e) { - Iris.reportError(e); - return; - } - - IrisDimension dim = worldAccess.getCompound().getRootDimension(); + IrisAccess worldAccess; + try { + worldAccess = Objects.requireNonNull(IrisWorlds.access(event.getWorld())); + } catch (Throwable e) { + Iris.reportError(e); + return; } + IrisTreeSettings settings = worldAccess.getCompound().getRootDimension().getSaplingSettings(); - // TODO: Remove this line - IrisDimension dimension = IrisDataManager.loadAnyDimension("overworld"); - + if (debugMe) Iris.info("Custom saplings are enabled: " + (settings.isEnabled() ? "Yes" : "No")); // Must have override enabled - if (!dimension.isOverrideSaplings()) return; + if (!settings.isEnabled()) return; - // TODO: Remove this line - Iris.info("Should replace sapling now!"); + KList treeObjects = new KList<>(); - IrisAccess worldAccess = IrisWorlds.access(event.getWorld()); - assert worldAccess != null; - KList replace = null; + // Get biome and region + IrisBiome biome = worldAccess.getBiome(event.getLocation().getBlockX(), event.getLocation().getBlockY(), event.getLocation().getBlockZ()); + IrisRegion region = worldAccess.getCompound().getDefaultEngine().getRegion(event.getLocation().getBlockX(), event.getLocation().getBlockZ()); - // Check biome - IrisBiome biome = worldAccess.getBiome(event.getLocation().getBlockX(), event.getLocation().getBlockZ()); - for (IrisSapling sapling : biome.getSaplings()){ - for (TreeType type : sapling.getTypes()){ - if (type == event.getSpecies()){ - replace = sapling.getReplace(); - // If we decide to do some sort of addition (biome + region + dim for options) we can do that here - } - } - } + if (debugMe) + Iris.info("Biome name: " + biome.getName() + " | List of saplings: " + biome.getSaplings().toString()); + if (debugMe) + Iris.info("Region name: " + region.getName() + " | List of saplings: " + region.getSaplings().toString()); + if (debugMe) + Iris.info("Dimension saplings: " + settings.getSaplings().toString()); + + int saplingSize = getSaplingSize(event.getLocation()); + + // Check biome, region and dimension + treeObjects.addAll(getSaplingsFrom(biome.getSaplings(), event.getSpecies(), saplingSize)); // Check region - if (replace == null) { - IrisRegion region = worldAccess.getCompound().getDefaultEngine().getRegion(event.getLocation().getBlockX(), event.getLocation().getBlockZ()); - for (IrisSapling sapling : region.getSaplings()) { - for (TreeType type : sapling.getTypes()) { - if (type == event.getSpecies()) { - replace = sapling.getReplace(); - // If we decide to do some sort of addition (biome + region + dim for options) we can do that here - } - } - } - } + if (settings.getMode() == IrisTreeModes.ALL || treeObjects.size() == 0) + treeObjects.addAll(getSaplingsFrom(region.getSaplings(), event.getSpecies(), saplingSize)); // Check dimension - if (replace == null) { - for (IrisSapling sapling : dimension.getSaplings()) { - for (TreeType type : sapling.getTypes()) { - if (type == event.getSpecies()) { - replace = sapling.getReplace(); - // If we decide to do some sort of addition (biome + region + dim for options) we can do that here - } - } - } - } + if (settings.getMode() == IrisTreeModes.ALL || treeObjects.size() == 0) + treeObjects.addAll(getSaplingsFrom(settings.getSaplings(), event.getSpecies(), saplingSize)); + + if (debugMe) Iris.info("List of saplings (together): " + treeObjects); // Check to make sure something was found - if (replace == null || replace.size() == 0) return; + if (treeObjects.size() == 0) return; // Pick a random object from the list of objects found - String object = replace.get(RNG.r.i(0, replace.size() - 1)); + String pickedObjectString = treeObjects.get(RNG.r.i(0, treeObjects.size() - 1)); // Cancel vanilla event event.setCancelled(true); // Retrieve & place the object - // TODO: Make this specific for this pack - Iris.info("Placing tree object instead of vanilla tree: " + object); - IrisObject obj = IrisDataManager.loadAnyObject(object); - obj.place(event.getLocation()); + if (debugMe) Iris.info("Placing tree object instead of vanilla tree: " + pickedObjectString); + IrisObject pickedObject = IrisDataManager.loadAnyObject(pickedObjectString); + + // Delete the saplings (some objects may not have blocks where the sapling is) + // TODO: Rewrite this to delete the saplings that matter + event.getBlocks().forEach(b -> b.setType(Material.AIR)); + + // Rotate and place the object + pickedObject.rotate(new IrisObjectRotation(), 0, 90 * RNG.r.i(0, 3), 0); + pickedObject.place(event.getLocation()); + } + + /** + * Find all sapling types of the given TreeType in the container + * @param container Iris sapling config + * @param tree The tree type to find + * @param size The `size * size` area of the saplings + * @return A list of found object name strings + */ + @NotNull + private KList getSaplingsFrom(KList container, TreeType tree, int size) { + + // Translate TreeType to Iris TreeType + IrisTreeType eventTreeType = IrisTreeType.fromTreeType(tree); + + KList objects = new KList<>(); + + // Loop over all saplings in the container + // and their entered sapling types + // and copy the trees in the list if matching. + for (IrisTree sapling : container) { + for (IrisTreeType configTreeType : sapling.getTreeTypes()) { + if (configTreeType == eventTreeType && size == sapling.getSize()) { + objects.addAll(sapling.getObjects()); + if (debugMe) Iris.info("Added replacements: " + sapling.getObjects().toString()); + } + } + } + return objects; + } + + /** + * Retrieve the `size * size` area of a sapling (any sapling in the area) + * @param location The location to start the search from + * @return The `x * x` area of saplings + */ + private int getSaplingSize(Location location){ + // TODO: Write this + return 1; } } diff --git a/src/main/java/com/volmit/iris/core/edit/DustRevealer.java b/src/main/java/com/volmit/iris/core/edit/DustRevealer.java index 750e975c3..0fa4344c2 100644 --- a/src/main/java/com/volmit/iris/core/edit/DustRevealer.java +++ b/src/main/java/com/volmit/iris/core/edit/DustRevealer.java @@ -49,6 +49,7 @@ public class DustRevealer { if (a.getObject(block.getX(), block.getY(), block.getZ()) != null) { sender.sendMessage("Found object " + a.getObject(block.getX(), block.getY(), block.getZ())); + Iris.info(sender.getName() + " found object " + a.getObject(block.getX(), block.getY(), block.getZ())); J.a(() -> { new DustRevealer(a, world, new BlockPosition(block.getX(), block.getY(), block.getZ()), a.getObject(block.getX(), block.getY(), block.getZ()), new KList<>()); }); diff --git a/src/main/java/com/volmit/iris/engine/object/IrisBiome.java b/src/main/java/com/volmit/iris/engine/object/IrisBiome.java index a7872f6ec..34353d1f7 100644 --- a/src/main/java/com/volmit/iris/engine/object/IrisBiome.java +++ b/src/main/java/com/volmit/iris/engine/object/IrisBiome.java @@ -82,8 +82,8 @@ public class IrisBiome extends IrisRegistrant implements IRare { private KList entityInitialSpawns = new KList<>(); @Desc("Sapling override settings") - @ArrayType(min = 1, type = IrisSapling.class) - private KList saplings = new KList<>(); + @ArrayType(min = 1, type = IrisTree.class) + private KList saplings = new KList<>(); @ArrayType(min = 1, type = IrisEffect.class) @Desc("Effects are ambient effects such as potion effects, random sounds, or even particles around each player. All of these effects are played via packets so two players won't see/hear each others effects.\nDue to performance reasons, effects will play arround the player even if where the effect was played is no longer in the biome the player is in.") diff --git a/src/main/java/com/volmit/iris/engine/object/IrisDimension.java b/src/main/java/com/volmit/iris/engine/object/IrisDimension.java index def631cf6..e3e7bad3a 100644 --- a/src/main/java/com/volmit/iris/engine/object/IrisDimension.java +++ b/src/main/java/com/volmit/iris/engine/object/IrisDimension.java @@ -74,11 +74,7 @@ public class IrisDimension extends IrisRegistrant { private boolean aggressiveBiomeReshuffle = false; @Desc("Sapling override settings") - @ArrayType(min = 1, type = IrisSapling.class) - private KList saplings = new KList<>(); - - @Desc("Enable sapling overrides") - private boolean overrideSaplings = false; + private IrisTreeSettings saplingSettings = new IrisTreeSettings(); @Desc("Instead of a flat bottom, applies a clamp (using this noise style) to the bottom instead of a flat bottom. Useful for carving out center-dimensions in a dimension composite world.") diff --git a/src/main/java/com/volmit/iris/engine/object/IrisRegion.java b/src/main/java/com/volmit/iris/engine/object/IrisRegion.java index 43f8ad114..8f555ce08 100644 --- a/src/main/java/com/volmit/iris/engine/object/IrisRegion.java +++ b/src/main/java/com/volmit/iris/engine/object/IrisRegion.java @@ -80,8 +80,8 @@ public class IrisRegion extends IrisRegistrant implements IRare { private KList entityInitialSpawns = new KList<>(); @Desc("Sapling override settings") - @ArrayType(min = 1, type = IrisSapling.class) - private KList saplings = new KList<>(); + @ArrayType(min = 1, type = IrisTree.class) + private KList saplings = new KList<>(); @MinNumber(1) @MaxNumber(128) diff --git a/src/main/java/com/volmit/iris/engine/object/IrisSapling.java b/src/main/java/com/volmit/iris/engine/object/IrisTree.java similarity index 62% rename from src/main/java/com/volmit/iris/engine/object/IrisSapling.java rename to src/main/java/com/volmit/iris/engine/object/IrisTree.java index cc80a38ba..1a7189857 100644 --- a/src/main/java/com/volmit/iris/engine/object/IrisSapling.java +++ b/src/main/java/com/volmit/iris/engine/object/IrisTree.java @@ -11,23 +11,23 @@ import org.bukkit.TreeType; @Accessors(chain = true) @AllArgsConstructor @NoArgsConstructor -@Desc("Sapling override settings") +@Desc("Tree replace options") @Data -public class IrisSapling { +public class IrisTree { @Required - @Desc("The types of saplings overwritten") + @Desc("The types of trees overwritten") @ArrayType(min = 1, type = TreeType.class) - private KList types; + private KList treeTypes; @RegistryListObject @Required @ArrayType(min = 1, type = String.class) - @Desc("List of objects to overwrite saplings with") - private KList replace = new KList<>(); + @Desc("List of objects to replace trees with") + private KList objects = new KList<>(); - @Desc("The size of the square of saplings this applies to (two means a 2 by 2 sapling area)") + @Desc("The size of the square of saplings this applies to (2 means a 2 * 2 sapling area)") @MinNumber(1) - @MaxNumber(4) + @MaxNumber(5) private int size = 1; } \ No newline at end of file diff --git a/src/main/java/com/volmit/iris/engine/object/IrisTreeModes.java b/src/main/java/com/volmit/iris/engine/object/IrisTreeModes.java new file mode 100644 index 000000000..d3474b036 --- /dev/null +++ b/src/main/java/com/volmit/iris/engine/object/IrisTreeModes.java @@ -0,0 +1,12 @@ +package com.volmit.iris.engine.object; + +import com.volmit.iris.engine.object.annotations.Desc; + +@Desc("Sapling override object picking options") +public enum IrisTreeModes { + @Desc("Check biome, then region, then dimension, pick the first one that has options") + FIRST, + + @Desc("Check biome, regions, and dimensions, and pick any option from the total list") + ALL +} \ No newline at end of file diff --git a/src/main/java/com/volmit/iris/engine/object/IrisTreeSettings.java b/src/main/java/com/volmit/iris/engine/object/IrisTreeSettings.java new file mode 100644 index 000000000..584fc9a64 --- /dev/null +++ b/src/main/java/com/volmit/iris/engine/object/IrisTreeSettings.java @@ -0,0 +1,29 @@ +package com.volmit.iris.engine.object; + +import com.volmit.iris.engine.object.annotations.ArrayType; +import com.volmit.iris.engine.object.annotations.Desc; +import com.volmit.iris.util.collection.KList; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.NoArgsConstructor; +import lombok.experimental.Accessors; + +@Accessors(chain = true) +@AllArgsConstructor +@NoArgsConstructor +@Desc("Tree growth override settings") +@Data +@EqualsAndHashCode(callSuper = false) +public class IrisTreeSettings { + + @Desc("Turn replacing on and off") + boolean enabled = false; + + @Desc("Object picking modes") + IrisTreeModes mode = IrisTreeModes.FIRST; + + @Desc("Tree override list") + @ArrayType(min = 1, type = IrisTree.class) + private KList saplings = new KList<>(); +} diff --git a/src/main/java/com/volmit/iris/engine/object/IrisTreeType.java b/src/main/java/com/volmit/iris/engine/object/IrisTreeType.java new file mode 100644 index 000000000..031336c4c --- /dev/null +++ b/src/main/java/com/volmit/iris/engine/object/IrisTreeType.java @@ -0,0 +1,75 @@ +package com.volmit.iris.engine.object; + +import org.bukkit.TreeType; + +public enum IrisTreeType { + + /** + * Oak tree (BIG_TREE, TREE) + */ + OAK, + /** + * Spruce tree (MEGA_REDWOOD, REDWOOD, SWAMP, TALL_REDWOOD) + */ + SPRUCE, + /** + * Birch tree (BIRCH, TALL_BIRCH) + */ + BIRCH, + /** + * Jungle tree (JUNGLE, SMALL_JUNGLE) + */ + JUNGLE, + /** + * Big red mushroom; short and fat + */ + RED_MUSHROOM, + /** + * Big brown mushroom; tall and umbrella-like + */ + BROWN_MUSHROOM, + /** + * Acacia tree + */ + ACACIA, + /** + * Dark Oak tree + */ + DARK_OAK, + /** + * Large crimson fungus native to the nether + */ + CRIMSON_FUNGUS, + /** + * Large warped fungus native to the nether + */ + WARPED_FUNGUS, + /** + * Tree with large roots which grows above lush caves + */ + AZALEA, + /** + * The fallback type for all other non-supported growth events + */ + NONE; + + public static IrisTreeType fromTreeType(TreeType type){ + IrisTreeType irisType; + switch(type){ + case BIG_TREE, TREE -> irisType = IrisTreeType.OAK; + case MEGA_REDWOOD, REDWOOD, SWAMP, TALL_REDWOOD -> irisType = IrisTreeType.SPRUCE; + case BIRCH, TALL_BIRCH -> irisType = IrisTreeType.BIRCH; + case JUNGLE, SMALL_JUNGLE -> irisType = IrisTreeType.JUNGLE; + case RED_MUSHROOM -> irisType = IrisTreeType.RED_MUSHROOM; + case BROWN_MUSHROOM -> irisType = IrisTreeType.BROWN_MUSHROOM; + case ACACIA -> irisType = IrisTreeType.ACACIA; + case DARK_OAK -> irisType = IrisTreeType.DARK_OAK; + case CRIMSON_FUNGUS -> irisType = IrisTreeType.CRIMSON_FUNGUS; + case WARPED_FUNGUS -> irisType = IrisTreeType.WARPED_FUNGUS; + case AZALEA -> irisType = IrisTreeType.AZALEA; + //case COCOA_TREE, CHORUS_PLANT, JUNGLE_BUSH -> irisType = IrisSaplingType.NONE; + default -> irisType = IrisTreeType.NONE; + } + return irisType; + } +} From af1b17cb98da8426fc007b8c15806889829f5c61 Mon Sep 17 00:00:00 2001 From: CocoTheOwner Date: Sun, 18 Jul 2021 18:00:10 +0200 Subject: [PATCH 11/41] Rename & rewrite, add limits & checks, better delete --- src/main/java/com/volmit/iris/Iris.java | 4 +- .../{SaplingManager.java => TreeManager.java} | 51 +++++++++++---- .../volmit/iris/engine/object/IrisTree.java | 5 +- .../iris/engine/object/IrisTreeType.java | 65 +++++++++---------- 4 files changed, 74 insertions(+), 51 deletions(-) rename src/main/java/com/volmit/iris/core/{SaplingManager.java => TreeManager.java} (77%) diff --git a/src/main/java/com/volmit/iris/Iris.java b/src/main/java/com/volmit/iris/Iris.java index a59f8a944..47e906057 100644 --- a/src/main/java/com/volmit/iris/Iris.java +++ b/src/main/java/com/volmit/iris/Iris.java @@ -77,7 +77,7 @@ public class Iris extends VolmitPlugin implements Listener { public static BKLink linkBK; public static MultiverseCoreLink linkMultiverseCore; public static MythicMobsLink linkMythicMobs; - public static SaplingManager saplingManager; + public static TreeManager saplingManager; private static final Queue syncJobs = new ShurikenQueue<>(); public static boolean customModels = doesSupportCustomModels(); public static boolean awareEntities = doesSupportAwareness(); @@ -233,7 +233,7 @@ public class Iris extends VolmitPlugin implements Listener { linkMultiverseCore = new MultiverseCoreLink(); linkBK = new BKLink(); linkMythicMobs = new MythicMobsLink(); - saplingManager = new SaplingManager(); + saplingManager = new TreeManager(); edit = new EditManager(); configWatcher = new FileWatcher(getDataFile("settings.json")); J.a(() -> IO.delete(getTemp())); diff --git a/src/main/java/com/volmit/iris/core/SaplingManager.java b/src/main/java/com/volmit/iris/core/TreeManager.java similarity index 77% rename from src/main/java/com/volmit/iris/core/SaplingManager.java rename to src/main/java/com/volmit/iris/core/TreeManager.java index 85927584a..31ef4f3b8 100644 --- a/src/main/java/com/volmit/iris/core/SaplingManager.java +++ b/src/main/java/com/volmit/iris/core/TreeManager.java @@ -9,6 +9,7 @@ import com.volmit.iris.util.math.RNG; import org.bukkit.Location; import org.bukkit.Material; import org.bukkit.TreeType; +import org.bukkit.block.data.type.Sapling; import org.bukkit.event.EventHandler; import org.bukkit.event.Listener; import org.bukkit.event.world.StructureGrowEvent; @@ -16,11 +17,13 @@ import org.jetbrains.annotations.NotNull; import java.util.Objects; -public class SaplingManager implements Listener { +public class TreeManager implements Listener { - private static final boolean debugMe = false; + private static final boolean debugMe = true; - public SaplingManager() { + public static final int maxSaplingPlane = 5; + + public TreeManager() { Iris.instance.registerListener(this); Iris.info("Loading Sapling Manager"); } @@ -70,7 +73,9 @@ public class SaplingManager implements Listener { if (debugMe) Iris.info("Dimension saplings: " + settings.getSaplings().toString()); - int saplingSize = getSaplingSize(event.getLocation()); + // Get sapling location + KList saplingLocations = getSaplingPlane(event.getLocation()); + int saplingSize = getSaplingSize(saplingLocations); // Check biome, region and dimension treeObjects.addAll(getSaplingsFrom(biome.getSaplings(), event.getSpecies(), saplingSize)); @@ -99,14 +104,24 @@ public class SaplingManager implements Listener { IrisObject pickedObject = IrisDataManager.loadAnyObject(pickedObjectString); // Delete the saplings (some objects may not have blocks where the sapling is) - // TODO: Rewrite this to delete the saplings that matter - event.getBlocks().forEach(b -> b.setType(Material.AIR)); + deleteSaplings(saplingLocations); // Rotate and place the object pickedObject.rotate(new IrisObjectRotation(), 0, 90 * RNG.r.i(0, 3), 0); pickedObject.place(event.getLocation()); } + /** + * Deletes all saplings at the + * @param locations sapling locations + */ + private void deleteSaplings(KList locations) { + locations.forEach(l -> { + if (debugMe) Iris.info("Deleting block of type: " + l.getBlock().getType()); + l.getBlock().setType(Material.AIR); + }); + } + /** * Find all sapling types of the given TreeType in the container * @param container Iris sapling config @@ -129,7 +144,6 @@ public class SaplingManager implements Listener { for (IrisTreeType configTreeType : sapling.getTreeTypes()) { if (configTreeType == eventTreeType && size == sapling.getSize()) { objects.addAll(sapling.getObjects()); - if (debugMe) Iris.info("Added replacements: " + sapling.getObjects().toString()); } } } @@ -138,11 +152,26 @@ public class SaplingManager implements Listener { /** * Retrieve the `size * size` area of a sapling (any sapling in the area) - * @param location The location to start the search from + * @param saplings The locations of the saplings in the plane * @return The `x * x` area of saplings */ - private int getSaplingSize(Location location){ - // TODO: Write this - return 1; + private int getSaplingSize(KList saplings){ + double size = Math.sqrt(saplings.size()); + if (size % 1 != 0) { + Iris.error("Size of sapling square array is not a power of an integer (not a square)"); + return -1; + } + return (int) size; + } + + /** + * Retrieve all saplings in a square area around the current sapling. + * This searches around the current sapling, and the next, etc, iteratively + * Note: This is limited by maxSaplingPlane + * @param location The location to search from (the originating sapling) + * @return A list of saplings in a square + */ + private KList getSaplingPlane(Location location){ + return new KList<>(); } } diff --git a/src/main/java/com/volmit/iris/engine/object/IrisTree.java b/src/main/java/com/volmit/iris/engine/object/IrisTree.java index 1a7189857..130a14a46 100644 --- a/src/main/java/com/volmit/iris/engine/object/IrisTree.java +++ b/src/main/java/com/volmit/iris/engine/object/IrisTree.java @@ -1,5 +1,6 @@ package com.volmit.iris.engine.object; +import com.volmit.iris.core.TreeManager; import com.volmit.iris.engine.object.annotations.*; import com.volmit.iris.util.collection.KList; import lombok.AllArgsConstructor; @@ -17,7 +18,7 @@ public class IrisTree { @Required @Desc("The types of trees overwritten") - @ArrayType(min = 1, type = TreeType.class) + @ArrayType(min = 1, type = IrisTreeType.class) private KList treeTypes; @RegistryListObject @@ -28,6 +29,6 @@ public class IrisTree { @Desc("The size of the square of saplings this applies to (2 means a 2 * 2 sapling area)") @MinNumber(1) - @MaxNumber(5) + @MaxNumber(TreeManager.maxSaplingPlane) private int size = 1; } \ No newline at end of file diff --git a/src/main/java/com/volmit/iris/engine/object/IrisTreeType.java b/src/main/java/com/volmit/iris/engine/object/IrisTreeType.java index 031336c4c..0d25f0e9d 100644 --- a/src/main/java/com/volmit/iris/engine/object/IrisTreeType.java +++ b/src/main/java/com/volmit/iris/engine/object/IrisTreeType.java @@ -1,56 +1,49 @@ package com.volmit.iris.engine.object; +import com.volmit.iris.engine.object.annotations.Desc; +import lombok.NoArgsConstructor; +import lombok.experimental.Accessors; import org.bukkit.TreeType; +@Accessors(chain = true) +@NoArgsConstructor +@Desc("Tree Types") public enum IrisTreeType { - /** - * Oak tree (BIG_TREE, TREE) - */ + @Desc("Oak tree (BIG_TREE, TREE)") OAK, - /** - * Spruce tree (MEGA_REDWOOD, REDWOOD, SWAMP, TALL_REDWOOD) - */ + + @Desc("Spruce tree (MEGA_REDWOOD, REDWOOD, SWAMP, TALL_REDWOOD)") SPRUCE, - /** - * Birch tree (BIRCH, TALL_BIRCH) - */ + + @Desc("Birch tree (BIRCH, TALL_BIRCH)") BIRCH, - /** - * Jungle tree (JUNGLE, SMALL_JUNGLE) - */ + + @Desc("Jungle tree (JUNGLE, SMALL_JUNGLE)") JUNGLE, - /** - * Big red mushroom; short and fat - */ + + @Desc("Big red mushroom; short and fat") RED_MUSHROOM, - /** - * Big brown mushroom; tall and umbrella-like - */ + + @Desc("Big brown mushroom; tall and umbrella-like") BROWN_MUSHROOM, - /** - * Acacia tree - */ + + @Desc("Acacia tree") ACACIA, - /** - * Dark Oak tree - */ + + @Desc("Dark Oak tree") DARK_OAK, - /** - * Large crimson fungus native to the nether - */ + + @Desc("Large crimson fungus native to the nether") CRIMSON_FUNGUS, - /** - * Large warped fungus native to the nether - */ + + @Desc("Large warped fungus native to the nether") WARPED_FUNGUS, - /** - * Tree with large roots which grows above lush caves - */ + + @Desc("Tree with large roots which grows above lush caves") AZALEA, - /** - * The fallback type for all other non-supported growth events - */ + + @Desc("The fallback type for all other non-supported growth events") NONE; public static IrisTreeType fromTreeType(TreeType type){ From d40e9e3d738580985b0e33eb27cabec340a681dd Mon Sep 17 00:00:00 2001 From: CocoTheOwner Date: Mon, 19 Jul 2021 01:31:09 +0200 Subject: [PATCH 12/41] Add todo cards --- .../com/volmit/iris/core/TreeManager.java | 48 +++++++++++++++++-- 1 file changed, 44 insertions(+), 4 deletions(-) diff --git a/src/main/java/com/volmit/iris/core/TreeManager.java b/src/main/java/com/volmit/iris/core/TreeManager.java index 31ef4f3b8..5ca639bdd 100644 --- a/src/main/java/com/volmit/iris/core/TreeManager.java +++ b/src/main/java/com/volmit/iris/core/TreeManager.java @@ -9,17 +9,18 @@ import com.volmit.iris.util.math.RNG; import org.bukkit.Location; import org.bukkit.Material; import org.bukkit.TreeType; -import org.bukkit.block.data.type.Sapling; import org.bukkit.event.EventHandler; import org.bukkit.event.Listener; import org.bukkit.event.world.StructureGrowEvent; +import org.bukkit.util.Vector; import org.jetbrains.annotations.NotNull; +import java.util.Arrays; import java.util.Objects; public class TreeManager implements Listener { - private static final boolean debugMe = true; + private static final boolean debugMe = false; public static final int maxSaplingPlane = 5; @@ -106,8 +107,11 @@ public class TreeManager implements Listener { // Delete the saplings (some objects may not have blocks where the sapling is) deleteSaplings(saplingLocations); - // Rotate and place the object + // Rotate the object randomly pickedObject.rotate(new IrisObjectRotation(), 0, 90 * RNG.r.i(0, 3), 0); + + // TODO: Consider adding a translation to object placement. + // Place the object pickedObject.place(event.getLocation()); } @@ -172,6 +176,42 @@ public class TreeManager implements Listener { * @return A list of saplings in a square */ private KList getSaplingPlane(Location location){ - return new KList<>(); + KList locations = new KList<>(); + + // TODO: Debug getBlockMap + boolean[][] map = getBlockMap(location); + + for (boolean[] row : map) + Iris.info(Arrays.toString(row)); + + // TODO: Write logic here that checks for the largest possible square with the Location included + // TODO: The boolean[][] map has true's where there's another sapling of the same type, and false if not. + // TODO: Fill the locations array with the found sapling locations and return the array. The rest is hopefully done. + // Note: I tested the system. Placing objects works. Removing saplings may not work perfectly. + + return locations; + } + + /** + * Get a boolean map which indicates if at positions in all directions the same block can be found + * @param location the center location around which we search + * @return A boolean 2d map of trues and false's + */ + private boolean[][] getBlockMap(Location location) { + Material blockMaterial = location.getBlock().getType(); + int size = maxSaplingPlane * 2 - 1; + boolean[][] map = new boolean[size][size]; + + for (int i = 0; i < size; i++){ + boolean[] row = new boolean[size]; + for (int j = 0; j < size; j++){ + Vector zdir = new Vector(0, 0, 1).multiply(i - maxSaplingPlane + 1); + Vector xdir = new Vector(1, 0, 0).multiply(j - maxSaplingPlane + 1); + Material foundBlock = location.add(xdir).add(zdir).getBlock().getType(); + row[j] = blockMaterial.name().equals(foundBlock.name()); + } + map[i] = row; + } + return map; } } From 5b662df7cd15b1188e8677f3f08913656335a5da Mon Sep 17 00:00:00 2001 From: CocoTheOwner Date: Mon, 19 Jul 2021 02:09:52 +0200 Subject: [PATCH 13/41] ifs --- .../com/volmit/iris/core/TreeManager.java | 43 ++++++++++--------- 1 file changed, 23 insertions(+), 20 deletions(-) diff --git a/src/main/java/com/volmit/iris/core/TreeManager.java b/src/main/java/com/volmit/iris/core/TreeManager.java index 5ca639bdd..7e56c2147 100644 --- a/src/main/java/com/volmit/iris/core/TreeManager.java +++ b/src/main/java/com/volmit/iris/core/TreeManager.java @@ -20,8 +20,6 @@ import java.util.Objects; public class TreeManager implements Listener { - private static final boolean debugMe = false; - public static final int maxSaplingPlane = 5; public TreeManager() { @@ -41,11 +39,12 @@ public class TreeManager implements Listener { @EventHandler public void onStructureGrowEvent(StructureGrowEvent event) { - if (debugMe) - Iris.info("Sapling grew @ " + event.getLocation() + " for " + event.getSpecies().name() + " usedBoneMeal is " + event.isFromBonemeal()); + Iris.debug("Sapling grew @ " + event.getLocation() + " for " + event.getSpecies().name() + " usedBoneMeal is " + event.isFromBonemeal()); // Must be iris world - if (!IrisWorlds.isIrisWorld(event.getWorld())) return; + if (!IrisWorlds.isIrisWorld(event.getWorld())) { + return; + } IrisAccess worldAccess; try { @@ -56,10 +55,12 @@ public class TreeManager implements Listener { } IrisTreeSettings settings = worldAccess.getCompound().getRootDimension().getSaplingSettings(); - if (debugMe) Iris.info("Custom saplings are enabled: " + (settings.isEnabled() ? "Yes" : "No")); + Iris.debug("Custom saplings are enabled: " + (settings.isEnabled() ? "Yes" : "No")); // Must have override enabled - if (!settings.isEnabled()) return; + if (!settings.isEnabled()) { + return; + } KList treeObjects = new KList<>(); @@ -67,12 +68,9 @@ public class TreeManager implements Listener { IrisBiome biome = worldAccess.getBiome(event.getLocation().getBlockX(), event.getLocation().getBlockY(), event.getLocation().getBlockZ()); IrisRegion region = worldAccess.getCompound().getDefaultEngine().getRegion(event.getLocation().getBlockX(), event.getLocation().getBlockZ()); - if (debugMe) - Iris.info("Biome name: " + biome.getName() + " | List of saplings: " + biome.getSaplings().toString()); - if (debugMe) - Iris.info("Region name: " + region.getName() + " | List of saplings: " + region.getSaplings().toString()); - if (debugMe) - Iris.info("Dimension saplings: " + settings.getSaplings().toString()); + Iris.debug("Biome name: " + biome.getName() + " | List of saplings: " + biome.getSaplings().toString()); + Iris.debug("Region name: " + region.getName() + " | List of saplings: " + region.getSaplings().toString()); + Iris.debug("Dimension saplings: " + settings.getSaplings().toString()); // Get sapling location KList saplingLocations = getSaplingPlane(event.getLocation()); @@ -82,17 +80,21 @@ public class TreeManager implements Listener { treeObjects.addAll(getSaplingsFrom(biome.getSaplings(), event.getSpecies(), saplingSize)); // Check region - if (settings.getMode() == IrisTreeModes.ALL || treeObjects.size() == 0) + if (settings.getMode() == IrisTreeModes.ALL || treeObjects.size() == 0) { treeObjects.addAll(getSaplingsFrom(region.getSaplings(), event.getSpecies(), saplingSize)); + } // Check dimension - if (settings.getMode() == IrisTreeModes.ALL || treeObjects.size() == 0) + if (settings.getMode() == IrisTreeModes.ALL || treeObjects.size() == 0) { treeObjects.addAll(getSaplingsFrom(settings.getSaplings(), event.getSpecies(), saplingSize)); + } - if (debugMe) Iris.info("List of saplings (together): " + treeObjects); + Iris.debug("List of saplings (together): " + treeObjects); // Check to make sure something was found - if (treeObjects.size() == 0) return; + if (treeObjects.size() == 0) { + return; + } // Pick a random object from the list of objects found String pickedObjectString = treeObjects.get(RNG.r.i(0, treeObjects.size() - 1)); @@ -101,7 +103,7 @@ public class TreeManager implements Listener { event.setCancelled(true); // Retrieve & place the object - if (debugMe) Iris.info("Placing tree object instead of vanilla tree: " + pickedObjectString); + Iris.debug("Placing tree object instead of vanilla tree: " + pickedObjectString); IrisObject pickedObject = IrisDataManager.loadAnyObject(pickedObjectString); // Delete the saplings (some objects may not have blocks where the sapling is) @@ -121,7 +123,7 @@ public class TreeManager implements Listener { */ private void deleteSaplings(KList locations) { locations.forEach(l -> { - if (debugMe) Iris.info("Deleting block of type: " + l.getBlock().getType()); + Iris.debug("Deleting block of type: " + l.getBlock().getType()); l.getBlock().setType(Material.AIR); }); } @@ -181,8 +183,9 @@ public class TreeManager implements Listener { // TODO: Debug getBlockMap boolean[][] map = getBlockMap(location); - for (boolean[] row : map) + for (boolean[] row : map) { Iris.info(Arrays.toString(row)); + } // TODO: Write logic here that checks for the largest possible square with the Location included // TODO: The boolean[][] map has true's where there's another sapling of the same type, and false if not. From 1534dcc9320825e785b48ed59e76b1edd88d3f5d Mon Sep 17 00:00:00 2001 From: CocoTheOwner Date: Mon, 19 Jul 2021 12:07:29 +0200 Subject: [PATCH 14/41] Rework according to discussed changes --- .../com/volmit/iris/core/TreeManager.java | 148 ------------------ .../volmit/iris/engine/object/IrisBiome.java | 6 +- .../engine/object/IrisObjectPlacement.java | 3 + .../volmit/iris/engine/object/IrisRegion.java | 4 - .../volmit/iris/engine/object/IrisTree.java | 14 +- .../iris/engine/object/IrisTreeOptions.java | 22 +++ .../iris/engine/object/IrisTreeSettings.java | 6 - .../iris/engine/object/IrisTreeSize.java | 35 +++++ .../iris/engine/object/IrisTreeType.java | 32 ++-- 9 files changed, 80 insertions(+), 190 deletions(-) create mode 100644 src/main/java/com/volmit/iris/engine/object/IrisTreeOptions.java create mode 100644 src/main/java/com/volmit/iris/engine/object/IrisTreeSize.java diff --git a/src/main/java/com/volmit/iris/core/TreeManager.java b/src/main/java/com/volmit/iris/core/TreeManager.java index 7e56c2147..5cdf80bd2 100644 --- a/src/main/java/com/volmit/iris/core/TreeManager.java +++ b/src/main/java/com/volmit/iris/core/TreeManager.java @@ -68,153 +68,5 @@ public class TreeManager implements Listener { IrisBiome biome = worldAccess.getBiome(event.getLocation().getBlockX(), event.getLocation().getBlockY(), event.getLocation().getBlockZ()); IrisRegion region = worldAccess.getCompound().getDefaultEngine().getRegion(event.getLocation().getBlockX(), event.getLocation().getBlockZ()); - Iris.debug("Biome name: " + biome.getName() + " | List of saplings: " + biome.getSaplings().toString()); - Iris.debug("Region name: " + region.getName() + " | List of saplings: " + region.getSaplings().toString()); - Iris.debug("Dimension saplings: " + settings.getSaplings().toString()); - - // Get sapling location - KList saplingLocations = getSaplingPlane(event.getLocation()); - int saplingSize = getSaplingSize(saplingLocations); - - // Check biome, region and dimension - treeObjects.addAll(getSaplingsFrom(biome.getSaplings(), event.getSpecies(), saplingSize)); - - // Check region - if (settings.getMode() == IrisTreeModes.ALL || treeObjects.size() == 0) { - treeObjects.addAll(getSaplingsFrom(region.getSaplings(), event.getSpecies(), saplingSize)); - } - - // Check dimension - if (settings.getMode() == IrisTreeModes.ALL || treeObjects.size() == 0) { - treeObjects.addAll(getSaplingsFrom(settings.getSaplings(), event.getSpecies(), saplingSize)); - } - - Iris.debug("List of saplings (together): " + treeObjects); - - // Check to make sure something was found - if (treeObjects.size() == 0) { - return; - } - - // Pick a random object from the list of objects found - String pickedObjectString = treeObjects.get(RNG.r.i(0, treeObjects.size() - 1)); - - // Cancel vanilla event - event.setCancelled(true); - - // Retrieve & place the object - Iris.debug("Placing tree object instead of vanilla tree: " + pickedObjectString); - IrisObject pickedObject = IrisDataManager.loadAnyObject(pickedObjectString); - - // Delete the saplings (some objects may not have blocks where the sapling is) - deleteSaplings(saplingLocations); - - // Rotate the object randomly - pickedObject.rotate(new IrisObjectRotation(), 0, 90 * RNG.r.i(0, 3), 0); - - // TODO: Consider adding a translation to object placement. - // Place the object - pickedObject.place(event.getLocation()); - } - - /** - * Deletes all saplings at the - * @param locations sapling locations - */ - private void deleteSaplings(KList locations) { - locations.forEach(l -> { - Iris.debug("Deleting block of type: " + l.getBlock().getType()); - l.getBlock().setType(Material.AIR); - }); - } - - /** - * Find all sapling types of the given TreeType in the container - * @param container Iris sapling config - * @param tree The tree type to find - * @param size The `size * size` area of the saplings - * @return A list of found object name strings - */ - @NotNull - private KList getSaplingsFrom(KList container, TreeType tree, int size) { - - // Translate TreeType to Iris TreeType - IrisTreeType eventTreeType = IrisTreeType.fromTreeType(tree); - - KList objects = new KList<>(); - - // Loop over all saplings in the container - // and their entered sapling types - // and copy the trees in the list if matching. - for (IrisTree sapling : container) { - for (IrisTreeType configTreeType : sapling.getTreeTypes()) { - if (configTreeType == eventTreeType && size == sapling.getSize()) { - objects.addAll(sapling.getObjects()); - } - } - } - return objects; - } - - /** - * Retrieve the `size * size` area of a sapling (any sapling in the area) - * @param saplings The locations of the saplings in the plane - * @return The `x * x` area of saplings - */ - private int getSaplingSize(KList saplings){ - double size = Math.sqrt(saplings.size()); - if (size % 1 != 0) { - Iris.error("Size of sapling square array is not a power of an integer (not a square)"); - return -1; - } - return (int) size; - } - - /** - * Retrieve all saplings in a square area around the current sapling. - * This searches around the current sapling, and the next, etc, iteratively - * Note: This is limited by maxSaplingPlane - * @param location The location to search from (the originating sapling) - * @return A list of saplings in a square - */ - private KList getSaplingPlane(Location location){ - KList locations = new KList<>(); - - // TODO: Debug getBlockMap - boolean[][] map = getBlockMap(location); - - for (boolean[] row : map) { - Iris.info(Arrays.toString(row)); - } - - // TODO: Write logic here that checks for the largest possible square with the Location included - // TODO: The boolean[][] map has true's where there's another sapling of the same type, and false if not. - // TODO: Fill the locations array with the found sapling locations and return the array. The rest is hopefully done. - // Note: I tested the system. Placing objects works. Removing saplings may not work perfectly. - - return locations; - } - - /** - * Get a boolean map which indicates if at positions in all directions the same block can be found - * @param location the center location around which we search - * @return A boolean 2d map of trues and false's - */ - private boolean[][] getBlockMap(Location location) { - Material blockMaterial = location.getBlock().getType(); - int size = maxSaplingPlane * 2 - 1; - boolean[][] map = new boolean[size][size]; - - for (int i = 0; i < size; i++){ - boolean[] row = new boolean[size]; - for (int j = 0; j < size; j++){ - Vector zdir = new Vector(0, 0, 1).multiply(i - maxSaplingPlane + 1); - Vector xdir = new Vector(1, 0, 0).multiply(j - maxSaplingPlane + 1); - Material foundBlock = location.add(xdir).add(zdir).getBlock().getType(); - row[j] = blockMaterial.name().equals(foundBlock.name()); - } - map[i] = row; - } - return map; } } diff --git a/src/main/java/com/volmit/iris/engine/object/IrisBiome.java b/src/main/java/com/volmit/iris/engine/object/IrisBiome.java index 34353d1f7..cb268b35e 100644 --- a/src/main/java/com/volmit/iris/engine/object/IrisBiome.java +++ b/src/main/java/com/volmit/iris/engine/object/IrisBiome.java @@ -81,12 +81,8 @@ public class IrisBiome extends IrisRegistrant implements IRare { @ArrayType(min = 1, type = IrisEntityInitialSpawn.class) private KList entityInitialSpawns = new KList<>(); - @Desc("Sapling override settings") - @ArrayType(min = 1, type = IrisTree.class) - private KList saplings = new KList<>(); - @ArrayType(min = 1, type = IrisEffect.class) - @Desc("Effects are ambient effects such as potion effects, random sounds, or even particles around each player. All of these effects are played via packets so two players won't see/hear each others effects.\nDue to performance reasons, effects will play arround the player even if where the effect was played is no longer in the biome the player is in.") + @Desc("Effects are ambient effects such as potion effects, random sounds, or even particles around each player. All of these effects are played via packets so two players won't see/hear each others effects.\nDue to performance reasons, effects will play around the player even if where the effect was played is no longer in the biome the player is in.") private KList effects = new KList<>(); diff --git a/src/main/java/com/volmit/iris/engine/object/IrisObjectPlacement.java b/src/main/java/com/volmit/iris/engine/object/IrisObjectPlacement.java index 67284be4e..ed716a78e 100644 --- a/src/main/java/com/volmit/iris/engine/object/IrisObjectPlacement.java +++ b/src/main/java/com/volmit/iris/engine/object/IrisObjectPlacement.java @@ -151,6 +151,9 @@ public class IrisObjectPlacement { @Desc("The loot tables to apply to these objects") private KList loot = new KList<>(); + @Desc("Tree growth overrides for these object placements") + private IrisTreeOptions treeOptions = new IrisTreeOptions(); + public IrisObjectPlacement toPlacement(String... place) { IrisObjectPlacement p = new IrisObjectPlacement(); p.setPlace(new KList<>(place)); diff --git a/src/main/java/com/volmit/iris/engine/object/IrisRegion.java b/src/main/java/com/volmit/iris/engine/object/IrisRegion.java index 8f555ce08..47a587219 100644 --- a/src/main/java/com/volmit/iris/engine/object/IrisRegion.java +++ b/src/main/java/com/volmit/iris/engine/object/IrisRegion.java @@ -79,10 +79,6 @@ public class IrisRegion extends IrisRegistrant implements IRare { @ArrayType(min = 1, type = IrisEntityInitialSpawn.class) private KList entityInitialSpawns = new KList<>(); - @Desc("Sapling override settings") - @ArrayType(min = 1, type = IrisTree.class) - private KList saplings = new KList<>(); - @MinNumber(1) @MaxNumber(128) @Desc("The rarity of the region") diff --git a/src/main/java/com/volmit/iris/engine/object/IrisTree.java b/src/main/java/com/volmit/iris/engine/object/IrisTree.java index 130a14a46..54154f769 100644 --- a/src/main/java/com/volmit/iris/engine/object/IrisTree.java +++ b/src/main/java/com/volmit/iris/engine/object/IrisTree.java @@ -12,23 +12,17 @@ import org.bukkit.TreeType; @Accessors(chain = true) @AllArgsConstructor @NoArgsConstructor -@Desc("Tree replace options") +@Desc("Tree replace options for this object placer") @Data public class IrisTree { @Required - @Desc("The types of trees overwritten") + @Desc("The types of trees overwritten by this object") @ArrayType(min = 1, type = IrisTreeType.class) private KList treeTypes; - @RegistryListObject @Required - @ArrayType(min = 1, type = String.class) - @Desc("List of objects to replace trees with") - private KList objects = new KList<>(); - @Desc("The size of the square of saplings this applies to (2 means a 2 * 2 sapling area)") - @MinNumber(1) - @MaxNumber(TreeManager.maxSaplingPlane) - private int size = 1; + @ArrayType(min = 1, type = IrisTreeSize.class) + private KList sizes = new KList<>(); } \ No newline at end of file diff --git a/src/main/java/com/volmit/iris/engine/object/IrisTreeOptions.java b/src/main/java/com/volmit/iris/engine/object/IrisTreeOptions.java new file mode 100644 index 000000000..2aea54e6e --- /dev/null +++ b/src/main/java/com/volmit/iris/engine/object/IrisTreeOptions.java @@ -0,0 +1,22 @@ +package com.volmit.iris.engine.object; + +import com.volmit.iris.engine.object.annotations.Desc; +import com.volmit.iris.util.collection.KList; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; +import lombok.experimental.Accessors; + +@Accessors(chain = true) +@AllArgsConstructor +@NoArgsConstructor +@Desc("Tree replace options for this object placer") +@Data +public class IrisTreeOptions { + + @Desc("Toggles this object placer's tree overrides") + private boolean enabled = false; + + @Desc("Tree overrides affected by these object placements") + private KList trees = new KList<>(); +} diff --git a/src/main/java/com/volmit/iris/engine/object/IrisTreeSettings.java b/src/main/java/com/volmit/iris/engine/object/IrisTreeSettings.java index 584fc9a64..9924b1ecd 100644 --- a/src/main/java/com/volmit/iris/engine/object/IrisTreeSettings.java +++ b/src/main/java/com/volmit/iris/engine/object/IrisTreeSettings.java @@ -1,8 +1,6 @@ package com.volmit.iris.engine.object; -import com.volmit.iris.engine.object.annotations.ArrayType; import com.volmit.iris.engine.object.annotations.Desc; -import com.volmit.iris.util.collection.KList; import lombok.AllArgsConstructor; import lombok.Data; import lombok.EqualsAndHashCode; @@ -22,8 +20,4 @@ public class IrisTreeSettings { @Desc("Object picking modes") IrisTreeModes mode = IrisTreeModes.FIRST; - - @Desc("Tree override list") - @ArrayType(min = 1, type = IrisTree.class) - private KList saplings = new KList<>(); } diff --git a/src/main/java/com/volmit/iris/engine/object/IrisTreeSize.java b/src/main/java/com/volmit/iris/engine/object/IrisTreeSize.java new file mode 100644 index 000000000..1f89ec267 --- /dev/null +++ b/src/main/java/com/volmit/iris/engine/object/IrisTreeSize.java @@ -0,0 +1,35 @@ +package com.volmit.iris.engine.object; + +import com.volmit.iris.engine.object.annotations.Desc; + +@Desc("Sapling override object picking options") +public enum IrisTreeSize { + + @Desc("Only one sapling") + ONE, + + @Desc("Two by two area") + TWO, + + @Desc("Three by three area with center") + THREE_CENTER, + + @Desc("Three by three any location") + THREE_ANY, + + @Desc("Four by four") + FOUR, + + @Desc("Five by five center") + FIVE_CENTER, + + @Desc("Five by five") + FIVE_ANY; + + public static boolean isAnySize(IrisTreeSize treeSize){ + return switch (treeSize) { + case THREE_CENTER, FIVE_CENTER -> false; + default -> true; + }; + } +} diff --git a/src/main/java/com/volmit/iris/engine/object/IrisTreeType.java b/src/main/java/com/volmit/iris/engine/object/IrisTreeType.java index 0d25f0e9d..df8728281 100644 --- a/src/main/java/com/volmit/iris/engine/object/IrisTreeType.java +++ b/src/main/java/com/volmit/iris/engine/object/IrisTreeType.java @@ -47,22 +47,20 @@ public enum IrisTreeType { NONE; public static IrisTreeType fromTreeType(TreeType type){ - IrisTreeType irisType; - switch(type){ - case BIG_TREE, TREE -> irisType = IrisTreeType.OAK; - case MEGA_REDWOOD, REDWOOD, SWAMP, TALL_REDWOOD -> irisType = IrisTreeType.SPRUCE; - case BIRCH, TALL_BIRCH -> irisType = IrisTreeType.BIRCH; - case JUNGLE, SMALL_JUNGLE -> irisType = IrisTreeType.JUNGLE; - case RED_MUSHROOM -> irisType = IrisTreeType.RED_MUSHROOM; - case BROWN_MUSHROOM -> irisType = IrisTreeType.BROWN_MUSHROOM; - case ACACIA -> irisType = IrisTreeType.ACACIA; - case DARK_OAK -> irisType = IrisTreeType.DARK_OAK; - case CRIMSON_FUNGUS -> irisType = IrisTreeType.CRIMSON_FUNGUS; - case WARPED_FUNGUS -> irisType = IrisTreeType.WARPED_FUNGUS; - case AZALEA -> irisType = IrisTreeType.AZALEA; - //case COCOA_TREE, CHORUS_PLANT, JUNGLE_BUSH -> irisType = IrisSaplingType.NONE; - default -> irisType = IrisTreeType.NONE; - } - return irisType; + return switch(type){ + case BIG_TREE, TREE -> IrisTreeType.OAK; + case MEGA_REDWOOD, REDWOOD, SWAMP, TALL_REDWOOD -> IrisTreeType.SPRUCE; + case BIRCH, TALL_BIRCH -> IrisTreeType.BIRCH; + case JUNGLE, SMALL_JUNGLE -> IrisTreeType.JUNGLE; + case RED_MUSHROOM -> IrisTreeType.RED_MUSHROOM; + case BROWN_MUSHROOM -> IrisTreeType.BROWN_MUSHROOM; + case ACACIA -> IrisTreeType.ACACIA; + case DARK_OAK -> IrisTreeType.DARK_OAK; + case CRIMSON_FUNGUS -> IrisTreeType.CRIMSON_FUNGUS; + case WARPED_FUNGUS -> IrisTreeType.WARPED_FUNGUS; + case AZALEA -> IrisTreeType.AZALEA; + //case COCOA_TREE, CHORUS_PLANT, JUNGLE_BUSH -> IrisSaplingType.NONE; + default -> IrisTreeType.NONE; + }; } } From c342c5c4f6b9199a7a1bfa4a8fc3a17e4af52745 Mon Sep 17 00:00:00 2001 From: CocoTheOwner Date: Mon, 19 Jul 2021 19:03:25 +0200 Subject: [PATCH 15/41] fixes and the majority of treesize retrieval --- .../com/volmit/iris/core/TreeManager.java | 163 ++++++++++++++-- .../iris/engine/object/IrisTreeOptions.java | 2 + .../iris/engine/object/IrisTreeSize.java | 182 +++++++++++++++++- 3 files changed, 325 insertions(+), 22 deletions(-) diff --git a/src/main/java/com/volmit/iris/core/TreeManager.java b/src/main/java/com/volmit/iris/core/TreeManager.java index 5cdf80bd2..fa64de21f 100644 --- a/src/main/java/com/volmit/iris/core/TreeManager.java +++ b/src/main/java/com/volmit/iris/core/TreeManager.java @@ -4,18 +4,17 @@ import com.volmit.iris.Iris; import com.volmit.iris.engine.IrisWorlds; import com.volmit.iris.engine.framework.IrisAccess; import com.volmit.iris.engine.object.*; +import com.volmit.iris.engine.object.common.IObjectPlacer; +import com.volmit.iris.engine.object.tile.TileData; import com.volmit.iris.util.collection.KList; import com.volmit.iris.util.math.RNG; import org.bukkit.Location; -import org.bukkit.Material; -import org.bukkit.TreeType; +import org.bukkit.block.TileState; +import org.bukkit.block.data.BlockData; import org.bukkit.event.EventHandler; import org.bukkit.event.Listener; import org.bukkit.event.world.StructureGrowEvent; -import org.bukkit.util.Vector; -import org.jetbrains.annotations.NotNull; -import java.util.Arrays; import java.util.Objects; public class TreeManager implements Listener { @@ -46,6 +45,7 @@ public class TreeManager implements Listener { return; } + // Get world access IrisAccess worldAccess; try { worldAccess = Objects.requireNonNull(IrisWorlds.access(event.getWorld())); @@ -53,20 +53,157 @@ public class TreeManager implements Listener { Iris.reportError(e); return; } - IrisTreeSettings settings = worldAccess.getCompound().getRootDimension().getSaplingSettings(); - Iris.debug("Custom saplings are enabled: " + (settings.isEnabled() ? "Yes" : "No")); + Iris.debug("Custom saplings are " + (worldAccess.getCompound().getRootDimension().getSaplingSettings().isEnabled() ? "" : "NOT") + " enabled."); - // Must have override enabled - if (!settings.isEnabled()) { + // Calculate size, type & placement + IrisTreeType type = IrisTreeType.fromTreeType(event.getSpecies()); + IrisTreeSize size = getTreeSize(event.getLocation(), type); + IrisObjectPlacement placement = getObjectPlacement(worldAccess, type, event.getLocation(), size); + + // Make sure placement was found + if (placement == null){ return; } - KList treeObjects = new KList<>(); + // Get object from placer + IrisObject f = worldAccess.getData().getObjectLoader().load(placement.getPlace().getRandom(RNG.r)); - // Get biome and region - IrisBiome biome = worldAccess.getBiome(event.getLocation().getBlockX(), event.getLocation().getBlockY(), event.getLocation().getBlockZ()); - IrisRegion region = worldAccess.getCompound().getDefaultEngine().getRegion(event.getLocation().getBlockX(), event.getLocation().getBlockZ()); + // TODO: Implement placer + IObjectPlacer placer = new IObjectPlacer(){ + @Override + public int getHighest(int x, int z) { + return 0; + } + + @Override + public int getHighest(int x, int z, boolean ignoreFluid) { + return 0; + } + + @Override + public void set(int x, int y, int z, BlockData d) { + + } + + @Override + public BlockData get(int x, int y, int z) { + return null; + } + + @Override + public boolean isPreventingDecay() { + return false; + } + + @Override + public boolean isSolid(int x, int y, int z) { + return false; + } + + @Override + public boolean isUnderwater(int x, int z) { + return false; + } + + @Override + public int getFluidHeight() { + return 0; + } + + @Override + public boolean isDebugSmartBore() { + return false; + } + + @Override + public void setTile(int xx, int yy, int zz, TileData tile) { + + } + }; + + // TODO: Figure out how to place without wrecking claims, other builds, etc. + // Especially with large object + + // Place the object with the placer + f.place( + event.getLocation().getBlockX(), + event.getLocation().getBlockY(), + event.getLocation().getBlockZ(), + placer, + placement, + RNG.r, + Objects.requireNonNull(IrisWorlds.access(event.getWorld())).getData() + ); + } + + /** + * Finds the tree size + * @param location The location the event triggers from. This sapling's Material type is used to check other locations + * @return The size of the tree + */ + private IrisTreeSize getTreeSize(Location location, IrisTreeType type) { + KList validSizes = new KList<>(); + + IrisTreeSize.isSizeValid(); + + return IrisTreeSize.bestSize(validSizes); + } + + /** + * Finds a single object placement (which may contain more than one object) for the requirements species, location & size + * @param worldAccess The world to access (check for biome, region, dimension, etc) + * @param type The bukkit TreeType to match + * @param location The location of the growth event (For biome/region finding) + * @param size The size of the sapling area + * @return An object placement which contains the matched tree, or null if none were found / it's disabled. + */ + private IrisObjectPlacement getObjectPlacement(IrisAccess worldAccess, IrisTreeType type, Location location, IrisTreeSize size) { + IrisDimension dimension = worldAccess.getCompound().getRootDimension(); + + // Return null if not enabled + if (!dimension.getSaplingSettings().isEnabled()) { + return null; + } + + KList placements = new KList<>(); + + // Retrieve objectPlacements of type `species` from biome + IrisBiome biome = worldAccess.getBiome(location.getBlockX(), location.getBlockY(), location.getBlockZ()); + placements.addAll(matchObjectPlacements(biome.getObjects(), size, type)); + + // Add more or find any in the region + if (dimension.getSaplingSettings().getMode().equals(IrisTreeModes.ALL) || placements.isEmpty()){ + IrisRegion region = worldAccess.getCompound().getDefaultEngine().getRegion(location.getBlockX(), location.getBlockZ()); + placements.addAll(matchObjectPlacements(region.getObjects(), size, type)); + } + + // Add more or find any in the dimension + if (dimension.getSaplingSettings().getMode().equals(IrisTreeModes.ALL) || placements.isEmpty()){ + //TODO: Implement object placement in dimension & here + //placements.addAll(matchObjectPlacements(dimension.getObjects(), size, type)); + } + + // Check if no matches were found, return a random one if they are + return placements.isNotEmpty() ? placements.getRandom(RNG.r) : null; + } + + /** + * Filters out mismatches and returns matches + * @param objects The object placements to check + * @param size The size of the sapling area to filter with + * @param type The type of the tree to filter with + * @return A list of objectPlacements that matched. May be empty. + */ + private KList matchObjectPlacements(KList objects, IrisTreeSize size, IrisTreeType type) { + KList objectPlacements = new KList<>(); + objects.stream() + .filter(objectPlacement -> objectPlacement.getTreeOptions().isEnabled()) + .filter(objectPlacement -> objectPlacement.getTreeOptions().getTrees().stream().anyMatch(irisTree -> + irisTree.getSizes().stream().anyMatch(treeSize -> treeSize == size) && + irisTree.getTreeTypes().stream().anyMatch(treeType -> treeType == type))) + .forEach(objectPlacements::add); + return objectPlacements; } } diff --git a/src/main/java/com/volmit/iris/engine/object/IrisTreeOptions.java b/src/main/java/com/volmit/iris/engine/object/IrisTreeOptions.java index 2aea54e6e..20cbd5881 100644 --- a/src/main/java/com/volmit/iris/engine/object/IrisTreeOptions.java +++ b/src/main/java/com/volmit/iris/engine/object/IrisTreeOptions.java @@ -1,5 +1,6 @@ package com.volmit.iris.engine.object; +import com.volmit.iris.engine.object.annotations.ArrayType; import com.volmit.iris.engine.object.annotations.Desc; import com.volmit.iris.util.collection.KList; import lombok.AllArgsConstructor; @@ -18,5 +19,6 @@ public class IrisTreeOptions { private boolean enabled = false; @Desc("Tree overrides affected by these object placements") + @ArrayType(min = 1, type = IrisTree.class) private KList trees = new KList<>(); } diff --git a/src/main/java/com/volmit/iris/engine/object/IrisTreeSize.java b/src/main/java/com/volmit/iris/engine/object/IrisTreeSize.java index 1f89ec267..71dcfe509 100644 --- a/src/main/java/com/volmit/iris/engine/object/IrisTreeSize.java +++ b/src/main/java/com/volmit/iris/engine/object/IrisTreeSize.java @@ -1,6 +1,11 @@ package com.volmit.iris.engine.object; import com.volmit.iris.engine.object.annotations.Desc; +import com.volmit.iris.util.collection.KList; +import org.bukkit.Location; +import org.bukkit.Material; + +import java.util.Objects; @Desc("Sapling override object picking options") public enum IrisTreeSize { @@ -11,25 +16,184 @@ public enum IrisTreeSize { @Desc("Two by two area") TWO, - @Desc("Three by three area with center") - THREE_CENTER, - @Desc("Three by three any location") THREE_ANY, + @Desc("Three by three area with center") + THREE_CENTER, + @Desc("Four by four") FOUR, - @Desc("Five by five center") - FIVE_CENTER, - @Desc("Five by five") - FIVE_ANY; + FIVE_ANY, - public static boolean isAnySize(IrisTreeSize treeSize){ + @Desc("Five by five center") + FIVE_CENTER; + + /** + * Whether the position of the any type (not fixed at a center) + * @param treeSize The treesize to check + */ + public static boolean isAnyPosition(IrisTreeSize treeSize){ return switch (treeSize) { - case THREE_CENTER, FIVE_CENTER -> false; + case ONE, THREE_CENTER, FIVE_CENTER -> false; default -> true; }; } + + /** + * Get the best size to match against from a list of sizes + * @param sizes The list of sizes + * @return The best size (highest & center > any) + */ + public static IrisTreeSize bestSize(KList sizes){ + if (sizes.contains(FIVE_CENTER)){ + return FIVE_CENTER; + } + else if (sizes.contains(FIVE_ANY)){ + return FIVE_ANY; + } + else if (sizes.contains(FOUR)){ + return FOUR; + } + else if (sizes.contains(THREE_CENTER)){ + return THREE_CENTER; + } + else if (sizes.contains(THREE_ANY)){ + return THREE_ANY; + } + else if (sizes.contains(TWO)){ + return TWO; + } + else if (sizes.contains(ONE)){ + return ONE; + } else { + return null; + } + } + + public static IrisTreeSize getBestSize(Location location){ + KList sizes = new KList<>(ONE, TWO, THREE_ANY, THREE_CENTER, FOUR, FIVE_ANY, FIVE_CENTER); + while (sizes.isNotEmpty()){ + + // Find the best size & remove from list + IrisTreeSize bestSize = bestSize(sizes); + assert bestSize != null; + sizes.remove(bestSize); + + // Find the best match + KList> best = isSizeValid(bestSize, location); + if (best != null){ + return bestSize; + } + } + return ONE; + } + + /** + * Check if the size at a specific location is valid + * @param size the IrisTreeSize to check + * @param location at this location + * @return A list of locations if any match, or null if not. + */ + public static KList> isSizeValid(IrisTreeSize size, Location location) { + switch (size){ + case ONE -> { + return new KList>(new KList<>(location)); + } + case TWO -> { + return loopLocation(location, 2, location.getBlock().getType()); + } + case THREE_ANY -> { + return loopLocation(location, 3, location.getBlock().getType()); + } + case THREE_CENTER -> { + KList> locations = getMap(3, location, true); + if (locations == null) { + return null; + } + return isMapValid(locations, location.getBlock().getType()) ? locations : null; + } + case FOUR -> { + return loopLocation(location, 4, location.getBlock().getType()); + } + case FIVE_ANY -> { + return loopLocation(location, 5, location.getBlock().getType()); + } + case FIVE_CENTER -> { + KList> locations = getMap(5, location, true); + if (locations == null) { + return null; + } + return isMapValid(locations, location.getBlock().getType()) ? locations : null; + } + default -> { + return null; + } + } + } + + /** + * Loops over all possible squares based on + * @param location top left position + * @param size a square size + * @param blockType and a type of a block + * @return A list of matching locations, or null. + */ + private static KList> loopLocation(Location location, int size, Material blockType){ + Location leftTop = location.add(-size + 1, 0, -size + 1); + KList> locations; + for (int i = -size + 1; i <= 0; i++){ + for (int j = -size + 1; j <= 0; j++){ + locations = getMap(size, leftTop.add(i, 0, j)); + if (isMapValid(locations, blockType)){ + return locations; + } + } + } + return null; + } + + /** + * Get if the map is valid, compared to a block material + * @param map The map to check inside of + * @param block The block material to check with + * @return True if it's valid + */ + private static boolean isMapValid(KList> map, Material block){ + return map.stream().allMatch(row -> row.stream().allMatch(location -> location.getBlock().getType().equals(block))); + } + + /** + * Get a map with all blocks in a + * @param size `size * size` square area + * @param leftTop starting from the here + * @return A map with all block locations in the area + */ + private static KList> getMap(int size, Location leftTop){ + KList> locations = new KList<>(); + for (int i = 0; i < size; i++){ + KList row = new KList<>(); + for (int j = 0; j < size; j++){ + row.add(leftTop.add(i, 0, j)); + } + locations.add(row); + } + return locations; + } + + /** + * Get a map with all blocks in a + * @param size `size * size` square to check, must be odd (returns null if not) + * @param center from a center + * @param useCenter boolean toggle to call this function over IrisTreeSize#getMap(size, leftTop) + * @return A map with all block locations in the area + */ + private static KList> getMap(int size, Location center, boolean useCenter){ + if (size % 2 != 1){ + return null; + } + return getMap(size, center.add(-(size - 1) / 2d, 0, -(size - 1) / 2d)); + } } From a6ec18690d1ff86f393a6f8df39a2c6d7e7e96f8 Mon Sep 17 00:00:00 2001 From: CocoTheOwner Date: Tue, 20 Jul 2021 14:25:34 +0200 Subject: [PATCH 16/41] Fix tree sapling detection math --- .../iris/engine/object/IrisTreeSize.java | 105 ++++++++++-------- 1 file changed, 60 insertions(+), 45 deletions(-) diff --git a/src/main/java/com/volmit/iris/engine/object/IrisTreeSize.java b/src/main/java/com/volmit/iris/engine/object/IrisTreeSize.java index 71dcfe509..52e2a9959 100644 --- a/src/main/java/com/volmit/iris/engine/object/IrisTreeSize.java +++ b/src/main/java/com/volmit/iris/engine/object/IrisTreeSize.java @@ -1,5 +1,6 @@ package com.volmit.iris.engine.object; +import com.volmit.iris.Iris; import com.volmit.iris.engine.object.annotations.Desc; import com.volmit.iris.util.collection.KList; import org.bukkit.Location; @@ -31,6 +32,16 @@ public enum IrisTreeSize { @Desc("Five by five center") FIVE_CENTER; + /** + * All sizes in this enum + */ + public static final KList sizes = new KList<>(ONE, TWO, THREE_ANY, THREE_CENTER, FOUR, FIVE_ANY, FIVE_CENTER); + + /** + * The best size in this enum + */ + public static final IrisTreeSize bestSize = FIVE_CENTER; + /** * Whether the position of the any type (not fixed at a center) * @param treeSize The treesize to check @@ -73,14 +84,28 @@ public enum IrisTreeSize { } } + /** + * Find the best size based on a location + * @param location The location to look from + * @return The best size + */ public static IrisTreeSize getBestSize(Location location){ - KList sizes = new KList<>(ONE, TWO, THREE_ANY, THREE_CENTER, FOUR, FIVE_ANY, FIVE_CENTER); - while (sizes.isNotEmpty()){ + return getBestSize(location, sizes.copy()); + } + + /** + * Find the best valid size based on a location and a list of sizes + * @param location The location to search from + * @param sizeList The list of sizes to pick from + * @return The best valid size + */ + public static IrisTreeSize getBestSize(Location location, KList sizeList){ + while (sizeList.isNotEmpty()){ // Find the best size & remove from list - IrisTreeSize bestSize = bestSize(sizes); + IrisTreeSize bestSize = bestSize(sizeList); assert bestSize != null; - sizes.remove(bestSize); + sizeList.remove(bestSize); // Find the best match KList> best = isSizeValid(bestSize, location); @@ -89,6 +114,7 @@ public enum IrisTreeSize { } } return ONE; + } /** @@ -98,56 +124,44 @@ public enum IrisTreeSize { * @return A list of locations if any match, or null if not. */ public static KList> isSizeValid(IrisTreeSize size, Location location) { - switch (size){ - case ONE -> { - return new KList>(new KList<>(location)); - } - case TWO -> { - return loopLocation(location, 2, location.getBlock().getType()); - } - case THREE_ANY -> { - return loopLocation(location, 3, location.getBlock().getType()); - } - case THREE_CENTER -> { - KList> locations = getMap(3, location, true); - if (locations == null) { - return null; - } - return isMapValid(locations, location.getBlock().getType()) ? locations : null; - } - case FOUR -> { - return loopLocation(location, 4, location.getBlock().getType()); - } - case FIVE_ANY -> { - return loopLocation(location, 5, location.getBlock().getType()); - } - case FIVE_CENTER -> { - KList> locations = getMap(5, location, true); - if (locations == null) { - return null; - } - return isMapValid(locations, location.getBlock().getType()) ? locations : null; - } - default -> { - return null; - } - } + return switch (size){ + case ONE -> new KList>(new KList<>(location)); + case TWO -> loopLocation(location, 2); + case THREE_ANY -> loopLocation(location, 3); + case FOUR -> loopLocation(location, 4); + case FIVE_ANY -> loopLocation(location, 5); + case THREE_CENTER -> isCenterMapValid(location, 3); + case FIVE_CENTER -> isCenterMapValid(location, 5); + }; } + /** + * Check a map with + * @param center this block location as a center + * @param size with this size map + * @return A 2d KList of locations or null + */ + private static KList> isCenterMapValid(Location center, int size) { + KList> locations = getMap(size, center, true); + return isMapValid(locations, center.getBlock().getType()) ? locations : null; + } + + /** * Loops over all possible squares based on - * @param location top left position + * @param center center position * @param size a square size - * @param blockType and a type of a block * @return A list of matching locations, or null. */ - private static KList> loopLocation(Location location, int size, Material blockType){ - Location leftTop = location.add(-size + 1, 0, -size + 1); + private static KList> loopLocation(Location center, int size){ + Material blockType = center.getBlock().getType(); KList> locations; for (int i = -size + 1; i <= 0; i++){ for (int j = -size + 1; j <= 0; j++){ - locations = getMap(size, leftTop.add(i, 0, j)); + locations = getMap(size, center.clone().add(i, 0, j)); if (isMapValid(locations, blockType)){ + Iris.info("Valid map for size " + size + " with material " + blockType.name() + " with center" + center); + Iris.info("Locations: " + locations); return locations; } } @@ -162,6 +176,7 @@ public enum IrisTreeSize { * @return True if it's valid */ private static boolean isMapValid(KList> map, Material block){ + if (map == null) return false; return map.stream().allMatch(row -> row.stream().allMatch(location -> location.getBlock().getType().equals(block))); } @@ -176,7 +191,7 @@ public enum IrisTreeSize { for (int i = 0; i < size; i++){ KList row = new KList<>(); for (int j = 0; j < size; j++){ - row.add(leftTop.add(i, 0, j)); + row.add(leftTop.clone().add(i, 0, j)); } locations.add(row); } @@ -194,6 +209,6 @@ public enum IrisTreeSize { if (size % 2 != 1){ return null; } - return getMap(size, center.add(-(size - 1) / 2d, 0, -(size - 1) / 2d)); + return getMap(size, center.clone().add(-(size - 1) / 2d, 0, -(size - 1) / 2d)); } } From a82279b068e7db8fee10921245783dce480dff45 Mon Sep 17 00:00:00 2001 From: CocoTheOwner Date: Tue, 20 Jul 2021 21:25:28 +0200 Subject: [PATCH 17/41] Refactor, cleanup, debug --- .../com/volmit/iris/core/TreeManager.java | 74 ++++++++++--------- .../iris/engine/object/IrisTreeSize.java | 30 +++++--- 2 files changed, 60 insertions(+), 44 deletions(-) diff --git a/src/main/java/com/volmit/iris/core/TreeManager.java b/src/main/java/com/volmit/iris/core/TreeManager.java index fa64de21f..24e9dfa65 100644 --- a/src/main/java/com/volmit/iris/core/TreeManager.java +++ b/src/main/java/com/volmit/iris/core/TreeManager.java @@ -4,13 +4,10 @@ import com.volmit.iris.Iris; import com.volmit.iris.engine.IrisWorlds; import com.volmit.iris.engine.framework.IrisAccess; import com.volmit.iris.engine.object.*; -import com.volmit.iris.engine.object.common.IObjectPlacer; -import com.volmit.iris.engine.object.tile.TileData; import com.volmit.iris.util.collection.KList; +import com.volmit.iris.util.collection.KMap; import com.volmit.iris.util.math.RNG; import org.bukkit.Location; -import org.bukkit.block.TileState; -import org.bukkit.block.data.BlockData; import org.bukkit.event.EventHandler; import org.bukkit.event.Listener; import org.bukkit.event.world.StructureGrowEvent; @@ -38,10 +35,11 @@ public class TreeManager implements Listener { @EventHandler public void onStructureGrowEvent(StructureGrowEvent event) { - Iris.debug("Sapling grew @ " + event.getLocation() + " for " + event.getSpecies().name() + " usedBoneMeal is " + event.isFromBonemeal()); + Iris.debug(this.getClass().getName() + " received a structure grow event"); // Must be iris world if (!IrisWorlds.isIrisWorld(event.getWorld())) { + Iris.debug(this.getClass().getName() + " passed it off to vanilla since not an Iris world"); return; } @@ -50,26 +48,45 @@ public class TreeManager implements Listener { try { worldAccess = Objects.requireNonNull(IrisWorlds.access(event.getWorld())); } catch (Throwable e) { + Iris.debug(this.getClass().getName() + " passed it off to vanilla because could not get IrisAccess for this world"); Iris.reportError(e); return; } - Iris.debug("Custom saplings are " + (worldAccess.getCompound().getRootDimension().getSaplingSettings().isEnabled() ? "" : "NOT") + " enabled."); + // Return null if not enabled + if (!worldAccess.getCompound().getRootDimension().getSaplingSettings().isEnabled()) { + Iris.debug(this.getClass().getName() + "cancelled because not"); + return; + } + + Iris.debug("Sapling grew @ " + event.getLocation() + " for " + event.getSpecies().name() + " usedBoneMeal is " + event.isFromBonemeal()); // Calculate size, type & placement IrisTreeType type = IrisTreeType.fromTreeType(event.getSpecies()); - IrisTreeSize size = getTreeSize(event.getLocation(), type); - IrisObjectPlacement placement = getObjectPlacement(worldAccess, type, event.getLocation(), size); + KMap>> sizes = IrisTreeSize.getValidSizes(event.getLocation()); + KList keys = sizes.k(); - // Make sure placement was found - if (placement == null){ + // Find best object placement based on size + IrisObjectPlacement placement = null; + while (placement == null && keys.isNotEmpty()){ + IrisTreeSize bestSize = IrisTreeSize.bestSizeInSizes(keys); + keys.remove(bestSize); + placement = getObjectPlacement(worldAccess, event.getLocation(), type, bestSize); + } + + // If none was found, just exit + if (placement == null) { return; } + // Cancel the placement + event.setCancelled(true); + // Get object from placer IrisObject f = worldAccess.getData().getObjectLoader().load(placement.getPlace().getRandom(RNG.r)); // TODO: Implement placer + /* IObjectPlacer placer = new IObjectPlacer(){ @Override @@ -122,11 +139,13 @@ public class TreeManager implements Listener { } }; + */ // TODO: Figure out how to place without wrecking claims, other builds, etc. // Especially with large object // Place the object with the placer + /* f.place( event.getLocation().getBlockX(), event.getLocation().getBlockY(), @@ -136,36 +155,20 @@ public class TreeManager implements Listener { RNG.r, Objects.requireNonNull(IrisWorlds.access(event.getWorld())).getData() ); - } - - /** - * Finds the tree size - * @param location The location the event triggers from. This sapling's Material type is used to check other locations - * @return The size of the tree - */ - private IrisTreeSize getTreeSize(Location location, IrisTreeType type) { - KList validSizes = new KList<>(); - - IrisTreeSize.isSizeValid(); - - return IrisTreeSize.bestSize(validSizes); + */ + // TODO: Place the object at the right location (one of the center positions) + f.place(event.getLocation()); } /** * Finds a single object placement (which may contain more than one object) for the requirements species, location & size * @param worldAccess The world to access (check for biome, region, dimension, etc) - * @param type The bukkit TreeType to match * @param location The location of the growth event (For biome/region finding) + * @param type The bukkit TreeType to match * @param size The size of the sapling area * @return An object placement which contains the matched tree, or null if none were found / it's disabled. */ - private IrisObjectPlacement getObjectPlacement(IrisAccess worldAccess, IrisTreeType type, Location location, IrisTreeSize size) { - IrisDimension dimension = worldAccess.getCompound().getRootDimension(); - - // Return null if not enabled - if (!dimension.getSaplingSettings().isEnabled()) { - return null; - } + private IrisObjectPlacement getObjectPlacement(IrisAccess worldAccess, Location location, IrisTreeType type, IrisTreeSize size) { KList placements = new KList<>(); @@ -174,16 +177,17 @@ public class TreeManager implements Listener { placements.addAll(matchObjectPlacements(biome.getObjects(), size, type)); // Add more or find any in the region - if (dimension.getSaplingSettings().getMode().equals(IrisTreeModes.ALL) || placements.isEmpty()){ + if (worldAccess.getCompound().getRootDimension().getSaplingSettings().getMode().equals(IrisTreeModes.ALL) || placements.isEmpty()){ IrisRegion region = worldAccess.getCompound().getDefaultEngine().getRegion(location.getBlockX(), location.getBlockZ()); placements.addAll(matchObjectPlacements(region.getObjects(), size, type)); } // Add more or find any in the dimension - if (dimension.getSaplingSettings().getMode().equals(IrisTreeModes.ALL) || placements.isEmpty()){ - //TODO: Implement object placement in dimension & here - //placements.addAll(matchObjectPlacements(dimension.getObjects(), size, type)); + /* TODO: Implement object placement in dimension & here + if (worldAccess.getCompound().getRootDimension().getSaplingSettings().getMode().equals(IrisTreeModes.ALL) || placements.isEmpty()){ + placements.addAll(matchObjectPlacements(worldAccess.getCompound().getRootDimension().getObjects(), size, type)); } + */ // Check if no matches were found, return a random one if they are return placements.isNotEmpty() ? placements.getRandom(RNG.r) : null; diff --git a/src/main/java/com/volmit/iris/engine/object/IrisTreeSize.java b/src/main/java/com/volmit/iris/engine/object/IrisTreeSize.java index 52e2a9959..41c6efff5 100644 --- a/src/main/java/com/volmit/iris/engine/object/IrisTreeSize.java +++ b/src/main/java/com/volmit/iris/engine/object/IrisTreeSize.java @@ -1,13 +1,11 @@ package com.volmit.iris.engine.object; -import com.volmit.iris.Iris; import com.volmit.iris.engine.object.annotations.Desc; import com.volmit.iris.util.collection.KList; +import com.volmit.iris.util.collection.KMap; import org.bukkit.Location; import org.bukkit.Material; -import java.util.Objects; - @Desc("Sapling override object picking options") public enum IrisTreeSize { @@ -58,7 +56,7 @@ public enum IrisTreeSize { * @param sizes The list of sizes * @return The best size (highest & center > any) */ - public static IrisTreeSize bestSize(KList sizes){ + public static IrisTreeSize bestSizeInSizes(KList sizes){ if (sizes.contains(FIVE_CENTER)){ return FIVE_CENTER; } @@ -103,12 +101,12 @@ public enum IrisTreeSize { while (sizeList.isNotEmpty()){ // Find the best size & remove from list - IrisTreeSize bestSize = bestSize(sizeList); + IrisTreeSize bestSize = bestSizeInSizes(sizeList); assert bestSize != null; sizeList.remove(bestSize); // Find the best match - KList> best = isSizeValid(bestSize, location); + KList> best = getPlacesIfValid(bestSize, location); if (best != null){ return bestSize; } @@ -123,7 +121,7 @@ public enum IrisTreeSize { * @param location at this location * @return A list of locations if any match, or null if not. */ - public static KList> isSizeValid(IrisTreeSize size, Location location) { + public static KList> getPlacesIfValid (IrisTreeSize size, Location location) { return switch (size){ case ONE -> new KList>(new KList<>(location)); case TWO -> loopLocation(location, 2); @@ -160,8 +158,6 @@ public enum IrisTreeSize { for (int j = -size + 1; j <= 0; j++){ locations = getMap(size, center.clone().add(i, 0, j)); if (isMapValid(locations, blockType)){ - Iris.info("Valid map for size " + size + " with material " + blockType.name() + " with center" + center); - Iris.info("Locations: " + locations); return locations; } } @@ -211,4 +207,20 @@ public enum IrisTreeSize { } return getMap(size, center.clone().add(-(size - 1) / 2d, 0, -(size - 1) / 2d)); } + + /** + * Get sizes hash with size -> location map + * @param location the location to search from + * @return A hash with IrisTreeSize -> KList-KList-Location + */ + public static KMap>> getValidSizes(Location location) { + KMap>> sizes = new KMap<>(); + IrisTreeSize.sizes.forEach(size -> { + KList> locations = getPlacesIfValid(size, location); + if (locations != null){ + sizes.put(size, locations); + } + }); + return sizes; + } } From 6932e468cfbcf0dbf81fd8672e04944133c85968 Mon Sep 17 00:00:00 2001 From: CocoTheOwner Date: Tue, 20 Jul 2021 21:46:56 +0200 Subject: [PATCH 18/41] comments, debug. --- .../com/volmit/iris/core/TreeManager.java | 20 ++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) diff --git a/src/main/java/com/volmit/iris/core/TreeManager.java b/src/main/java/com/volmit/iris/core/TreeManager.java index 24e9dfa65..11dcb6fd9 100644 --- a/src/main/java/com/volmit/iris/core/TreeManager.java +++ b/src/main/java/com/volmit/iris/core/TreeManager.java @@ -25,11 +25,10 @@ public class TreeManager implements Listener { /**This function does the following *
1. Is the sapling growing in an Iris world? No -> exit
- *
2. Is the sapling overwriting setting on in that dimension? No -> exit
- *
3. Check biome for overrides for that sapling type -> Found -> use
- *
4. Check region ...
- *
5. Check dimension ...
- *
6. Exit if none are found
+ *
2. Is the Iris world accessible? No -> exit
+ *
3. Is the sapling overwriting setting on in that dimension? No -> exit
+ *
4. Check biome, region and dimension for overrides for that sapling type -> Found -> use
+ *
5. Exit if none are found, cancel event if one or more are.
* @param event Checks the given event for sapling overrides */ @EventHandler @@ -66,7 +65,13 @@ public class TreeManager implements Listener { KMap>> sizes = IrisTreeSize.getValidSizes(event.getLocation()); KList keys = sizes.k(); - // Find best object placement based on size + // Check if any were returned + if (keys.isEmpty()) { + Iris.debug(this.getClass().getName() + " found no matching sapling sizes for the grow event, which should be impossible (considering ONE is an option)"); + return; + } + + // Find best object placement based on sizes IrisObjectPlacement placement = null; while (placement == null && keys.isNotEmpty()){ IrisTreeSize bestSize = IrisTreeSize.bestSizeInSizes(keys); @@ -74,8 +79,9 @@ public class TreeManager implements Listener { placement = getObjectPlacement(worldAccess, event.getLocation(), type, bestSize); } - // If none was found, just exit + // If none were found, just exit if (placement == null) { + Iris.debug(this.getClass().getName() + " had options but did not manage to find objectplacements for them"); return; } From c48c74a0cf023c4c542901f9041695cee2f27646 Mon Sep 17 00:00:00 2001 From: CocoTheOwner Date: Wed, 21 Jul 2021 11:10:43 +0200 Subject: [PATCH 19/41] Remove saplings, update debug, improve object placing functions --- .../java/com/volmit/iris/core/TreeManager.java | 16 +++++++++------- .../volmit/iris/engine/object/IrisObject.java | 4 ++++ 2 files changed, 13 insertions(+), 7 deletions(-) diff --git a/src/main/java/com/volmit/iris/core/TreeManager.java b/src/main/java/com/volmit/iris/core/TreeManager.java index 11dcb6fd9..49a310231 100644 --- a/src/main/java/com/volmit/iris/core/TreeManager.java +++ b/src/main/java/com/volmit/iris/core/TreeManager.java @@ -8,6 +8,7 @@ import com.volmit.iris.util.collection.KList; import com.volmit.iris.util.collection.KMap; import com.volmit.iris.util.math.RNG; import org.bukkit.Location; +import org.bukkit.Material; import org.bukkit.event.EventHandler; import org.bukkit.event.Listener; import org.bukkit.event.world.StructureGrowEvent; @@ -73,21 +74,25 @@ public class TreeManager implements Listener { // Find best object placement based on sizes IrisObjectPlacement placement = null; + IrisTreeSize bestSize = null; while (placement == null && keys.isNotEmpty()){ - IrisTreeSize bestSize = IrisTreeSize.bestSizeInSizes(keys); + bestSize = IrisTreeSize.bestSizeInSizes(keys); keys.remove(bestSize); placement = getObjectPlacement(worldAccess, event.getLocation(), type, bestSize); } // If none were found, just exit if (placement == null) { - Iris.debug(this.getClass().getName() + " had options but did not manage to find objectplacements for them"); + Iris.debug(this.getClass().getName() + " had options but did not manage to find objectPlacements for them"); return; } // Cancel the placement event.setCancelled(true); + // Delete existing saplings + sizes.get(bestSize).forEach(row -> row.forEach(location -> location.getBlock().setType(Material.AIR))); + // Get object from placer IrisObject f = worldAccess.getData().getObjectLoader().load(placement.getPlace().getRandom(RNG.r)); @@ -153,17 +158,14 @@ public class TreeManager implements Listener { // Place the object with the placer /* f.place( - event.getLocation().getBlockX(), - event.getLocation().getBlockY(), - event.getLocation().getBlockZ(), + event.getLocation() // TODO: Place the object at the right location (one of the center positions) placer, placement, RNG.r, Objects.requireNonNull(IrisWorlds.access(event.getWorld())).getData() ); */ - // TODO: Place the object at the right location (one of the center positions) - f.place(event.getLocation()); + //f.place(event.getLocation()); } /** diff --git a/src/main/java/com/volmit/iris/engine/object/IrisObject.java b/src/main/java/com/volmit/iris/engine/object/IrisObject.java index 9832af511..846546e58 100644 --- a/src/main/java/com/volmit/iris/engine/object/IrisObject.java +++ b/src/main/java/com/volmit/iris/engine/object/IrisObject.java @@ -415,6 +415,10 @@ public class IrisObject extends IrisRegistrant { return place(x, yv, z, placer, config, rng, null, null, rdata); } + public int place(Location loc, IObjectPlacer placer, IrisObjectPlacement config, RNG rng, IrisDataManager rdata) { + return place(loc.getBlockX(), loc.getBlockY(), loc.getBlockZ(), placer, config, rng, rdata); + } + public int place(int x, int yv, int z, IObjectPlacer oplacer, IrisObjectPlacement config, RNG rng, Consumer listener, CarveResult c, IrisDataManager rdata) { IObjectPlacer placer = (config.getHeightmap() != null) ? new IObjectPlacer() { final long s = rng.nextLong() + yv + z - x; From 52cba23190bd5d559da3964e1d4b4a19d00e311e Mon Sep 17 00:00:00 2001 From: CocoTheOwner Date: Wed, 21 Jul 2021 11:24:54 +0200 Subject: [PATCH 20/41] Add object placement to dimension It is not enabled to place objects, but will work with sapling overrides --- src/main/java/com/volmit/iris/engine/object/IrisDimension.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/main/java/com/volmit/iris/engine/object/IrisDimension.java b/src/main/java/com/volmit/iris/engine/object/IrisDimension.java index e3e7bad3a..91ba03a51 100644 --- a/src/main/java/com/volmit/iris/engine/object/IrisDimension.java +++ b/src/main/java/com/volmit/iris/engine/object/IrisDimension.java @@ -61,6 +61,9 @@ public class IrisDimension extends IrisRegistrant { @ArrayType(min = 1, type = IrisDimensionIndex.class) private KList dimensionalComposite = new KList<>(); + @ArrayType(min = 1, type = IrisObjectPlacement.class) + @Desc("Objects define what schematics (iob files) iris will place in this biome. ONLY FOR SAPLINGS UNTIL FURTHER NOTICE!") + private KList objects = new KList<>(); @Desc("Create an inverted dimension in the sky (like the nether)") private IrisDimension sky = null; From aaf7ae8fc316a8ee0f724c05a22ab27bfdc80070 Mon Sep 17 00:00:00 2001 From: CocoTheOwner Date: Wed, 21 Jul 2021 11:25:22 +0200 Subject: [PATCH 21/41] Remove unused, add & implement ANY treeSize --- .../com/volmit/iris/core/TreeManager.java | 6 +- .../iris/engine/object/IrisTreeSize.java | 64 ++++--------------- 2 files changed, 14 insertions(+), 56 deletions(-) diff --git a/src/main/java/com/volmit/iris/core/TreeManager.java b/src/main/java/com/volmit/iris/core/TreeManager.java index 49a310231..9cc4e4faa 100644 --- a/src/main/java/com/volmit/iris/core/TreeManager.java +++ b/src/main/java/com/volmit/iris/core/TreeManager.java @@ -17,8 +17,6 @@ import java.util.Objects; public class TreeManager implements Listener { - public static final int maxSaplingPlane = 5; - public TreeManager() { Iris.instance.registerListener(this); Iris.info("Loading Sapling Manager"); @@ -191,11 +189,9 @@ public class TreeManager implements Listener { } // Add more or find any in the dimension - /* TODO: Implement object placement in dimension & here if (worldAccess.getCompound().getRootDimension().getSaplingSettings().getMode().equals(IrisTreeModes.ALL) || placements.isEmpty()){ placements.addAll(matchObjectPlacements(worldAccess.getCompound().getRootDimension().getObjects(), size, type)); } - */ // Check if no matches were found, return a random one if they are return placements.isNotEmpty() ? placements.getRandom(RNG.r) : null; @@ -213,7 +209,7 @@ public class TreeManager implements Listener { objects.stream() .filter(objectPlacement -> objectPlacement.getTreeOptions().isEnabled()) .filter(objectPlacement -> objectPlacement.getTreeOptions().getTrees().stream().anyMatch(irisTree -> - irisTree.getSizes().stream().anyMatch(treeSize -> treeSize == size) && + irisTree.getSizes().stream().anyMatch(treeSize -> treeSize == IrisTreeSize.ANY || treeSize == size) && irisTree.getTreeTypes().stream().anyMatch(treeType -> treeType == type))) .forEach(objectPlacements::add); return objectPlacements; diff --git a/src/main/java/com/volmit/iris/engine/object/IrisTreeSize.java b/src/main/java/com/volmit/iris/engine/object/IrisTreeSize.java index 41c6efff5..fe707e9e5 100644 --- a/src/main/java/com/volmit/iris/engine/object/IrisTreeSize.java +++ b/src/main/java/com/volmit/iris/engine/object/IrisTreeSize.java @@ -1,5 +1,6 @@ package com.volmit.iris.engine.object; +import com.volmit.iris.Iris; import com.volmit.iris.engine.object.annotations.Desc; import com.volmit.iris.util.collection.KList; import com.volmit.iris.util.collection.KMap; @@ -28,36 +29,26 @@ public enum IrisTreeSize { FIVE_ANY, @Desc("Five by five center") - FIVE_CENTER; + FIVE_CENTER, + + @Desc("Any size") + ANY; /** * All sizes in this enum */ public static final KList sizes = new KList<>(ONE, TWO, THREE_ANY, THREE_CENTER, FOUR, FIVE_ANY, FIVE_CENTER); - /** - * The best size in this enum - */ - public static final IrisTreeSize bestSize = FIVE_CENTER; - - /** - * Whether the position of the any type (not fixed at a center) - * @param treeSize The treesize to check - */ - public static boolean isAnyPosition(IrisTreeSize treeSize){ - return switch (treeSize) { - case ONE, THREE_CENTER, FIVE_CENTER -> false; - default -> true; - }; - } - /** * Get the best size to match against from a list of sizes * @param sizes The list of sizes * @return The best size (highest & center > any) */ public static IrisTreeSize bestSizeInSizes(KList sizes){ - if (sizes.contains(FIVE_CENTER)){ + if (sizes.contains(ANY)){ + return ANY; + } + else if (sizes.contains(FIVE_CENTER)){ return FIVE_CENTER; } else if (sizes.contains(FIVE_ANY)){ @@ -82,39 +73,6 @@ public enum IrisTreeSize { } } - /** - * Find the best size based on a location - * @param location The location to look from - * @return The best size - */ - public static IrisTreeSize getBestSize(Location location){ - return getBestSize(location, sizes.copy()); - } - - /** - * Find the best valid size based on a location and a list of sizes - * @param location The location to search from - * @param sizeList The list of sizes to pick from - * @return The best valid size - */ - public static IrisTreeSize getBestSize(Location location, KList sizeList){ - while (sizeList.isNotEmpty()){ - - // Find the best size & remove from list - IrisTreeSize bestSize = bestSizeInSizes(sizeList); - assert bestSize != null; - sizeList.remove(bestSize); - - // Find the best match - KList> best = getPlacesIfValid(bestSize, location); - if (best != null){ - return bestSize; - } - } - return ONE; - - } - /** * Check if the size at a specific location is valid * @param size the IrisTreeSize to check @@ -122,6 +80,9 @@ public enum IrisTreeSize { * @return A list of locations if any match, or null if not. */ public static KList> getPlacesIfValid (IrisTreeSize size, Location location) { + if (size == ANY){ + Iris.debug("ANY was passed to getPlacesIfValid while it should never!"); + } return switch (size){ case ONE -> new KList>(new KList<>(location)); case TWO -> loopLocation(location, 2); @@ -130,6 +91,7 @@ public enum IrisTreeSize { case FIVE_ANY -> loopLocation(location, 5); case THREE_CENTER -> isCenterMapValid(location, 3); case FIVE_CENTER -> isCenterMapValid(location, 5); + case ANY -> null; }; } From f6305378979a83ee52845a612e65c3b268cc90fb Mon Sep 17 00:00:00 2001 From: CocoTheOwner Date: Wed, 21 Jul 2021 11:27:21 +0200 Subject: [PATCH 22/41] ANY treetype --- src/main/java/com/volmit/iris/core/TreeManager.java | 2 +- src/main/java/com/volmit/iris/engine/object/IrisTreeType.java | 3 +++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/src/main/java/com/volmit/iris/core/TreeManager.java b/src/main/java/com/volmit/iris/core/TreeManager.java index 9cc4e4faa..821edd00b 100644 --- a/src/main/java/com/volmit/iris/core/TreeManager.java +++ b/src/main/java/com/volmit/iris/core/TreeManager.java @@ -210,7 +210,7 @@ public class TreeManager implements Listener { .filter(objectPlacement -> objectPlacement.getTreeOptions().isEnabled()) .filter(objectPlacement -> objectPlacement.getTreeOptions().getTrees().stream().anyMatch(irisTree -> irisTree.getSizes().stream().anyMatch(treeSize -> treeSize == IrisTreeSize.ANY || treeSize == size) && - irisTree.getTreeTypes().stream().anyMatch(treeType -> treeType == type))) + irisTree.getTreeTypes().stream().anyMatch(treeType -> treeType == IrisTreeType.ANY || treeType == type))) .forEach(objectPlacements::add); return objectPlacements; } diff --git a/src/main/java/com/volmit/iris/engine/object/IrisTreeType.java b/src/main/java/com/volmit/iris/engine/object/IrisTreeType.java index df8728281..1b34941a4 100644 --- a/src/main/java/com/volmit/iris/engine/object/IrisTreeType.java +++ b/src/main/java/com/volmit/iris/engine/object/IrisTreeType.java @@ -43,6 +43,9 @@ public enum IrisTreeType { @Desc("Tree with large roots which grows above lush caves") AZALEA, + @Desc("Any tree type (all will match, including mushrooms & nether trees") + ANY, + @Desc("The fallback type for all other non-supported growth events") NONE; From d865e646b9b3d27b7528617d4ce90cc7e3479e49 Mon Sep 17 00:00:00 2001 From: CocoTheOwner Date: Wed, 21 Jul 2021 11:30:26 +0200 Subject: [PATCH 23/41] Remove @Required from object place chance (default = 1 already) --- .../com/volmit/iris/engine/object/IrisObjectPlacement.java | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/main/java/com/volmit/iris/engine/object/IrisObjectPlacement.java b/src/main/java/com/volmit/iris/engine/object/IrisObjectPlacement.java index ed716a78e..308a3a742 100644 --- a/src/main/java/com/volmit/iris/engine/object/IrisObjectPlacement.java +++ b/src/main/java/com/volmit/iris/engine/object/IrisObjectPlacement.java @@ -61,8 +61,7 @@ public class IrisObjectPlacement { @MaxNumber(1) @Desc("The maximum layer level of a snow filter overtop of this placement. Set to 0 to disable. Max of 1.") private double snow = 0; - - @Required + @MinNumber(0) @MaxNumber(1) @Desc("The chance for this to place in a chunk. If you need multiple per chunk, set this to 1 and use density.") From bfa13583e3061551352e74b44cc51ba5f31b5ebc Mon Sep 17 00:00:00 2001 From: CocoTheOwner Date: Wed, 21 Jul 2021 11:33:42 +0200 Subject: [PATCH 24/41] Sapling now called tree --- .../java/com/volmit/iris/engine/object/IrisDimension.java | 4 ++-- .../com/volmit/iris/engine/object/IrisObjectPlacement.java | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/main/java/com/volmit/iris/engine/object/IrisDimension.java b/src/main/java/com/volmit/iris/engine/object/IrisDimension.java index 91ba03a51..189360432 100644 --- a/src/main/java/com/volmit/iris/engine/object/IrisDimension.java +++ b/src/main/java/com/volmit/iris/engine/object/IrisDimension.java @@ -76,8 +76,8 @@ public class IrisDimension extends IrisRegistrant { @Desc("Improves the biome grid variation by shuffling the cell grid more depending on the seed. This makes biomes across multiple seeds look far different than before.") private boolean aggressiveBiomeReshuffle = false; - @Desc("Sapling override settings") - private IrisTreeSettings saplingSettings = new IrisTreeSettings(); + @Desc("Tree growth override settings") + private IrisTreeSettings treeSettings = new IrisTreeSettings(); @Desc("Instead of a flat bottom, applies a clamp (using this noise style) to the bottom instead of a flat bottom. Useful for carving out center-dimensions in a dimension composite world.") diff --git a/src/main/java/com/volmit/iris/engine/object/IrisObjectPlacement.java b/src/main/java/com/volmit/iris/engine/object/IrisObjectPlacement.java index 308a3a742..ab1c8e1b6 100644 --- a/src/main/java/com/volmit/iris/engine/object/IrisObjectPlacement.java +++ b/src/main/java/com/volmit/iris/engine/object/IrisObjectPlacement.java @@ -61,7 +61,7 @@ public class IrisObjectPlacement { @MaxNumber(1) @Desc("The maximum layer level of a snow filter overtop of this placement. Set to 0 to disable. Max of 1.") private double snow = 0; - + @MinNumber(0) @MaxNumber(1) @Desc("The chance for this to place in a chunk. If you need multiple per chunk, set this to 1 and use density.") From 66a8db598fc6c7afaf431b34b5bd0cd756b3bae8 Mon Sep 17 00:00:00 2001 From: CocoTheOwner Date: Wed, 21 Jul 2021 11:34:34 +0200 Subject: [PATCH 25/41] Require toggle in treeSettings --- .../java/com/volmit/iris/engine/object/IrisTreeSettings.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/main/java/com/volmit/iris/engine/object/IrisTreeSettings.java b/src/main/java/com/volmit/iris/engine/object/IrisTreeSettings.java index 9924b1ecd..2182f2322 100644 --- a/src/main/java/com/volmit/iris/engine/object/IrisTreeSettings.java +++ b/src/main/java/com/volmit/iris/engine/object/IrisTreeSettings.java @@ -1,6 +1,7 @@ package com.volmit.iris.engine.object; import com.volmit.iris.engine.object.annotations.Desc; +import com.volmit.iris.engine.object.annotations.Required; import lombok.AllArgsConstructor; import lombok.Data; import lombok.EqualsAndHashCode; @@ -15,6 +16,7 @@ import lombok.experimental.Accessors; @EqualsAndHashCode(callSuper = false) public class IrisTreeSettings { + @Required @Desc("Turn replacing on and off") boolean enabled = false; From 6a868f975e5887e0f182934bcc37fc95faa387ca Mon Sep 17 00:00:00 2001 From: CocoTheOwner Date: Wed, 21 Jul 2021 11:39:27 +0200 Subject: [PATCH 26/41] Rename treeoptions & improve debug --- src/main/java/com/volmit/iris/core/TreeManager.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/main/java/com/volmit/iris/core/TreeManager.java b/src/main/java/com/volmit/iris/core/TreeManager.java index 821edd00b..e0d0f5aa7 100644 --- a/src/main/java/com/volmit/iris/core/TreeManager.java +++ b/src/main/java/com/volmit/iris/core/TreeManager.java @@ -52,8 +52,8 @@ public class TreeManager implements Listener { } // Return null if not enabled - if (!worldAccess.getCompound().getRootDimension().getSaplingSettings().isEnabled()) { - Iris.debug(this.getClass().getName() + "cancelled because not"); + if (!worldAccess.getCompound().getRootDimension().getTreeSettings().isEnabled()) { + Iris.debug(this.getClass().getName() + " cancelled because tree overrides are disabled"); return; } @@ -183,13 +183,13 @@ public class TreeManager implements Listener { placements.addAll(matchObjectPlacements(biome.getObjects(), size, type)); // Add more or find any in the region - if (worldAccess.getCompound().getRootDimension().getSaplingSettings().getMode().equals(IrisTreeModes.ALL) || placements.isEmpty()){ + if (worldAccess.getCompound().getRootDimension().getTreeSettings().getMode().equals(IrisTreeModes.ALL) || placements.isEmpty()){ IrisRegion region = worldAccess.getCompound().getDefaultEngine().getRegion(location.getBlockX(), location.getBlockZ()); placements.addAll(matchObjectPlacements(region.getObjects(), size, type)); } // Add more or find any in the dimension - if (worldAccess.getCompound().getRootDimension().getSaplingSettings().getMode().equals(IrisTreeModes.ALL) || placements.isEmpty()){ + if (worldAccess.getCompound().getRootDimension().getTreeSettings().getMode().equals(IrisTreeModes.ALL) || placements.isEmpty()){ placements.addAll(matchObjectPlacements(worldAccess.getCompound().getRootDimension().getObjects(), size, type)); } From eb193f230b530751530db0a94b00726d23a585dd Mon Sep 17 00:00:00 2001 From: CocoTheOwner Date: Wed, 21 Jul 2021 11:40:16 +0200 Subject: [PATCH 27/41] Re-enable dirty placer. needs fixin' --- src/main/java/com/volmit/iris/core/TreeManager.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/com/volmit/iris/core/TreeManager.java b/src/main/java/com/volmit/iris/core/TreeManager.java index e0d0f5aa7..e850d3a93 100644 --- a/src/main/java/com/volmit/iris/core/TreeManager.java +++ b/src/main/java/com/volmit/iris/core/TreeManager.java @@ -163,7 +163,7 @@ public class TreeManager implements Listener { Objects.requireNonNull(IrisWorlds.access(event.getWorld())).getData() ); */ - //f.place(event.getLocation()); + f.place(event.getLocation()); } /** From 20f3efced93cc6a24303cba5a1848fff10d9c7cd Mon Sep 17 00:00:00 2001 From: CocoTheOwner Date: Wed, 21 Jul 2021 16:58:09 +0200 Subject: [PATCH 28/41] Convert to toolbelt --- src/main/java/com/volmit/iris/core/TreeManager.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/main/java/com/volmit/iris/core/TreeManager.java b/src/main/java/com/volmit/iris/core/TreeManager.java index e850d3a93..cd908d7b1 100644 --- a/src/main/java/com/volmit/iris/core/TreeManager.java +++ b/src/main/java/com/volmit/iris/core/TreeManager.java @@ -1,7 +1,7 @@ package com.volmit.iris.core; import com.volmit.iris.Iris; -import com.volmit.iris.engine.IrisWorlds; +import com.volmit.iris.core.tools.IrisToolbelt; import com.volmit.iris.engine.framework.IrisAccess; import com.volmit.iris.engine.object.*; import com.volmit.iris.util.collection.KList; @@ -36,7 +36,7 @@ public class TreeManager implements Listener { Iris.debug(this.getClass().getName() + " received a structure grow event"); // Must be iris world - if (!IrisWorlds.isIrisWorld(event.getWorld())) { + if (!IrisToolbelt.isIrisWorld(event.getWorld())) { Iris.debug(this.getClass().getName() + " passed it off to vanilla since not an Iris world"); return; } @@ -44,7 +44,7 @@ public class TreeManager implements Listener { // Get world access IrisAccess worldAccess; try { - worldAccess = Objects.requireNonNull(IrisWorlds.access(event.getWorld())); + worldAccess = Objects.requireNonNull(IrisToolbelt.access(event.getWorld())); } catch (Throwable e) { Iris.debug(this.getClass().getName() + " passed it off to vanilla because could not get IrisAccess for this world"); Iris.reportError(e); From 3e892f30ca05753b4ab70ac4980678ecc5e70c8f Mon Sep 17 00:00:00 2001 From: CocoTheOwner Date: Wed, 21 Jul 2021 16:59:46 +0200 Subject: [PATCH 29/41] Remove requireNonNull and do safer --- src/main/java/com/volmit/iris/core/TreeManager.java | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/src/main/java/com/volmit/iris/core/TreeManager.java b/src/main/java/com/volmit/iris/core/TreeManager.java index cd908d7b1..f9b19b0a1 100644 --- a/src/main/java/com/volmit/iris/core/TreeManager.java +++ b/src/main/java/com/volmit/iris/core/TreeManager.java @@ -42,12 +42,10 @@ public class TreeManager implements Listener { } // Get world access - IrisAccess worldAccess; - try { - worldAccess = Objects.requireNonNull(IrisToolbelt.access(event.getWorld())); - } catch (Throwable e) { + IrisAccess worldAccess = IrisToolbelt.access(event.getWorld()); + if (worldAccess == null){ Iris.debug(this.getClass().getName() + " passed it off to vanilla because could not get IrisAccess for this world"); - Iris.reportError(e); + Iris.reportError(new NullPointerException(event.getWorld().getName() + " could not be accessed despite being an Iris world")); return; } From b15b64065230a6caae0b473f0176d737850e3b62 Mon Sep 17 00:00:00 2001 From: CocoTheOwner Date: Wed, 21 Jul 2021 18:12:45 +0200 Subject: [PATCH 30/41] Probably wise to quicksave --- .../com/volmit/iris/core/TreeManager.java | 178 +++++++++++++----- .../engine/object/IrisObjectPlacement.java | 5 +- .../volmit/iris/engine/object/IrisTree.java | 11 +- .../iris/engine/object/IrisTreeOptions.java | 24 --- .../iris/engine/object/IrisTreeType.java | 69 ------- 5 files changed, 138 insertions(+), 149 deletions(-) delete mode 100644 src/main/java/com/volmit/iris/engine/object/IrisTreeOptions.java delete mode 100644 src/main/java/com/volmit/iris/engine/object/IrisTreeType.java diff --git a/src/main/java/com/volmit/iris/core/TreeManager.java b/src/main/java/com/volmit/iris/core/TreeManager.java index f9b19b0a1..c593143dc 100644 --- a/src/main/java/com/volmit/iris/core/TreeManager.java +++ b/src/main/java/com/volmit/iris/core/TreeManager.java @@ -2,18 +2,26 @@ package com.volmit.iris.core; import com.volmit.iris.Iris; import com.volmit.iris.core.tools.IrisToolbelt; +import com.volmit.iris.engine.framework.Engine; import com.volmit.iris.engine.framework.IrisAccess; import com.volmit.iris.engine.object.*; +import com.volmit.iris.engine.object.common.IObjectPlacer; +import com.volmit.iris.engine.object.tile.TileData; import com.volmit.iris.util.collection.KList; -import com.volmit.iris.util.collection.KMap; +import com.volmit.iris.util.data.Cuboid; +import com.volmit.iris.util.math.BlockPosition; import com.volmit.iris.util.math.RNG; -import org.bukkit.Location; -import org.bukkit.Material; +import com.volmit.iris.util.math.Vector2d; +import org.bukkit.*; +import org.bukkit.block.Block; +import org.bukkit.block.TileState; +import org.bukkit.block.data.BlockData; import org.bukkit.event.EventHandler; import org.bukkit.event.Listener; import org.bukkit.event.world.StructureGrowEvent; import java.util.Objects; +import java.util.function.Predicate; public class TreeManager implements Listener { @@ -43,7 +51,7 @@ public class TreeManager implements Listener { // Get world access IrisAccess worldAccess = IrisToolbelt.access(event.getWorld()); - if (worldAccess == null){ + if (worldAccess == null) { Iris.debug(this.getClass().getName() + " passed it off to vanilla because could not get IrisAccess for this world"); Iris.reportError(new NullPointerException(event.getWorld().getName() + " could not be accessed despite being an Iris world")); return; @@ -58,24 +66,16 @@ public class TreeManager implements Listener { Iris.debug("Sapling grew @ " + event.getLocation() + " for " + event.getSpecies().name() + " usedBoneMeal is " + event.isFromBonemeal()); // Calculate size, type & placement - IrisTreeType type = IrisTreeType.fromTreeType(event.getSpecies()); - KMap>> sizes = IrisTreeSize.getValidSizes(event.getLocation()); - KList keys = sizes.k(); + Cuboid saplingPlane = getSaplings(event.getLocation(), blockData -> event.getLocation().getBlock().getBlockData().equals(blockData), event.getWorld()); // Check if any were returned - if (keys.isEmpty()) { - Iris.debug(this.getClass().getName() + " found no matching sapling sizes for the grow event, which should be impossible (considering ONE is an option)"); + if (saplingPlane == null) { + Iris.debug(this.getClass().getName() + " found no matching sapling sizes for the grow event, which should be impossible (considering the one that grew is an option)"); return; } // Find best object placement based on sizes - IrisObjectPlacement placement = null; - IrisTreeSize bestSize = null; - while (placement == null && keys.isNotEmpty()){ - bestSize = IrisTreeSize.bestSizeInSizes(keys); - keys.remove(bestSize); - placement = getObjectPlacement(worldAccess, event.getLocation(), type, bestSize); - } + IrisObjectPlacement placement = getObjectPlacement(worldAccess, event.getLocation(), event.getSpecies(), null); // If none were found, just exit if (placement == null) { @@ -87,43 +87,48 @@ public class TreeManager implements Listener { event.setCancelled(true); // Delete existing saplings - sizes.get(bestSize).forEach(row -> row.forEach(location -> location.getBlock().setType(Material.AIR))); + saplingPlane.forEach(block -> block.setType(Material.AIR)); // Get object from placer - IrisObject f = worldAccess.getData().getObjectLoader().load(placement.getPlace().getRandom(RNG.r)); + IrisObject object = worldAccess.getData().getObjectLoader().load(placement.getPlace().getRandom(RNG.r)); - // TODO: Implement placer - /* + // Create object placer IObjectPlacer placer = new IObjectPlacer(){ @Override public int getHighest(int x, int z) { - return 0; + return event.getWorld().getHighestBlockYAt(x, z); } @Override public int getHighest(int x, int z, boolean ignoreFluid) { - return 0; + return event.getWorld().getHighestBlockYAt(x, z, ignoreFluid ? HeightMap.OCEAN_FLOOR : HeightMap.WORLD_SURFACE); } @Override public void set(int x, int y, int z, BlockData d) { + Block b = event.getWorld().getBlockAt(x, y, z); + // Set the block + b.setBlockData(d, false); + + // Tell bukkit what you're doing here + //TODO event.getBlockStates().add(b.getState()); } @Override public BlockData get(int x, int y, int z) { - return null; + return event.getWorld().getBlockAt(x, y, z).getBlockData(); } @Override public boolean isPreventingDecay() { - return false; + return true; } @Override public boolean isSolid(int x, int y, int z) { - return false; + return get(x,y,z).getMaterial().isSolid(); } @Override @@ -133,7 +138,7 @@ public class TreeManager implements Listener { @Override public int getFluidHeight() { - return 0; + return ((Engine)worldAccess.getEngineAccess(event.getLocation().getBlockY())).getDimension().getFluidHeight(); } @Override @@ -146,22 +151,15 @@ public class TreeManager implements Listener { } }; - */ - - // TODO: Figure out how to place without wrecking claims, other builds, etc. - // Especially with large object // Place the object with the placer - /* - f.place( - event.getLocation() // TODO: Place the object at the right location (one of the center positions) + object.place( + saplingPlane.getCenter(), placer, placement, RNG.r, - Objects.requireNonNull(IrisWorlds.access(event.getWorld())).getData() + Objects.requireNonNull(worldAccess).getData() ); - */ - f.place(event.getLocation()); } /** @@ -172,24 +170,26 @@ public class TreeManager implements Listener { * @param size The size of the sapling area * @return An object placement which contains the matched tree, or null if none were found / it's disabled. */ - private IrisObjectPlacement getObjectPlacement(IrisAccess worldAccess, Location location, IrisTreeType type, IrisTreeSize size) { + private IrisObjectPlacement getObjectPlacement(IrisAccess worldAccess, Location location, TreeType type, IrisTreeSize size) { KList placements = new KList<>(); + boolean isUseAll = ((Engine)worldAccess.getEngineAccess(location.getBlockY())).getDimension().getTreeSettings().getMode().equals(IrisTreeModes.ALL); // Retrieve objectPlacements of type `species` from biome IrisBiome biome = worldAccess.getBiome(location.getBlockX(), location.getBlockY(), location.getBlockZ()); placements.addAll(matchObjectPlacements(biome.getObjects(), size, type)); // Add more or find any in the region - if (worldAccess.getCompound().getRootDimension().getTreeSettings().getMode().equals(IrisTreeModes.ALL) || placements.isEmpty()){ + if (isUseAll || placements.isEmpty()){ IrisRegion region = worldAccess.getCompound().getDefaultEngine().getRegion(location.getBlockX(), location.getBlockZ()); placements.addAll(matchObjectPlacements(region.getObjects(), size, type)); } - // Add more or find any in the dimension - if (worldAccess.getCompound().getRootDimension().getTreeSettings().getMode().equals(IrisTreeModes.ALL) || placements.isEmpty()){ - placements.addAll(matchObjectPlacements(worldAccess.getCompound().getRootDimension().getObjects(), size, type)); - } + // TODO: Add more or find any in the dimension + // Add object placer to dimension + // if (isUseAll || placements.isEmpty()){ + // placements.addAll(matchObjectPlacements(worldAccess.getCompound().getRootDimension().getObjects(), size, type)); + // } // Check if no matches were found, return a random one if they are return placements.isNotEmpty() ? placements.getRandom(RNG.r) : null; @@ -202,14 +202,90 @@ public class TreeManager implements Listener { * @param type The type of the tree to filter with * @return A list of objectPlacements that matched. May be empty. */ - private KList matchObjectPlacements(KList objects, IrisTreeSize size, IrisTreeType type) { - KList objectPlacements = new KList<>(); - objects.stream() - .filter(objectPlacement -> objectPlacement.getTreeOptions().isEnabled()) - .filter(objectPlacement -> objectPlacement.getTreeOptions().getTrees().stream().anyMatch(irisTree -> - irisTree.getSizes().stream().anyMatch(treeSize -> treeSize == IrisTreeSize.ANY || treeSize == size) && - irisTree.getTreeTypes().stream().anyMatch(treeType -> treeType == IrisTreeType.ANY || treeType == type))) - .forEach(objectPlacements::add); - return objectPlacements; + private KList matchObjectPlacements(KList objects, IrisTreeSize size, TreeType type) { + + Predicate isValid = irisTree -> ( + irisTree.isAnySize() || irisTree.getSizes().stream().anyMatch(treeSize -> treeSize == IrisTreeSize.ANY || treeSize == size)) && ( + irisTree.isAnyTree() || irisTree.getTreeTypes().stream().anyMatch(treeType -> treeType == type)); + + objects.removeIf(objectPlacement -> objectPlacement.getTrees().stream().noneMatch(isValid)); + + return objects; + } + + /** + * Get the Cuboid of sapling sizes at a location & blockData predicate + * @param at this location + * @param valid with this blockData predicate + * @param world the world to check in + * @return A cuboid containing only saplings + */ + public Cuboid getSaplings(Location at, Predicate valid, World world) { + KList blockPositions = new KList<>(); + grow(at.getWorld(), new BlockPosition(at.getBlockX(), at.getBlockY(), at.getBlockZ()), valid, blockPositions); + BlockPosition a = new BlockPosition(Integer.MIN_VALUE, Integer.MIN_VALUE, Integer.MIN_VALUE); + BlockPosition b = new BlockPosition(Integer.MAX_VALUE, Integer.MAX_VALUE, Integer.MAX_VALUE); + + // Maximise the block position in x and z to get max cuboid bounds + for(BlockPosition blockPosition : blockPositions) + { + a.max(blockPosition); + b.min(blockPosition); + } + + // Create a cuboid with the size calculated before + Cuboid cuboid = new Cuboid(a.toBlock(world).getLocation(), b.toBlock(world).getLocation()); + boolean cuboidIsValid = true; + + // Loop while the cuboid is larger than 2 + while(Math.min(cuboid.getSizeX(), cuboid.getSizeZ()) > 0) + { + checking: + for(int i = cuboid.getLowerX(); i < cuboid.getUpperX(); i++) + { + for(int j = cuboid.getLowerY(); j < cuboid.getUpperY(); j++) + { + for(int k = cuboid.getLowerZ(); k < cuboid.getUpperZ(); k++) + { + if(!blockPositions.contains(new BlockPosition(i,j,k))) + { + cuboidIsValid = false; + break checking; + } + } + } + } + + // Return this cuboid if it's valid + if(cuboidIsValid) + { + return cuboid; + } + + // Inset the cuboid and try again (revalidate) + cuboid = cuboid.inset(Cuboid.CuboidDirection.Horizontal, 1); + cuboidIsValid = true; + } + + return null; + } + + /** + * Grows the blockPosition list by means of checking neighbours in + * @param world the world to check in + * @param center the location of this position + * @param valid validation on blockData to check block with + * @param l list of block positions to add new neighbors too + */ + private void grow(World world, BlockPosition center, Predicate valid, KList l) { + // Make sure size is less than 50, the block to check isn't already in, and make sure the blockData still matches + if(l.size() <= 50 && !l.contains(center) && valid.test(center.toBlock(world).getBlockData())) + { + l.add(center); + grow(world, center.add(1, 0, 0), valid, l); + grow(world, center.add(-1, 0, 0), valid, l); + grow(world, center.add(0, 0, 1), valid, l); + grow(world, center.add(0, 0, -1), valid, l); + } } } diff --git a/src/main/java/com/volmit/iris/engine/object/IrisObjectPlacement.java b/src/main/java/com/volmit/iris/engine/object/IrisObjectPlacement.java index ab1c8e1b6..c7f092b29 100644 --- a/src/main/java/com/volmit/iris/engine/object/IrisObjectPlacement.java +++ b/src/main/java/com/volmit/iris/engine/object/IrisObjectPlacement.java @@ -150,8 +150,9 @@ public class IrisObjectPlacement { @Desc("The loot tables to apply to these objects") private KList loot = new KList<>(); - @Desc("Tree growth overrides for these object placements") - private IrisTreeOptions treeOptions = new IrisTreeOptions(); + @Desc("This objects overrides these trees when they grow...") + @ArrayType(min = 1, type = IrisTree.class) + private KList trees = new KList<>(); public IrisObjectPlacement toPlacement(String... place) { IrisObjectPlacement p = new IrisObjectPlacement(); diff --git a/src/main/java/com/volmit/iris/engine/object/IrisTree.java b/src/main/java/com/volmit/iris/engine/object/IrisTree.java index 54154f769..0614a8480 100644 --- a/src/main/java/com/volmit/iris/engine/object/IrisTree.java +++ b/src/main/java/com/volmit/iris/engine/object/IrisTree.java @@ -1,6 +1,5 @@ package com.volmit.iris.engine.object; -import com.volmit.iris.core.TreeManager; import com.volmit.iris.engine.object.annotations.*; import com.volmit.iris.util.collection.KList; import lombok.AllArgsConstructor; @@ -18,11 +17,17 @@ public class IrisTree { @Required @Desc("The types of trees overwritten by this object") - @ArrayType(min = 1, type = IrisTreeType.class) - private KList treeTypes; + @ArrayType(min = 1, type = TreeType.class) + private KList treeTypes; + + @Desc("If enabled, overrides any TreeType") + private boolean anyTree = false; @Required @Desc("The size of the square of saplings this applies to (2 means a 2 * 2 sapling area)") @ArrayType(min = 1, type = IrisTreeSize.class) private KList sizes = new KList<>(); + + @Desc("If enabled, overrides trees of any size") + private boolean anySize; } \ No newline at end of file diff --git a/src/main/java/com/volmit/iris/engine/object/IrisTreeOptions.java b/src/main/java/com/volmit/iris/engine/object/IrisTreeOptions.java deleted file mode 100644 index 20cbd5881..000000000 --- a/src/main/java/com/volmit/iris/engine/object/IrisTreeOptions.java +++ /dev/null @@ -1,24 +0,0 @@ -package com.volmit.iris.engine.object; - -import com.volmit.iris.engine.object.annotations.ArrayType; -import com.volmit.iris.engine.object.annotations.Desc; -import com.volmit.iris.util.collection.KList; -import lombok.AllArgsConstructor; -import lombok.Data; -import lombok.NoArgsConstructor; -import lombok.experimental.Accessors; - -@Accessors(chain = true) -@AllArgsConstructor -@NoArgsConstructor -@Desc("Tree replace options for this object placer") -@Data -public class IrisTreeOptions { - - @Desc("Toggles this object placer's tree overrides") - private boolean enabled = false; - - @Desc("Tree overrides affected by these object placements") - @ArrayType(min = 1, type = IrisTree.class) - private KList trees = new KList<>(); -} diff --git a/src/main/java/com/volmit/iris/engine/object/IrisTreeType.java b/src/main/java/com/volmit/iris/engine/object/IrisTreeType.java deleted file mode 100644 index 1b34941a4..000000000 --- a/src/main/java/com/volmit/iris/engine/object/IrisTreeType.java +++ /dev/null @@ -1,69 +0,0 @@ -package com.volmit.iris.engine.object; - -import com.volmit.iris.engine.object.annotations.Desc; -import lombok.NoArgsConstructor; -import lombok.experimental.Accessors; -import org.bukkit.TreeType; - -@Accessors(chain = true) -@NoArgsConstructor -@Desc("Tree Types") -public enum IrisTreeType { - - @Desc("Oak tree (BIG_TREE, TREE)") - OAK, - - @Desc("Spruce tree (MEGA_REDWOOD, REDWOOD, SWAMP, TALL_REDWOOD)") - SPRUCE, - - @Desc("Birch tree (BIRCH, TALL_BIRCH)") - BIRCH, - - @Desc("Jungle tree (JUNGLE, SMALL_JUNGLE)") - JUNGLE, - - @Desc("Big red mushroom; short and fat") - RED_MUSHROOM, - - @Desc("Big brown mushroom; tall and umbrella-like") - BROWN_MUSHROOM, - - @Desc("Acacia tree") - ACACIA, - - @Desc("Dark Oak tree") - DARK_OAK, - - @Desc("Large crimson fungus native to the nether") - CRIMSON_FUNGUS, - - @Desc("Large warped fungus native to the nether") - WARPED_FUNGUS, - - @Desc("Tree with large roots which grows above lush caves") - AZALEA, - - @Desc("Any tree type (all will match, including mushrooms & nether trees") - ANY, - - @Desc("The fallback type for all other non-supported growth events") - NONE; - - public static IrisTreeType fromTreeType(TreeType type){ - return switch(type){ - case BIG_TREE, TREE -> IrisTreeType.OAK; - case MEGA_REDWOOD, REDWOOD, SWAMP, TALL_REDWOOD -> IrisTreeType.SPRUCE; - case BIRCH, TALL_BIRCH -> IrisTreeType.BIRCH; - case JUNGLE, SMALL_JUNGLE -> IrisTreeType.JUNGLE; - case RED_MUSHROOM -> IrisTreeType.RED_MUSHROOM; - case BROWN_MUSHROOM -> IrisTreeType.BROWN_MUSHROOM; - case ACACIA -> IrisTreeType.ACACIA; - case DARK_OAK -> IrisTreeType.DARK_OAK; - case CRIMSON_FUNGUS -> IrisTreeType.CRIMSON_FUNGUS; - case WARPED_FUNGUS -> IrisTreeType.WARPED_FUNGUS; - case AZALEA -> IrisTreeType.AZALEA; - //case COCOA_TREE, CHORUS_PLANT, JUNGLE_BUSH -> IrisSaplingType.NONE; - default -> IrisTreeType.NONE; - }; - } -} From 8f37dc85702da3064b0555ee7da70b37cda0d1f3 Mon Sep 17 00:00:00 2001 From: CocoTheOwner Date: Wed, 21 Jul 2021 18:24:09 +0200 Subject: [PATCH 31/41] Cleanup & fix --- src/main/java/com/volmit/iris/core/TreeManager.java | 10 ++++++++-- .../volmit/iris/engine/object/IrisObjectPlacement.java | 2 +- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/src/main/java/com/volmit/iris/core/TreeManager.java b/src/main/java/com/volmit/iris/core/TreeManager.java index c593143dc..e5ee2967c 100644 --- a/src/main/java/com/volmit/iris/core/TreeManager.java +++ b/src/main/java/com/volmit/iris/core/TreeManager.java @@ -93,7 +93,7 @@ public class TreeManager implements Listener { IrisObject object = worldAccess.getData().getObjectLoader().load(placement.getPlace().getRandom(RNG.r)); // Create object placer - IObjectPlacer placer = new IObjectPlacer(){ + IObjectPlacer placer = new IObjectPlacer() { @Override public int getHighest(int x, int z) { @@ -138,7 +138,13 @@ public class TreeManager implements Listener { @Override public int getFluidHeight() { - return ((Engine)worldAccess.getEngineAccess(event.getLocation().getBlockY())).getDimension().getFluidHeight(); + Engine engine; + if (worldAccess.getCompound().getSize() > 1) { + engine = worldAccess.getCompound().getEngine(0); + } else { + engine = (Engine) worldAccess.getCompound().getRootDimension(); + } + return engine.getDimension().getFluidHeight(); } @Override diff --git a/src/main/java/com/volmit/iris/engine/object/IrisObjectPlacement.java b/src/main/java/com/volmit/iris/engine/object/IrisObjectPlacement.java index c7f092b29..7ad941aa2 100644 --- a/src/main/java/com/volmit/iris/engine/object/IrisObjectPlacement.java +++ b/src/main/java/com/volmit/iris/engine/object/IrisObjectPlacement.java @@ -150,7 +150,7 @@ public class IrisObjectPlacement { @Desc("The loot tables to apply to these objects") private KList loot = new KList<>(); - @Desc("This objects overrides these trees when they grow...") + @Desc("This object / these objects override the following trees when they grow...") @ArrayType(min = 1, type = IrisTree.class) private KList trees = new KList<>(); From 71f067f6785422ca58e42a2863a5faae97e98332 Mon Sep 17 00:00:00 2001 From: CocoTheOwner Date: Wed, 21 Jul 2021 21:10:16 +0200 Subject: [PATCH 32/41] Next step to free sizes for saplongs --- .../com/volmit/iris/core/TreeManager.java | 6 +- .../iris/engine/object/IrisTreeSize.java | 197 ++---------------- 2 files changed, 24 insertions(+), 179 deletions(-) diff --git a/src/main/java/com/volmit/iris/core/TreeManager.java b/src/main/java/com/volmit/iris/core/TreeManager.java index e5ee2967c..7a17e1af0 100644 --- a/src/main/java/com/volmit/iris/core/TreeManager.java +++ b/src/main/java/com/volmit/iris/core/TreeManager.java @@ -75,7 +75,7 @@ public class TreeManager implements Listener { } // Find best object placement based on sizes - IrisObjectPlacement placement = getObjectPlacement(worldAccess, event.getLocation(), event.getSpecies(), null); + IrisObjectPlacement placement = getObjectPlacement(worldAccess, event.getLocation(), event.getSpecies(), new IrisTreeSize(1, 1)); // If none were found, just exit if (placement == null) { @@ -211,8 +211,8 @@ public class TreeManager implements Listener { private KList matchObjectPlacements(KList objects, IrisTreeSize size, TreeType type) { Predicate isValid = irisTree -> ( - irisTree.isAnySize() || irisTree.getSizes().stream().anyMatch(treeSize -> treeSize == IrisTreeSize.ANY || treeSize == size)) && ( - irisTree.isAnyTree() || irisTree.getTreeTypes().stream().anyMatch(treeType -> treeType == type)); + irisTree.isAnySize() || irisTree.getSizes().stream().anyMatch(treeSize -> treeSize.doesMatch(size))) && ( + irisTree.isAnyTree() || irisTree.getTreeTypes().stream().anyMatch(treeType -> treeType.equals(type))); objects.removeIf(objectPlacement -> objectPlacement.getTrees().stream().noneMatch(isValid)); diff --git a/src/main/java/com/volmit/iris/engine/object/IrisTreeSize.java b/src/main/java/com/volmit/iris/engine/object/IrisTreeSize.java index fe707e9e5..9dccad345 100644 --- a/src/main/java/com/volmit/iris/engine/object/IrisTreeSize.java +++ b/src/main/java/com/volmit/iris/engine/object/IrisTreeSize.java @@ -1,188 +1,33 @@ package com.volmit.iris.engine.object; -import com.volmit.iris.Iris; import com.volmit.iris.engine.object.annotations.Desc; -import com.volmit.iris.util.collection.KList; -import com.volmit.iris.util.collection.KMap; -import org.bukkit.Location; -import org.bukkit.Material; +import com.volmit.iris.engine.object.annotations.Required; +import lombok.AllArgsConstructor; +import lombok.Data; + import lombok.NoArgsConstructor; +import lombok.experimental.Accessors; +@Accessors(chain = true) +@NoArgsConstructor +@AllArgsConstructor @Desc("Sapling override object picking options") -public enum IrisTreeSize { +@Data +public class IrisTreeSize { - @Desc("Only one sapling") - ONE, + @Required + @Desc("The width of the sapling area") + int width = 1; - @Desc("Two by two area") - TWO, - - @Desc("Three by three any location") - THREE_ANY, - - @Desc("Three by three area with center") - THREE_CENTER, - - @Desc("Four by four") - FOUR, - - @Desc("Five by five") - FIVE_ANY, - - @Desc("Five by five center") - FIVE_CENTER, - - @Desc("Any size") - ANY; + @Required + @Desc("The depth of the sapling area") + int depth = 1; /** - * All sizes in this enum + * Does the size match + * @param size the size to check match + * @return true if it matches (fits within width and depth) */ - public static final KList sizes = new KList<>(ONE, TWO, THREE_ANY, THREE_CENTER, FOUR, FIVE_ANY, FIVE_CENTER); - - /** - * Get the best size to match against from a list of sizes - * @param sizes The list of sizes - * @return The best size (highest & center > any) - */ - public static IrisTreeSize bestSizeInSizes(KList sizes){ - if (sizes.contains(ANY)){ - return ANY; - } - else if (sizes.contains(FIVE_CENTER)){ - return FIVE_CENTER; - } - else if (sizes.contains(FIVE_ANY)){ - return FIVE_ANY; - } - else if (sizes.contains(FOUR)){ - return FOUR; - } - else if (sizes.contains(THREE_CENTER)){ - return THREE_CENTER; - } - else if (sizes.contains(THREE_ANY)){ - return THREE_ANY; - } - else if (sizes.contains(TWO)){ - return TWO; - } - else if (sizes.contains(ONE)){ - return ONE; - } else { - return null; - } - } - - /** - * Check if the size at a specific location is valid - * @param size the IrisTreeSize to check - * @param location at this location - * @return A list of locations if any match, or null if not. - */ - public static KList> getPlacesIfValid (IrisTreeSize size, Location location) { - if (size == ANY){ - Iris.debug("ANY was passed to getPlacesIfValid while it should never!"); - } - return switch (size){ - case ONE -> new KList>(new KList<>(location)); - case TWO -> loopLocation(location, 2); - case THREE_ANY -> loopLocation(location, 3); - case FOUR -> loopLocation(location, 4); - case FIVE_ANY -> loopLocation(location, 5); - case THREE_CENTER -> isCenterMapValid(location, 3); - case FIVE_CENTER -> isCenterMapValid(location, 5); - case ANY -> null; - }; - } - - /** - * Check a map with - * @param center this block location as a center - * @param size with this size map - * @return A 2d KList of locations or null - */ - private static KList> isCenterMapValid(Location center, int size) { - KList> locations = getMap(size, center, true); - return isMapValid(locations, center.getBlock().getType()) ? locations : null; - } - - - /** - * Loops over all possible squares based on - * @param center center position - * @param size a square size - * @return A list of matching locations, or null. - */ - private static KList> loopLocation(Location center, int size){ - Material blockType = center.getBlock().getType(); - KList> locations; - for (int i = -size + 1; i <= 0; i++){ - for (int j = -size + 1; j <= 0; j++){ - locations = getMap(size, center.clone().add(i, 0, j)); - if (isMapValid(locations, blockType)){ - return locations; - } - } - } - return null; - } - - /** - * Get if the map is valid, compared to a block material - * @param map The map to check inside of - * @param block The block material to check with - * @return True if it's valid - */ - private static boolean isMapValid(KList> map, Material block){ - if (map == null) return false; - return map.stream().allMatch(row -> row.stream().allMatch(location -> location.getBlock().getType().equals(block))); - } - - /** - * Get a map with all blocks in a - * @param size `size * size` square area - * @param leftTop starting from the here - * @return A map with all block locations in the area - */ - private static KList> getMap(int size, Location leftTop){ - KList> locations = new KList<>(); - for (int i = 0; i < size; i++){ - KList row = new KList<>(); - for (int j = 0; j < size; j++){ - row.add(leftTop.clone().add(i, 0, j)); - } - locations.add(row); - } - return locations; - } - - /** - * Get a map with all blocks in a - * @param size `size * size` square to check, must be odd (returns null if not) - * @param center from a center - * @param useCenter boolean toggle to call this function over IrisTreeSize#getMap(size, leftTop) - * @return A map with all block locations in the area - */ - private static KList> getMap(int size, Location center, boolean useCenter){ - if (size % 2 != 1){ - return null; - } - return getMap(size, center.clone().add(-(size - 1) / 2d, 0, -(size - 1) / 2d)); - } - - /** - * Get sizes hash with size -> location map - * @param location the location to search from - * @return A hash with IrisTreeSize -> KList-KList-Location - */ - public static KMap>> getValidSizes(Location location) { - KMap>> sizes = new KMap<>(); - IrisTreeSize.sizes.forEach(size -> { - KList> locations = getPlacesIfValid(size, location); - if (locations != null){ - sizes.put(size, locations); - } - }); - return sizes; + public boolean doesMatch(IrisTreeSize size){ + return (width <= size.getWidth() && depth <= size.getDepth()) || (depth <= size.getWidth() && width <= size.getDepth()); } } From e5165e6fba8e14da09eaa9680548ebeb82469cd9 Mon Sep 17 00:00:00 2001 From: CocoTheOwner Date: Thu, 22 Jul 2021 16:25:24 +0200 Subject: [PATCH 33/41] add some todos --- src/main/java/com/volmit/iris/core/TreeManager.java | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/src/main/java/com/volmit/iris/core/TreeManager.java b/src/main/java/com/volmit/iris/core/TreeManager.java index 7a17e1af0..7d3a49332 100644 --- a/src/main/java/com/volmit/iris/core/TreeManager.java +++ b/src/main/java/com/volmit/iris/core/TreeManager.java @@ -83,9 +83,6 @@ public class TreeManager implements Listener { return; } - // Cancel the placement - event.setCancelled(true); - // Delete existing saplings saplingPlane.forEach(block -> block.setType(Material.AIR)); @@ -158,6 +155,13 @@ public class TreeManager implements Listener { } }; + // TODO: Prevent placing on claimed blocks (however that's defined, idk) + + // TODO: Prevent placing object when overriding blocks + + // Cancel the vanilla placement + event.setCancelled(true); + // Place the object with the placer object.place( saplingPlane.getCenter(), From 09f830c315383abb8708498535853c61aeedfcef Mon Sep 17 00:00:00 2001 From: CocoTheOwner Date: Thu, 22 Jul 2021 23:40:25 +0200 Subject: [PATCH 34/41] patch faulty null exit --- src/main/java/com/volmit/iris/core/TreeManager.java | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/src/main/java/com/volmit/iris/core/TreeManager.java b/src/main/java/com/volmit/iris/core/TreeManager.java index 7d3a49332..04c2bdd4a 100644 --- a/src/main/java/com/volmit/iris/core/TreeManager.java +++ b/src/main/java/com/volmit/iris/core/TreeManager.java @@ -67,12 +67,7 @@ public class TreeManager implements Listener { // Calculate size, type & placement Cuboid saplingPlane = getSaplings(event.getLocation(), blockData -> event.getLocation().getBlock().getBlockData().equals(blockData), event.getWorld()); - - // Check if any were returned - if (saplingPlane == null) { - Iris.debug(this.getClass().getName() + " found no matching sapling sizes for the grow event, which should be impossible (considering the one that grew is an option)"); - return; - } + Iris.debug("Sapling plane is: " + saplingPlane.getSizeX() + " by " + saplingPlane.getSizeZ()); // Find best object placement based on sizes IrisObjectPlacement placement = getObjectPlacement(worldAccess, event.getLocation(), event.getSpecies(), new IrisTreeSize(1, 1)); @@ -183,16 +178,19 @@ public class TreeManager implements Listener { private IrisObjectPlacement getObjectPlacement(IrisAccess worldAccess, Location location, TreeType type, IrisTreeSize size) { KList placements = new KList<>(); + KList allObjects = new KList<>(); boolean isUseAll = ((Engine)worldAccess.getEngineAccess(location.getBlockY())).getDimension().getTreeSettings().getMode().equals(IrisTreeModes.ALL); // Retrieve objectPlacements of type `species` from biome IrisBiome biome = worldAccess.getBiome(location.getBlockX(), location.getBlockY(), location.getBlockZ()); placements.addAll(matchObjectPlacements(biome.getObjects(), size, type)); + allObjects.addAll(biome.getObjects()); // Add more or find any in the region if (isUseAll || placements.isEmpty()){ IrisRegion region = worldAccess.getCompound().getDefaultEngine().getRegion(location.getBlockX(), location.getBlockZ()); placements.addAll(matchObjectPlacements(region.getObjects(), size, type)); + allObjects.addAll(region.getObjects()); } // TODO: Add more or find any in the dimension @@ -277,7 +275,7 @@ public class TreeManager implements Listener { cuboidIsValid = true; } - return null; + return new Cuboid(at, at); } /** From 48f57068d8bb69bf9d177c7243ba3581f5667656 Mon Sep 17 00:00:00 2001 From: CocoTheOwner Date: Sun, 25 Jul 2021 23:17:19 +0200 Subject: [PATCH 35/41] width & depth must be equal, not smaller --- src/main/java/com/volmit/iris/engine/object/IrisTreeSize.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/com/volmit/iris/engine/object/IrisTreeSize.java b/src/main/java/com/volmit/iris/engine/object/IrisTreeSize.java index 9dccad345..a92dc375d 100644 --- a/src/main/java/com/volmit/iris/engine/object/IrisTreeSize.java +++ b/src/main/java/com/volmit/iris/engine/object/IrisTreeSize.java @@ -28,6 +28,6 @@ public class IrisTreeSize { * @return true if it matches (fits within width and depth) */ public boolean doesMatch(IrisTreeSize size){ - return (width <= size.getWidth() && depth <= size.getDepth()) || (depth <= size.getWidth() && width <= size.getDepth()); + return (width == size.getWidth() && depth == size.getDepth()) || (depth == size.getWidth() && width == size.getDepth()); } } From 83a89427249661d2e29548967a06613ceed63587 Mon Sep 17 00:00:00 2001 From: CocoTheOwner Date: Sun, 25 Jul 2021 23:21:43 +0200 Subject: [PATCH 36/41] ok --- src/main/java/com/volmit/iris/engine/object/IrisTreeSize.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/com/volmit/iris/engine/object/IrisTreeSize.java b/src/main/java/com/volmit/iris/engine/object/IrisTreeSize.java index a92dc375d..d089f5158 100644 --- a/src/main/java/com/volmit/iris/engine/object/IrisTreeSize.java +++ b/src/main/java/com/volmit/iris/engine/object/IrisTreeSize.java @@ -4,7 +4,7 @@ import com.volmit.iris.engine.object.annotations.Desc; import com.volmit.iris.engine.object.annotations.Required; import lombok.AllArgsConstructor; import lombok.Data; - import lombok.NoArgsConstructor; +import lombok.NoArgsConstructor; import lombok.experimental.Accessors; @Accessors(chain = true) From 74318fb3c0f8f0ffa327ecfab154c9a82beeb3f9 Mon Sep 17 00:00:00 2001 From: CocoTheOwner Date: Sun, 25 Jul 2021 23:36:12 +0200 Subject: [PATCH 37/41] Call new bukkit event with the grow event data from here --- src/main/java/com/volmit/iris/core/TreeManager.java | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/main/java/com/volmit/iris/core/TreeManager.java b/src/main/java/com/volmit/iris/core/TreeManager.java index 04c2bdd4a..233cb0663 100644 --- a/src/main/java/com/volmit/iris/core/TreeManager.java +++ b/src/main/java/com/volmit/iris/core/TreeManager.java @@ -14,12 +14,14 @@ import com.volmit.iris.util.math.RNG; import com.volmit.iris.util.math.Vector2d; import org.bukkit.*; import org.bukkit.block.Block; +import org.bukkit.block.BlockState; import org.bukkit.block.TileState; import org.bukkit.block.data.BlockData; import org.bukkit.event.EventHandler; import org.bukkit.event.Listener; import org.bukkit.event.world.StructureGrowEvent; +import java.util.List; import java.util.Objects; import java.util.function.Predicate; @@ -157,6 +159,12 @@ public class TreeManager implements Listener { // Cancel the vanilla placement event.setCancelled(true); + // Send out a new event + List blockStateList = new KList<>(); + saplingPlane.forEach(b -> blockStateList.add(b.getState())); + StructureGrowEvent iGrow = new StructureGrowEvent(event.getLocation(), event.getSpecies(), event.isFromBonemeal(), event.getPlayer(), blockStateList); + Bukkit.getServer().getPluginManager().callEvent(iGrow); + // Place the object with the placer object.place( saplingPlane.getCenter(), From c80edcfe9f078f736d7182441db5a0772c34cca4 Mon Sep 17 00:00:00 2001 From: CocoTheOwner Date: Sun, 25 Jul 2021 23:37:29 +0200 Subject: [PATCH 38/41] Patch set command (I get what you mean now) --- src/main/java/com/volmit/iris/core/TreeManager.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/com/volmit/iris/core/TreeManager.java b/src/main/java/com/volmit/iris/core/TreeManager.java index 233cb0663..e8253f78e 100644 --- a/src/main/java/com/volmit/iris/core/TreeManager.java +++ b/src/main/java/com/volmit/iris/core/TreeManager.java @@ -107,7 +107,7 @@ public class TreeManager implements Listener { b.setBlockData(d, false); // Tell bukkit what you're doing here - //TODO event.getBlockStates().add(b.getState()); + event.getBlocks().add(b.getState()); } @Override From 80545ce1f209c66d1ad4d4f960b0822690ad387c Mon Sep 17 00:00:00 2001 From: CocoTheOwner Date: Sun, 25 Jul 2021 23:40:38 +0200 Subject: [PATCH 39/41] 1 more todo --- src/main/java/com/volmit/iris/core/TreeManager.java | 1 + 1 file changed, 1 insertion(+) diff --git a/src/main/java/com/volmit/iris/core/TreeManager.java b/src/main/java/com/volmit/iris/core/TreeManager.java index e8253f78e..2b5b9fe77 100644 --- a/src/main/java/com/volmit/iris/core/TreeManager.java +++ b/src/main/java/com/volmit/iris/core/TreeManager.java @@ -68,6 +68,7 @@ public class TreeManager implements Listener { Iris.debug("Sapling grew @ " + event.getLocation() + " for " + event.getSpecies().name() + " usedBoneMeal is " + event.isFromBonemeal()); // Calculate size, type & placement + // TODO: Patch algorithm to retrieve saplings, as it's not working as intended (only ever returns 1x1) Cuboid saplingPlane = getSaplings(event.getLocation(), blockData -> event.getLocation().getBlock().getBlockData().equals(blockData), event.getWorld()); Iris.debug("Sapling plane is: " + saplingPlane.getSizeX() + " by " + saplingPlane.getSizeZ()); From 696cf61fe9e11788d819bfe771180329b2b704d1 Mon Sep 17 00:00:00 2001 From: CocoTheOwner Date: Mon, 26 Jul 2021 20:02:59 +0200 Subject: [PATCH 40/41] Remove log on creation --- src/main/java/com/volmit/iris/core/TreeManager.java | 1 - 1 file changed, 1 deletion(-) diff --git a/src/main/java/com/volmit/iris/core/TreeManager.java b/src/main/java/com/volmit/iris/core/TreeManager.java index 2b5b9fe77..f683bc098 100644 --- a/src/main/java/com/volmit/iris/core/TreeManager.java +++ b/src/main/java/com/volmit/iris/core/TreeManager.java @@ -29,7 +29,6 @@ public class TreeManager implements Listener { public TreeManager() { Iris.instance.registerListener(this); - Iris.info("Loading Sapling Manager"); } /**This function does the following From 68e6bd668cfda89ea30936e695e877fbeea4bff4 Mon Sep 17 00:00:00 2001 From: CocoTheOwner Date: Mon, 26 Jul 2021 20:20:49 +0200 Subject: [PATCH 41/41] Sync grow event, patch set fnction, path blockstateslist --- .../com/volmit/iris/core/TreeManager.java | 41 ++++++++++++------- 1 file changed, 26 insertions(+), 15 deletions(-) diff --git a/src/main/java/com/volmit/iris/core/TreeManager.java b/src/main/java/com/volmit/iris/core/TreeManager.java index f683bc098..f50581dc3 100644 --- a/src/main/java/com/volmit/iris/core/TreeManager.java +++ b/src/main/java/com/volmit/iris/core/TreeManager.java @@ -12,6 +12,7 @@ import com.volmit.iris.util.data.Cuboid; import com.volmit.iris.util.math.BlockPosition; import com.volmit.iris.util.math.RNG; import com.volmit.iris.util.math.Vector2d; +import com.volmit.iris.util.scheduling.J; import org.bukkit.*; import org.bukkit.block.Block; import org.bukkit.block.BlockState; @@ -86,6 +87,10 @@ public class TreeManager implements Listener { // Get object from placer IrisObject object = worldAccess.getData().getObjectLoader().load(placement.getPlace().getRandom(RNG.r)); + // List of new blocks + List blockStateList = new KList<>(); + saplingPlane.forEach(b -> blockStateList.add(b.getState())); + // Create object placer IObjectPlacer placer = new IObjectPlacer() { @@ -102,12 +107,9 @@ public class TreeManager implements Listener { @Override public void set(int x, int y, int z, BlockData d) { Block b = event.getWorld().getBlockAt(x, y, z); - - // Set the block - b.setBlockData(d, false); - - // Tell bukkit what you're doing here - event.getBlocks().add(b.getState()); + BlockState state = b.getState(); + state.setBlockData(d); + blockStateList.add(b.getState()); } @Override @@ -156,15 +158,6 @@ public class TreeManager implements Listener { // TODO: Prevent placing object when overriding blocks - // Cancel the vanilla placement - event.setCancelled(true); - - // Send out a new event - List blockStateList = new KList<>(); - saplingPlane.forEach(b -> blockStateList.add(b.getState())); - StructureGrowEvent iGrow = new StructureGrowEvent(event.getLocation(), event.getSpecies(), event.isFromBonemeal(), event.getPlayer(), blockStateList); - Bukkit.getServer().getPluginManager().callEvent(iGrow); - // Place the object with the placer object.place( saplingPlane.getCenter(), @@ -173,6 +166,24 @@ public class TreeManager implements Listener { RNG.r, Objects.requireNonNull(worldAccess).getData() ); + + // Cancel the vanilla placement + event.setCancelled(true); + + // Queue sync task + J.s(() -> { + + // Send out a new event + StructureGrowEvent iGrow = new StructureGrowEvent(event.getLocation(), event.getSpecies(), event.isFromBonemeal(), event.getPlayer(), blockStateList); + Bukkit.getServer().getPluginManager().callEvent(iGrow); + + // Check if blocks need to be updated + if(!iGrow.isCancelled()){ + for (BlockState block : iGrow.getBlocks()) { + block.update(true, false); + } + } + }); } /**