feat:cooking food ingredient(aka:compound) implementation (#1858)

* feat:cooking food ingredient(aka:compound) implementation

Implement food ingredient(compound) feature.Need a thorough test and still has some work to do.

* small bug fix;implement fish processing

* Update src/main/java/emu/grasscutter/server/packet/send/PacketItemAddHintNotify.java

Co-authored-by: Luke H-W <Birdulon@users.noreply.github.com>

* Update Inventory.java

* Update Inventory.java

Co-authored-by: Luke H-W <Birdulon@users.noreply.github.com>
This commit is contained in:
dragon
2022-10-17 16:48:05 +08:00
committed by GitHub
parent 1ecc3f4390
commit cf67c44f22
27 changed files with 7265 additions and 77 deletions

View File

@@ -68,6 +68,7 @@ public class GameData {
@Getter private static final Int2ObjectMap<CombineData> combineDataMap = new Int2ObjectOpenHashMap<>();
@Getter private static final Int2ObjectMap<CookBonusData> cookBonusDataMap = new Int2ObjectOpenHashMap<>();
@Getter private static final Int2ObjectMap<CookRecipeData> cookRecipeDataMap = new Int2ObjectOpenHashMap<>();
@Getter private static final Int2ObjectMap<CompoundData> compoundDataMap=new Int2ObjectOpenHashMap<>();
@Getter private static final Int2ObjectMap<DailyDungeonData> dailyDungeonDataMap = new Int2ObjectOpenHashMap<>();
@Getter private static final Int2ObjectMap<DungeonData> dungeonDataMap = new Int2ObjectOpenHashMap<>();
@Getter private static final Int2ObjectMap<DungeonEntryData> dungeonEntryDataMap = new Int2ObjectOpenHashMap<>();

View File

@@ -0,0 +1,26 @@
package emu.grasscutter.data.excels;
import emu.grasscutter.data.GameResource;
import emu.grasscutter.data.ResourceType;
import emu.grasscutter.data.common.ItemParamData;
import lombok.Getter;
import java.util.List;
@ResourceType(name = {"CompoundExcelConfigData.json"},loadPriority = ResourceType.LoadPriority.LOW)
public class CompoundData extends GameResource {
private int id;
@Override
public int getId(){return this.id;}
@Getter private int groupId;
@Getter private int rankLevel;
@Getter private boolean isDefaultUnlocked;
@Getter private int costTime;
@Getter private int queueSize;
@Getter private List<ItemParamData> inputVec;
@Getter private List<ItemParamData> outputVec;
@Override
public void onLoad(){}
}

View File

@@ -6,44 +6,23 @@ import emu.grasscutter.data.GameResource;
import emu.grasscutter.data.ResourceType;
import emu.grasscutter.data.ResourceType.LoadPriority;
import emu.grasscutter.data.common.ItemParamData;
import emu.grasscutter.net.proto.ItemParamOuterClass.ItemParam;
import lombok.Getter;
@ResourceType(name = {"CookRecipeExcelConfigData.json"}, loadPriority = LoadPriority.LOW)
public class CookRecipeData extends GameResource {
private int id;
private int rankLevel;
private boolean isDefaultUnlocked;
private int maxProficiency;
@Getter private int rankLevel;
@Getter boolean isDefaultUnlocked;
@Getter int maxProficiency;
private List<ItemParamData> qualityOutputVec;
private List<ItemParamData> inputVec;
@Getter List<ItemParamData> qualityOutputVec;
@Getter List<ItemParamData> inputVec;
@Override
public int getId() {
return this.id;
}
public int getRankLevel() {
return this.rankLevel;
}
public boolean isDefaultUnlocked() {
return this.isDefaultUnlocked;
}
public int getMaxProficiency() {
return this.maxProficiency;
}
public List<ItemParamData> getQualityOutputVec() {
return this.qualityOutputVec;
}
public List<ItemParamData> getInputVec() {
return this.inputVec;
}
@Override
public void onLoad() {
}

View File

@@ -1,12 +1,5 @@
package emu.grasscutter.game.inventory;
import static emu.grasscutter.config.Configuration.*;
import java.util.Collection;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import emu.grasscutter.GameConstants;
import emu.grasscutter.data.GameData;
import emu.grasscutter.data.common.ItemParamData;
@@ -15,14 +8,14 @@ import emu.grasscutter.data.excels.AvatarData;
import emu.grasscutter.data.excels.AvatarFlycloakData;
import emu.grasscutter.data.excels.ItemData;
import emu.grasscutter.database.DatabaseHelper;
import emu.grasscutter.game.avatar.AvatarStorage;
import emu.grasscutter.game.avatar.Avatar;
import emu.grasscutter.game.avatar.AvatarStorage;
import emu.grasscutter.game.player.BasePlayerManager;
import emu.grasscutter.game.player.Player;
import emu.grasscutter.game.props.ActionReason;
import emu.grasscutter.game.props.ItemUseAction.UseItemParams;
import emu.grasscutter.game.props.PlayerProperty;
import emu.grasscutter.game.props.WatcherTriggerType;
import emu.grasscutter.game.props.ItemUseAction.UseItemParams;
import emu.grasscutter.net.proto.ItemParamOuterClass.ItemParam;
import emu.grasscutter.server.packet.send.PacketAvatarEquipChangeNotify;
import emu.grasscutter.server.packet.send.PacketItemAddHintNotify;
@@ -33,6 +26,13 @@ import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap;
import it.unimi.dsi.fastutil.longs.Long2ObjectMap;
import it.unimi.dsi.fastutil.longs.Long2ObjectOpenHashMap;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;
import static emu.grasscutter.config.Configuration.INVENTORY_LIMITS;
public class Inventory extends BasePlayerManager implements Iterable<GameItem> {
private final Long2ObjectMap<GameItem> store;
private final Int2ObjectMap<InventoryTab> inventoryTypes;
@@ -138,26 +138,23 @@ public class Inventory extends BasePlayerManager implements Iterable<GameItem> {
this.addItems(items, null);
}
public void addItems(Collection<GameItem> items, ActionReason reason) {
List<GameItem> changedItems = new LinkedList<>();
for (GameItem item : items) {
List<GameItem> changedItems = new ArrayList<>();
for (var item : items) {
if (item.getItemId() == 0) continue;
GameItem result = putItem(item);
if (result != null) {
getPlayer().getBattlePassManager().triggerMission(WatcherTriggerType.TRIGGER_OBTAIN_MATERIAL_NUM, result.getItemId(), result.getCount());
changedItems.add(result);
}
}
if (changedItems.size() == 0) {
return;
}
if (reason != null) {
getPlayer().sendPacket(new PacketItemAddHintNotify(changedItems, reason));
}
getPlayer().sendPacket(new PacketStoreItemChangeNotify(changedItems));
}
@@ -394,6 +391,7 @@ public class Inventory extends BasePlayerManager implements Iterable<GameItem> {
return false;
// All costs are satisfied, now remove them all
costItems.forEach(cost -> this.payVirtualItem(cost.getId(), cost.getCount() * quantity));
//TODO:handle the reason(need to send certain package)
return true;
}

View File

@@ -0,0 +1,59 @@
package emu.grasscutter.game.managers.cooking;
import dev.morphia.annotations.Entity;
import lombok.Getter;
@Entity
public class ActiveCookCompoundData {
private final int costTime;
@Getter
private final int compoundId;
@Getter
private int totalCount;
private int startTime;
public ActiveCookCompoundData(int compoundId, int processTime, int count, int startTime) {
this.compoundId = compoundId;
this.costTime = processTime;
this.totalCount = count;
this.startTime = startTime;
}
public int getOutputCount(int currentTime) {
int cnt = (currentTime - startTime) / costTime;
if (cnt > totalCount) return totalCount;
else return cnt;
}
public int getWaitCount(int currentTime) {
return totalCount - getOutputCount(currentTime);
}
/**
* Get the timestamp of next output.
* If all finished,return 0
*/
public int getOutputTime(int currentTime) {
int cnt = getOutputCount(currentTime);
if (cnt == totalCount) return 0;
else return startTime + (cnt + 1) * costTime;
}
public void addCompound(int count, int currentTime) {
if (getOutputCount(currentTime) == totalCount) startTime = currentTime - totalCount * costTime;
totalCount += count;
}
/**
* Take away all finished compound.
*
* @return The number of finished items.
*/
public int takeCompound(int currentTime) {
int count = getOutputCount(currentTime);
startTime += costTime * count;
totalCount -= count;
return count;
}
}

View File

@@ -0,0 +1,132 @@
package emu.grasscutter.game.managers.cooking;
import emu.grasscutter.data.GameData;
import emu.grasscutter.data.common.ItemParamData;
import emu.grasscutter.data.excels.CompoundData;
import emu.grasscutter.game.inventory.GameItem;
import emu.grasscutter.game.player.BasePlayerManager;
import emu.grasscutter.game.player.Player;
import emu.grasscutter.game.props.ActionReason;
import emu.grasscutter.net.proto.CompoundQueueDataOuterClass.CompoundQueueData;
import emu.grasscutter.net.proto.GetCompoundDataReqOuterClass.GetCompoundDataReq;
import emu.grasscutter.net.proto.ItemParamOuterClass.ItemParam;
import emu.grasscutter.net.proto.PlayerCompoundMaterialReqOuterClass.PlayerCompoundMaterialReq;
import emu.grasscutter.net.proto.RetcodeOuterClass.Retcode;
import emu.grasscutter.net.proto.TakeCompoundOutputReqOuterClass.TakeCompoundOutputReq;
import emu.grasscutter.server.packet.send.PackageTakeCompoundOutputRsp;
import emu.grasscutter.server.packet.send.PacketGetCompoundDataRsp;
import emu.grasscutter.server.packet.send.PacketPlayerCompoundMaterialRsp;
import emu.grasscutter.utils.Utils;
import java.util.*;
public class CookingCompoundManager extends BasePlayerManager {
private static Set<Integer> defaultUnlockedCompounds;
private static Map<Integer, Set<Integer>> compoundGroups;
//TODO:bind it to player
private static Set<Integer> unlocked;
public CookingCompoundManager(Player player) {
super(player);
}
public static void initialize() {
defaultUnlockedCompounds = new HashSet<>();
compoundGroups = new HashMap<>();
for (var compound : GameData.getCompoundDataMap().values()) {
if (compound.isDefaultUnlocked()) {
defaultUnlockedCompounds.add(compound.getId());
}
if (!compoundGroups.containsKey(compound.getGroupId())) {
compoundGroups.put(compound.getGroupId(), new HashSet<>());
}
compoundGroups.get(compound.getGroupId()).add(compound.getId());
}
//TODO:Because we haven't implemented fishing feature,unlock all compounds related to fish.Besides,it should be bound to player rather than manager.
unlocked = new HashSet<>(defaultUnlockedCompounds);
unlocked.addAll(compoundGroups.get(3));
}
private synchronized List<CompoundQueueData> getCompoundQueueData() {
List<CompoundQueueData> compoundQueueData = new ArrayList<>(player.getActiveCookCompounds().size());
int currentTime = Utils.getCurrentSeconds();
for (var item : player.getActiveCookCompounds().values()) {
var data = CompoundQueueData.newBuilder().setCompoundId(item.getCompoundId()).setOutputCount(item.getOutputCount(currentTime)).setOutputTime(item.getOutputTime(currentTime)).setWaitCount(item.getWaitCount(currentTime)).build();
compoundQueueData.add(data);
}
return compoundQueueData;
}
public synchronized void handleGetCompoundDataReq(GetCompoundDataReq req) {
player.sendPacket(new PacketGetCompoundDataRsp(unlocked, getCompoundQueueData()));
}
public synchronized void handlePlayerCompoundMaterialReq(PlayerCompoundMaterialReq req) {
int id = req.getCompoundId(), count = req.getCount();
CompoundData compound = GameData.getCompoundDataMap().get(id);
var activeCompounds = player.getActiveCookCompounds();
//check whether the compound is available
//TODO:add other compounds,see my pr for detail
if (!unlocked.contains(id)) {
player.sendPacket(new PacketPlayerCompoundMaterialRsp(Retcode.RET_FAIL_VALUE));
return;
}
//check whether the queue is full
if (activeCompounds.containsKey(id) && activeCompounds.get(id).getTotalCount() + count > compound.getQueueSize()) {
player.sendPacket(new PacketPlayerCompoundMaterialRsp(Retcode.RET_COMPOUND_QUEUE_FULL_VALUE));
return;
}
//try to consume raw materials
if (!player.getInventory().payItems(compound.getInputVec(), count)) {
//TODO:I'm not sure whether retcode is correct.
player.sendPacket(new PacketPlayerCompoundMaterialRsp(Retcode.RET_ITEM_COUNT_NOT_ENOUGH_VALUE));
return;
}
ActiveCookCompoundData c;
int currentTime = Utils.getCurrentSeconds();
if (activeCompounds.containsKey(id)) {
c = activeCompounds.get(id);
c.addCompound(count, currentTime);
} else {
c = new ActiveCookCompoundData(id, compound.getCostTime(), count, currentTime);
activeCompounds.put(id, c);
}
var data = CompoundQueueData.newBuilder().setCompoundId(id).setOutputCount(c.getOutputCount(currentTime)).setOutputTime(c.getOutputTime(currentTime)).setWaitCount(c.getWaitCount(currentTime)).build();
player.sendPacket(new PacketPlayerCompoundMaterialRsp(data));
}
public synchronized void handleTakeCompoundOutputReq(TakeCompoundOutputReq req) {
//Client won't set compound_id and will set group_id instead.
int groupId = req.getCompoundGroupId();
var activeCompounds = player.getActiveCookCompounds();
int now = Utils.getCurrentSeconds();
//check available queues
boolean success = false;
Map<Integer, GameItem> allRewards = new HashMap<>();
for (int id : compoundGroups.get(groupId)) {
if (!activeCompounds.containsKey(id)) continue;
int quantity = activeCompounds.get(id).takeCompound(now);
if (activeCompounds.get(id).getTotalCount() == 0) activeCompounds.remove(id);
if (quantity == 0) continue;
List<ItemParamData> rewards = GameData.getCompoundDataMap().get(id).getOutputVec();
for (var i : rewards) {
if (i.getId() == 0) continue;
if (allRewards.containsKey(i.getId())) {
GameItem item = allRewards.get(i.getId());
item.setCount(item.getCount() + i.getCount() * quantity);
} else {
allRewards.put(i.getId(), new GameItem(i.getId(), i.getCount()*quantity));
}
}
success = true;
}
//give player the rewards
if (success) {
player.getInventory().addItems(allRewards.values(), ActionReason.Compound);
player.sendPacket(new PackageTakeCompoundOutputRsp(allRewards.values().stream().map(i -> ItemParam.newBuilder().setItemId(i.getItemId()).setCount(i.getCount()).build()).toList(), Retcode.RET_SUCC_VALUE));
} else {
player.sendPacket(new PackageTakeCompoundOutputRsp(null, Retcode.RET_COMPOUND_NOT_FINISH_VALUE));
}
}
}

View File

@@ -1,4 +1,4 @@
package emu.grasscutter.game.managers;
package emu.grasscutter.game.managers.cooking;
import java.util.ArrayList;
import java.util.HashSet;

View File

@@ -1,7 +1,6 @@
package emu.grasscutter.game.managers.forging;
import dev.morphia.annotations.Entity;
import emu.grasscutter.utils.Utils;
@Entity
public class ActiveForgeData {
@@ -17,7 +16,7 @@ public class ActiveForgeData {
public int getFinishedCount(int currentTime) {
int timeDelta = currentTime - this.startTime;
int finishedCount = (int)Math.floor(timeDelta / this.forgeTime);
int finishedCount = timeDelta / this.forgeTime;
return Math.min(finishedCount, this.count);
}

View File

@@ -146,7 +146,8 @@ public class ForgingManager extends BasePlayerManager {
boolean success = player.getInventory().payItems(material, req.getForgeCount(), ActionReason.ForgeCost);
if (!success) {
this.player.sendPacket(new PacketForgeStartRsp(Retcode.RET_FORGE_POINT_NOT_ENOUGH)); //ToDo: Probably the wrong return code.
//TODO:I'm not sure this one is correct.
this.player.sendPacket(new PacketForgeStartRsp(Retcode.RET_ITEM_COUNT_NOT_ENOUGH)); //ToDo: Probably the wrong return code.
}
// Consume forge points.
@@ -171,7 +172,7 @@ public class ForgingManager extends BasePlayerManager {
Forge queue manipulation (obtaining results and cancelling forges).
**********/
private synchronized void obtainItems(int queueId) {
// Determin how many items are finished.
// Determine how many items are finished.
int currentTime = Utils.getCurrentSeconds();
ActiveForgeData forge = this.player.getActiveForges().get(queueId - 1);
@@ -271,14 +272,10 @@ public class ForgingManager extends BasePlayerManager {
// Handle according to the manipulation type.
switch (manipulateType) {
case FORGE_QUEUE_MANIPULATE_TYPE_RECEIVE_OUTPUT:
this.obtainItems(queueId);
break;
case FORGE_QUEUE_MANIPULATE_TYPE_STOP_FORGE:
this.cancelForge(queueId);
break;
default:
break; //Should never happen.
case FORGE_QUEUE_MANIPULATE_TYPE_RECEIVE_OUTPUT -> this.obtainItems(queueId);
case FORGE_QUEUE_MANIPULATE_TYPE_STOP_FORGE -> this.cancelForge(queueId);
default -> {
} //Should never happen.
}
}
@@ -296,9 +293,7 @@ public class ForgingManager extends BasePlayerManager {
}
boolean hasChanges = this.player.getActiveForges().stream()
.filter(forge -> forge.updateChanged(currentTime))
.findAny()
.isPresent();
.anyMatch(forge -> forge.updateChanged(currentTime));
if (!hasChanges) {
return;

View File

@@ -24,7 +24,9 @@ import emu.grasscutter.game.inventory.GameItem;
import emu.grasscutter.game.inventory.Inventory;
import emu.grasscutter.game.mail.Mail;
import emu.grasscutter.game.mail.MailHandler;
import emu.grasscutter.game.managers.CookingManager;
import emu.grasscutter.game.managers.cooking.ActiveCookCompoundData;
import emu.grasscutter.game.managers.cooking.CookingCompoundManager;
import emu.grasscutter.game.managers.cooking.CookingManager;
import emu.grasscutter.game.managers.FurnitureManager;
import emu.grasscutter.game.managers.ResinManager;
import emu.grasscutter.game.managers.deforestation.DeforestationManager;
@@ -122,6 +124,7 @@ public class Player {
@Getter private Map<Long, ExpeditionInfo> expeditionInfo;
@Getter private Map<Integer, Integer> unlockedRecipies;
@Getter private List<ActiveForgeData> activeForges;
@Getter private Map<Integer, ActiveCookCompoundData> activeCookCompounds;
@Getter private Map<Integer, Integer> questGlobalVariables;
@Getter private Map<Integer, Integer> openStates;
@Getter @Setter private Map<Integer, Set<Integer>> unlockedSceneAreas;
@@ -154,6 +157,7 @@ public class Player {
@Getter private transient FurnitureManager furnitureManager;
@Getter private transient BattlePassManager battlePassManager;
@Getter private transient CookingManager cookingManager;
@Getter private transient CookingCompoundManager cookingCompoundManager;
@Getter private transient ActivityManager activityManager;
@Getter private transient PlayerBuffManager buffManager;
@Getter private transient PlayerProgressManager progressManager;
@@ -225,6 +229,7 @@ public class Player {
this.unlockedCombines = new HashSet<>();
this.unlockedFurniture = new HashSet<>();
this.unlockedFurnitureSuite = new HashSet<>();
this.activeCookCompounds=new HashMap<>();
this.activeForges = new ArrayList<>();
this.unlockedRecipies = new HashMap<>();
this.questGlobalVariables = new HashMap<>();
@@ -256,6 +261,7 @@ public class Player {
this.progressManager = new PlayerProgressManager(this);
this.furnitureManager = new FurnitureManager(this);
this.cookingManager = new CookingManager(this);
this.cookingCompoundManager=new CookingCompoundManager(this);
}
// On player creation
@@ -290,6 +296,7 @@ public class Player {
this.progressManager = new PlayerProgressManager(this);
this.furnitureManager = new FurnitureManager(this);
this.cookingManager = new CookingManager(this);
this.cookingCompoundManager=new CookingCompoundManager(this);
}
public int getUid() {
@@ -557,11 +564,11 @@ public class Player {
public void onEnterRegion(SceneRegion region) {
getQuestManager().forEachActiveQuest(quest -> {
if (quest.getTriggers().containsKey("ENTER_REGION_"+ String.valueOf(region.config_id))) {
if (quest.getTriggers().containsKey("ENTER_REGION_"+ region.config_id)) {
// If trigger hasn't been fired yet
if (!Boolean.TRUE.equals(quest.getTriggers().put("ENTER_REGION_"+ String.valueOf(region.config_id), true))) {
if (!Boolean.TRUE.equals(quest.getTriggers().put("ENTER_REGION_"+ region.config_id, true))) {
//getSession().send(new PacketServerCondMeetQuestListUpdateNotify());
getQuestManager().triggerEvent(QuestTrigger.QUEST_CONTENT_TRIGGER_FIRE, quest.getTriggerData().get("ENTER_REGION_"+ String.valueOf(region.config_id)).getId(),0);
getQuestManager().triggerEvent(QuestTrigger.QUEST_CONTENT_TRIGGER_FIRE, quest.getTriggerData().get("ENTER_REGION_"+ region.config_id).getId(),0);
}
}
});
@@ -570,11 +577,11 @@ public class Player {
public void onLeaveRegion(SceneRegion region) {
getQuestManager().forEachActiveQuest(quest -> {
if (quest.getTriggers().containsKey("LEAVE_REGION_"+ String.valueOf(region.config_id))) {
if (quest.getTriggers().containsKey("LEAVE_REGION_"+ region.config_id)) {
// If trigger hasn't been fired yet
if (!Boolean.TRUE.equals(quest.getTriggers().put("LEAVE_REGION_"+ String.valueOf(region.config_id), true))) {
if (!Boolean.TRUE.equals(quest.getTriggers().put("LEAVE_REGION_"+ region.config_id, true))) {
getSession().send(new PacketServerCondMeetQuestListUpdateNotify());
getQuestManager().triggerEvent(QuestTrigger.QUEST_CONTENT_TRIGGER_FIRE, quest.getTriggerData().get("LEAVE_REGION_"+ String.valueOf(region.config_id)).getId(),0);
getQuestManager().triggerEvent(QuestTrigger.QUEST_CONTENT_TRIGGER_FIRE, quest.getTriggerData().get("LEAVE_REGION_"+ region.config_id).getId(),0);
}
}
});
@@ -1287,16 +1294,14 @@ public class Player {
@Getter private final int value;
private SceneLoadState(int value) {
SceneLoadState(int value) {
this.value = value;
}
}
public int getPropertyMin(PlayerProperty prop) {
if (prop.isDynamicRange()) {
return switch (prop) {
default -> 0;
};
return 0;
} else {
return prop.getMin();
}

View File

@@ -13,7 +13,8 @@ import emu.grasscutter.game.dungeons.DungeonSystem;
import emu.grasscutter.game.dungeons.challenge.DungeonChallenge;
import emu.grasscutter.game.expedition.ExpeditionSystem;
import emu.grasscutter.game.gacha.GachaSystem;
import emu.grasscutter.game.managers.CookingManager;
import emu.grasscutter.game.managers.cooking.CookingCompoundManager;
import emu.grasscutter.game.managers.cooking.CookingManager;
import emu.grasscutter.game.managers.energy.EnergyManager;
import emu.grasscutter.game.managers.stamina.StaminaManager;
import emu.grasscutter.game.player.Player;
@@ -95,6 +96,7 @@ public final class GameServer extends KcpServer {
EnergyManager.initialize();
StaminaManager.initialize();
CookingManager.initialize();
CookingCompoundManager.initialize();
CombineManger.initialize();
// Game Server base

View File

@@ -0,0 +1,16 @@
package emu.grasscutter.server.packet.recv;
import emu.grasscutter.net.packet.Opcodes;
import emu.grasscutter.net.packet.PacketHandler;
import emu.grasscutter.net.packet.PacketOpcodes;
import emu.grasscutter.net.proto.GetCompoundDataReqOuterClass;
import emu.grasscutter.server.game.GameSession;
@Opcodes(PacketOpcodes.GetCompoundDataReq)
public class HandlerGetCompoundDataReq extends PacketHandler {
@Override
public void handle(GameSession session, byte[] header, byte[] payload) throws Exception {
var req = GetCompoundDataReqOuterClass.GetCompoundDataReq.parseFrom(payload);
session.getPlayer().getCookingCompoundManager().handleGetCompoundDataReq(req);
}
}

View File

@@ -0,0 +1,17 @@
package emu.grasscutter.server.packet.recv;
import emu.grasscutter.net.packet.Opcodes;
import emu.grasscutter.net.packet.PacketHandler;
import emu.grasscutter.net.packet.PacketOpcodes;
import emu.grasscutter.net.proto.PlayerCompoundMaterialReqOuterClass;
import emu.grasscutter.server.game.GameSession;
@Opcodes(PacketOpcodes.PlayerCompoundMaterialReq)
public class HandlerPlayerCompoundMaterialReq extends PacketHandler {
@Override
public void handle(GameSession session, byte[] header, byte[] payload) throws Exception {
var req = PlayerCompoundMaterialReqOuterClass.PlayerCompoundMaterialReq.parseFrom(payload);
session.getPlayer().getCookingCompoundManager().handlePlayerCompoundMaterialReq(req);
}
}

View File

@@ -0,0 +1,16 @@
package emu.grasscutter.server.packet.recv;
import emu.grasscutter.net.packet.Opcodes;
import emu.grasscutter.net.packet.PacketHandler;
import emu.grasscutter.net.packet.PacketOpcodes;
import emu.grasscutter.net.proto.TakeCompoundOutputReqOuterClass;
import emu.grasscutter.server.game.GameSession;
@Opcodes(PacketOpcodes.TakeCompoundOutputReq)
public class HandlerTakeCompoundOutputReq extends PacketHandler {
@Override
public void handle(GameSession session, byte[] header, byte[] payload) throws Exception {
var req = TakeCompoundOutputReqOuterClass.TakeCompoundOutputReq.parseFrom(payload);
session.getPlayer().getCookingCompoundManager().handleTakeCompoundOutputReq(req);
}
}

View File

@@ -0,0 +1,17 @@
package emu.grasscutter.server.packet.send;
import emu.grasscutter.net.packet.BasePacket;
import emu.grasscutter.net.packet.PacketOpcodes;
import emu.grasscutter.net.proto.ItemParamOuterClass.ItemParam;
import emu.grasscutter.net.proto.TakeCompoundOutputRspOuterClass.TakeCompoundOutputRsp;
public class PackageTakeCompoundOutputRsp extends BasePacket {
public PackageTakeCompoundOutputRsp(Iterable<ItemParam> itemList, int retcode) {
super(PacketOpcodes.TakeCompoundOutputRsp);
var builder = TakeCompoundOutputRsp.newBuilder()
.addAllItemList(itemList)
.setRetcode(retcode);
setData(builder.build());
}
}

View File

@@ -1,14 +1,10 @@
package emu.grasscutter.server.packet.send;
import emu.grasscutter.game.player.Player;
import emu.grasscutter.net.packet.BasePacket;
import emu.grasscutter.net.packet.PacketOpcodes;
import emu.grasscutter.net.proto.ForgeStartRspOuterClass.ForgeStartRsp;
import emu.grasscutter.net.proto.RetcodeOuterClass.Retcode;
import java.util.ArrayList;
import java.util.List;
public class PacketForgeStartRsp extends BasePacket {
public PacketForgeStartRsp(Retcode retcode) {
@@ -17,7 +13,7 @@ public class PacketForgeStartRsp extends BasePacket {
ForgeStartRsp proto = ForgeStartRsp.newBuilder()
.setRetcode(retcode.getNumber())
.build();
this.setData(proto);
}
}
}

View File

@@ -0,0 +1,22 @@
package emu.grasscutter.server.packet.send;
import emu.grasscutter.net.packet.BasePacket;
import emu.grasscutter.net.packet.PacketOpcodes;
import emu.grasscutter.net.proto.CompoundQueueDataOuterClass.CompoundQueueData;
import emu.grasscutter.net.proto.GetCompoundDataRspOuterClass.GetCompoundDataRsp;
import emu.grasscutter.net.proto.RetcodeOuterClass.Retcode;
import java.util.List;
import java.util.Set;
public class PacketGetCompoundDataRsp extends BasePacket {
public PacketGetCompoundDataRsp(Set<Integer> unlockedCompounds, List<CompoundQueueData> compundQueueData) {
super(PacketOpcodes.GetCompoundDataRsp);
var proto = GetCompoundDataRsp.newBuilder()
.addAllUnlockCompoundList(unlockedCompounds)
.addAllCompoundQueDataList(compundQueueData)
.setRetcode(Retcode.RET_SUCC_VALUE)
.build();
setData(proto);
}
}

View File

@@ -0,0 +1,36 @@
package emu.grasscutter.server.packet.send;
import emu.grasscutter.net.packet.BasePacket;
import emu.grasscutter.net.packet.PacketOpcodes;
import emu.grasscutter.net.proto.CompoundQueueDataOuterClass.CompoundQueueData;
import emu.grasscutter.net.proto.PlayerCompoundMaterialRspOuterClass.PlayerCompoundMaterialRsp;
import emu.grasscutter.net.proto.RetcodeOuterClass.Retcode;
public class PacketPlayerCompoundMaterialRsp extends BasePacket {
/**
* Builder for successful message.
*
* @param compoundQueueData new compound queue
*/
public PacketPlayerCompoundMaterialRsp(CompoundQueueData compoundQueueData) {
super(PacketOpcodes.PlayerCompoundMaterialRsp);
PlayerCompoundMaterialRsp proto = PlayerCompoundMaterialRsp.newBuilder()
.setCompoundQueData(compoundQueueData)
.setRetcode(Retcode.RET_SUCC_VALUE)
.build();
setData(proto);
}
/**
* Builder for failed message.
* @param retcode error code
*/
public PacketPlayerCompoundMaterialRsp(int retcode) {
super(PacketOpcodes.PlayerCompoundMaterialRsp);
PlayerCompoundMaterialRsp proto = PlayerCompoundMaterialRsp.newBuilder()
.setRetcode(retcode)
.build();
setData(proto);
}
}