summaryrefslogtreecommitdiff
path: root/src/main/java/net/uomc/mineshaft/farm/FarmCommand.java
diff options
context:
space:
mode:
authordavidovski <david@davidovski.xyz>2025-10-19 16:16:05 +0100
committerdavidovski <david@davidovski.xyz>2025-10-19 16:16:05 +0100
commitfff63aaea786a5f1c59bbf99c999a2aa7bb810e5 (patch)
treeb8c55be02d1e1f8575f5434a254d1593ede63432 /src/main/java/net/uomc/mineshaft/farm/FarmCommand.java
parentda9ece80133a33aff456d30854adc095b8f303ab (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.java277
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();
+ }
+}