Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

WIP on epicItemShop SE #2707

Merged
merged 4 commits into from
Dec 18, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
79 changes: 79 additions & 0 deletions Core/src/core/smallEvents/epicItemShop.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
import {Shop} from "./interfaces/Shop";
import {GenericItem} from "../../data/GenericItem";
import {RandomUtils} from "../../../../Lib/src/utils/RandomUtils";
import {SmallEventConstants} from "../../../../Lib/src/constants/SmallEventConstants";
import {generateRandomItem} from "../utils/ItemUtils";
import {ItemCategory, ItemConstants} from "../../../../Lib/src/constants/ItemConstants";
import {makePacket} from "../../../../Lib/src/packets/DraftBotPacket";
import {SmallEventFuncs} from "../../data/SmallEvent";
import {MapConstants} from "../../../../Lib/src/constants/MapConstants";
import Player from "../database/game/models/Player";
import {
SmallEventEpicItemShopAcceptPacket,
SmallEventEpicItemShopCannotBuyPacket,
SmallEventEpicItemShopRefusePacket
} from "../../../../Lib/src/packets/smallEvents/SmallEventEpicItemShopPacket";
import {
ReactionCollectorEpicShopSmallEvent,
ReactionCollectorEpicShopSmallEventData
} from "../../../../Lib/src/packets/interaction/ReactionCollectorEpicShopSmallEvent";

class ShopSmallEvent extends Shop<
SmallEventEpicItemShopAcceptPacket,
SmallEventEpicItemShopRefusePacket,
SmallEventEpicItemShopCannotBuyPacket,
ReactionCollectorEpicShopSmallEvent
> {
getPriceMultiplier(player: Player): number {
const destination = player.getDestination();
const origin = player.getPreviousMap();
if (destination.id === MapConstants.LOCATIONS_IDS.ROAD_OF_WONDERS || origin.id === MapConstants.LOCATIONS_IDS.ROAD_OF_WONDERS) {
return SmallEventConstants.EPIC_ITEM_SHOP.ROAD_OF_WONDERS_MULTIPLIER;
}
return RandomUtils.draftbotRandom.bool(SmallEventConstants.EPIC_ITEM_SHOP.GREAT_DEAL_PROBABILITY) ?
SmallEventConstants.EPIC_ITEM_SHOP.GREAT_DEAL_MULTIPLAYER : SmallEventConstants.EPIC_ITEM_SHOP.BASE_MULTIPLIER;
}

getRandomItem(): GenericItem {

Check warning on line 38 in Core/src/core/smallEvents/epicItemShop.ts

View workflow job for this annotation

GitHub Actions / eslint-core-module

Trailing spaces not allowed
// We exclude potions from the list of possible items
const categories = Object.values(ItemCategory).filter(
(value): value is ItemCategory => value !== ItemCategory.POTION
);

const randomCategory = RandomUtils.draftbotRandom.pick(categories);

return generateRandomItem(
randomCategory,
ItemConstants.RARITY.EPIC,
ItemConstants.RARITY.LEGENDARY
);
}

getAcceptPacket(): SmallEventEpicItemShopAcceptPacket {
return makePacket(SmallEventEpicItemShopAcceptPacket, {});
}

getRefusePacket(): SmallEventEpicItemShopRefusePacket {
return makePacket(SmallEventEpicItemShopRefusePacket, {});
}

getCannotBuyPacket(): SmallEventEpicItemShopCannotBuyPacket {
return makePacket(SmallEventEpicItemShopCannotBuyPacket, {});
}

getPopulatedReactionCollector(basePacket: ReactionCollectorEpicShopSmallEventData): ReactionCollectorEpicShopSmallEvent {
return new ReactionCollectorEpicShopSmallEvent({
...basePacket,
tip: RandomUtils.draftbotRandom.bool(SmallEventConstants.EPIC_ITEM_SHOP.REDUCTION_TIP_PROBABILITY)
&& this.itemMultiplier > SmallEventConstants.EPIC_ITEM_SHOP.ROAD_OF_WONDERS_MULTIPLIER
});
}
}

const shopSmallEvent = new ShopSmallEvent();

export const smallEventFuncs: SmallEventFuncs = {
canBeExecuted: shopSmallEvent.canBeExecuted,
executeSmallEvent: shopSmallEvent.executeSmallEvent
};
24 changes: 17 additions & 7 deletions Core/src/core/smallEvents/interfaces/Shop.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,18 @@ import {InventorySlots} from "../../database/game/models/InventorySlot";
import {SmallEventConstants} from "../../../../../Lib/src/constants/SmallEventConstants";
import {NumberChangeReason} from "../../../../../Lib/src/constants/LogsConstants";
import {DraftBotPacket} from "../../../../../Lib/src/packets/DraftBotPacket";
import {ReactionCollectorMerchant} from "../../../../../Lib/src/packets/interaction/ReactionCollectorMerchant";
import {ReactionCollectorAcceptReaction} from "../../../../../Lib/src/packets/interaction/ReactionCollectorPacket";
import {
ReactionCollector,
ReactionCollectorAcceptReaction
} from "../../../../../Lib/src/packets/interaction/ReactionCollectorPacket";
import {ReactionCollectorAnyShopSmallEventData} from "../../../../../Lib/src/packets/interaction/ReactionCollectorAnyShopSmallEvent";

export abstract class Shop<AcceptPacket extends SmallEventAnyShopAcceptedPacket, RefusePacket extends SmallEventAnyShopRefusedPacket, CannotBuyPacket extends SmallEventAnyShopCannotBuyPacket> {
export abstract class Shop<
Accept extends SmallEventAnyShopAcceptedPacket,
Refuse extends SmallEventAnyShopRefusedPacket,
CannotBuy extends SmallEventAnyShopCannotBuyPacket,
Collector extends ReactionCollector
> {
canBeExecuted = Maps.isOnContinent;

protected itemMultiplier: number;
Expand All @@ -31,18 +39,20 @@ export abstract class Shop<AcceptPacket extends SmallEventAnyShopAcceptedPacket,

abstract getPriceMultiplier(player: Player): number | Promise<number>;

abstract getAcceptPacket(): AcceptPacket;
abstract getAcceptPacket(): Accept;

abstract getRefusePacket(): Refuse;

abstract getRefusePacket(): RefusePacket;
abstract getCannotBuyPacket(): CannotBuy;

abstract getCannotBuyPacket(): CannotBuyPacket;
abstract getPopulatedReactionCollector(basePacket: ReactionCollectorAnyShopSmallEventData): Collector;

public executeSmallEvent: ExecuteSmallEventLike = async (context, response, player) => {
this.itemMultiplier = await this.getPriceMultiplier(player);
this.randomItem = await this.getRandomItem();
this.itemPrice = Math.round(getItemValue(this.randomItem) * this.itemMultiplier);

const collector = new ReactionCollectorMerchant({
const collector = this.getPopulatedReactionCollector({
item: toItemWithDetails(this.randomItem),
price: this.itemPrice
});
Expand Down
10 changes: 9 additions & 1 deletion Core/src/core/smallEvents/shop.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,12 @@ import {generateRandomItem} from "../utils/ItemUtils";
import {ItemRarity} from "../../../../Lib/src/constants/ItemConstants";
import {makePacket} from "../../../../Lib/src/packets/DraftBotPacket";
import {SmallEventFuncs} from "../../data/SmallEvent";
import {
ReactionCollectorShopSmallEvent,
ReactionCollectorShopSmallEventData
} from "../../../../Lib/src/packets/interaction/ReactionCollectorShopSmallEvent";

class ShopSmallEvent extends Shop<SmallEventShopAcceptPacket, SmallEventShopRefusePacket, SmallEventShopCannotBuyPacket> {
class ShopSmallEvent extends Shop<SmallEventShopAcceptPacket, SmallEventShopRefusePacket, SmallEventShopCannotBuyPacket, ReactionCollectorShopSmallEvent> {
getPriceMultiplier(): number | Promise<number> {
return RandomUtils.draftbotRandom.bool(SmallEventConstants.SHOP.SCAM_PROBABILITY) ? SmallEventConstants.SHOP.SCAM_MULTIPLIER : SmallEventConstants.SHOP.BASE_MULTIPLIER;
}
Expand All @@ -32,6 +36,10 @@ class ShopSmallEvent extends Shop<SmallEventShopAcceptPacket, SmallEventShopRefu
getCannotBuyPacket(): SmallEventShopCannotBuyPacket {
return makePacket(SmallEventShopCannotBuyPacket, {});
}

getPopulatedReactionCollector(basePacket: ReactionCollectorShopSmallEventData): ReactionCollectorShopSmallEvent {
return new ReactionCollectorShopSmallEvent(basePacket);
}
}

const shopSmallEvent = new ShopSmallEvent();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,10 @@ import {ReactionCollectorGobletsGameData} from "../../../../Lib/src/packets/inte
import {gobletsGameCollector} from "../../smallEvents/gobletsGame";
import {createUnlockCollector} from "../../commands/player/UnlockCommand";
import {ReactionCollectorUnlockData} from "../../../../Lib/src/packets/interaction/ReactionCollectorUnlock";
import {ReactionCollectorMerchantData} from "../../../../Lib/src/packets/interaction/ReactionCollectorMerchant";
import {smallShopCollector} from "../../smallEvents/shop";
import {epicItemShopCollector} from "../../smallEvents/epicItemShop";
import {ReactionCollectorEpicShopSmallEventData} from "../../../../Lib/src/packets/interaction/ReactionCollectorEpicShopSmallEvent";
import {ReactionCollectorShopSmallEventData} from "../../../../Lib/src/packets/interaction/ReactionCollectorShopSmallEvent";

export default class ReactionCollectorHandler {

Expand All @@ -62,7 +64,8 @@ export default class ReactionCollectorHandler {
ReactionCollectorHandler.collectorMap.set(ReactionCollectorGuildInviteData.name, createGuildInviteCollector);
ReactionCollectorHandler.collectorMap.set(ReactionCollectorGobletsGameData.name, gobletsGameCollector);
ReactionCollectorHandler.collectorMap.set(ReactionCollectorUnlockData.name, createUnlockCollector);
ReactionCollectorHandler.collectorMap.set(ReactionCollectorMerchantData.name, smallShopCollector);
ReactionCollectorHandler.collectorMap.set(ReactionCollectorShopSmallEventData.name, smallShopCollector);
ReactionCollectorHandler.collectorMap.set(ReactionCollectorEpicShopSmallEventData.name, epicItemShopCollector);
}

@packetHandler(ReactionCollectorCreationPacket)
Expand Down
20 changes: 20 additions & 0 deletions Discord/src/packetHandlers/handlers/SmallEventsHandler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,11 @@ import {MissionUtils} from "../../utils/MissionUtils";
import {DraftBotEmbed} from "../../messages/DraftBotEmbed";
import {baseFunctionHandler} from "../../smallEvents/shop";
import {StringConstants} from "../../../../Lib/src/constants/StringConstants";
import {epicItemShopHandler} from "../../smallEvents/epicItemShop";
import {
SmallEventEpicItemShopAcceptPacket, SmallEventEpicItemShopCannotBuyPacket,
SmallEventEpicItemShopRefusePacket
} from "../../../../Lib/src/packets/smallEvents/SmallEventEpicItemShopPacket";


export function getRandomSmallEventIntro(language: Language): string {
Expand Down Expand Up @@ -847,4 +852,19 @@ export default class SmallEventsHandler {
]
});
}

@packetHandler(SmallEventEpicItemShopRefusePacket)
async smallEventEpicItemShopRefuse(packet: SmallEventEpicItemShopRefusePacket, context: PacketContext): Promise<void> {
await epicItemShopHandler(context, "smallEvents:epicItemShop.refused");
}

@packetHandler(SmallEventEpicItemShopAcceptPacket)
async smallEventEpicItemShopAccept(packet: SmallEventEpicItemShopAcceptPacket, context: PacketContext): Promise<void> {
await epicItemShopHandler(context, "smallEvents:epicItemShop.purchased");
}

@packetHandler(SmallEventEpicItemShopCannotBuyPacket)
async smallEventEpicItemShopCannotBuy(packet: SmallEventEpicItemShopCannotBuyPacket, context: PacketContext): Promise<void> {
await epicItemShopHandler(context, "smallEvents:epicItemShop.notEnoughMoney");
}
}
62 changes: 62 additions & 0 deletions Discord/src/smallEvents/epicItemShop.ts
BastLast marked this conversation as resolved.
Show resolved Hide resolved
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
import {ReactionCollectorCreationPacket} from "../../../Lib/src/packets/interaction/ReactionCollectorPacket";
import {PacketContext} from "../../../Lib/src/packets/DraftBotPacket";
import {DiscordCache} from "../bot/DiscordCache";
import {DraftbotSmallEventEmbed} from "../messages/DraftbotSmallEventEmbed";
import {StringUtils} from "../utils/StringUtils";
import {DiscordCollectorUtils} from "../utils/DiscordCollectorUtils";
import {DisplayUtils} from "../utils/DisplayUtils";
import {Constants} from "../../../Lib/src/constants/Constants";
import i18n from "../translations/i18n";
import {ReactionCollectorEpicShopSmallEventData} from "../../../Lib/src/packets/interaction/ReactionCollectorEpicShopSmallEvent";

/**
* Send the initial embed for this small event
* @param packet
* @param context
*/
export async function epicItemShopCollector(packet: ReactionCollectorCreationPacket, context: PacketContext): Promise<void> {
const interaction = DiscordCache.getInteraction(context.discord!.interaction)!;
if (!interaction) {
return;
}
const lng = interaction.userLanguage;
const data = packet.data.data as ReactionCollectorEpicShopSmallEventData;
const tip = data.tip ? i18n.t("smallEvents:epicItemShop.reductionTip", {lng}) : "";

const embed = new DraftbotSmallEventEmbed(
"epicItemShop",
StringUtils.getRandomTranslation("smallEvents:epicItemShop.intro", lng)
+ tip
+ StringUtils.getRandomTranslation("smallEvents:shop.end", lng, {
item: DisplayUtils.getItemDisplayWithStats(data.item, lng),
price: data.price,
type: `${Constants.REACTIONS.ITEM_CATEGORIES[data.item.category]}${i18n.t("smallEvents:shop.types", {
returnObjects: true,
lng
})[data.item.category]}`,
interpolation: {escapeValue: false}
}),
interaction.user,
lng
);

await DiscordCollectorUtils.createAcceptRefuseCollector(interaction, embed, packet, context);
}

export async function epicItemShopHandler(context: PacketContext, translationKey: string): Promise<void> {
const originalInteraction = DiscordCache.getInteraction(context.discord!.interaction!);
if (!originalInteraction) {
return;
}
const buttonInteraction = DiscordCache.getButtonInteraction(context.discord!.buttonInteraction!);
await buttonInteraction?.editReply({
embeds: [
new DraftbotSmallEventEmbed(
"epicItemShop",
StringUtils.getRandomTranslation(translationKey, originalInteraction.userLanguage),
buttonInteraction.user,
originalInteraction.userLanguage
)
]
});
}
4 changes: 2 additions & 2 deletions Discord/src/smallEvents/shop.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,12 @@ import {DiscordCache} from "../bot/DiscordCache";
import {DraftbotSmallEventEmbed} from "../messages/DraftbotSmallEventEmbed";
import {StringUtils} from "../utils/StringUtils";
import {DiscordCollectorUtils} from "../utils/DiscordCollectorUtils";
import {ReactionCollectorMerchantData} from "../../../Lib/src/packets/interaction/ReactionCollectorMerchant";
import {RandomUtils} from "../../../Lib/src/utils/RandomUtils";
import {DisplayUtils} from "../utils/DisplayUtils";
import {Constants} from "../../../Lib/src/constants/Constants";
import i18n from "../translations/i18n";
import {StringConstants} from "../../../Lib/src/constants/StringConstants";
import {ReactionCollectorShopSmallEventData} from "../../../Lib/src/packets/interaction/ReactionCollectorShopSmallEvent";

/**
* Send the initial embed for this small event
Expand All @@ -18,7 +18,7 @@ import {StringConstants} from "../../../Lib/src/constants/StringConstants";
*/
export async function smallShopCollector(packet: ReactionCollectorCreationPacket, context: PacketContext): Promise<void> {
const interaction = DiscordCache.getInteraction(context.discord!.interaction)!;
const data = packet.data.data as ReactionCollectorMerchantData;
const data = packet.data.data as ReactionCollectorShopSmallEventData;
const gender = RandomUtils.draftbotRandom.bool() ? StringConstants.SEX.MALE : StringConstants.SEX.FEMALE;
const name = StringUtils.getRandomTranslation("smallEvents:shop.names", interaction.userLanguage, {context: gender.short});

Expand Down
32 changes: 31 additions & 1 deletion Lang/fr/smallEvents.json
Original file line number Diff line number Diff line change
Expand Up @@ -1567,5 +1567,35 @@
"refused": [
"Vous déclinez l'offre et reprenez votre chemin."
]
},

"epicItemShop" : {
"intro": [
"Progressant vers votre destination, une rencontre inattendue se produit. Aldéric l'antiquaire surgit à l'horizon, son chariot de trésors en remorque, prêt à discuter d'une affaire spéciale.",
"En route, un individu étrange apparaît. Aldéric l'antiquaire, charmant marchand ambulant, se présente avec une offre captivante.",
"Marchant paisiblement vers l'inconnu, une silhouette familière émerge : Aldéric l'antiquaire, le marchand vagabond, vous tend une proposition intrigante.",
"Pendant votre voyage sans encombre, un événement singulier survient. Aldéric l'antiquaire, l'artiste ambulant des antiquités, vous invite à une transaction mémorable.",
"Au cours de votre voyage, une interruption surprenante se produit. C'est Aldéric l'antiquaire, le marchand itinérant, qui vous présente un trésor inattendu.",
"Pendant une courte pause sous un arbre, un personnage mystérieux fait son apparition. C'est Aldéric l'antiquaire, le vagabond de l'insolite, prêt à vous immerger dans une offre alléchante.",
"Avançant paisiblement sur votre chemin, le bruit des roues d'une charrette attire votre attention. Aldéric l'antiquaire, un homme d'âge mûr vêtu de manière pittoresque, arpente les routes en tant que marchand itinérant. Avec un sourire amical, il vous invite à explorer sa collection d'objets fascinants.",
"Marchant sur un chemin de pierre poussiéreux, une charrette portant l'inscription Aldéric l'antiquaire - marchand d'objets super\" se présente à vous. Une transaction est bientôt amorcée.",
"Marchant tranquillement, un chariot en bois qui attise votre curiosité apparaît à l'horizon. À son bord, Aldéric l'antiquaire, un homme distingué marqué par le temps. Sa charrette est remplie d'antiquités soigneusement disposées et il se propose de vous montrer ses trésors, tous chargés d'histoires.",
"Repartant après une courte pause, un individu étonnamment bien habillé s'approche de vous. Il se présente comme Aldéric l'antiquaire, un marchand ambulant renommé. Sa tenue, mélange de tissus anciens et d'accessoires mystérieux, reflète son amour pour les objets d'antan. Avec un accent empreint d'excitation, il vous raconte l'histoire de ses trouvailles uniques.",
"Pendant votre promenade tranquille, une charrette ressemblant à un trésor ambulant s'arrête devant vous. Son conducteur, Aldéric l'antiquaire, est un homme chaleureux portant une tenue vintage. Il vous invite à explorer sa collection de curiosités, chacune accompagnée d'une histoire qui vous émerveillera.",
"Lors d'une pause à l'ombre d'un grand arbre, un homme distingué vous aborde avec un sourire amical. C'est Aldéric l'antiquaire, un marchand de renom. Son costume évoque une époque révolue et il vous montre avec soin sa collection d'objets anciens exposés dans sa charrette.",
"Après de longues heures de marche, un homme d'âge mûr vêtu de vêtements d'une époque passée vous aborde avec courtoisie. Se présentant comme Aldéric l'antiquaire, un passionné d'antiquités, il vous invite à découvrir sa collection d'objets fascinants, racontant avec plaisir l'histoire de chacun d'entre eux."
],
"reductionTip": "Il incline légèrement la tête et vous confie en aparté, 'Si vous avez l'intention de vous aventurer jusqu'à la Route des Merveilles et que vous réussissez à me trouver là-bas, soyez assuré que je vous réserverai une offre des plus avantageuses.",
"purchased": [
"Satisfait de votre achat, vous reprenez votre route tranquillement.",
"Vous lui tendez une bourse afin de procéder à l'achat, une fois le bien acquis vous continuez votre chemin."
],
"notEnoughMoney": [
"Vous n'avez malheureusement pas assez d'argent, vous reprenez donc votre route.",
"Vous tendez une bourse vide en espérant que cela passe sans emcombre mais vous vous faites vite chasser, vous reprenez votre chemin triste et déçu."
],
"refused": [
"Vous déclinez l'offre et reprenez votre chemin."
]
}
}
}
Loading
Loading