From 10b327e9f6441a8863227ce3e075a5a587654065 Mon Sep 17 00:00:00 2001 From: davidovski Date: Sat, 11 Oct 2025 04:55:51 +0100 Subject: v0.3.1 --- src/main/java/net/uomc/mineshaft/MineCommand.java | 280 ++++++++++++++++++++++ 1 file changed, 280 insertions(+) create mode 100644 src/main/java/net/uomc/mineshaft/MineCommand.java (limited to 'src/main/java/net/uomc/mineshaft/MineCommand.java') diff --git a/src/main/java/net/uomc/mineshaft/MineCommand.java b/src/main/java/net/uomc/mineshaft/MineCommand.java new file mode 100644 index 0000000..ecee140 --- /dev/null +++ b/src/main/java/net/uomc/mineshaft/MineCommand.java @@ -0,0 +1,280 @@ +package net.uomc.mineshaft; + + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.LinkedHashMap; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; +import java.util.concurrent.TimeUnit; +import java.util.function.Consumer; +import java.util.stream.Collectors; + +import org.json.JSONObject; + +import com.mouldycheerio.dbot.CustomBot; +import com.mouldycheerio.dbot.commands.CommandDetails; +import com.mouldycheerio.dbot.commands.cooldowns.CooldownCommand; +import com.mouldycheerio.dbot.util.EventWaiter; +import com.mouldycheerio.dbot.util.PeelingUtils; +import com.vdurmont.emoji.EmojiParser; + +import net.dv8tion.jda.api.EmbedBuilder; +import net.dv8tion.jda.api.entities.Member; +import net.dv8tion.jda.api.entities.Message; +import net.dv8tion.jda.api.entities.channel.middleman.GuildMessageChannel; +import net.dv8tion.jda.api.entities.channel.middleman.MessageChannel; +import net.dv8tion.jda.api.entities.emoji.Emoji; +import net.dv8tion.jda.api.events.message.MessageReceivedEvent; +import net.uomc.mineshaft.resources.ResourceManager; + +public class MineCommand extends CooldownCommand { + + private static final String DROP_END_MESSAGE2 = "Too late!"; + private static final String DROP_END_MESSAGE = "The ore has disappeared!"; + private static final long DROP_DURATION_SECONDS = 90; + private static final String DROP_TITLE = "An ore has spawned!"; + private static final String DROP_DESCRIPTION = "Say `%s` to mine it!\nHurry though, it will be gone %s"; + private static final double COAL_SPAWN_AMOUNT = 64; + private static final double IRON_SPAWN_AMOUNT = 8; + private static final double COPPER_SPAWN_AMOUNT = 8; + private static final double LAPIS_SPAWN_AMOUNT = 16; + private static final double REDSTONE_SPAWN_AMOUNT = 16; + private static final double GOLD_SPAWN_AMOUNT = 8; + private static final double EMERALD_SPAWN_AMOUNT = 1; + private static final double DIAMOND_SPAWN_AMOUNT = 1; + private static final double OBSIDIAN_SPAWN_AMOUNT = 1; + private static final double XP_SPAWN_AMOUNT = 1000; + + private Map ores; + private List oresList; + + private Mineshaft bot; + + protected MineCommand(Mineshaft bot) { + super(bot); + this.bot = bot; + + setCooldown(15l * 1000l); + setDetails(CommandDetails.from("mine", "mine diamonds")); + + this.ores = loadOreImages(); + oresList = loadOreOrder(); + } + + public List loadOreOrder() { + // lololol no + return List.of( + "coal", + "copper", + "iron", + "lapis", + "redstone", + "gold", + "diamond", + "emerald", + "obsidian" + ); + } + + public Map loadOreImages() { + Map ores = new LinkedHashMap(); + JSONObject config = bot.getConfig(); + + if (!config.has("mineshaft")) + return ores; + + JSONObject mineshaftConfig = config.getJSONObject("mineshaft"); + if (!mineshaftConfig.has("ores")) + return ores; + + JSONObject oresConfig = mineshaftConfig.getJSONObject("ores"); + oresConfig.keySet().forEach(k -> ores.put(k, oresConfig.getString(k))); + return ores; + } + + public MineshaftItem getOre(int pickaxe) { + double random = Math.random(); + int maxOre = levelToMaxOre(pickaxe); + + int i = (int) Math.floor(Math.pow(random, 2) * maxOre); + String oreName = oresList.get(i); + MineshaftItem ore = MineshaftItem.valueOf(oreName.toUpperCase()); + return ore; + } + + @Override + public boolean trigger(MessageReceivedEvent e) { + + int pickaxe = bot.getPickaxes().getPickaxeLevel(e.getMember()); + MineshaftItem ore = getOre(pickaxe); + int i = oresList.indexOf(ore.toString().toLowerCase()); + + spawnDrop(e.getChannel(), ore, i, m -> {}); + e.getMessage().addReaction(Emoji.fromUnicode(EmojiParser.parseToUnicode(":pick:"))).queue(); + return true; + } + + private int levelToMaxOre(int pickaxe) { + switch (pickaxe) { + case 0: // stone pickaxe + return 2; // copper + case 1: // copper pickaxe + return 4; // lapis + case 2: // iron pickaxe + return 6; // gold + case 3: // gold pickaxe + return 8; // diamond + case 4: // diamond pickaxe + return 9; // obsidian + // TODO for obsidian u can make nether portal + } + return 9; + } + + public void spawnDrop(MessageChannel channel, MineshaftItem ore, int oreLevel, Consumer then) { + sendDrop(channel, ore, m -> { + EventWaiter eventWaiter = new EventWaiter(); + channel.getJDA().addEventListener(eventWaiter); + + eventWaiter.waitForEvent(MessageReceivedEvent.class, + e -> { + if (!e.getMessage().getContentRaw().equalsIgnoreCase(getPickString(ore))) + return false; + + if (oreLevel > levelToMaxOre(bot.getPickaxes().getPickaxeLevel(e.getMember()))) + return false; + + return true; + }, e -> { + awardDrop(e.getMember(), channel, ore, message -> { + cleanup(channel, m, ore); + then.accept(channel); + message.delete().queueAfter(5, TimeUnit.SECONDS); + }); + }, DROP_DURATION_SECONDS, TimeUnit.SECONDS, () -> { + cleanup(channel, m, ore); + endDrop(m, ore); + }); + + }); + } + + public void cleanup(MessageChannel channel, Message message, MineshaftItem ore) { + message.delete().queue(); + + channel.getHistoryAfter(message, 100).queueAfter(5, TimeUnit.SECONDS, h -> { + ArrayList msgs = new ArrayList(); + h.getRetrievedHistory().forEach(m -> { + if (m.getContentRaw().equalsIgnoreCase(getPickString(ore))) { + msgs.add(m); + } + }); + PeelingUtils.bulkDelte(channel, msgs); + }); + ; + } + + public void sendDrop(MessageChannel channel, MineshaftItem ore, Consumer callback) { + EmbedBuilder embedBuilder = new EmbedBuilder(); + + embedBuilder.setColor(bot.getColor()); + embedBuilder.setImage(getOreUrl(ore)); + + embedBuilder.setTitle(String.format(DROP_TITLE)); + embedBuilder.setDescription(String.format(DROP_DESCRIPTION, getPickString(ore), PeelingUtils.formatTimeRelativeFromNow(DROP_DURATION_SECONDS * 1000l))); + + channel.sendMessageEmbeds(embedBuilder.build()).queue(callback); + + } + + public void awardDrop(Member member, MessageChannel channel, MineshaftItem ore, Consumer callback) { + + EmbedBuilder embedBuilder = new EmbedBuilder(); + embedBuilder.setColor(bot.getColor()); + + Map awards = getAwards(member, ore); + int fortune = bot.getPickaxes().getPickaxeFortune(member); + if (fortune > 0) { + bot.multiply(awards, fortune + 1); + } + + bot.addItems(member, awards); + String awardsList = bot.createItemList(awards, "+%s"); + + embedBuilder.setDescription(member.getAsMention() + " mined the ore!\n " + awardsList); + + channel.sendMessageEmbeds(embedBuilder.build()).queue(callback); + } + + public void endDrop(Message message, MineshaftItem ore) { + + EmbedBuilder embedBuilder = new EmbedBuilder(); + + embedBuilder.setColor(bot.color); + embedBuilder.setTitle(DROP_END_MESSAGE); + embedBuilder.setDescription(DROP_END_MESSAGE2); + + message.editMessageEmbeds(embedBuilder.build()).queue(m -> { + message.delete().queueAfter(1, TimeUnit.MINUTES); + }); + } + + public String getOreUrl(MineshaftItem ore) { + String oreName = ore.toString(); + if (ores.containsKey(oreName)) + return ores.get(oreName); + + if (ores.size() == 0) + return ""; + + return ores.entrySet().stream().findFirst().get().getValue(); + } + + public String getPickString(MineshaftItem ore) { + return "mine " + ore.toString(); + } + + public Map getAwards(Member member, MineshaftItem ore) { + Map award = new HashMap<>(); + switch (ore) { + case COAL: + award.put(MineshaftItem.COAL, (long) Math.ceil(Math.random() * COAL_SPAWN_AMOUNT)); + award.put(MineshaftItem.XP, (long) Math.ceil(Math.random() * XP_SPAWN_AMOUNT)); + break; + case IRON: + award.put(MineshaftItem.IRON, (long) Math.ceil(Math.random() * IRON_SPAWN_AMOUNT)); + break; + case COPPER: + award.put(MineshaftItem.COPPER, (long) Math.ceil(Math.random() * COPPER_SPAWN_AMOUNT)); + break; + case LAPIS: + award.put(MineshaftItem.LAPIS, (long) Math.ceil(Math.random() * LAPIS_SPAWN_AMOUNT)); + award.put(MineshaftItem.XP, (long) Math.ceil(Math.random() * XP_SPAWN_AMOUNT * 2l)); + break; + case REDSTONE: + award.put(MineshaftItem.REDSTONE, (long) Math.ceil(Math.random() * REDSTONE_SPAWN_AMOUNT)); + award.put(MineshaftItem.XP, (long) Math.ceil(Math.random() * XP_SPAWN_AMOUNT * 5l)); + break; + case GOLD: + award.put(MineshaftItem.GOLD, (long) Math.ceil(Math.random() * GOLD_SPAWN_AMOUNT)); + break; + case EMERALD: + award.put(MineshaftItem.EMERALD, (long) Math.ceil(Math.random() * EMERALD_SPAWN_AMOUNT)); + break; + case DIAMOND: + award.put(MineshaftItem.DIAMOND, (long) Math.ceil(Math.random() * DIAMOND_SPAWN_AMOUNT)); + award.put(MineshaftItem.XP, (long) Math.ceil(Math.random() * XP_SPAWN_AMOUNT * 10l)); + break; + case OBSIDIAN: + award.put(MineshaftItem.OBSIDIAN, (long) Math.ceil(Math.random() * OBSIDIAN_SPAWN_AMOUNT)); + award.put(MineshaftItem.XP, (long) Math.ceil(Math.random() * XP_SPAWN_AMOUNT * 10l)); + break; + default: + break; + } + + return award; + } +} -- cgit v1.2.3