mirror of
https://github.com/Grasscutters/Grasscutter.git
synced 2025-01-23 11:22:55 +08:00
Attempt to implement bargaining (untested)
This commit is contained in:
parent
40bbfd90e1
commit
597574ddda
@ -140,6 +140,10 @@ public final class GameData {
|
|||||||
private static final Int2ObjectMap<AvatarTalentData> avatarTalentDataMap =
|
private static final Int2ObjectMap<AvatarTalentData> avatarTalentDataMap =
|
||||||
new Int2ObjectOpenHashMap<>();
|
new Int2ObjectOpenHashMap<>();
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
private static final Int2ObjectMap<BargainData> bargainDataMap
|
||||||
|
= new Int2ObjectOpenHashMap<>();
|
||||||
|
|
||||||
@Getter
|
@Getter
|
||||||
private static final Int2ObjectMap<BattlePassMissionData> battlePassMissionDataMap =
|
private static final Int2ObjectMap<BattlePassMissionData> battlePassMissionDataMap =
|
||||||
new Int2ObjectOpenHashMap<>();
|
new Int2ObjectOpenHashMap<>();
|
||||||
|
49
src/main/java/emu/grasscutter/data/excels/BargainData.java
Normal file
49
src/main/java/emu/grasscutter/data/excels/BargainData.java
Normal file
@ -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<Integer> 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<Integer> expectedValue;
|
||||||
|
private int space;
|
||||||
|
|
||||||
|
private List<Integer> 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<Integer> 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<Integer> singleFailTalkId;
|
||||||
|
|
||||||
|
private boolean deleteItem;
|
||||||
|
private int itemId;
|
||||||
|
}
|
@ -2,7 +2,7 @@ package emu.grasscutter.game.player;
|
|||||||
|
|
||||||
import dev.morphia.annotations.*;
|
import dev.morphia.annotations.*;
|
||||||
import emu.grasscutter.Grasscutter;
|
import emu.grasscutter.Grasscutter;
|
||||||
import emu.grasscutter.game.quest.ItemGiveRecord;
|
import emu.grasscutter.game.quest.*;
|
||||||
import emu.grasscutter.game.quest.enums.QuestContent;
|
import emu.grasscutter.game.quest.enums.QuestContent;
|
||||||
import it.unimi.dsi.fastutil.ints.*;
|
import it.unimi.dsi.fastutil.ints.*;
|
||||||
import lombok.*;
|
import lombok.*;
|
||||||
@ -29,12 +29,14 @@ public class PlayerProgress {
|
|||||||
private Map<String, Integer> questProgressCountMap;
|
private Map<String, Integer> questProgressCountMap;
|
||||||
|
|
||||||
private Map<Integer, ItemGiveRecord> itemGivings;
|
private Map<Integer, ItemGiveRecord> itemGivings;
|
||||||
|
private Map<Integer, BargainRecord> bargains;
|
||||||
|
|
||||||
public PlayerProgress() {
|
public PlayerProgress() {
|
||||||
this.questProgressCountMap = new ConcurrentHashMap<>();
|
this.questProgressCountMap = new ConcurrentHashMap<>();
|
||||||
this.completedDungeons = new IntArrayList();
|
this.completedDungeons = new IntArrayList();
|
||||||
this.itemHistory = new Int2ObjectOpenHashMap<>();
|
this.itemHistory = new Int2ObjectOpenHashMap<>();
|
||||||
this.itemGivings = new Int2ObjectOpenHashMap<>();
|
this.itemGivings = new Int2ObjectOpenHashMap<>();
|
||||||
|
this.bargains = new Int2ObjectOpenHashMap<>();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
109
src/main/java/emu/grasscutter/game/quest/BargainRecord.java
Normal file
109
src/main/java/emu/grasscutter/game/quest/BargainRecord.java
Normal file
@ -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();
|
||||||
|
}
|
||||||
|
}
|
@ -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() {
|
public void sendGivingRecords() {
|
||||||
// Send the record to the player.
|
// Send the record to the player.
|
||||||
|
@ -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;
|
||||||
|
}
|
||||||
|
}
|
@ -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;
|
||||||
|
}
|
||||||
|
}
|
@ -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;
|
||||||
|
}
|
||||||
|
}
|
@ -51,9 +51,9 @@ public enum QuestContent implements QuestTrigger {
|
|||||||
QUEST_CONTENT_QUEST_VAR_LESS(121),
|
QUEST_CONTENT_QUEST_VAR_LESS(121),
|
||||||
QUEST_CONTENT_OBTAIN_VARIOUS_ITEM(122), // missing, finish
|
QUEST_CONTENT_OBTAIN_VARIOUS_ITEM(122), // missing, finish
|
||||||
QUEST_CONTENT_FINISH_TOWER_LEVEL(123), // missing, currently unused
|
QUEST_CONTENT_FINISH_TOWER_LEVEL(123), // missing, currently unused
|
||||||
QUEST_CONTENT_BARGAIN_SUCC(124), // missing, finish
|
QUEST_CONTENT_BARGAIN_SUCC(124),
|
||||||
QUEST_CONTENT_BARGAIN_FAIL(125), // missing, fail
|
QUEST_CONTENT_BARGAIN_FAIL(125),
|
||||||
QUEST_CONTENT_ITEM_LESS_THAN_BARGAIN(126), // missing, fail
|
QUEST_CONTENT_ITEM_LESS_THAN_BARGAIN(126),
|
||||||
QUEST_CONTENT_ACTIVITY_TRIGGER_FAILED(127), // missing, fail
|
QUEST_CONTENT_ACTIVITY_TRIGGER_FAILED(127), // missing, fail
|
||||||
QUEST_CONTENT_MAIN_COOP_ENTER_SAVE_POINT(128), // missing, finish
|
QUEST_CONTENT_MAIN_COOP_ENTER_SAVE_POINT(128), // missing, finish
|
||||||
QUEST_CONTENT_ANY_MANUAL_TRANSPORT(129),
|
QUEST_CONTENT_ANY_MANUAL_TRANSPORT(129),
|
||||||
|
@ -47,8 +47,8 @@ public enum QuestExec implements QuestTrigger {
|
|||||||
QUEST_EXEC_ACTIVE_ACTIVITY_COND_STATE(37), // missing
|
QUEST_EXEC_ACTIVE_ACTIVITY_COND_STATE(37), // missing
|
||||||
QUEST_EXEC_INACTIVE_ACTIVITY_COND_STATE(38), // missing
|
QUEST_EXEC_INACTIVE_ACTIVITY_COND_STATE(38), // missing
|
||||||
QUEST_EXEC_ADD_CUR_AVATAR_ENERGY(39),
|
QUEST_EXEC_ADD_CUR_AVATAR_ENERGY(39),
|
||||||
QUEST_EXEC_START_BARGAIN(41), // missing
|
QUEST_EXEC_START_BARGAIN(41),
|
||||||
QUEST_EXEC_STOP_BARGAIN(42), // missing
|
QUEST_EXEC_STOP_BARGAIN(42),
|
||||||
QUEST_EXEC_SET_QUEST_GLOBAL_VAR(43),
|
QUEST_EXEC_SET_QUEST_GLOBAL_VAR(43),
|
||||||
QUEST_EXEC_INC_QUEST_GLOBAL_VAR(44),
|
QUEST_EXEC_INC_QUEST_GLOBAL_VAR(44),
|
||||||
QUEST_EXEC_DEC_QUEST_GLOBAL_VAR(45),
|
QUEST_EXEC_DEC_QUEST_GLOBAL_VAR(45),
|
||||||
|
@ -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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -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));
|
||||||
|
}
|
||||||
|
}
|
@ -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()));
|
||||||
|
}
|
||||||
|
}
|
@ -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));
|
||||||
|
}
|
||||||
|
}
|
@ -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));
|
||||||
|
}
|
||||||
|
}
|
@ -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()));
|
||||||
|
}
|
||||||
|
}
|
@ -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));
|
||||||
|
}
|
||||||
|
}
|
@ -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<BargainRecord> records) {
|
||||||
|
super(PacketOpcodes.GetAllActivatedBargainDataRsp);
|
||||||
|
|
||||||
|
this.setData(GetAllActivatedBargainDataRsp.newBuilder()
|
||||||
|
.setRetcode(Retcode.RET_SUCC.getNumber())
|
||||||
|
.addAllSnapshotList(records.stream()
|
||||||
|
.map(BargainRecord::toSnapshot)
|
||||||
|
.toList()));
|
||||||
|
}
|
||||||
|
}
|
@ -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()));
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user