use of com.sx4.bot.entities.economy.item.Crate in project Sx4 by sx4-discord-bot.
the class AdventCalendarCommand method onCommand.
public void onCommand(Sx4CommandEvent event) {
ZonedDateTime now = ZonedDateTime.now(ZoneOffset.UTC);
int day = now.getDayOfMonth();
if (now.getMonthValue() != 12 || day > 24) {
event.replyFormat("There's no advent calendar box for the %s %s :no_entry:", NumberUtility.getSuffixed(day), now.getMonth().getDisplayName(TextStyle.FULL, Locale.UK)).queue();
return;
}
EconomyManager manager = event.getBot().getEconomyManager();
event.getMongo().withTransaction(session -> {
Document data = event.getMongo().getUsers().findOneAndUpdate(session, Filters.eq("_id", event.getAuthor().getIdLong()), Updates.addToSet("economy.opened", day), new FindOneAndUpdateOptions().upsert(true));
List<Integer> opened = data == null ? Collections.emptyList() : data.getEmbedded(List.of("economy", "opened"), Collections.emptyList());
if (opened.contains(day)) {
long secondsTillTomorrow = now.toLocalDate().atStartOfDay(ZoneOffset.UTC).plusDays(1).toEpochSecond() - now.toEpochSecond();
event.replyFormat("You've already opened today's box on your advent calendar%s :no_entry:", day != 24 ? ", you can open tomorrows in **" + TimeUtility.LONG_TIME_FORMATTER.parse(Duration.of(secondsTillTomorrow, ChronoUnit.SECONDS)) + "**" : "").queue();
session.abortTransaction();
return null;
}
List<Item> items = manager.getItems();
items.sort(Comparator.comparingLong(Item::getPrice).reversed());
Item item = items.get(items.size() - 1);
for (Item winnableItem : items) {
if (winnableItem instanceof Tool) {
continue;
}
int equation = (int) Math.ceil(winnableItem.getPrice() / Math.pow(day * 3, 2));
if (manager.getRandom().nextInt(equation + 1) == 0) {
item = winnableItem;
break;
}
}
if (opened.size() == 23) {
Crate present = manager.getItemById(PRESENT_CRATE, Crate.class);
List<Bson> update = List.of(Operators.set("item", present.toData()), Operators.set("amount", Operators.add(Operators.ifNull("$amount", 0L), 1L)));
event.getMongo().getItems().updateOne(session, Filters.and(Filters.eq("userId", event.getAuthor().getIdLong()), Filters.eq("item.id", item.getId())), update, new UpdateOptions().upsert(true));
}
List<Bson> update = List.of(Operators.set("item", item.toData()), Operators.set("amount", Operators.add(Operators.ifNull("$amount", 0L), 1L)));
event.getMongo().getItems().updateOne(session, Filters.and(Filters.eq("userId", event.getAuthor().getIdLong()), Filters.eq("item.id", item.getId())), update, new UpdateOptions().upsert(true));
return "You opened your advent calendar for the " + NumberUtility.getSuffixed(day) + " and got **" + item.getName() + "**" + (opened.size() == 23 ? " and a **Present Crate**" : "") + " :christmas_tree:";
}).whenComplete((content, exception) -> {
if (ExceptionUtility.sendExceptionally(event, exception) || content == null) {
return;
}
event.reply(content).queue();
});
}
use of com.sx4.bot.entities.economy.item.Crate in project Sx4 by sx4-discord-bot.
the class CrateCommand method buy.
@Command(value = "buy", description = "Buy a crate from the `crate shop`")
@CommandId(412)
@Examples({ "crate buy 2 Shoe Crate", "crate buy Shoe Crate", "crate buy 5 Shoe" })
public void buy(Sx4CommandEvent event, @Argument(value = "crates", endless = true) ItemStack<Crate> stack) {
long amount = stack.getAmount();
if (amount < 1) {
event.replyFailure("You need to buy at least 1 crate").queue();
return;
}
long price = stack.getTotalPrice();
Crate crate = stack.getItem();
event.getMongo().withTransaction(session -> {
UpdateResult result = event.getMongo().getUsers().updateOne(session, Filters.eq("_id", event.getAuthor().getIdLong()), List.of(EconomyUtility.decreaseBalanceUpdate(price)));
if (result.getModifiedCount() == 0) {
event.replyFormat("You do not have **$%,d** %s", price, event.getConfig().getFailureEmote()).queue();
session.abortTransaction();
return;
}
Bson filter = Filters.and(Filters.eq("userId", event.getAuthor().getIdLong()), Filters.eq("item.id", crate.getId()));
List<Bson> update = List.of(Operators.set("item", crate.toData()), Operators.set("amount", Operators.add(Operators.ifNull("$amount", 0L), amount)));
event.getMongo().getItems().updateOne(session, filter, update, new UpdateOptions().upsert(true));
}).whenComplete((updated, exception) -> {
if (ExceptionUtility.sendExceptionally(event, exception) || !updated) {
return;
}
event.replyFormat("You just bought `%,d %s` for **$%,d** %s", amount, crate.getName(), price, event.getConfig().getSuccessEmote()).queue();
});
}
use of com.sx4.bot.entities.economy.item.Crate in project Sx4 by sx4-discord-bot.
the class CrateCommand method shop.
@Command(value = "shop", description = "View all the crates you can buy")
@CommandId(411)
@Examples({ "crate shop" })
@BotPermissions(permissions = { Permission.MESSAGE_EMBED_LINKS })
public void shop(Sx4CommandEvent event) {
List<Crate> crates = event.getBot().getEconomyManager().getItems(Crate.class).stream().filter(Predicate.not(Crate::isHidden)).collect(Collectors.toList());
PagedResult<Crate> paged = new PagedResult<>(event.getBot(), crates).setPerPage(12).setCustomFunction(page -> {
EmbedBuilder embed = new EmbedBuilder().setDescription("Crates give you a random item, the better the crate the better the chance of a better item").setAuthor("Crate Shop", null, event.getSelfUser().getEffectiveAvatarUrl()).setTitle("Page " + page.getPage() + "/" + page.getMaxPage()).setFooter(PagedResult.DEFAULT_FOOTER_TEXT);
page.forEach((crate, index) -> embed.addField(crate.getName(), String.format("Price: $%,d\nContents: %s", crate.getPrice(), crate.getContentString()), true));
return new MessageBuilder().setEmbeds(embed.build());
});
paged.execute(event);
}
use of com.sx4.bot.entities.economy.item.Crate in project Sx4 by sx4-discord-bot.
the class DailyCommand method onCommand.
public void onCommand(Sx4CommandEvent event) {
List<Bson> update = List.of(Operators.set("economy.balance", Operators.let(new Document("reset", Operators.ifNull("$economy.resets.daily", 0L)).append("balance", Operators.ifNull("$economy.balance", 0L)), Operators.let(new Document("streak", Operators.cond(Operators.and(Operators.gte(Operators.nowEpochSecond(), "$$reset"), Operators.lt(Operators.nowEpochSecond(), Operators.add("$$reset", DailyCommand.COOLDOWN))), Operators.add(Operators.ifNull("$economy.streak", 0), 1), 0)), Operators.cond(Operators.lt(Operators.nowEpochSecond(), "$$reset"), "$$balance", Operators.add("$$balance", Operators.add(100L, Operators.multiply(Operators.min(10L, "$$streak"), Operators.add(20L, Operators.multiply(Operators.min(10L, "$$streak"), 5L))))))))), Operators.set("economy.streak", Operators.let(new Document("reset", Operators.ifNull("$economy.resets.daily", 0L)).append("streak", Operators.ifNull("$economy.streak", 0)), Operators.cond(Operators.and(Operators.gte(Operators.nowEpochSecond(), "$$reset"), Operators.lt(Operators.nowEpochSecond(), Operators.add("$$reset", DailyCommand.COOLDOWN))), Operators.add("$$streak", 1), Operators.cond(Operators.lt(Operators.nowEpochSecond(), "$$reset"), "$$streak", 0)))), Operators.set("economy.resets.daily", Operators.let(new Document("reset", Operators.ifNull("$economy.resets.daily", 0L)), Operators.cond(Operators.lt(Operators.nowEpochSecond(), "$$reset"), "$$reset", Operators.add(Operators.nowEpochSecond(), DailyCommand.COOLDOWN)))));
FindOneAndUpdateOptions options = new FindOneAndUpdateOptions().returnDocument(ReturnDocument.BEFORE).projection(Projections.include("economy.resets.daily", "economy.streak")).upsert(true);
EmbedBuilder embed = new EmbedBuilder().setAuthor(event.getAuthor().getName(), null, event.getAuthor().getEffectiveAvatarUrl()).setColor(event.getMember().getColor());
event.getMongo().findAndUpdateUserById(event.getAuthor().getIdLong(), update, options).thenCompose(data -> {
Document economy = (data == null ? MongoDatabase.EMPTY_DOCUMENT : data).get("economy", MongoDatabase.EMPTY_DOCUMENT);
long reset = economy.getEmbedded(List.of("resets", "daily"), 0L), timestamp = Clock.systemUTC().instant().getEpochSecond();
if (timestamp < reset) {
event.reply("Slow down! You can collect your daily in " + TimeUtility.LONG_TIME_FORMATTER.parse(reset - timestamp) + " :stopwatch:").queue();
return CompletableFuture.completedFuture(null);
}
int previousStreak = economy.get("streak", 0);
int streak = timestamp < reset + DailyCommand.COOLDOWN ? previousStreak + 1 : 0;
long money = 100 + Math.min(10, streak) * (20 + Math.min(10, streak) * 5L);
embed.setDescription("You have collected your daily money (**$" + money + "**)" + (streak == 0 && previousStreak != streak ? "\n\nIt has been over 2 days since you last collected your daily, your streak has been reset" : streak == 0 ? "" : "\nYou had a bonus of $" + (money - 100) + String.format(" for having a %,d day streak", streak)));
List<Crate> crates = new ArrayList<>();
if (streak != 0) {
for (Crate crate : event.getBot().getEconomyManager().getItems(Crate.class)) {
if (crate.isHidden()) {
continue;
}
double randomDouble = event.getBot().getEconomyManager().getRandom().nextDouble();
if (randomDouble <= Math.min(1D / Math.ceil((crate.getPrice() / 10D / streak) * 4), 1)) {
crates.add(crate);
}
}
}
crates.sort(Comparator.comparingLong(Crate::getPrice).reversed());
if (!crates.isEmpty()) {
Crate crate = crates.get(0);
embed.appendDescription(String.format("\n\nYou also received a `%s` (**$%,d**), it has been added to your items.", crate.getName(), crate.getPrice()));
List<Bson> crateUpdate = List.of(Operators.set("item", crate.toData()), Operators.set("amount", Operators.add(Operators.ifNull("$amount", 0L), 1L)));
return event.getMongo().updateItem(Filters.and(Filters.eq("userId", event.getAuthor().getIdLong()), Filters.eq("item.id", crate.getId())), crateUpdate, new UpdateOptions().upsert(true));
}
return CompletableFuture.completedFuture(UpdateResult.acknowledged(0L, 0L, null));
}).whenComplete((result, exception) -> {
if (ExceptionUtility.sendExceptionally(event, exception) || result == null) {
return;
}
event.reply(embed.build()).queue();
});
}
Aggregations