summaryrefslogtreecommitdiff
path: root/src/main/java/net/uomc/mineshaft/farm/TradeCommand.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/TradeCommand.java
parentda9ece80133a33aff456d30854adc095b8f303ab (diff)
Add farm, sleep and trade
Diffstat (limited to 'src/main/java/net/uomc/mineshaft/farm/TradeCommand.java')
-rw-r--r--src/main/java/net/uomc/mineshaft/farm/TradeCommand.java239
1 files changed, 239 insertions, 0 deletions
diff --git a/src/main/java/net/uomc/mineshaft/farm/TradeCommand.java b/src/main/java/net/uomc/mineshaft/farm/TradeCommand.java
new file mode 100644
index 0000000..f512afe
--- /dev/null
+++ b/src/main/java/net/uomc/mineshaft/farm/TradeCommand.java
@@ -0,0 +1,239 @@
+package net.uomc.mineshaft.farm;
+
+import java.awt.Color;
+import java.util.ArrayList;
+import java.util.concurrent.TimeUnit;
+import java.util.function.Consumer;
+
+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.MessageChannel;
+import net.dv8tion.jda.api.entities.emoji.Emoji;
+import net.dv8tion.jda.api.entities.emoji.UnicodeEmoji;
+import net.dv8tion.jda.api.events.message.MessageReceivedEvent;
+import net.dv8tion.jda.api.events.message.react.MessageReactionAddEvent;
+import net.uomc.mineshaft.Mineshaft;
+import net.uomc.mineshaft.MineshaftItem;
+import net.uomc.mineshaft.resources.Resource;
+
+public class TradeCommand extends CooldownCommand {
+
+ private static final UnicodeEmoji EXCLAIM = Emoji.fromUnicode(EmojiParser.parseToUnicode(":grey_exclamation:"));
+ private static final UnicodeEmoji YES = Emoji.fromUnicode(EmojiParser.parseToUnicode(":white_check_mark:"));
+ private static final UnicodeEmoji NO = Emoji.fromUnicode(EmojiParser.parseToUnicode(":x:"));
+ private static final Color COMMAND_COLOR = PeelingUtils.hex2Rgb("#375482");
+ private static final String COMMAND_IMAGE = "https://minecraft.wiki/images/thumb/Wandering_Trader_JE1_BE1.png/270px-Wandering_Trader_JE1_BE1.png?62e9e";
+ private static final String COMMAND_TITLE = "A wandering trader has spawned";
+ private static final String ACCEPT_STRING = "accept";
+ private static final double VALUE_MULTIPLIER = 1.1;
+ private static final double NEW_ITEM_ITEM_VALUE = 0.3;
+ private static final long TRADE_DURATION_SECONDS = 90;
+
+ private static final double MAX_AMOUNT_PERCENT = 0.2;
+
+ public static MineshaftItem[] traderItems = {
+ MineshaftItem.CARROT,
+ MineshaftItem.CANE,
+ MineshaftItem.POTATO,
+ MineshaftItem.BOOK,
+ MineshaftItem.LAPIS,
+ MineshaftItem.COAL,
+ };
+
+ public static MineshaftItem[] buyingItems = {
+ MineshaftItem.CARROT,
+ MineshaftItem.CANE,
+ MineshaftItem.POTATO
+ };
+
+ Mineshaft bot;
+
+ public TradeCommand(Mineshaft bot) {
+ super(bot);
+ setCommandDetails(CommandDetails.from("trade,trader,wanderingtrader", "trade with the wandering trader", "trade"));
+ this.bot = bot;
+
+ setCooldown(90l * 60l * 1000l);
+ }
+
+
+ @Override
+ public boolean trigger(MessageReceivedEvent e) {
+
+ long villagers = bot.getItem(e.getMember(), MineshaftItem.VILLAGER);
+
+ if (villagers < 1) {
+ bot.sendErrorMessage(e, ":x: You need to have at least **"
+ + bot.getItem(MineshaftItem.VILLAGER).prettyValue(1)
+ + "** to use this!");
+ return false;
+ }
+
+ String description = "The trader has a deal for you:\n\n";
+
+ MineshaftItem trade = newTrade();
+ boolean inverse = isInverseTrade(e.getMember(), trade);
+
+ MineshaftItem giveItem;
+ MineshaftItem getItem;
+
+ if (inverse) {
+ giveItem = trade;
+ getItem = MineshaftItem.EMERALD;
+ } else {
+ getItem = trade;
+ giveItem = MineshaftItem.EMERALD;
+ }
+
+ long q = getTradeQuantity(e.getMember(), getItem);
+ long p = getPrice(giveItem, getItem, q);
+
+ long userGive = bot.getItem(e.getMember(), giveItem);
+ long userGet = bot.getItem(e.getMember(), getItem);
+
+ description += String.format("**%s**->**%s**", bot.getItem(giveItem).prettyValue(p), bot.getItem(getItem).prettyValue(q));
+
+ description += String.format(
+ "\n\n:warning:Warning this offer expires in %s and you will need to wait `%s` before trading again",
+ PeelingUtils.formatTimeRelativeFromNow(TRADE_DURATION_SECONDS * 1000l),
+ PeelingUtils.formatTime(getCooldown(), false)
+ );
+
+ description += String.format("\n\nYou have **%s**", bot.getItem(giveItem).prettyValue(userGive));
+ if (userGet > 0) {
+ description += String.format(", **%s**", bot.getItem(getItem).prettyValue(userGet));
+ }
+
+ EmbedBuilder em = new EmbedBuilder();
+ em.setTitle(COMMAND_TITLE);
+ em.setDescription(description);
+ em.setThumbnail(COMMAND_IMAGE);
+ em.setColor(COMMAND_COLOR);
+
+ e.getMessage().replyEmbeds(em.build()).queue(m -> {
+ m.addReaction(YES).queue(m1 -> {
+ m.addReaction(NO).queue(m2 -> {
+ EventWaiter eventWaiter = new EventWaiter();
+ e.getMessage().getJDA().addEventListener(eventWaiter);
+
+ eventWaiter.waitForEvent(MessageReactionAddEvent.class,
+ e1 -> {
+ if (!e1.getMessageId().equals(m.getId()))
+ return false;
+
+ if (!e1.getMember().getId().equals(e.getMember().getId()))
+ return false;
+
+
+ if (e1.getEmoji().asUnicode().getFormatted().equals(YES.getFormatted()))
+ return true;
+
+ if (e1.getEmoji().asUnicode().getFormatted().equals(NO.getFormatted()))
+ return true;
+
+ return false;
+ }, e1 -> {
+ if (e1.getEmoji().asUnicode().getFormatted().equals(YES.getFormatted())) {
+ acceptTrade(e.getMember(), giveItem, getItem, q, p, m);
+ } else {
+ m.delete().queue();
+ }
+ }, TRADE_DURATION_SECONDS, TimeUnit.SECONDS, () -> {
+ m.delete().queue();
+ });
+ });
+ });
+
+ });
+
+ e.getMessage().addReaction(EXCLAIM).queue();
+ return true;
+ }
+
+ private void acceptTrade(Member member, MineshaftItem giveItem, MineshaftItem getItem, long quantity, long price, Message message) {
+ String description = "";
+ long userGive = bot.getItem(member, giveItem);
+
+ if (userGive >= price) {
+ bot.removeItem(member, giveItem, price);
+ bot.addItem(member, getItem, quantity);
+
+ description = String.format("You accepted the trade! +**%s**, -**%s**", bot.getItem(getItem).prettyValue(quantity), bot.getItem(giveItem).prettyValue(price));
+ } else {
+ description = String.format("You don't have enough! You have **%s**", bot.getItem(giveItem).prettyValue(userGive));
+ }
+
+ description += "\nThe trader leaves, for now...";
+
+ EmbedBuilder em = new EmbedBuilder();
+ em.setTitle(COMMAND_TITLE);
+ em.setDescription(description);
+ em.setThumbnail(COMMAND_IMAGE);
+ em.setColor(COMMAND_COLOR);
+
+ message.clearReactions().queue(m -> {
+ message.editMessageEmbeds(em.build()).queue(m2 -> {
+ //m2.delete().queueAfter(10, TimeUnit.SECONDS);
+ });
+ });
+ }
+
+ public void cleanup(MessageChannel channel, Message message) {
+ message.delete().queue(a -> {}, x -> {});
+
+ channel.getHistoryAfter(message, 100).queueAfter(5, TimeUnit.SECONDS, h -> {
+ ArrayList<Message> msgs = new ArrayList<Message>();
+ h.getRetrievedHistory().forEach(m -> {
+ if (m.getContentRaw().equalsIgnoreCase(ACCEPT_STRING)) {
+ msgs.add(m);
+ }
+ });
+ PeelingUtils.bulkDelte(channel, msgs);
+ });
+ ;
+ }
+
+
+ public MineshaftItem newTrade() {
+ return traderItems[(int) (traderItems.length * Math.random())];
+ }
+
+ public long getTradeQuantity(Member m, MineshaftItem item) {
+ return (long) ((Math.random() * MAX_AMOUNT_PERCENT * bot.getItem(m, item)) + 1);
+ }
+
+ public long getPrice(MineshaftItem giveItem, MineshaftItem getItem, long quantity) {
+ long giveValue = bot.getItem(giveItem).getValue();
+ if (giveValue <= 0) {
+ giveValue = (long) (bot.getResourceManager().getTotalResources() * NEW_ITEM_ITEM_VALUE * Math.random());
+ }
+
+ long getValue = bot.getItem(getItem).getValue();
+ if (getValue <= 0) {
+ getValue = (long) (bot.getResourceManager().getTotalResources() * NEW_ITEM_ITEM_VALUE * Math.random());
+ }
+
+ return (long) (quantity * getValue * VALUE_MULTIPLIER / giveValue) + 1;
+ }
+
+ public boolean isInverseTrade(Member member, MineshaftItem item) {
+ boolean isBuying = false;
+ for (int i = 0; i < buyingItems.length; i++) {
+ if (buyingItems[i] == item) {
+ isBuying = true;
+ break;
+ }
+ }
+ if (isBuying)
+ return bot.getItem(member, item) > 0;
+
+ return false;
+ }
+}