package net.uomc.mineshaft; import java.util.ArrayList; import java.util.Comparator; import java.util.HashMap; import java.util.Map; import java.util.Optional; import java.util.Random; import java.util.concurrent.TimeUnit; import java.util.stream.Collectors; import org.jetbrains.annotations.NotNull; import com.mouldycheerio.dbot.commands.CommandDetails; import com.mouldycheerio.dbot.commands.cooldowns.CooldownCommand; import com.mouldycheerio.dbot.util.PeelingUtils; import com.mouldycheerio.dbot.util.EventWaiter; 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.MessageEmbed; 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; public class RobCommand extends CooldownCommand { private static final int TO_PICK = 3; private static final double MAX_AMOUNT_PERCENT = 0.35; private static final long DROP_DURATION_SECONDS = 90; private static final String LOOT_STRING = "loot"; private Mineshaft bot; private @NotNull String embedTitle; protected RobCommand(Mineshaft bot) { super(bot); setCooldown(60l * 30l * 1000l); this.bot = bot; setDetails(CommandDetails.from("kill,pvp,rob", "kill another player")); embedTitle = EmojiParser.parseToUnicode(":crossed_swords:"); } @Override public boolean trigger(MessageReceivedEvent e) { String[] args = e.getMessage().getContentRaw().split(" "); if (args.length < 2) { e.getMessage().reply(":x: Please specify a target! `kill @user`").queue(); return false; } Optional mentionToMember = PeelingUtils.mentionToMember(args[1], e.getGuild()); if (!mentionToMember.isPresent()) { e.getMessage().reply(":x: Invalid Target! `kill @user`").queue(); return false; } Member target = mentionToMember.get(); if (bot.getPickaxes().isNether(target) != bot.getPickaxes().isNether(e.getMember())) { e.getMessage().reply(":x: You tried to kill " + target.getAsMention() + " but they were in a different dimension!").queue(); return false; } String response = target.getAsMention() + " was slain by " + e.getAuthor().getAsMention(); Map rob = getRob(target); EmbedBuilder eb = new EmbedBuilder(); eb.setTitle(embedTitle); eb.getDescriptionBuilder().append(response); eb.getDescriptionBuilder().append("\nThey dropped:\n\n"); eb.getDescriptionBuilder().append(bot.createItemList(rob)); eb.getDescriptionBuilder().append("\n\nSay `" + LOOT_STRING + "` to loot these items.\nHurry you only have " +PeelingUtils.formatTimeRelativeFromNow(DROP_DURATION_SECONDS * 1000l) + " to collect them!"); eb.setColor(bot.color); e.getMessage().addReaction(Emoji.fromUnicode(EmojiParser.parseToUnicode(":crossed_swords:"))).queue(); spawnDrop(e, eb.build(), target, rob); return true; } public Map getRob(Member member) { Map rob = new HashMap<>(); Map inventory = bot.getInventory(member); int items = TO_PICK; if (bot.getItem(member, MineshaftItem.XP) > 0) { rob.put(MineshaftItem.XP, (long) Math.ceil(bot.getItem(member, MineshaftItem.XP) * (Math.random() * MAX_AMOUNT_PERCENT)) ); items--; } int random = new Random().nextInt(); inventory.entrySet().stream().filter(e-> e.getValue() > 0 && e.getKey() != MineshaftItem.XP) .sorted(Comparator.comparingInt(o -> System.identityHashCode(o) ^ random)) .limit(items).collect(Collectors.toList()).forEach(e -> { rob.put(e.getKey(), (long) Math.ceil(e.getValue() * (Math.random() * MAX_AMOUNT_PERCENT)) ); }); return rob; } public void spawnDrop(MessageReceivedEvent event, MessageEmbed embed, Member target, Map rob) { bot.removeItems(target, rob); event.getChannel().sendMessageEmbeds(embed).queue( m -> { EventWaiter eventWaiter = new EventWaiter(); event.getChannel().getJDA().addEventListener(eventWaiter); eventWaiter.waitForEvent(MessageReceivedEvent.class, e -> { if (!e.getMessage().getContentRaw().equalsIgnoreCase(LOOT_STRING)) return false; return true; }, e -> { bot.addItems(e.getMember(), rob); bot.editMessage(m, embedTitle, e.getMember().getAsMention() + " claimed the loot!\n**" + bot.createItemList(rob, "+%s") + "**"); cleanup(event.getChannel(), m); }, DROP_DURATION_SECONDS, TimeUnit.SECONDS, () -> { m.delete().queue(); cleanup(event.getChannel(), m); }); }); } public void cleanup(MessageChannel channel, Message message) { message.delete().queueAfter(60, TimeUnit.SECONDS); channel.getHistoryAfter(message, 100).queueAfter(1, TimeUnit.SECONDS, h -> { ArrayList msgs = new ArrayList(); h.getRetrievedHistory().forEach(m -> { if (m.getContentRaw().equalsIgnoreCase(LOOT_STRING)) { msgs.add(m); } }); PeelingUtils.bulkDelte(channel, msgs); }); ; } }