package net.uomc.mineshaft.farm; import static net.uomc.mineshaft.PlayerHealths.HP_EMOJI; import java.awt.Color; import java.util.ArrayList; import java.util.Arrays; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Optional; import java.util.concurrent.atomic.AtomicLong; import java.util.stream.Stream; import com.mouldycheerio.dbot.CustomBot; import com.mouldycheerio.dbot.commands.CommandDetails; import com.mouldycheerio.dbot.commands.CommandFail; import com.mouldycheerio.dbot.commands.DetailedCommand; 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.events.message.MessageReceivedEvent; import net.uomc.mineshaft.Mineshaft; import net.uomc.mineshaft.MineshaftItem; public class CampfireCommand extends DetailedCommand { private static final Color COMMAND_COLOUR = PeelingUtils.hex2Rgb("#a45802"); private static final String COMMAND_TITLE = "Campfire"; private static final String COMMAND_IMAGE = "https://minecraft.wiki/images/Campfire_%28S%29_JE2_BE2.gif"; public static final int ITEMS_PER_CAMPFIRE = 4; public static final long POTATO_COOKING_TIME = 1000l * 40l; public static final long FISH_COOKING_TIME = 1000l * 90l; Mineshaft bot; List farms; public CampfireCommand(Mineshaft bot) { setCommandDetails(CommandDetails.from("campfire", "cook your food", "farm")); this.bot = bot; farms = new ArrayList<>(); farms.add(new Campfire(bot, MineshaftItem.FISH, MineshaftItem.COOKED_FISH, FISH_COOKING_TIME)); farms.add(new Campfire(bot, MineshaftItem.POTATO, MineshaftItem.BAKED_POTATO, POTATO_COOKING_TIME)); bot.getCommandController().addCommand("cook", (e, b, args) -> { execute(e, bot, Stream.concat(Stream.of("cook"), Arrays.stream(args)).toArray(String[]::new)); }); } @Override public void execute(MessageReceivedEvent e, CustomBot b, String[] args) throws CommandFail { Member m = e.getMember(); List argList = Arrays.asList(args); long campfires = bot.getItem(m, MineshaftItem.CAMPFIRE); if (campfires < 1) { b.sendErrorMessage(e, ":x: You need to have at least **" + bot.getItem(MineshaftItem.CAMPFIRE).prettyValue(1) + "** to use this!"); return; } update(m); if (args.length > 1 && "cook".equalsIgnoreCase(args[0])) { if (!cook(e, argList)) bot.sendErrorMessage(e, String.format(":x: Usage `%scook [potato|fish] [amount] `", bot.getPrefixManager().getPrefix(e.getGuild()))); return; } StringBuilder description = new StringBuilder(); description.append(String.format("This is your campfire. You currently have %s\nUse `%scook [potato|fish] [amount]` to cook your food.\n\n", bot.prettyValue(MineshaftItem.CAMPFIRE, campfires), bot.getPrefixManager().getPrefix(e.getGuild()) )); Map award = new HashMap<>(); List cooking = new ArrayList<>(); AtomicLong waitingAmount = new AtomicLong(); // remove items if there are too many items for the num of campfires // long already = farms.stream().mapToLong(f -> f.getPlanted(m) + f.getQuantity(m)).sum(); if (already > campfires * ITEMS_PER_CAMPFIRE) { AtomicLong toRemove = new AtomicLong(already - (campfires * ITEMS_PER_CAMPFIRE)); while (toRemove.get() > 0) { long amountEach = toRemove.get(); farms.forEach(f -> { long amount = amountEach; if (amount == 0 || toRemove.get() < 1) return; // we already removed enough if (f.getQuantity(m) >= amount) { // count the cooked as removed toRemove.addAndGet(-f.getQuantity(m)); return; } if (f.getPlanted(m) < amount) { amount = f.getPlanted(m); } // otherwise remove from planted toRemove.addAndGet(-amount); f.setPlanted(m, f.getPlanted(m) - amount); award.put(f.getItem(), amount); }); } } // add the cooked items to the award // farms.forEach(farm -> { long cooked = farm.getQuantity(m); long waiting = farm.getPlanted(m); if (cooked > 0) { award.put(farm.getCookedItem(), cooked); farm.setQuantity(m, 0); cooked = 0; } if (waiting < 1) return; cooking.add(String.format("%s%s", waiting, bot.getItem(farm.getItem()).getSymbol())); waitingAmount.addAndGet(waiting); }); if (waitingAmount.get() == 0) { description.append("*You have nothing on your campfire*\n"); } else { description.append("You are currently cooking: " + String.join(",", cooking) + "\n"); } if (award.size() > 0) { description.append("\n"); description.append(bot.createItemList(award, "+%s")); } EmbedBuilder em = new EmbedBuilder(); em.setTitle(COMMAND_TITLE); em.setThumbnail(COMMAND_IMAGE); em.setDescription(description); em.setColor(COMMAND_COLOUR); bot.addItems(m, award); if (campfires <= 1) { em.setFooter(EmojiParser.parseToUnicode(":bulb:") + "Get more campfires to cook more food at a time"); } else { em.setFooter(EmojiParser.parseToUnicode(":bulb:") + String.format("Cooking food increases the amount of %s it gives when you %seat it.", "HP", bot.getPrefixManager().getPrefix(e.getGuild()))); } e.getMessage().replyEmbeds(em.build()).queue(); } public boolean cook(MessageReceivedEvent e, List args) { if (args.size() > 3) return false; Optional resourceName = args.stream().filter(s -> !s.equalsIgnoreCase("all") && !s.equalsIgnoreCase("cook") && !PeelingUtils.isLong(s)).findFirst(); if (resourceName.isEmpty()) return false; MineshaftItem item = MineshaftItem.valueOf(resourceName.get().toUpperCase()); if (item == null) { bot.sendErrorMessage(e, ":x: Please provide a valid item!"); return true; } long campfires = bot.getItem(e.getMember(), MineshaftItem.CAMPFIRE); long already = farms.stream().mapToLong(f -> f.getPlanted(e.getMember()) + f.getQuantity(e.getMember())).sum(); long q = 0; Optional all = args.stream().filter(s -> s.equals("all")).findFirst(); if (all.isEmpty()) { Optional quantity = args.stream().filter(s -> PeelingUtils.isLong(s)).map(s -> Long.parseLong(s)).findFirst(); if (quantity.isEmpty()) return false; q = Math.abs(quantity.get()); } else { q = Math.min(bot.getItem(item).get(e.getMember()), (campfires * ITEMS_PER_CAMPFIRE) - already ) ; } if (already + q > campfires * ITEMS_PER_CAMPFIRE) { bot.sendErrorMessage(e, String.format(":x: You can only have %s items cooking at the same time!", campfires * ITEMS_PER_CAMPFIRE)); return true; } Optional farm = farms.stream().filter(f -> f.getItem() == item).findFirst(); if (farm.isEmpty()) { bot.sendErrorMessage(e, ":x: This item cannot be cooked"); return true; } if (q > bot.getItem(item).get(e.getMember())) { bot.sendErrorMessage(e, ":x: You dont have enough " + bot.getItem(item).getSymbol()); return true; } if (farm.get().getPlanted(e.getMember()) == 0) { farm.get().setNextUpdate(e.getMember(), System.currentTimeMillis() + farm.get().getCookingTime()); } bot.removeItem(e.getMember(), item, q); farm.get().setPlanted(e.getMember(), farm.get().getPlanted(e.getMember()) + q); bot.sendSuccessMessage(e, String.format("You put %s on your campfire%s! Come back later when they have finished cooking", bot.getItem(item).prettyValue(q), campfires > 1 ? "s" : "")); return true; } public void update(Member m) { farms.forEach(farm -> { update(farm, m); }); } public void update(Campfire farm, Member m) { long next = farm.getNextUpdate(m); long now = System.currentTimeMillis(); if (next == 0) { next = now; } if (next > now) return; long since = now - next; long updates = since / farm.getCookingTime(); //System.out.printf("[farm %s] updates is %d\n", farm.getItem(), updates); long campfires = bot.getItem(m, MineshaftItem.CAMPFIRE); long planted = farm.getPlanted(m); if (planted > 0) { long toCook = (campfires * updates); if (toCook > planted) { toCook = planted; } farm.setQuantity(m, farm.getQuantity(m) + toCook); farm.setPlanted(m, planted - toCook); } farm.setNextUpdate(m, farm.getNextUpdate(m) + farm.getCookingTime()*updates); } }