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; } }