diff --git a/plugin/src/main/java/com/alttd/cometskyblock/CometSkyBlockPlugin.java b/plugin/src/main/java/com/alttd/cometskyblock/CometSkyBlockPlugin.java index aaf75f4..f23165d 100644 --- a/plugin/src/main/java/com/alttd/cometskyblock/CometSkyBlockPlugin.java +++ b/plugin/src/main/java/com/alttd/cometskyblock/CometSkyBlockPlugin.java @@ -8,6 +8,8 @@ import com.alttd.cometskyblock.commands.island.IslandCommand; import com.alttd.cometskyblock.configuration.*; import com.alttd.cometskyblock.gui.GUIListener; import com.alttd.cometskyblock.island.IslandData; +import com.alttd.cometskyblock.island.oregenerator.GeneratorHandler; +import com.alttd.cometskyblock.island.oregenerator.GeneratorLoader; import com.alttd.cometskyblock.listeners.BedListener; import com.alttd.cometskyblock.listeners.CobbestoneGeneratorListener; import com.alttd.cometskyblock.listeners.PlayerJoinListener; @@ -28,13 +30,14 @@ public class CometSkyBlockPlugin extends JavaPlugin implements CometSkyBlockAPI @Getter private ConfigurationContainer pluginConfiguration; @Getter private ConfigurationContainer databaseConfiguration; @Getter private ConfigurationContainer messagesConfiguration; - @Getter private ConfigurationContainer cobblestoneGeneratorConfiguration; @Getter private ConfigurationContainer worldBorderConfiguration; @Getter private IslandManager islandManager; @Getter private MasterWorldGenerator worldGenerator; @Getter private ChallengeHandler challengeHandler; @Getter private ChallengeLoader challengeLoader; + @Getter private GeneratorLoader generatorLoader; + @Getter private GeneratorHandler generatorHandler; @Override public void onLoad() { @@ -66,6 +69,8 @@ public class CometSkyBlockPlugin extends JavaPlugin implements CometSkyBlockAPI worldGenerator = new MasterWorldGenerator(this); challengeHandler = new ChallengeHandler(this); loadChallenges(); + generatorHandler = new GeneratorHandler(this); + new GeneratorLoader(this).loadAllGenerators(); worldGenerator.checkMasterIslandWorld(); } @@ -90,7 +95,6 @@ public class CometSkyBlockPlugin extends JavaPlugin implements CometSkyBlockAPI pluginConfiguration = ConfigurationContainer.load(logger, path, PluginConfiguration.class, "config"); databaseConfiguration = ConfigurationContainer.load(logger, path, DatabaseConfiguration.class, "database"); messagesConfiguration = ConfigurationContainer.load(logger, path, MessageConfiguration.class, "messages"); - cobblestoneGeneratorConfiguration = ConfigurationContainer.load(logger, path, CobblestoneGeneratorConfiguration.class, "coblestonegenerator"); worldBorderConfiguration = ConfigurationContainer.load(logger, path, WorldBorderConfiguration.class, "worldborder"); } diff --git a/plugin/src/main/java/com/alttd/cometskyblock/configuration/CobblestoneGeneratorConfiguration.java b/plugin/src/main/java/com/alttd/cometskyblock/configuration/CobblestoneGeneratorConfiguration.java deleted file mode 100644 index 344077a..0000000 --- a/plugin/src/main/java/com/alttd/cometskyblock/configuration/CobblestoneGeneratorConfiguration.java +++ /dev/null @@ -1,16 +0,0 @@ -package com.alttd.cometskyblock.configuration; - -import com.alttd.cometskyblock.island.CobblestoneGeneratorLevel; -import lombok.Getter; -import org.spongepowered.configurate.objectmapping.ConfigSerializable; - -import java.util.ArrayList; -import java.util.List; - -@Getter -@ConfigSerializable -@SuppressWarnings({"CanBeFinal", "FieldMayBeFinal"}) -public class CobblestoneGeneratorConfiguration implements Configuration { - - private List levels = new ArrayList<>(); -} diff --git a/plugin/src/main/java/com/alttd/cometskyblock/island/CobblestoneGeneratorLevel.java b/plugin/src/main/java/com/alttd/cometskyblock/island/CobblestoneGeneratorLevel.java deleted file mode 100644 index 8c2da37..0000000 --- a/plugin/src/main/java/com/alttd/cometskyblock/island/CobblestoneGeneratorLevel.java +++ /dev/null @@ -1,24 +0,0 @@ -package com.alttd.cometskyblock.island; - -import lombok.Getter; -import org.bukkit.Material; -import org.spongepowered.configurate.objectmapping.ConfigSerializable; - -@Getter -@ConfigSerializable -public class CobblestoneGeneratorLevel { - - private int level; - private int islandLevel; - private Material type; - private double chance; - - @Override - public String toString() { - return "CobblestoneGeneratorLevel:" + - " level: " + level + - " islandLevel: " + islandLevel + - " type: " + type.toString() + - " chane: " + chance; - } -} diff --git a/plugin/src/main/java/com/alttd/cometskyblock/island/Island.java b/plugin/src/main/java/com/alttd/cometskyblock/island/Island.java index 1cd42aa..b44b8d6 100644 --- a/plugin/src/main/java/com/alttd/cometskyblock/island/Island.java +++ b/plugin/src/main/java/com/alttd/cometskyblock/island/Island.java @@ -1,11 +1,11 @@ package com.alttd.cometskyblock.island; import com.alttd.cometskyblock.CometSkyBlockPlugin; +import com.alttd.cometskyblock.island.oregenerator.GeneratorTier; import com.alttd.cometskyblock.records.IslandRecord; import com.alttd.cometskyblock.request.Request; import lombok.Getter; import lombok.Setter; -import net.kyori.adventure.text.minimessage.tag.resolver.Placeholder; import net.kyori.adventure.text.minimessage.tag.resolver.TagResolver; import org.bukkit.Bukkit; import org.bukkit.Location; @@ -14,7 +14,6 @@ import org.bukkit.configuration.file.YamlConfiguration; import org.bukkit.entity.Player; import org.bukkit.potion.PotionEffect; import org.bukkit.potion.PotionEffectType; -import org.jetbrains.annotations.NotNull; import java.io.File; import java.util.*; @@ -188,15 +187,6 @@ public class Island extends YamlConfiguration { return true; } - public int cobblegenLevel() { - return getInt("island.generator.level", 0); - } - - public void cobblegenLevel(int level) { - set("island.generator.level", level); - save(); - } - public int worldBorderLevel() { return getInt("island.worldborder.level", 0); } @@ -261,4 +251,22 @@ public class Island extends YamlConfiguration { set("challenges." + key, amount); save(); } + + public int oreGeneratorLevel(GeneratorTier generatorTier) { + return getInt("generator-level." + generatorTier.toString().toLowerCase(), 0); + } + + public void oreGeneratorLevel(GeneratorTier generatorTier, int level) { + set("generator-level." + generatorTier.toString().toLowerCase(), level); + save(); + } + + public boolean unlockedGeneratorTier(GeneratorTier generatorTier) { + switch (generatorTier) { + case COBBLESTONE, BASALT -> { + return true; + } + } + return contains("generator-level." + generatorTier.toString().toLowerCase(), true); + } } diff --git a/plugin/src/main/java/com/alttd/cometskyblock/island/gui/UpgradesGUI.java b/plugin/src/main/java/com/alttd/cometskyblock/island/gui/UpgradesGUI.java index 229886d..cb07203 100644 --- a/plugin/src/main/java/com/alttd/cometskyblock/island/gui/UpgradesGUI.java +++ b/plugin/src/main/java/com/alttd/cometskyblock/island/gui/UpgradesGUI.java @@ -3,9 +3,9 @@ package com.alttd.cometskyblock.island.gui; import com.alttd.cometskyblock.CometSkyBlockPlugin; import com.alttd.cometskyblock.configuration.MessageConfiguration; import com.alttd.cometskyblock.gui.GUIInventory; -import com.alttd.cometskyblock.island.CobblestoneGeneratorLevel; import com.alttd.cometskyblock.island.Island; import com.alttd.cometskyblock.island.WorldBorderLevel; +import com.alttd.cometskyblock.island.oregenerator.GeneratorGUI; import com.alttd.cometskyblock.util.Experience; import net.kyori.adventure.text.minimessage.MiniMessage; import net.kyori.adventure.text.minimessage.tag.resolver.Placeholder; @@ -59,20 +59,9 @@ public class UpgradesGUI extends GUIInventory { decorate(player); })); // Cobble Gen - addButton(11, createMenuButton(Material.COBBLESTONE, "Upgrade your cobble stone generator", List.of( - "Level: " + island.cobblegenLevel() + "", - "Ore tier: " + getOreTier(island.cobblegenLevel()) + "", - "Next tier: " + getOreTier(island.cobblegenLevel() + 1) + "" - ), event -> { - int requiredIslandLevel = getRequiredIslandCobbleLevel(island.cobblegenLevel() + 1); - if (island.level() < requiredIslandLevel) { - player.sendRichMessage(islandMessages.cobbeGen().requiredLevel(), Placeholder.parsed("islandlevel", "" + requiredIslandLevel + "")); - return; - } - island.cobblegenLevel(island.cobblegenLevel() + 1); - island.broadCast(islandMessages.cobbeGen().upgraded(), Placeholder.parsed("level", "" + island.cobblegenLevel() + "")); + addButton(11, createMenuButton(Material.COBBLESTONE, "Upgrade your ore generators", new ArrayList<>(), event -> { player.closeInventory(); - decorate(player); + new GeneratorGUI(island).open(player); })); // Level addButton(12, createMenuButton(Material.EXPERIENCE_BOTTLE, "Increase your island level", List.of( @@ -96,32 +85,6 @@ public class UpgradesGUI extends GUIInventory { super.decorate(player); } - Integer getRequiredIslandCobbleLevel(int generatorLevel) { - CobblestoneGeneratorLevel level = getLevel(generatorLevel); - return level != null ? level.islandLevel() : 0; - } - - CobblestoneGeneratorLevel getLevel(int generatorLevel) { - if (generatorLevel == 0) { - return null; - } - CometSkyBlockPlugin plugin = CometSkyBlockPlugin.instance(); - if (plugin.cobblestoneGeneratorConfiguration().get().levels().size() < generatorLevel) { - return null; - } - for (CobblestoneGeneratorLevel level : plugin.cobblestoneGeneratorConfiguration().get().levels()) { - if (level.level() == generatorLevel) { - return level; - } - } - return null; - } - - Material getOreTier(int generatorLevel) { - CobblestoneGeneratorLevel level = getLevel(generatorLevel); - return level != null ? level.type() : Material.COBBLESTONE; - } - Integer getRequiredIslandWorldBorderLevel(int generatorLevel) { WorldBorderLevel level = getWorldBorderLevel(generatorLevel); return level != null ? level.islandLevel() : 0; diff --git a/plugin/src/main/java/com/alttd/cometskyblock/island/oregenerator/GeneratorGUI.java b/plugin/src/main/java/com/alttd/cometskyblock/island/oregenerator/GeneratorGUI.java new file mode 100644 index 0000000..247b4c3 --- /dev/null +++ b/plugin/src/main/java/com/alttd/cometskyblock/island/oregenerator/GeneratorGUI.java @@ -0,0 +1,136 @@ +package com.alttd.cometskyblock.island.oregenerator; + +import com.alttd.cometskyblock.CometSkyBlockPlugin; +import com.alttd.cometskyblock.gui.GUIButton; +import com.alttd.cometskyblock.gui.GUIInventory; +import com.alttd.cometskyblock.island.Island; +import com.alttd.cometskyblock.util.PlayerUtils; +import it.unimi.dsi.fastutil.objects.Object2IntMap; +import net.kyori.adventure.text.Component; +import net.kyori.adventure.text.minimessage.MiniMessage; +import net.kyori.adventure.text.minimessage.tag.resolver.Placeholder; +import net.kyori.adventure.text.minimessage.tag.resolver.TagResolver; +import org.bukkit.Bukkit; +import org.bukkit.Material; +import org.bukkit.enchantments.Enchantment; +import org.bukkit.entity.Player; +import org.bukkit.event.inventory.InventoryClickEvent; +import org.bukkit.inventory.Inventory; +import org.bukkit.inventory.ItemFlag; +import org.bukkit.inventory.ItemStack; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.Map; +import java.util.function.Consumer; + +public class GeneratorGUI extends GUIInventory { + + public GeneratorGUI(Island island) { + super(island); + } + + @Override + protected Inventory createInventory() { // TODO - config + return Bukkit.createInventory(this, 36, MiniMessage.miniMessage().deserialize("Island - Ore Generator upgrades")); + } + + @Override + public void decorate(Player player) { + resetButtons(); + makeMenuBar(player); + currentSlot = 0; + int startIndex = pageIndex * (getInventory().getSize() - 9); + List generators = Arrays.stream(GeneratorTier.values()).toList(); + for (int i = startIndex; i < generators.size(); i++) { + GeneratorTier generatorTier = generators.get(i); + GUIButton guiButton = createGeneratorButton(generatorTier, event -> { + int requiredLevel = CometSkyBlockPlugin.instance().generatorHandler().requiredLevel(generatorTier); + boolean hasRequiredLevel = island.level() >= requiredLevel; + if (!hasRequiredLevel) { + player.sendRichMessage("You need island level to unlock this ore generator.", Placeholder.unparsed("level", requiredLevel + "")); + return; + } + int generatorLevel = island.oreGeneratorLevel(generatorTier); + TagResolver placeholders = TagResolver.resolver( + Placeholder.unparsed("generatortier", generatorTier.name().toLowerCase()), + Placeholder.unparsed("level", generatorLevel + 1 + "") + ); + if (!island.unlockedGeneratorTier(generatorTier)) { + island.oreGeneratorLevel(generatorTier, 0); + this.decorate(player); + island.broadCast("You have unlocked ore generator.", placeholders); + return; + } + if (generatorTier.generatorLevel(generatorLevel + 1).level() == generatorLevel) { + player.sendRichMessage("This ore generator has no upgrades available."); + return; + } + if (!PlayerUtils.hasRequiredItems(player.getInventory(), generatorTier.upgradeCost(generatorLevel + 1))) { + player.sendRichMessage("You do not have the required items to perform this upgrade."); + return; + } + PlayerUtils.takeRequiredItems(player.getInventory(), generatorTier.upgradeCost(generatorLevel + 1)); + island.oreGeneratorLevel(generatorTier, generatorLevel + 1); + island.broadCast("Your ore generator has been upgraded to level .", placeholders); + this.decorate(player); + }); + + if (!addItem(guiButton)) { + createNextPageButton(player); + break; + } + } + if (pageIndex > 0) { + createPrevPageButton(player); + } + super.decorate(player); + } + + private GUIButton createGeneratorButton(GeneratorTier generatorTier, Consumer eventConsumer) { + return new GUIButton() + .creator(player -> { + int generatorLevel = island.oreGeneratorLevel(generatorTier); + ItemStack itemStack = new ItemStack(generatorTier.ore(), Math.min(Math.max(1, generatorLevel), 64)); + itemStack.editMeta(meta -> { + MiniMessage miniMessage = MiniMessage.miniMessage(); + meta.displayName(miniMessage.deserialize(generatorTier.name().toLowerCase())); + int requiredLevel = CometSkyBlockPlugin.instance().generatorHandler().requiredLevel(generatorTier); + boolean hasRequiredLevel = island.level() >= requiredLevel; + List lore = new ArrayList<>(); + meta.addItemFlags(ItemFlag.values()); + TagResolver placeholders = TagResolver.resolver( + Placeholder.unparsed("requiredlevel", requiredLevel + ""), + Placeholder.unparsed("level", generatorLevel + ""), + Placeholder.unparsed("chance", generatorTier.generatorLevel(generatorLevel).chance() + ""), + Placeholder.unparsed("nextchance", generatorTier.generatorLevel(generatorLevel + 1).chance() + "") + ); + if (!hasRequiredLevel) { + lore.add(miniMessage.deserialize("You need island level to unlock this.", placeholders)); + meta.lore(lore); + return; + } + if (!island.unlockedGeneratorTier(generatorTier)) { + lore.add(miniMessage.deserialize("Click to unlock!", placeholders)); + meta.lore(lore); + return; + } + meta.addEnchant(Enchantment.MENDING, 1, true); + lore.add(miniMessage.deserialize("Level: ", placeholders)); + lore.add(miniMessage.deserialize("Chance: ", placeholders)); + if (generatorTier.generatorLevel(generatorLevel + 1).level() > generatorLevel) { + lore.add(miniMessage.deserialize("Next chance: ", placeholders)); + lore.add(miniMessage.deserialize("Upgrade cost: ", placeholders)); + Object2IntMap upgradeCost = generatorTier.upgradeCost(generatorLevel + 1); + for (Map.Entry entry : upgradeCost.object2IntEntrySet()) { + lore.add(miniMessage.deserialize("" + entry.getKey().name().toLowerCase().replace("_", " ") + ": " + entry.getValue(), placeholders)); + } + } + meta.lore(lore); + }); + return itemStack; + }) + .consumer(eventConsumer); + } +} diff --git a/plugin/src/main/java/com/alttd/cometskyblock/island/oregenerator/GeneratorHandler.java b/plugin/src/main/java/com/alttd/cometskyblock/island/oregenerator/GeneratorHandler.java new file mode 100644 index 0000000..111477d --- /dev/null +++ b/plugin/src/main/java/com/alttd/cometskyblock/island/oregenerator/GeneratorHandler.java @@ -0,0 +1,93 @@ +package com.alttd.cometskyblock.island.oregenerator; + +import com.alttd.cometskyblock.CometSkyBlockPlugin; +import com.alttd.cometskyblock.island.Island; +import it.unimi.dsi.fastutil.objects.Object2IntMap; +import it.unimi.dsi.fastutil.objects.Object2IntOpenHashMap; +import org.bukkit.Material; + +public class GeneratorHandler { + + private final Object2IntMap generatorLevels = new Object2IntOpenHashMap<>(); + + private final CometSkyBlockPlugin plugin; + + public GeneratorHandler(CometSkyBlockPlugin plugin) { + this.plugin = plugin; + generatorLevels.defaultReturnValue(0); + } + + + public void addGeneratorLevel(GeneratorTier tier, Integer level) { + generatorLevels.putIfAbsent(tier, level); + } + + public int requiredLevel(GeneratorTier tier) { + return generatorLevels.getInt(tier); + } + + public Material generateOre(Island island, boolean cobblestone, int depth) { + boolean deepslate = depth <= 16 && cobblestone; + Material ore = rollGenerator(island, cobblestone); + return deepslate ? deepslateVariant(ore) : ore; + } + + private Material rollGenerator(Island island, boolean cobblestone) { + double random = Math.random() * 100; + double checkedChance = 0; + + for(GeneratorTier generatorTier : GeneratorTier.values()) { + switch (generatorTier) { + case COBBLESTONE, BASALT -> { + continue; + } + } + if (!island.unlockedGeneratorTier(generatorTier) || generatorTier.isCobbleStoneGenerator() != cobblestone) + continue; + + GeneratorLevel generatorLevel = generatorTier.generatorLevel(island.oreGeneratorLevel(generatorTier)); + checkedChance += generatorLevel.chance(); + if (checkedChance > random) { + return generatorTier.ore(); + } + } + + return cobblestone ? Material.COBBLESTONE : Material.BASALT; + } + + public Material deepslateVariant(Material material) { + switch (material) { + case COBBLESTONE -> { + return Material.DEEPSLATE; + } + case COAL_ORE -> { + return Material.DEEPSLATE_COAL_ORE; + } + case IRON_ORE -> { + return Material.DEEPSLATE_IRON_ORE; + } + case COPPER_ORE -> { + return Material.DEEPSLATE_COPPER_ORE; + } + case GOLD_ORE -> { + return Material.DEEPSLATE_GOLD_ORE; + } + case REDSTONE_ORE -> { + return Material.DEEPSLATE_REDSTONE_ORE; + } + case LAPIS_ORE -> { + return Material.DEEPSLATE_LAPIS_ORE; + } + case EMERALD_ORE -> { + return Material.DEEPSLATE_EMERALD_ORE; + } + case DIAMOND_ORE -> { + return Material.DEEPSLATE_DIAMOND_ORE; + } + default -> { + return material; + } + } + } + +} \ No newline at end of file diff --git a/plugin/src/main/java/com/alttd/cometskyblock/island/oregenerator/GeneratorLevel.java b/plugin/src/main/java/com/alttd/cometskyblock/island/oregenerator/GeneratorLevel.java new file mode 100644 index 0000000..ae8b428 --- /dev/null +++ b/plugin/src/main/java/com/alttd/cometskyblock/island/oregenerator/GeneratorLevel.java @@ -0,0 +1,13 @@ +package com.alttd.cometskyblock.island.oregenerator; + +import lombok.Getter; +import lombok.Setter; + +@Getter @Setter +public class GeneratorLevel { + + private int level; + private int islandLevel; + private double chance; + +} diff --git a/plugin/src/main/java/com/alttd/cometskyblock/island/oregenerator/GeneratorLoader.java b/plugin/src/main/java/com/alttd/cometskyblock/island/oregenerator/GeneratorLoader.java new file mode 100644 index 0000000..f50910e --- /dev/null +++ b/plugin/src/main/java/com/alttd/cometskyblock/island/oregenerator/GeneratorLoader.java @@ -0,0 +1,98 @@ +package com.alttd.cometskyblock.island.oregenerator; + +import com.alttd.cometskyblock.CometSkyBlockPlugin; +import com.alttd.cometskyblock.api.challenges.ChallengeDifficulty; +import com.alttd.cometskyblock.api.challenges.ChallengeType; +import com.alttd.cometskyblock.challenges.Challenge; +import org.bukkit.Material; +import org.bukkit.configuration.ConfigurationSection; +import org.bukkit.configuration.file.YamlConfiguration; +import org.bukkit.inventory.ItemStack; + +import java.io.File; +import java.util.ArrayList; +import java.util.List; +import java.util.Set; + +/** + * Data loader for Ore Generators + * Parse the data and build them to be used by the plugin. + */ +public class GeneratorLoader extends YamlConfiguration { + + private final CometSkyBlockPlugin plugin; + private final File file; + private final Object saveLock = new Object(); + + public GeneratorLoader(CometSkyBlockPlugin plugin) { + super(); + this.plugin = plugin; + this.file = new File(plugin.getDataFolder(), "generators.yml"); + reload(); + } + + private void reload() { + synchronized (saveLock) { + try { + load(file); + } catch (Exception ignore) { + } + } + } + + public void loadAllGenerators() { + for (GeneratorTier tier : GeneratorTier.values()) { + if (!LoadGenerators(tier)) { + plugin.getLogger().warning(String.format("could not load %s ore generator", tier.toString())); + } + loadGeneratorLevel(tier); + } + } + + private void loadGeneratorLevel(GeneratorTier tier) { + if (tier == null) { + plugin.getLogger().warning("Could not load ore generator level!"); + return; + } + String tierString = tier.toString().toLowerCase(); + int level = getInt("level." + tierString, 0); + if (level > 0) + plugin.generatorHandler().addGeneratorLevel(tier, level); + } + + private boolean LoadGenerators(GeneratorTier generatorTier) { + if (generatorTier == null) { + plugin.getLogger().warning("Could not load ore generators!"); + return false; + } + String tier = generatorTier.toString().toLowerCase(); + ConfigurationSection section = getConfigurationSection(tier); + if (section == null) { + plugin.getLogger().warning(String.format("could not load ore generator for tier %s", tier)); + return false; + } + Set levels = section.getKeys(false); + for (String current : levels) { + if (!isNumber(current)) + continue; + int level = Integer.parseInt(current); + int islandLevel = section.getInt(current + ".islandLevel", 0); + double chance = section.getDouble(current + ".chance", 0); + GeneratorLevel generatorLevel = new GeneratorLevel() + .level(level) + .islandLevel(islandLevel) + .chance(chance); + generatorTier.addGeneratorLevel(generatorLevel); + } + return true; + } + + private boolean isNumber(String s) { + try { + Integer.parseInt(s); + } catch (NumberFormatException nfe) { + return false; + } + return true; + } +} diff --git a/plugin/src/main/java/com/alttd/cometskyblock/island/oregenerator/GeneratorTier.java b/plugin/src/main/java/com/alttd/cometskyblock/island/oregenerator/GeneratorTier.java new file mode 100644 index 0000000..3de52bc --- /dev/null +++ b/plugin/src/main/java/com/alttd/cometskyblock/island/oregenerator/GeneratorTier.java @@ -0,0 +1,88 @@ +package com.alttd.cometskyblock.island.oregenerator; + +import com.alttd.cometskyblock.CometSkyBlockPlugin; +import com.alttd.cometskyblock.util.WeightedChoice; +import it.unimi.dsi.fastutil.objects.Object2IntMap; +import it.unimi.dsi.fastutil.objects.Object2IntOpenHashMap; +import org.bukkit.Location; +import org.bukkit.Material; +import org.bukkit.entity.Player; + +import java.util.*; + +public enum GeneratorTier { + + // Cobble/stone gen + COBBLESTONE(Material.COBBLESTONE), + COAL(Material.COAL_ORE), + IRON(Material.IRON_ORE), + COPPER(Material.COPPER_ORE), + GOLD(Material.GOLD_ORE), + REDSTONE(Material.REDSTONE_ORE), + LAPIS(Material.LAPIS_ORE), + EMERALD(Material.EMERALD_ORE), + DIAMOND(Material.DIAMOND_ORE), + + // Basalt gen + BASALT(Material.BASALT), + NETHERRACK(Material.CRIMSON_NYLIUM, Material.WARPED_NYLIUM), + BLACKSTONE(Material.BLACKSTONE), + NETHERQUARTZ(Material.NETHER_QUARTZ_ORE), + NETHERGOLD(Material.NETHER_GOLD_ORE), + ANCIENTDEBRIS(Material.ANCIENT_DEBRIS); + + private final WeightedChoice ores; + private final NavigableMap generatorLevels = new TreeMap<>(); + GeneratorTier(Material ... materials) { + ores = new WeightedChoice<>(); + double weight = (double) 100 / materials.length; + for (Material material : materials) { + ores.add(weight, material); + } + } + + public Material ore() { + return ores.next(); + } + + public boolean isCobbleStoneGenerator() { + return switch (this) { + case COBBLESTONE, COAL, IRON, COPPER, GOLD, REDSTONE, LAPIS, EMERALD, DIAMOND -> true; + default -> false; + }; + } + + public void addGeneratorLevel(GeneratorLevel level) { + generatorLevels.put(level.level(), level); + } + + public GeneratorLevel generatorLevel(int level) { + return generatorLevels.floorEntry(level).getValue(); + } + + public Object2IntMap upgradeCost(int level) { + Object2IntMap materials = new Object2IntOpenHashMap<>(); + materials.defaultReturnValue(0); + + Material baseMaterial = isCobbleStoneGenerator() ? Material.COBBLESTONE : Material.BASALT; + int baseCost = 64; + int secondaryCost = CometSkyBlockPlugin.instance().generatorHandler().requiredLevel(this); + int multiplier = Math.max(secondaryCost / 5, 1); + + materials.putIfAbsent(baseMaterial, baseCost * multiplier * level); + materials.put(secondaryUpgradeMaterial(), materials.getInt(secondaryUpgradeMaterial()) + secondaryCost * level); + return materials; + } + + private Material secondaryUpgradeMaterial() { + return switch (this) { + case COBBLESTONE, COAL -> Material.COBBLESTONE; + case IRON, COPPER -> Material.COAL; + case GOLD, REDSTONE, LAPIS -> Material.RAW_IRON; + case EMERALD, DIAMOND -> Material.RAW_GOLD; + case BASALT, NETHERRACK, BLACKSTONE -> Material.BASALT; + case NETHERQUARTZ, NETHERGOLD -> Material.NETHERRACK; + case ANCIENTDEBRIS -> Material.DIAMOND; + }; + } +} diff --git a/plugin/src/main/java/com/alttd/cometskyblock/listeners/CobbestoneGeneratorListener.java b/plugin/src/main/java/com/alttd/cometskyblock/listeners/CobbestoneGeneratorListener.java index e612045..7cb2abe 100644 --- a/plugin/src/main/java/com/alttd/cometskyblock/listeners/CobbestoneGeneratorListener.java +++ b/plugin/src/main/java/com/alttd/cometskyblock/listeners/CobbestoneGeneratorListener.java @@ -1,7 +1,6 @@ package com.alttd.cometskyblock.listeners; import com.alttd.cometskyblock.CometSkyBlockPlugin; -import com.alttd.cometskyblock.island.CobblestoneGeneratorLevel; import com.alttd.cometskyblock.island.Island; import com.google.common.cache.Cache; import com.google.common.cache.CacheBuilder; @@ -18,28 +17,37 @@ import java.util.concurrent.TimeUnit; public class CobbestoneGeneratorListener implements Listener { private final CometSkyBlockPlugin plugin; - public static Cache generatorCache = CacheBuilder.newBuilder() - .maximumSize(1000) - .expireAfterAccess(10, TimeUnit.MINUTES) - .build(); +// public static Cache generatorCache = CacheBuilder.newBuilder() +// .maximumSize(1000) +// .expireAfterAccess(10, TimeUnit.MINUTES) +// .build(); public CobbestoneGeneratorListener(CometSkyBlockPlugin plugin) { this.plugin = plugin; } @EventHandler - public void cobblestoneGeneratorForm(BlockFormEvent blockFormEvent) { + public void onBockForm(BlockFormEvent blockFormEvent) { Block block = blockFormEvent.getNewState().getBlock(); - Material newmaterial = blockFormEvent.getNewState().getType(); - Location location = blockFormEvent.getNewState().getLocation(); - if (newmaterial.equals(Material.COBBLESTONE)) { - Island island = Island.getIsland(block.getWorld().getUID()); - if (island.worldName() == null || island.worldName().isEmpty()) // Worlds not generated by us will have this as null or empty - return; + Island island = Island.getIsland(block.getWorld().getUID()); + if (island.worldName() == null || island.worldName().isEmpty()) // Worlds not generated by us will have this as null or empty + return; - blockFormEvent.getNewState().setType(rollGenerator(island.cobblegenLevel(), location)); + Material formedMaterial = blockFormEvent.getNewState().getType(); + boolean cobblestone; + switch (formedMaterial) { + case STONE, COBBLESTONE -> cobblestone = true; + case BASALT -> cobblestone = false; + default -> { + return; + } } + Material generatedMaterial = plugin.generatorHandler().generateOre(island, cobblestone, blockFormEvent.getBlock().getLocation().getBlockY()); + blockFormEvent.getNewState().setType(generatedMaterial); + // TODO - set to infested variants - turn them into ore when breaking them? + // if infested block -> rollgenerator -> block::breaknaturally? } + // @EventHandler // public void cobblestoneGeneratorDrops(BlockBreakEvent event) { // // TODO - multiply drops from cobble gen? @@ -54,21 +62,6 @@ public class CobbestoneGeneratorListener implements Listener { // } // } - private Material rollGenerator(int generatorLevel, Location location) { - double random = Math.random() * 100; - double checkedChance = 0; - - for (CobblestoneGeneratorLevel cobblestoneGeneratorLevel : plugin.cobblestoneGeneratorConfiguration().get().levels()) { - if (cobblestoneGeneratorLevel.level() <= generatorLevel) { - checkedChance += cobblestoneGeneratorLevel.chance(); - if (checkedChance > random) { - return cobblestoneGeneratorLevel.type(); - } - } - } - return Material.COBBLESTONE; - } - boolean relativeEqualsMaterial(Block block, Material material) { return block.getRelative(BlockFace.NORTH).getType().equals(material) || block.getRelative(BlockFace.EAST).getType().equals(material) diff --git a/plugin/src/main/java/com/alttd/cometskyblock/util/PlayerUtils.java b/plugin/src/main/java/com/alttd/cometskyblock/util/PlayerUtils.java index df594e6..ab7e4af 100644 --- a/plugin/src/main/java/com/alttd/cometskyblock/util/PlayerUtils.java +++ b/plugin/src/main/java/com/alttd/cometskyblock/util/PlayerUtils.java @@ -112,4 +112,53 @@ public class PlayerUtils { } } } + + public static boolean hasRequiredItems(Inventory inventory, Object2IntMap items) { + if (inventory == null || items == null) + return false; + + for (Map.Entry entry : items.object2IntEntrySet()) { + int requiredAmount = entry.getValue(); + Material requiredMaterial = entry.getKey(); + for (int slot = 0; slot < inventory.getSize(); slot++) { + if (inventory.getItem(slot) != null) { + if (inventory.getItem(slot).getType().equals(requiredMaterial)) { + requiredAmount = requiredAmount - inventory.getItem(slot).getAmount(); + } + } + } + if (requiredAmount > 0) { + return false; + } + } + return true; + } + + public static void takeRequiredItems(Inventory inventory, Object2IntMap items) { + if (inventory == null || items == null) + return; + + for (Map.Entry entry : items.object2IntEntrySet()) { + int requiredAmount = entry.getValue(); + Material requiredMaterial = entry.getKey(); + for (int slot = 0; slot < inventory.getSize(); slot++) { + ItemStack inventoryItem = inventory.getItem(slot); + if (inventoryItem != null) { + if (inventoryItem.getType().equals(requiredMaterial)) { + int newAmount = inventoryItem.getAmount() - requiredAmount; + if (newAmount > 0) { + inventoryItem.setAmount(newAmount); + break; + } else { + inventory.clear(slot); + requiredAmount = requiredAmount - inventoryItem.getAmount(); + if (requiredAmount == 0) { + break; + } + } + } + } + } + } + } } diff --git a/plugin/src/main/resources/generators.yml b/plugin/src/main/resources/generators.yml new file mode 100644 index 0000000..9dd7b24 --- /dev/null +++ b/plugin/src/main/resources/generators.yml @@ -0,0 +1,412 @@ +level: + cobblestone: 0 + coal: 5 + iron: 10 + copper: 10 + gold: 15 + redstone: 20 + lapis: 20 + emerald: 25 + diamond: 50 + basalt: 0 + netherrack: 5 + blackstone: 10 + netherquartz: 25 + nethergold: 25 + ancientdebris: 100 +cobblestone: + 0: + islandLevel: 0 + chance: 100 +coal: + 0: + islandLevel: 5 + chance: 3.0 + 1: + islandLevel: 10 + chance: 3.5 + 2: + islandLevel: 15 + chance: 4.0 + 3: + islandLevel: 20 + chance: 4.5 + 4: + islandLevel: 25 + chance: 5.0 + 5: + islandLevel: 30 + chance: 5.5 + 6: + islandLevel: 35 + chance: 6.0 + 7: + islandLevel: 40 + chance: 7.0 + 8: + islandLevel: 45 + chance: 8.0 + 9: + islandLevel: 50 + chance: 9.0 + 10: + islandLevel: 55 + chance: 10.0 +iron: + 0: + islandLevel: 10 + chance: 3.0 + 1: + islandLevel: 15 + chance: 3.5 + 2: + islandLevel: 20 + chance: 4.0 + 3: + islandLevel: 25 + chance: 4.5 + 4: + islandLevel: 30 + chance: 5.0 + 5: + islandLevel: 35 + chance: 5.5 + 6: + islandLevel: 40 + chance: 6.0 + 7: + islandLevel: 45 + chance: 7.0 + 8: + islandLevel: 50 + chance: 8.0 + 9: + islandLevel: 55 + chance: 9.0 + 10: + islandLevel: 60 + chance: 10.0 +copper: + 0: + islandLevel: 10 + chance: 3.0 + 1: + islandLevel: 15 + chance: 3.5 + 2: + islandLevel: 20 + chance: 4.0 + 3: + islandLevel: 25 + chance: 4.5 + 4: + islandLevel: 30 + chance: 5.0 + 5: + islandLevel: 35 + chance: 5.5 + 6: + islandLevel: 40 + chance: 6.0 + 7: + islandLevel: 45 + chance: 7.0 + 8: + islandLevel: 50 + chance: 8.0 + 9: + islandLevel: 55 + chance: 9.0 + 10: + islandLevel: 60 + chance: 10.0 +gold: + 0: + islandLevel: 15 + chance: 3.0 + 1: + islandLevel: 20 + chance: 3.5 + 2: + islandLevel: 25 + chance: 4.0 + 3: + islandLevel: 30 + chance: 4.5 + 4: + islandLevel: 35 + chance: 5.0 + 5: + islandLevel: 40 + chance: 5.5 + 6: + islandLevel: 45 + chance: 6.0 + 7: + islandLevel: 50 + chance: 7.0 + 8: + islandLevel: 55 + chance: 8.0 + 9: + islandLevel: 60 + chance: 9.0 + 10: + islandLevel: 65 + chance: 10.0 +redstone: + 0: + islandLevel: 20 + chance: 3.0 + 1: + islandLevel: 25 + chance: 3.5 + 2: + islandLevel: 30 + chance: 4.0 + 3: + islandLevel: 35 + chance: 4.5 + 4: + islandLevel: 40 + chance: 5.0 + 5: + islandLevel: 45 + chance: 5.5 + 6: + islandLevel: 50 + chance: 6.0 + 7: + islandLevel: 55 + chance: 7.0 + 8: + islandLevel: 60 + chance: 8.0 + 9: + islandLevel: 65 + chance: 9.0 + 10: + islandLevel: 70 + chance: 10.0 +lapis: + 0: + islandLevel: 20 + chance: 3.0 + 1: + islandLevel: 25 + chance: 3.5 + 2: + islandLevel: 30 + chance: 4.0 + 3: + islandLevel: 35 + chance: 4.5 + 4: + islandLevel: 40 + chance: 5.0 + 5: + islandLevel: 45 + chance: 5.5 + 6: + islandLevel: 50 + chance: 6.0 + 7: + islandLevel: 55 + chance: 7.0 + 8: + islandLevel: 60 + chance: 8.0 + 9: + islandLevel: 65 + chance: 9.0 + 10: + islandLevel: 70 + chance: 10.0 +emerald: + 0: + islandLevel: 25 + chance: 3.0 + 1: + islandLevel: 30 + chance: 3.5 + 2: + islandLevel: 35 + chance: 4.0 + 3: + islandLevel: 40 + chance: 4.5 + 4: + islandLevel: 45 + chance: 5.0 + 5: + islandLevel: 50 + chance: 5.5 + 6: + islandLevel: 55 + chance: 6.0 + 7: + islandLevel: 60 + chance: 7.0 + 8: + islandLevel: 65 + chance: 8.0 + 9: + islandLevel: 70 + chance: 9.0 + 10: + islandLevel: 75 + chance: 10.0 +diamond: + 0: + islandLevel: 50 + chance: 3.0 + 1: + islandLevel: 60 + chance: 3.5 + 2: + islandLevel: 70 + chance: 4.0 + 3: + islandLevel: 80 + chance: 4.5 + 4: + islandLevel: 90 + chance: 5.0 + 5: + islandLevel: 100 + chance: 5.5 +basalt: + 0: + islandLevel: 0 + chance: 100 +netherrack: + 0: + islandLevel: 5 + chance: 50.0 + 1: + islandLevel: 10 + chance: 75.0 + 2: + islandLevel: 15 + chance: 100.0 +blackstone: + 0: + islandLevel: 10 + chance: 3.0 + 1: + islandLevel: 15 + chance: 3.5 + 2: + islandLevel: 20 + chance: 4.0 + 3: + islandLevel: 25 + chance: 4.5 + 4: + islandLevel: 30 + chance: 5.0 + 5: + islandLevel: 35 + chance: 5.5 + 6: + islandLevel: 40 + chance: 6.0 + 7: + islandLevel: 45 + chance: 7.0 + 8: + islandLevel: 50 + chance: 8.0 + 9: + islandLevel: 55 + chance: 9.0 + 10: + islandLevel: 60 + chance: 10.0 +netherquartz: + 0: + islandLevel: 25 + chance: 3.0 + 1: + islandLevel: 30 + chance: 3.5 + 2: + islandLevel: 35 + chance: 4.0 + 3: + islandLevel: 40 + chance: 4.5 + 4: + islandLevel: 45 + chance: 5.0 + 5: + islandLevel: 50 + chance: 5.5 + 6: + islandLevel: 55 + chance: 6.0 + 7: + islandLevel: 60 + chance: 7.0 + 8: + islandLevel: 65 + chance: 8.0 + 9: + islandLevel: 70 + chance: 9.0 + 10: + islandLevel: 75 + chance: 10.0 +nethergold: + 0: + islandLevel: 25 + chance: 3.0 + 1: + islandLevel: 30 + chance: 3.5 + 2: + islandLevel: 35 + chance: 4.0 + 3: + islandLevel: 40 + chance: 4.5 + 4: + islandLevel: 45 + chance: 5.0 + 5: + islandLevel: 50 + chance: 5.5 + 6: + islandLevel: 55 + chance: 6.0 + 7: + islandLevel: 60 + chance: 7.0 + 8: + islandLevel: 65 + chance: 8.0 + 9: + islandLevel: 70 + chance: 9.0 + 10: + islandLevel: 75 + chance: 10.0 +ancientdebris: + 0: + islandLevel: 100 + chance: 0.3 + 1: + islandLevel: 105 + chance: 0.5 + 2: + islandLevel: 110 + chance: 1.0 + 3: + islandLevel: 115 + chance: 1.5 + 4: + islandLevel: 120 + chance: 2.0 + 5: + islandLevel: 125 + chance: 2.5 \ No newline at end of file