Skip to content

Commit 97a03ab

Browse files
Add /crash command
1 parent 2656409 commit 97a03ab

5 files changed

Lines changed: 148 additions & 3 deletions

File tree

src/main/java/technobot/commands/CommandRegistry.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
import technobot.commands.automation.AutoRoleCommand;
1515
import technobot.commands.casino.BlackjackCommand;
1616
import technobot.commands.casino.CoinflipCommand;
17+
import technobot.commands.casino.CrashCommand;
1718
import technobot.commands.casino.SlotsCommand;
1819
import technobot.commands.economy.*;
1920
import technobot.commands.fun.*;
@@ -58,6 +59,7 @@ public CommandRegistry(TechnoBot bot) {
5859
//Casino commands
5960
new BlackjackCommand(bot),
6061
new SlotsCommand(bot),
62+
new CrashCommand(bot),
6163
new CoinflipCommand(bot),
6264

6365
//Automation commands

src/main/java/technobot/commands/casino/CoinflipCommand.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ public CoinflipCommand(TechnoBot bot) {
3232
this.args.add(new OptionData(OptionType.STRING, "choice", "The side you think the coin will land on", true)
3333
.addChoice("heads", "heads")
3434
.addChoice("tails", "tails"));
35-
this.args.add(new OptionData(OptionType.INTEGER, "bet", "The amount you want to wager", true).setMinValue(0));
35+
this.args.add(new OptionData(OptionType.INTEGER, "bet", "The amount you want to wager", true).setMinValue(1));
3636
}
3737

3838
@Override
@@ -85,7 +85,7 @@ public void execute(SlashCommandInteractionEvent event) {
8585
new Timer().schedule(new TimerTask() {
8686
@Override
8787
public void run() {
88-
msg.retrieveOriginal().flatMap(hook -> hook.editMessage(" ").setEmbeds(embed.build())).queue();
88+
msg.editOriginalEmbeds(embed.build()).queue();
8989
}
9090
}, 2500L);
9191
});
Lines changed: 137 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,137 @@
1+
package technobot.commands.casino;
2+
3+
import net.dv8tion.jda.api.EmbedBuilder;
4+
import net.dv8tion.jda.api.entities.Guild;
5+
import net.dv8tion.jda.api.entities.MessageEmbed;
6+
import net.dv8tion.jda.api.entities.User;
7+
import net.dv8tion.jda.api.events.interaction.command.SlashCommandInteractionEvent;
8+
import net.dv8tion.jda.api.interactions.commands.OptionType;
9+
import net.dv8tion.jda.api.interactions.commands.build.OptionData;
10+
import net.dv8tion.jda.api.interactions.components.buttons.Button;
11+
import technobot.TechnoBot;
12+
import technobot.commands.Category;
13+
import technobot.commands.Command;
14+
import technobot.data.GuildData;
15+
import technobot.handlers.economy.EconomyHandler;
16+
import technobot.listeners.ButtonListener;
17+
import technobot.util.embeds.EmbedColor;
18+
import technobot.util.embeds.EmbedUtils;
19+
20+
import java.util.*;
21+
import java.util.concurrent.*;
22+
23+
/**
24+
* Command that plays the crash gambling game.
25+
*
26+
* @author TechnoVision
27+
*/
28+
public class CrashCommand extends Command {
29+
30+
public static final HashMap<Long, CrashGame> games = new HashMap<>();
31+
private static final ScheduledExecutorService tasks = Executors.newScheduledThreadPool(5);
32+
33+
public CrashCommand(TechnoBot bot) {
34+
super(bot);
35+
this.name = "crash";
36+
this.description = "Bet against a multiplier that crashes at any moment.";
37+
this.category = Category.CASINO;
38+
this.args.add(new OptionData(OptionType.INTEGER, "bet", "The amount you want to wager", true).setMinValue(1));
39+
}
40+
41+
@Override
42+
public void execute(SlashCommandInteractionEvent event) {
43+
// Get command data
44+
User user = event.getUser();
45+
long bet = event.getOption("bet").getAsLong();
46+
if (games.containsKey(user.getIdLong())) {
47+
String text = "You are already playing a game of crash!";
48+
event.replyEmbeds(EmbedUtils.createError(text)).setEphemeral(true).queue();
49+
return;
50+
}
51+
52+
// Charge player for bet
53+
EconomyHandler economyHandler = GuildData.get(event.getGuild()).economyHandler;
54+
long balance = economyHandler.getBalance(user.getIdLong());
55+
if (balance < bet) {
56+
String currency = economyHandler.getCurrency() + " **" + balance + "**";
57+
String text = "You don't have enough money for this bet. You currently have " + currency + " in cash.";
58+
event.replyEmbeds(EmbedUtils.createError(text)).setEphemeral(true).queue();
59+
return;
60+
}
61+
economyHandler.removeMoney(user.getIdLong(), bet);
62+
63+
// Setup crash game
64+
double multiplier = 0.01 + (0.99 / ThreadLocalRandom.current().nextDouble());
65+
if (multiplier > 30) multiplier = 30;
66+
double finalMultiplier = multiplier;
67+
EmbedBuilder embed = new EmbedBuilder()
68+
.setColor(EmbedColor.DEFAULT.color)
69+
.setAuthor(user.getAsTag(), null, user.getEffectiveAvatarUrl())
70+
.setDescription("Your profit: " + economyHandler.getCurrency() + " " + EconomyHandler.FORMATTER.format(bet))
71+
.addField("Multiplier", "x1.00", false);
72+
73+
// Start crash game
74+
String uuid = user.getId() + ":" + UUID.randomUUID();
75+
Button button = Button.primary("crash:cashout:"+uuid+":"+bet, "Cashout");
76+
ButtonListener.buttons.put(uuid, List.of(button));
77+
event.replyEmbeds(embed.build()).addActionRow(button).queue(msg -> {
78+
ScheduledFuture task = tasks.scheduleAtFixedRate(() -> {
79+
CrashGame game = games.get(user.getIdLong());
80+
game.currMultiplier += 0.1;
81+
String multiplierString = "x"+String.format("%.2f", game.currMultiplier);
82+
EmbedBuilder embed2 = new EmbedBuilder().setAuthor(user.getAsTag(), null, user.getEffectiveAvatarUrl());
83+
if (game.currMultiplier >= game.maxMultiplier) {
84+
embed2.setColor(EmbedColor.ERROR.color);
85+
embed2.setDescription("Result: Loss " + economyHandler.getCurrency() + " -" + EconomyHandler.FORMATTER.format(bet));
86+
embed2.addField("Crashed At", multiplierString, false);
87+
msg.editOriginalEmbeds(embed2.build()).queue();
88+
games.remove(user.getIdLong()).task.cancel(true);
89+
ButtonListener.buttons.remove(uuid);
90+
} else {
91+
int profit = (int) (((double)bet)*game.currMultiplier);
92+
embed2.setColor(EmbedColor.DEFAULT.color);
93+
embed2.setDescription("Your profit: " + economyHandler.getCurrency() + " " + EconomyHandler.FORMATTER.format(profit));
94+
embed2.addField("Multiplier", multiplierString, false);
95+
msg.editOriginalEmbeds(embed2.build()).queue();
96+
}
97+
}, 1500, 1500, TimeUnit.MILLISECONDS);
98+
99+
games.put(user.getIdLong(), new CrashGame(task, 1.0, finalMultiplier, bet));
100+
});
101+
}
102+
103+
public static MessageEmbed cashout(Guild guild, User user) {
104+
// Cancel game
105+
CrashGame game = games.remove(user.getIdLong());
106+
game.task.cancel(true);
107+
108+
// Award profit
109+
int profit = (int) (((double)game.bet)*game.currMultiplier);
110+
EconomyHandler econ = GuildData.get(guild).economyHandler;
111+
econ.addMoney(user.getIdLong(), profit);
112+
113+
// Send result embed
114+
String multiplierString = "x"+String.format("%.2f", game.currMultiplier);
115+
return new EmbedBuilder()
116+
.setColor(EmbedColor.SUCCESS.color)
117+
.setAuthor(user.getAsTag(), null, user.getEffectiveAvatarUrl())
118+
.setDescription("Result: Win " + econ.getCurrency() + " " + EconomyHandler.FORMATTER.format(profit))
119+
.addField("Multiplier", multiplierString, false)
120+
.build();
121+
}
122+
123+
public static class CrashGame {
124+
125+
ScheduledFuture task;
126+
double currMultiplier;
127+
double maxMultiplier;
128+
long bet;
129+
130+
public CrashGame(ScheduledFuture task, double currMultiplier, double maxMultiplier, long bet) {
131+
this.task = task;
132+
this.currMultiplier = currMultiplier;
133+
this.maxMultiplier = maxMultiplier;
134+
this.bet = bet;
135+
}
136+
}
137+
}

src/main/java/technobot/commands/casino/SlotsCommand.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ public SlotsCommand(TechnoBot bot) {
3232
this.name = "slots";
3333
this.description = "Spin the slot machine.";
3434
this.category = Category.CASINO;
35-
this.args.add(new OptionData(OptionType.INTEGER, "bet", "The amount you want to wager", true).setMinValue(0));
35+
this.args.add(new OptionData(OptionType.INTEGER, "bet", "The amount you want to wager", true).setMinValue(1));
3636
this.args.add(new OptionData(OptionType.STRING, "theme", "The theme of the slot machine")
3737
.addChoice("fruity", "fruity")
3838
.addChoice("luxury", "luxury")

src/main/java/technobot/listeners/ButtonListener.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
import net.dv8tion.jda.api.requests.restaction.WebhookMessageAction;
1515
import net.dv8tion.jda.api.requests.restaction.interactions.ReplyCallbackAction;
1616
import technobot.commands.casino.BlackjackCommand;
17+
import technobot.commands.casino.CrashCommand;
1718
import technobot.data.GuildData;
1819
import technobot.util.embeds.EmbedUtils;
1920
import technobot.util.enums.Cards;
@@ -221,5 +222,10 @@ else if (pressedArgs[0].equals("blackjack") && storedArgs[0].equals("blackjack")
221222
}
222223
event.editComponents(ActionRow.of(buttons.get(uuid))).setEmbeds(embed).queue();
223224
}
225+
else if (pressedArgs[0].equals("crash") && storedArgs[0].equals("crash")) {
226+
MessageEmbed embed = CrashCommand.cashout(event.getGuild(), event.getUser());
227+
Button disabledButton = buttons.remove(uuid).get(0).asDisabled();
228+
event.editComponents(ActionRow.of(disabledButton)).setEmbeds(embed).queue();
229+
}
224230
}
225231
}

0 commit comments

Comments
 (0)