diff --git a/src/main/java/emu/grasscutter/data/GameData.java b/src/main/java/emu/grasscutter/data/GameData.java index a688bf753..023f2977e 100644 --- a/src/main/java/emu/grasscutter/data/GameData.java +++ b/src/main/java/emu/grasscutter/data/GameData.java @@ -140,6 +140,10 @@ public final class GameData { private static final Int2ObjectMap avatarTalentDataMap = new Int2ObjectOpenHashMap<>(); + @Getter + private static final Int2ObjectMap bargainDataMap + = new Int2ObjectOpenHashMap<>(); + @Getter private static final Int2ObjectMap battlePassMissionDataMap = new Int2ObjectOpenHashMap<>(); diff --git a/src/main/java/emu/grasscutter/data/excels/BargainData.java b/src/main/java/emu/grasscutter/data/excels/BargainData.java new file mode 100644 index 000000000..b51912951 --- /dev/null +++ b/src/main/java/emu/grasscutter/data/excels/BargainData.java @@ -0,0 +1,49 @@ +package emu.grasscutter.data.excels; + +import emu.grasscutter.data.*; +import lombok.Getter; + +import java.util.List; + +@Getter +@ResourceType(name = "BargainExcelConfigData.json") +public final class BargainData extends GameResource { + @Getter private int id; + private int questId; + + private List dialogId; + + /** + * This is a list of 2 integers. + * The first integer is the minimum value of the bargain. + * The second integer is the maximum value of the bargain. + */ + private List expectedValue; + private int space; + + private List successTalkId; + private int failTalkId; + private int moodNpcId; + + /** + * This is a list of 2 integers. + * The first integer is the minimum value of the mood. + * The second integer is the maximum value of the mood. + */ + private List randomMood; + private int moodAlertLimit; + private int moodLowLimit; + private int singleFailMoodDeduction; + + private long moodLowLimitTextTextMapHash; + private long titleTextTextMapHash; + private long affordTextTextMapHash; + private long storageTextTextMapHash; + private long moodHintTextTextMapHash; + private long moodDescTextTextMapHash; + + private List singleFailTalkId; + + private boolean deleteItem; + private int itemId; +} diff --git a/src/main/java/emu/grasscutter/game/player/PlayerProgress.java b/src/main/java/emu/grasscutter/game/player/PlayerProgress.java index 0c34eaedb..638d8c5da 100644 --- a/src/main/java/emu/grasscutter/game/player/PlayerProgress.java +++ b/src/main/java/emu/grasscutter/game/player/PlayerProgress.java @@ -2,7 +2,7 @@ package emu.grasscutter.game.player; import dev.morphia.annotations.*; import emu.grasscutter.Grasscutter; -import emu.grasscutter.game.quest.ItemGiveRecord; +import emu.grasscutter.game.quest.*; import emu.grasscutter.game.quest.enums.QuestContent; import it.unimi.dsi.fastutil.ints.*; import lombok.*; @@ -29,12 +29,14 @@ public class PlayerProgress { private Map questProgressCountMap; private Map itemGivings; + private Map bargains; public PlayerProgress() { this.questProgressCountMap = new ConcurrentHashMap<>(); this.completedDungeons = new IntArrayList(); this.itemHistory = new Int2ObjectOpenHashMap<>(); this.itemGivings = new Int2ObjectOpenHashMap<>(); + this.bargains = new Int2ObjectOpenHashMap<>(); } /** diff --git a/src/main/java/emu/grasscutter/game/quest/BargainRecord.java b/src/main/java/emu/grasscutter/game/quest/BargainRecord.java new file mode 100644 index 000000000..d7a74c9b3 --- /dev/null +++ b/src/main/java/emu/grasscutter/game/quest/BargainRecord.java @@ -0,0 +1,109 @@ +package emu.grasscutter.game.quest; + +import dev.morphia.annotations.Entity; +import emu.grasscutter.data.GameData; +import emu.grasscutter.data.excels.BargainData; +import emu.grasscutter.net.proto.BargainResultTypeOuterClass.BargainResultType; +import emu.grasscutter.net.proto.BargainSnapshotOuterClass.BargainSnapshot; +import emu.grasscutter.utils.Utils; +import lombok.*; + +@Data +@Entity +@Builder +public final class BargainRecord { + /** + * Provides an instance of a bargain record. + * Uses information from game resources. + * + * @param bargainId The ID of the bargain. + * @return An instance of a bargain record. + */ + public static BargainRecord resolve(int bargainId) { + var bargainData = GameData.getBargainDataMap().get(bargainId); + if (bargainData == null) throw new RuntimeException("No bargain data found for " + bargainId + "."); + + return BargainRecord.builder() + .bargainId(bargainId) + .build() + .determineBase(bargainData); + } + + private int bargainId; + private int lowestPrice; + private int expectedPrice; + + private int currentMood; + + private boolean finished; + private BargainResultType result; + + /** + * Determines the price of the bargain. + */ + public BargainRecord determineBase(BargainData data) { + // Set the expected price. + var price = data.getExpectedValue(); + this.setExpectedPrice(Utils.randomRange( + price.get(0), price.get(1))); + // Set the lowest price. + this.setLowestPrice(price.get(0)); + + // Set the base mood. + var mood = data.getRandomMood(); + this.setCurrentMood(Utils.randomRange( + mood.get(0), mood.get(1))); + + return this; + } + + /** + * Computes an offer's validity. + * + * @param offer The offer to compute. + * @return The result of the offer. + */ + public BargainResultType applyOffer(int offer) { + if (offer < this.getLowestPrice()) { + // Decrease the mood. + this.currentMood -= Utils.randomRange(1, 3); + // Return a failure. + return this.result = BargainResultType.BARGAIN_SINGLE_FAIL; + } + + if (offer > this.getExpectedPrice()) { + // Complete the bargain. + this.setFinished(true); + // Return a success. + return this.result = BargainResultType.BARGAIN_COMPLETE_SUCC; + } + + // Compare the offer against the mood & expected price. + // The mood is out of 100; 1 mood should decrease the price by 100. + var moodAdjustment = (int) Math.floor(this.getCurrentMood() / 100.0); + var expectedPrice = this.getExpectedPrice() - moodAdjustment; + if (offer < expectedPrice) { + // Decrease the mood. + this.currentMood -= Utils.randomRange(1, 3); + // Return a failure. + return this.result = BargainResultType.BARGAIN_SINGLE_FAIL; + } else { + // Complete the bargain. + this.setFinished(true); + // Return a success. + return this.result = BargainResultType.BARGAIN_COMPLETE_SUCC; + } + } + + /** + * @return A snapshot of this bargain record. + */ + public BargainSnapshot toSnapshot() { + return BargainSnapshot.newBuilder() + .setBargainId(this.getBargainId()) + .setCurMood(this.getCurrentMood()) + .setPJHMEHGELGC(this.getExpectedPrice()) + .setHADMOPEJFIC(this.getLowestPrice()) + .build(); + } +} diff --git a/src/main/java/emu/grasscutter/game/quest/QuestManager.java b/src/main/java/emu/grasscutter/game/quest/QuestManager.java index b382b1436..b7b301160 100644 --- a/src/main/java/emu/grasscutter/game/quest/QuestManager.java +++ b/src/main/java/emu/grasscutter/game/quest/QuestManager.java @@ -170,7 +170,54 @@ public final class QuestManager extends BasePlayerManager { } /** - * Attempts to remove the giving action. + * Attempts to start the bargain. + * + * @param bargainId The bargain ID. + */ + public void startBargain(int bargainId) { + var progress = this.player.getPlayerProgress(); + var bargains = progress.getBargains(); + + // Check if the bargain is already present. + if (bargains.containsKey(bargainId)) { + throw new IllegalStateException("Bargain " + bargainId + " is already active."); + } + + // Add the action. + var bargain = BargainRecord.resolve(bargainId); + bargains.put(bargainId, bargain); + // Save the bargains. + this.player.save(); + + // Send the player the start packet. + this.player.sendPacket(new PacketBargainStartNotify(bargain)); + } + + /** + * Attempts to stop the bargain. + * + * @param bargainId The bargain ID. + */ + public void stopBargain(int bargainId) { + var progress = this.player.getPlayerProgress(); + var bargains = progress.getBargains(); + + // Check if the bargain is already present. + if (!bargains.containsKey(bargainId)) { + throw new IllegalStateException("Bargain " + bargainId + " is not active."); + } + + // Remove the action. + bargains.remove(bargainId); + // Save the bargains. + this.player.save(); + + // Send the player the stop packet. + this.player.sendPacket(new PacketBargainTerminateNotify(bargainId)); + } + + /** + * Sends the giving records to the player. */ public void sendGivingRecords() { // Send the record to the player. diff --git a/src/main/java/emu/grasscutter/game/quest/content/ContentBargainFail.java b/src/main/java/emu/grasscutter/game/quest/content/ContentBargainFail.java new file mode 100644 index 000000000..08f1bda24 --- /dev/null +++ b/src/main/java/emu/grasscutter/game/quest/content/ContentBargainFail.java @@ -0,0 +1,20 @@ +package emu.grasscutter.game.quest.content; + +import emu.grasscutter.data.excels.quest.QuestData; +import emu.grasscutter.game.quest.*; +import emu.grasscutter.game.quest.enums.QuestContent; +import emu.grasscutter.net.proto.BargainResultTypeOuterClass.BargainResultType; + +@QuestValueContent(QuestContent.QUEST_CONTENT_BARGAIN_FAIL) +public final class ContentBargainFail extends BaseContent { + @Override + public boolean execute(GameQuest quest, QuestData.QuestContentCondition condition, String paramStr, int... params) { + var bargain = quest.getOwner() + .getPlayerProgress() + .getBargains() + .get(condition.getParam()[0]); + if (bargain == null) return false; + + return bargain.getResult() == BargainResultType.BARGAIN_COMPLETE_FAIL; + } +} diff --git a/src/main/java/emu/grasscutter/game/quest/content/ContentBargainLessThan.java b/src/main/java/emu/grasscutter/game/quest/content/ContentBargainLessThan.java new file mode 100644 index 000000000..b6da9796d --- /dev/null +++ b/src/main/java/emu/grasscutter/game/quest/content/ContentBargainLessThan.java @@ -0,0 +1,20 @@ +package emu.grasscutter.game.quest.content; + +import emu.grasscutter.data.excels.quest.QuestData; +import emu.grasscutter.game.quest.*; +import emu.grasscutter.game.quest.enums.QuestContent; +import emu.grasscutter.net.proto.BargainResultTypeOuterClass.BargainResultType; + +@QuestValueContent(QuestContent.QUEST_CONTENT_ITEM_LESS_THAN_BARGAIN) +public final class ContentBargainLessThan extends BaseContent { + @Override + public boolean execute(GameQuest quest, QuestData.QuestContentCondition condition, String paramStr, int... params) { + var bargain = quest.getOwner() + .getPlayerProgress() + .getBargains() + .get(condition.getParam()[0]); + if (bargain == null) return false; + + return bargain.getResult() == BargainResultType.BARGAIN_SINGLE_FAIL; + } +} diff --git a/src/main/java/emu/grasscutter/game/quest/content/ContentBargainSuccess.java b/src/main/java/emu/grasscutter/game/quest/content/ContentBargainSuccess.java new file mode 100644 index 000000000..1deeeeb52 --- /dev/null +++ b/src/main/java/emu/grasscutter/game/quest/content/ContentBargainSuccess.java @@ -0,0 +1,20 @@ +package emu.grasscutter.game.quest.content; + +import emu.grasscutter.data.excels.quest.QuestData; +import emu.grasscutter.game.quest.*; +import emu.grasscutter.game.quest.enums.QuestContent; +import emu.grasscutter.net.proto.BargainResultTypeOuterClass.BargainResultType; + +@QuestValueContent(QuestContent.QUEST_CONTENT_BARGAIN_SUCC) +public final class ContentBargainSuccess extends BaseContent { + @Override + public boolean execute(GameQuest quest, QuestData.QuestContentCondition condition, String paramStr, int... params) { + var bargain = quest.getOwner() + .getPlayerProgress() + .getBargains() + .get(condition.getParam()[0]); + if (bargain == null) return false; + + return bargain.getResult() == BargainResultType.BARGAIN_COMPLETE_SUCC; + } +} diff --git a/src/main/java/emu/grasscutter/game/quest/enums/QuestContent.java b/src/main/java/emu/grasscutter/game/quest/enums/QuestContent.java index ba805674e..ac81fa623 100644 --- a/src/main/java/emu/grasscutter/game/quest/enums/QuestContent.java +++ b/src/main/java/emu/grasscutter/game/quest/enums/QuestContent.java @@ -51,9 +51,9 @@ public enum QuestContent implements QuestTrigger { QUEST_CONTENT_QUEST_VAR_LESS(121), QUEST_CONTENT_OBTAIN_VARIOUS_ITEM(122), // missing, finish QUEST_CONTENT_FINISH_TOWER_LEVEL(123), // missing, currently unused - QUEST_CONTENT_BARGAIN_SUCC(124), // missing, finish - QUEST_CONTENT_BARGAIN_FAIL(125), // missing, fail - QUEST_CONTENT_ITEM_LESS_THAN_BARGAIN(126), // missing, fail + QUEST_CONTENT_BARGAIN_SUCC(124), + QUEST_CONTENT_BARGAIN_FAIL(125), + QUEST_CONTENT_ITEM_LESS_THAN_BARGAIN(126), QUEST_CONTENT_ACTIVITY_TRIGGER_FAILED(127), // missing, fail QUEST_CONTENT_MAIN_COOP_ENTER_SAVE_POINT(128), // missing, finish QUEST_CONTENT_ANY_MANUAL_TRANSPORT(129), diff --git a/src/main/java/emu/grasscutter/game/quest/enums/QuestExec.java b/src/main/java/emu/grasscutter/game/quest/enums/QuestExec.java index 1466c15ff..aa906a63d 100644 --- a/src/main/java/emu/grasscutter/game/quest/enums/QuestExec.java +++ b/src/main/java/emu/grasscutter/game/quest/enums/QuestExec.java @@ -47,8 +47,8 @@ public enum QuestExec implements QuestTrigger { QUEST_EXEC_ACTIVE_ACTIVITY_COND_STATE(37), // missing QUEST_EXEC_INACTIVE_ACTIVITY_COND_STATE(38), // missing QUEST_EXEC_ADD_CUR_AVATAR_ENERGY(39), - QUEST_EXEC_START_BARGAIN(41), // missing - QUEST_EXEC_STOP_BARGAIN(42), // missing + QUEST_EXEC_START_BARGAIN(41), + QUEST_EXEC_STOP_BARGAIN(42), QUEST_EXEC_SET_QUEST_GLOBAL_VAR(43), QUEST_EXEC_INC_QUEST_GLOBAL_VAR(44), QUEST_EXEC_DEC_QUEST_GLOBAL_VAR(45), diff --git a/src/main/java/emu/grasscutter/game/quest/exec/ExecStartBargain.java b/src/main/java/emu/grasscutter/game/quest/exec/ExecStartBargain.java new file mode 100644 index 000000000..87b03ec23 --- /dev/null +++ b/src/main/java/emu/grasscutter/game/quest/exec/ExecStartBargain.java @@ -0,0 +1,27 @@ +package emu.grasscutter.game.quest.exec; + +import emu.grasscutter.Grasscutter; +import emu.grasscutter.data.excels.quest.QuestData; +import emu.grasscutter.game.quest.*; +import emu.grasscutter.game.quest.enums.QuestExec; +import emu.grasscutter.game.quest.handlers.QuestExecHandler; + +@QuestValueExec(QuestExec.QUEST_EXEC_START_BARGAIN) +public final class ExecStartBargain extends QuestExecHandler { + @Override + public boolean execute(GameQuest quest, QuestData.QuestExecParam condition, String... paramStr) { + // Get the bargain data from the quest parameters. + var bargainId = Integer.parseInt(condition.getParam()[0]); + + try { + // Start the bargain. + quest.getOwner().getQuestManager() + .startBargain(bargainId); + Grasscutter.getLogger().debug("Bargain {} started.", bargainId); + return true; + } catch (RuntimeException ignored) { + Grasscutter.getLogger().debug("Bargain {} does not exist.", bargainId); + return false; + } + } +} diff --git a/src/main/java/emu/grasscutter/game/quest/exec/ExecStopBargain.java b/src/main/java/emu/grasscutter/game/quest/exec/ExecStopBargain.java new file mode 100644 index 000000000..0b5d09531 --- /dev/null +++ b/src/main/java/emu/grasscutter/game/quest/exec/ExecStopBargain.java @@ -0,0 +1,27 @@ +package emu.grasscutter.game.quest.exec; + +import emu.grasscutter.Grasscutter; +import emu.grasscutter.data.excels.quest.QuestData; +import emu.grasscutter.game.quest.*; +import emu.grasscutter.game.quest.enums.QuestExec; +import emu.grasscutter.game.quest.handlers.QuestExecHandler; + +@QuestValueExec(QuestExec.QUEST_EXEC_STOP_BARGAIN) +public final class ExecStopBargain extends QuestExecHandler { + @Override + public boolean execute(GameQuest quest, QuestData.QuestExecParam condition, String... paramStr) { + // Get the bargain data from the quest parameters. + var bargainId = Integer.parseInt(condition.getParam()[0]); + + try { + // Start the bargain. + quest.getOwner().getQuestManager() + .stopBargain(bargainId); + Grasscutter.getLogger().debug("Bargain {} stopped.", bargainId); + return true; + } catch (RuntimeException ignored) { + Grasscutter.getLogger().debug("Bargain {} does not exist.", bargainId); + return false; + } + } +} diff --git a/src/main/java/emu/grasscutter/server/packet/recv/HandlerBargainOfferPriceReq.java b/src/main/java/emu/grasscutter/server/packet/recv/HandlerBargainOfferPriceReq.java new file mode 100644 index 000000000..fbc776154 --- /dev/null +++ b/src/main/java/emu/grasscutter/server/packet/recv/HandlerBargainOfferPriceReq.java @@ -0,0 +1,43 @@ +package emu.grasscutter.server.packet.recv; + +import emu.grasscutter.game.quest.enums.QuestContent; +import emu.grasscutter.net.packet.*; +import emu.grasscutter.net.proto.BargainOfferPriceReqOuterClass.BargainOfferPriceReq; +import emu.grasscutter.server.game.GameSession; +import emu.grasscutter.server.packet.send.PacketBargainOfferPriceRsp; + +@Opcodes(PacketOpcodes.BargainOfferPriceReq) +public final class HandlerBargainOfferPriceReq extends PacketHandler { + @Override + public void handle(GameSession session, byte[] header, byte[] payload) + throws Exception { + var packet = BargainOfferPriceReq.parseFrom(payload); + var player = session.getPlayer(); + + // Fetch the active bargain. + var bargainId = packet.getBargainId(); + var progress = player.getPlayerProgress(); + var bargain = progress.getBargains().get(bargainId); + if (bargain == null) return; + + // Apply the offer. + var result = bargain.applyOffer(packet.getPrice()); + + // Queue the quest content event. + var questManager = player.getQuestManager(); + switch (result) { + case BARGAIN_COMPLETE_SUCC -> questManager.queueEvent( + QuestContent.QUEST_CONTENT_BARGAIN_SUCC, + bargainId, 0); + case BARGAIN_SINGLE_FAIL -> questManager.queueEvent( + QuestContent.QUEST_CONTENT_ITEM_LESS_THAN_BARGAIN, + bargainId, 0); + case BARGAIN_COMPLETE_FAIL -> questManager.queueEvent( + QuestContent.QUEST_CONTENT_BARGAIN_FAIL, + bargainId, 0); + } + + // Return the resulting packet. + session.send(new PacketBargainOfferPriceRsp(result, bargain)); + } +} diff --git a/src/main/java/emu/grasscutter/server/packet/recv/HandlerGetAllActivatedBargainDataReq.java b/src/main/java/emu/grasscutter/server/packet/recv/HandlerGetAllActivatedBargainDataReq.java new file mode 100644 index 000000000..9955f356e --- /dev/null +++ b/src/main/java/emu/grasscutter/server/packet/recv/HandlerGetAllActivatedBargainDataReq.java @@ -0,0 +1,17 @@ +package emu.grasscutter.server.packet.recv; + +import emu.grasscutter.net.packet.*; +import emu.grasscutter.server.game.GameSession; +import emu.grasscutter.server.packet.send.PacketGetAllActivatedBargainDataRsp; + +@Opcodes(PacketOpcodes.GetAllActivatedBargainDataReq) +public final class HandlerGetAllActivatedBargainDataReq extends PacketHandler { + @Override + public void handle(GameSession session, byte[] header, byte[] payload) { + session.send(new PacketGetAllActivatedBargainDataRsp( + session.getPlayer() + .getPlayerProgress() + .getBargains() + .values())); + } +} diff --git a/src/main/java/emu/grasscutter/server/packet/recv/HandlerGetBargainDataReq.java b/src/main/java/emu/grasscutter/server/packet/recv/HandlerGetBargainDataReq.java new file mode 100644 index 000000000..aed038239 --- /dev/null +++ b/src/main/java/emu/grasscutter/server/packet/recv/HandlerGetBargainDataReq.java @@ -0,0 +1,29 @@ +package emu.grasscutter.server.packet.recv; + +import emu.grasscutter.net.packet.*; +import emu.grasscutter.net.proto.GetBargainDataReqOuterClass.GetBargainDataReq; +import emu.grasscutter.net.proto.RetcodeOuterClass.Retcode; +import emu.grasscutter.server.game.GameSession; +import emu.grasscutter.server.packet.send.PacketGetBargainDataRsp; + +@Opcodes(PacketOpcodes.GetBargainDataReq) +public final class HandlerGetBargainDataReq extends PacketHandler { + @Override + public void handle(GameSession session, byte[] header, byte[] payload) + throws Exception { + var packet = GetBargainDataReq.parseFrom(payload); + + var bargainId = packet.getBargainId(); + var bargain = session.getPlayer() + .getPlayerProgress() + .getBargains() + .get(bargainId); + if (bargain == null) { + session.send(new PacketGetBargainDataRsp( + Retcode.RET_BARGAIN_NOT_ACTIVATED)); + return; + } + + session.send(new PacketGetBargainDataRsp(bargain)); + } +} diff --git a/src/main/java/emu/grasscutter/server/packet/send/PacketBargainOfferPriceRsp.java b/src/main/java/emu/grasscutter/server/packet/send/PacketBargainOfferPriceRsp.java new file mode 100644 index 000000000..a9bdee9ba --- /dev/null +++ b/src/main/java/emu/grasscutter/server/packet/send/PacketBargainOfferPriceRsp.java @@ -0,0 +1,21 @@ +package emu.grasscutter.server.packet.send; + +import emu.grasscutter.game.quest.BargainRecord; +import emu.grasscutter.net.packet.*; +import emu.grasscutter.net.proto.BargainOfferPriceRspOuterClass.BargainOfferPriceRsp; +import emu.grasscutter.net.proto.BargainResultTypeOuterClass.BargainResultType; +import emu.grasscutter.net.proto.RetcodeOuterClass.Retcode; + +public final class PacketBargainOfferPriceRsp extends BasePacket { + public PacketBargainOfferPriceRsp(BargainResultType result, BargainRecord record) { + super(PacketOpcodes.BargainOfferPriceRsp); + + this.setData(BargainOfferPriceRsp.newBuilder() + .setRetcode(record.isFinished() ? + Retcode.RET_BARGAIN_FINISHED.getNumber() : + Retcode.RET_BARGAIN_NOT_ACTIVATED.getNumber()) + .setCurMood(record.getCurrentMood()) + .setBargainResult(result) + .setResultParam(0)); + } +} diff --git a/src/main/java/emu/grasscutter/server/packet/send/PacketBargainStartNotify.java b/src/main/java/emu/grasscutter/server/packet/send/PacketBargainStartNotify.java new file mode 100644 index 000000000..ec0a88d1a --- /dev/null +++ b/src/main/java/emu/grasscutter/server/packet/send/PacketBargainStartNotify.java @@ -0,0 +1,15 @@ +package emu.grasscutter.server.packet.send; + +import emu.grasscutter.game.quest.BargainRecord; +import emu.grasscutter.net.packet.*; +import emu.grasscutter.net.proto.BargainStartNotifyOuterClass.BargainStartNotify; + +public final class PacketBargainStartNotify extends BasePacket { + public PacketBargainStartNotify(BargainRecord record) { + super(PacketOpcodes.BargainStartNotify); + + this.setData(BargainStartNotify.newBuilder() + .setBargainId(record.getBargainId()) + .setSnapshot(record.toSnapshot())); + } +} diff --git a/src/main/java/emu/grasscutter/server/packet/send/PacketBargainTerminateNotify.java b/src/main/java/emu/grasscutter/server/packet/send/PacketBargainTerminateNotify.java new file mode 100644 index 000000000..1dff443c9 --- /dev/null +++ b/src/main/java/emu/grasscutter/server/packet/send/PacketBargainTerminateNotify.java @@ -0,0 +1,13 @@ +package emu.grasscutter.server.packet.send; + +import emu.grasscutter.net.packet.*; +import emu.grasscutter.net.proto.BargainTerminateNotifyOuterClass.BargainTerminateNotify; + +public final class PacketBargainTerminateNotify extends BasePacket { + public PacketBargainTerminateNotify(int bargainId) { + super(PacketOpcodes.BargainTerminateNotify); + + this.setData(BargainTerminateNotify.newBuilder() + .setBargainId(bargainId)); + } +} diff --git a/src/main/java/emu/grasscutter/server/packet/send/PacketGetAllActivatedBargainDataRsp.java b/src/main/java/emu/grasscutter/server/packet/send/PacketGetAllActivatedBargainDataRsp.java new file mode 100644 index 000000000..1cb54b6a3 --- /dev/null +++ b/src/main/java/emu/grasscutter/server/packet/send/PacketGetAllActivatedBargainDataRsp.java @@ -0,0 +1,20 @@ +package emu.grasscutter.server.packet.send; + +import emu.grasscutter.game.quest.BargainRecord; +import emu.grasscutter.net.packet.*; +import emu.grasscutter.net.proto.GetAllActivatedBargainDataRspOuterClass.GetAllActivatedBargainDataRsp; +import emu.grasscutter.net.proto.RetcodeOuterClass.Retcode; + +import java.util.Collection; + +public final class PacketGetAllActivatedBargainDataRsp extends BasePacket { + public PacketGetAllActivatedBargainDataRsp(Collection records) { + super(PacketOpcodes.GetAllActivatedBargainDataRsp); + + this.setData(GetAllActivatedBargainDataRsp.newBuilder() + .setRetcode(Retcode.RET_SUCC.getNumber()) + .addAllSnapshotList(records.stream() + .map(BargainRecord::toSnapshot) + .toList())); + } +} diff --git a/src/main/java/emu/grasscutter/server/packet/send/PacketGetBargainDataRsp.java b/src/main/java/emu/grasscutter/server/packet/send/PacketGetBargainDataRsp.java new file mode 100644 index 000000000..965ae51d4 --- /dev/null +++ b/src/main/java/emu/grasscutter/server/packet/send/PacketGetBargainDataRsp.java @@ -0,0 +1,24 @@ +package emu.grasscutter.server.packet.send; + +import emu.grasscutter.game.quest.BargainRecord; +import emu.grasscutter.net.packet.*; +import emu.grasscutter.net.proto.GetBargainDataRspOuterClass.GetBargainDataRsp; +import emu.grasscutter.net.proto.RetcodeOuterClass.Retcode; + +public final class PacketGetBargainDataRsp extends BasePacket { + public PacketGetBargainDataRsp(Retcode retcode) { + super(PacketOpcodes.GetBargainDataRsp); + + this.setData(GetBargainDataRsp.newBuilder() + .setRetcode(retcode.getNumber())); + } + + public PacketGetBargainDataRsp(BargainRecord record) { + super(PacketOpcodes.GetBargainDataRsp); + + this.setData(GetBargainDataRsp.newBuilder() + .setRetcode(Retcode.RET_SUCC.getNumber()) + .setBargainId(record.getBargainId()) + .setSnapshot(record.toSnapshot())); + } +}