From 5a008748459e230de0e875afff59e3b92c7aca0c Mon Sep 17 00:00:00 2001 From: davidovski Date: Fri, 31 Oct 2025 17:49:48 +0000 Subject: Work on v0.6 --- src/main/java/net/uomc/mineshaft/RobCommand.java | 178 ++++++++++++++++++----- 1 file changed, 140 insertions(+), 38 deletions(-) (limited to 'src/main/java/net/uomc/mineshaft/RobCommand.java') diff --git a/src/main/java/net/uomc/mineshaft/RobCommand.java b/src/main/java/net/uomc/mineshaft/RobCommand.java index ace95e7..bfc0c51 100644 --- a/src/main/java/net/uomc/mineshaft/RobCommand.java +++ b/src/main/java/net/uomc/mineshaft/RobCommand.java @@ -1,47 +1,41 @@ 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 java.util.function.Consumer; 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.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.MessageEmbed; -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; public class RobCommand extends CooldownCommand { - private static final long DROP_DURATION_SECONDS = 90; - private static final String LOOT_STRING = "loot"; - - private static final long MAX_DAMAGE = 20; + private static final UnicodeEmoji FLEE_EMOJI = Emoji.fromUnicode(EmojiParser.parseToUnicode(":runner:")); + private static final UnicodeEmoji FIGHT_EMOJI = Emoji.fromUnicode(EmojiParser.parseToUnicode(":crossed_swords:")); + private static final long BASE_DAMAGE = 14; + private static final long CONFIRM_WAIT_SECONDS = 10; + private static final double FLEE_CHANCE = 0.3; private Mineshaft bot; - private @NotNull String embedTitle; - private @NotNull String pvpEmoji; + private String pvpEmoji; protected RobCommand(Mineshaft bot) { super(bot); - setCooldown(60l * 30l * 1000l); + // TODO reset this + // setCooldown(60l * 30l * 1000l); + setCooldown(0l); this.bot = bot; - setDetails(CommandDetails.from("kill,pvp,rob", "kill another player")); - embedTitle = EmojiParser.parseToUnicode(":crossed_swords:"); + setDetails(CommandDetails.from("kill,pvp,rob,fight,challenge", "kill another player")); pvpEmoji = EmojiParser.parseToUnicode(":crossed_swords:"); } @@ -59,36 +53,144 @@ public class RobCommand extends CooldownCommand { return false; } Member target = mentionToMember.get(); + if (target.equals(e.getMember())) { + e.getMessage().reply(":x: You cannot fight yourself!").queue(); + return false; + } - 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(); + if (!canFight(e.getMember())) { + e.getMessage().reply(":x: You tried to kill " + target.getAsMention() + + " you don't have a sword to fight with!\nUse `m!blacksmith` to forge one").queue(); + return false; + } + + if (bot.getPlayerStats().isNether(target) != bot.getPlayerStats().isNether(e.getMember())) { + e.getMessage().reply( + ":x: You tried to kill " + target.getAsMention() + " but they were in a different dimension!") + .queue(); return false; } e.getMessage().addReaction(Emoji.fromUnicode(pvpEmoji)).queue(); EmbedBuilder eb = new EmbedBuilder(); - eb.setTitle(pvpEmoji); - eb.getDescriptionBuilder().append(e.getAuthor().getAsMention() + " is fighting " + target.getAsMention() + "..." ); + eb.setTitle("pvp"); + String startString = e.getAuthor().getAsMention() + " is fighting " + target.getAsMention() + "...\n\n"; + eb.getDescriptionBuilder().append(startString); + + eb.appendDescription(target.getAsMention() + ": React with " + FLEE_EMOJI.getFormatted() + " to flee"); + if (canFight(target)) { + eb.appendDescription(" or " + FIGHT_EMOJI.getFormatted() + " to fight back!"); + } + + eb.appendDescription("\n"); + eb.appendDescription(":warning: This chance will expire " + + PeelingUtils.formatTimeRelativeFromNow(CONFIRM_WAIT_SECONDS * 1000l) + "\n"); + eb.setColor(bot.color); - long damage = getDamage(e.getMember()); + long damage = bot.getHealths().calculateDamage(target, e.getMember(), false, BASE_DAMAGE); + + e.getMessage().replyEmbeds(eb.build()).queue(message -> { + + message.addReaction(FLEE_EMOJI).queue(); + if (canFight(target)) { + message.addReaction(FIGHT_EMOJI).queue(); + } + + message.addReaction(FLEE_EMOJI).queue((Void ignored) -> { + EventWaiter eventWaiter = new EventWaiter(); + e.getChannel().getJDA().addEventListener(eventWaiter); + + eventWaiter.waitForEvent(MessageReactionAddEvent.class, + e1 -> e1.getMessageId().equals(message.getId()) && e1.getUser().getId().equals(target.getId()) + && (FLEE_EMOJI.equals(e1.getReaction().getEmoji().asUnicode()) + || FIGHT_EMOJI.equals(e1.getReaction().getEmoji().asUnicode())), + e1 -> { + message.clearReactions().queue(); + eb.setDescription(startString); + + // target has a chance to evade the battle entirely + if (FLEE_EMOJI.equals(e1.getReaction().getEmoji().asUnicode())) { + if (Math.random() < FLEE_CHANCE) { + eb.appendDescription(FLEE_EMOJI.getFormatted() + target.getAsMention() + + " Managed to escape!\n"); + message.editMessageEmbeds(eb.build()).queueAfter(1, TimeUnit.SECONDS, m -> { + m.editMessageEmbeds(eb.build()).queue(); + }); + return; + + } else { + // fight happens anyway, if they can fight they will fight second + eb.appendDescription( + ":x:" + target.getAsMention() + " tried running away but failed!\n\n"); + message.editMessageEmbeds(eb.build()).queueAfter(1, TimeUnit.SECONDS, m1 -> { + fightBack(m1, e.getMember(), target, damage, eb); + }); + return; + } + } + + // target gets to fight first then attacker fights + if (FIGHT_EMOJI.equals(e1.getReaction().getEmoji().asUnicode()) && canFight(target)) { + eb.appendDescription(FIGHT_EMOJI.getFormatted() + target.getAsMention() + + " Anticipated the attack and got the first strike\n"); + message.editMessageEmbeds(eb.build()).queueAfter(1, TimeUnit.SECONDS, m1 -> { + fightBack(m1, target, e.getMember(), damage, eb); + }); + return; + } + + // attacker gets an attack and thats it + addFightMessage(message, target, e.getMember(), eb, damage, null); + }, CONFIRM_WAIT_SECONDS, TimeUnit.SECONDS, () -> { + message.clearReactions().queue(); + eb.setDescription(startString); + message.editMessageEmbeds(eb.build()).queueAfter(1, TimeUnit.SECONDS, m -> { + // attacker gets an attack (ambush) + addFightMessage(m, target, e.getMember(), eb, damage, null); + }); + }); + }); + }); + return true; + } + + public void fightBack(Message message, Member target, Member agressor, long attackerDamage, EmbedBuilder eb) { + long damage = bot.getHealths().calculateDamage(agressor, target, false, BASE_DAMAGE); + + addFightMessage(message, agressor, target, eb, damage, m -> { + addFightMessage(message, target, agressor, eb, attackerDamage, null); + }); + } + + public void addFightMessage(Message message, Member target, Member attacker, EmbedBuilder eb, long damage, + Consumer callback) { + String damageString = " (" + PlayerHealths.getHPString(-damage) + ")"; - e.getMessage().replyEmbeds(eb.build()).delay(5, TimeUnit.SECONDS, e.getJDA().getRateLimitPool()).flatMap(m -> { - String deathMessage = pvpEmoji + target.getAsMention() + " was slain by " + e.getAuthor().getAsMention() - + damageString; - long hp = bot.getHealths().damage(m, target, damage, deathMessage); - return hp > 0; - }, m -> { - eb.setDescription(e.getAuthor().getAsMention() + " attacked " + target.getAsMention() + damageString - + "\n\n" + "They are now on " + bot.getHealths().getHPString(target)); - return m.editMessageEmbeds(eb.build()); - }).queue(); - return true; + String swordEmoji = bot.getSword(attacker).getEmoji(); + String deathMessage = swordEmoji + target.getAsMention() + " was slain by " + attacker.getAsMention() + + damageString; + long hp = bot.getHealths().damage(message, target, damage, deathMessage); + + if (hp <= 0) { + return; + } + + eb.appendDescription( + swordEmoji + attacker.getAsMention() + " attacked " + target.getAsMention() + damageString + "\n"); + + if (callback != null) { + message.editMessageEmbeds(eb.build()).queue(callback); + } else { + eb.appendDescription("\n" + target.getAsMention() + " is now on " + bot.getHealths().getHPString(target)); + message.editMessageEmbeds(eb.build()).queue(); + } + return; } - private long getDamage(Member member) { - return (long) Math.ceil(MAX_DAMAGE * Math.random()); + public boolean canFight(Member member) { + return bot.getSword(member).getLevel() != 0; } } -- cgit v1.2.3