diff options
| author | davidovski <david@davidovski.xyz> | 2025-10-19 16:16:05 +0100 |
|---|---|---|
| committer | davidovski <david@davidovski.xyz> | 2025-10-19 16:16:05 +0100 |
| commit | fff63aaea786a5f1c59bbf99c999a2aa7bb810e5 (patch) | |
| tree | b8c55be02d1e1f8575f5434a254d1593ede63432 /src/main/java/net/uomc/mineshaft/farm/FarmCommand.java | |
| parent | da9ece80133a33aff456d30854adc095b8f303ab (diff) | |
Add farm, sleep and trade
Diffstat (limited to 'src/main/java/net/uomc/mineshaft/farm/FarmCommand.java')
| -rw-r--r-- | src/main/java/net/uomc/mineshaft/farm/FarmCommand.java | 277 |
1 files changed, 277 insertions, 0 deletions
diff --git a/src/main/java/net/uomc/mineshaft/farm/FarmCommand.java b/src/main/java/net/uomc/mineshaft/farm/FarmCommand.java new file mode 100644 index 0000000..43b7576 --- /dev/null +++ b/src/main/java/net/uomc/mineshaft/farm/FarmCommand.java @@ -0,0 +1,277 @@ +package net.uomc.mineshaft.farm; + +import static java.util.stream.Collectors.toMap; + +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.IntStream; + +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 FarmCommand extends DetailedCommand { + + private static final Color COMMAND_COLOUR = PeelingUtils.hex2Rgb("#589430"); + public static final long TIME_BETWEEN_UPDATES = 1000l * 60l * 10l; + public static final int MAX_CROP_LEVEL = 2; + private static final String COMMAND_TITLE = "Farm"; + public static final long XP_PER_ITEM = 5000l; + + Mineshaft bot; + List<Farm> farms; + + public FarmCommand(Mineshaft bot) { + setCommandDetails(CommandDetails.from("farm", "access your farm", "farm")); + this.bot = bot; + + farms = new ArrayList<>(); + farms.add(new Farm(bot, MineshaftItem.CANE)); + farms.add(new Farm(bot, MineshaftItem.CARROT)); + farms.add(new Farm(bot, MineshaftItem.POTATO)); + } + + @Override + public void execute(MessageReceivedEvent e, CustomBot b, String[] args) throws CommandFail { + List<String> argList = Arrays.asList(args); + + if (bot.getPickaxes().isNether(e.getMember())) { + bot.sendErrorMessage(e, ":x: You cannot access your farm from the nether"); + return; + } + update(e.getMember()); + + if (args.length > 0 && "harvest".equalsIgnoreCase(args[0])) { + harvest(e, args); + return; + } + + if (args.length > 0 && "expand".equalsIgnoreCase(args[0])) { + expand(e, argList); + return; + } + + if (args.length > 0 && "plant".equalsIgnoreCase(args[0])) { + if (!plant(e, argList)) + bot.sendErrorMessage(e, String.format(":x: Usage `%sfarm plant [amount] [carrot|potato|cane]`", bot.getPrefixManager().getPrefix(e.getGuild()))); + return; + } + + long farmLevel = bot.getPickaxes().getFarmLevel(e.getMember()); + StringBuilder description = new StringBuilder(); + description.append(String.format("This is your farm.\nUse `%sfarm plant [carrot|potato|cane] [amount]` to plant\nUse `%sfarm harvest` to harvest your crops\nUse %s to expand your farm with `%sfarm expand`\n\n", + bot.getPrefixManager().getPrefix(e.getGuild()), + bot.getPrefixManager().getPrefix(e.getGuild()), + bot.getItem(MineshaftItem.BONEMEAL).getSymbol(), + bot.getPrefixManager().getPrefix(e.getGuild()))); + + description.append(String.format("Your farm current can currently hold `%s` crops\n\n", PeelingUtils.amountToString(farmLevel))); + + AtomicLong amount = new AtomicLong(); + farms.forEach(farm -> { + long level = Math.min(farm.getQuantity(e.getMember()), MAX_CROP_LEVEL); + long planted = farm.getPlanted(e.getMember()); + amount.addAndGet(planted); + + String emoji = getCropEmoji(farm.getItem(), (int) level); + + if (planted < 1) + return; + + IntStream.range(0, (int) Math.min(planted,12)).forEach(i -> { + description.append(emoji); + }); + + description.append(String.format("(%sx%s)\n", bot.getItem(farm.getItem()).getSymbol(), planted)); + }); + + if (amount.get() == 0) { + description.append("*You have no crops*"); + } + + EmbedBuilder em = new EmbedBuilder(); + em.setTitle(COMMAND_TITLE); + em.setDescription(description); + em.setColor(COMMAND_COLOUR); + + if (farmLevel == 0) { + em.setFooter(EmojiParser.parseToUnicode(":bulb:") +"Use bonemeal to expand your farm with m!farm expand"); + } + + e.getMessage().replyEmbeds(em.build()).queue(); + } + + private boolean expand(MessageReceivedEvent e, List<String> args) { + MineshaftItem item = MineshaftItem.BONEMEAL; + + long q = getItemAmountFromArgs(e, args, item); + if (q > bot.getItem(e.getMember(), item) || q < 1) { + bot.sendErrorMessage(e, ":x: You do not have enough " + bot.getItem(item).getSymbol()); + return false; + } + + bot.removeItem(e.getMember(), item, q); + long farmLevel = bot.getPickaxes().getFarmLevel(e.getMember()); + bot.getPickaxes().setFarmLevel(e.getMember(), farmLevel + q); + farmLevel = bot.getPickaxes().getFarmLevel(e.getMember()); + + bot.sendSuccessMessage(e, ":white_check_mark: You expanded your farm. Now it can hold " + farmLevel + " crops"); + return true; + } + + private long getItemAmountFromArgs(MessageReceivedEvent e, List<String> args, MineshaftItem item) { + Optional<String> all = args.stream().filter(s -> s.equals("all")).findFirst(); + if (all.isEmpty()) { + Optional<Long> quantity = args.stream().filter(s -> PeelingUtils.isLong(s)).map(s -> Long.parseLong(s)).findFirst(); + if (quantity.isPresent()) + return Math.abs(quantity.get()); + } + + return bot.getItem(item).get(e.getMember()); + } + + public String getCropEmoji(MineshaftItem item, int level) { + return Crop.valueOf(item.toString().toUpperCase()).getEmoji()[(int)Math.max(0, Math.min(2, level))]; + } + + public void update(Member m) { + farms.forEach(farm -> { + update(farm, m); + }); + } + + public void update(Farm 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 / TIME_BETWEEN_UPDATES; + + farm.setQuantity(m, Math.min(farm.getQuantity(m) + updates, MAX_CROP_LEVEL)); + farm.setNextUpdate(m, next + TIME_BETWEEN_UPDATES*updates); + } + + public void harvest(MessageReceivedEvent e, String[] args) { + Map<MineshaftItem, Long> award = new HashMap<>(); + AtomicLong total = new AtomicLong(); + farms.forEach( f -> { + long amount = harvest(f, e.getMember()); + total.addAndGet(amount); + if (amount > 0) + award.put(f.getItem(), amount); + }); + + String description = String.format("You harvested your crops: %s\nDon't forget to replant your farm!", bot.createItemList(award, "+%s", ",")); + + if (total.get() == 0) { + bot.sendErrorMessage(e, ":x: You have no crops!"); + return; + } + + EmbedBuilder em = new EmbedBuilder(); + em.setTitle(COMMAND_TITLE); + em.setDescription(description); + em.setColor(COMMAND_COLOUR); + + e.getMessage().replyEmbeds(em.build()).queue(); + } + + public boolean plant(MessageReceivedEvent e, List<String> args) { + if (args.size() > 3) + return false; + + Optional<String> resourceName = args.stream().filter(s -> !s.equalsIgnoreCase("all") && !s.equalsIgnoreCase("plant") && !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 q = 0; + Optional<String> all = args.stream().filter(s -> s.equals("all")).findFirst(); + if (all.isEmpty()) { + Optional<Long> 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 = bot.getItem(item).get(e.getMember()); + } + + + Optional<Farm> farm = farms.stream().filter(f -> f.getItem() == item).findFirst(); + if (farm.isEmpty()) { + bot.sendErrorMessage(e, ":x: This item cannot be planted"); + return true; + } + + if (q > bot.getItem(item).get(e.getMember())) { + bot.sendErrorMessage(e, ":x: You dont have enough " + bot.getItem(item).getSymbol()); + return true; + } + + long planted = plant(farm.get(), e.getMember(), q); + if (planted > 0) + bot.sendSuccessMessage(e, String.format("You planted %s in your farm", bot.getItem(item).prettyValue(planted))); + else + bot.sendErrorMessage(e, ":x: You have no more space in your farm!\n Expand with `m!farm expand [amount]`"); + return true; + } + + public long harvest(Farm farm, Member member) { + long toGive = ((1+farm.getQuantity(member))) * farm.getPlanted(member); + farm.setQuantity(member, 0); + farm.setPlanted(member, 0); + + bot.addItem(member, farm.getItem(), toGive); + bot.addItem(member, MineshaftItem.XP, (long) (Math.random() * XP_PER_ITEM * toGive)); + return toGive; + } + + public long plant(Farm farm, Member member, long amount) { + long farmLevel = bot.getPickaxes().getFarmLevel(member); + long totalPlanted = getTotalPlanted(member); + if (totalPlanted + amount > farmLevel) { + amount = farmLevel - totalPlanted; + } + + if (amount <= 0) { + return 0; + } + + farm.incrementPlanted(member, amount); + farm.setQuantity(member, 0); + + bot.removeItem(member, farm.getItem(), amount); + return amount; + } + + public long getTotalPlanted(Member m) { + return farms.stream().mapToLong(f -> f.getPlanted(m)).sum(); + } +} |
