mirror of
https://github.com/Grasscutters/Grasscutter.git
synced 2025-01-09 17:32:53 +08:00
Cooking and unlocking recipies.
This commit is contained in:
parent
a957b8c5b8
commit
d95a30a1a5
@ -7,11 +7,23 @@ import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import emu.grasscutter.data.GameData;
|
||||
import emu.grasscutter.data.common.ItemParamData;
|
||||
import emu.grasscutter.data.excels.ItemData;
|
||||
import emu.grasscutter.game.inventory.GameItem;
|
||||
import emu.grasscutter.game.player.Player;
|
||||
import emu.grasscutter.game.props.ActionReason;
|
||||
import emu.grasscutter.net.proto.CookRecipeDataOuterClass;
|
||||
import emu.grasscutter.net.proto.PlayerCookArgsReqOuterClass.PlayerCookArgsReq;
|
||||
import emu.grasscutter.net.proto.PlayerCookReqOuterClass.PlayerCookReq;
|
||||
import emu.grasscutter.net.proto.RetcodeOuterClass.Retcode;
|
||||
import emu.grasscutter.server.packet.send.PacketCookDataNotify;
|
||||
import emu.grasscutter.server.packet.send.PacketCookRecipeDataNotify;
|
||||
import emu.grasscutter.server.packet.send.PacketPlayerCookArgsRsp;
|
||||
import emu.grasscutter.server.packet.send.PacketPlayerCookRsp;
|
||||
|
||||
public class CookingManager {
|
||||
private static final int MANUAL_PERFECT_COOK_QUALITY = 3;
|
||||
|
||||
private static Set<Integer> defaultUnlockedRecipies;
|
||||
private final Player player;
|
||||
|
||||
@ -30,10 +42,83 @@ public class CookingManager {
|
||||
}
|
||||
}
|
||||
|
||||
/********************
|
||||
* Unlocking for recipies.
|
||||
********************/
|
||||
public synchronized boolean unlockRecipe(GameItem recipeItem) {
|
||||
// Make sure this is actually a cooking recipe.
|
||||
if (!recipeItem.getItemData().getItemUse().get(0).getUseOp().equals("ITEM_USE_UNLOCK_COOK_RECIPE")) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Determine the recipe we should unlock.
|
||||
int recipeId = Integer.parseInt(recipeItem.getItemData().getItemUse().get(0).getUseParam().get(0));
|
||||
|
||||
// Remove the item from the player's inventory.
|
||||
// We need to do this here, before sending CookRecipeDataNotify, or the the UI won't correctly update.
|
||||
player.getInventory().removeItem(recipeItem, 1);
|
||||
|
||||
// Tell the client that this blueprint is now unlocked and add the unlocked item to the player.
|
||||
this.player.getUnlockedRecipies().put(recipeId, 0);
|
||||
this.player.sendPacket(new PacketCookRecipeDataNotify(recipeId));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/********************
|
||||
* Perform cooking.
|
||||
********************/
|
||||
|
||||
public void handlePlayerCookReq(PlayerCookReq req) {
|
||||
// Get info from the request.
|
||||
int recipeId = req.getRecipeId();
|
||||
int quality = req.getQteQuality();
|
||||
int count = req.getCookCount();
|
||||
|
||||
// Get recipe data.
|
||||
var recipeData = GameData.getCookRecipeDataMap().get(recipeId);
|
||||
if (recipeData == null) {
|
||||
this.player.sendPacket(new PacketPlayerCookRsp(Retcode.RET_FAIL));
|
||||
return;
|
||||
}
|
||||
|
||||
// Get proficiency for player.
|
||||
int proficiency = this.player.getUnlockedRecipies().getOrDefault(recipeId, 0);
|
||||
|
||||
// Try consuming materials.
|
||||
boolean success = player.getInventory().payItems(recipeData.getInputVec().toArray(new ItemParamData[0]), count, ActionReason.Cook);
|
||||
if (!success) {
|
||||
this.player.sendPacket(new PacketPlayerCookRsp(Retcode.RET_FAIL)); //ToDo: Probably the wrong return code.
|
||||
}
|
||||
|
||||
// Obtain results.
|
||||
int qualityIndex =
|
||||
quality == 0
|
||||
? 2
|
||||
: quality - 1;
|
||||
|
||||
ItemParamData resultParam = recipeData.getQualityOutputVec().get(qualityIndex);
|
||||
ItemData resultItemData = GameData.getItemDataMap().get(resultParam.getItemId());
|
||||
|
||||
GameItem cookResult = new GameItem(resultItemData, resultParam.getCount() * count);
|
||||
this.player.getInventory().addItem(cookResult);
|
||||
|
||||
// Increase player proficiency, if this was a manual perfect cook.
|
||||
if (quality == MANUAL_PERFECT_COOK_QUALITY) {
|
||||
proficiency = Math.min(proficiency + 1, recipeData.getMaxProficiency());
|
||||
this.player.getUnlockedRecipies().put(recipeId, proficiency);
|
||||
}
|
||||
|
||||
// Send response.
|
||||
this.player.sendPacket(new PacketPlayerCookRsp(cookResult, quality, count, recipeId, proficiency));
|
||||
}
|
||||
|
||||
|
||||
/********************
|
||||
* Cooking arguments.
|
||||
********************/
|
||||
public void handleCookArgsReq(PlayerCookArgsReq req) {
|
||||
this.player.sendPacket(new PacketPlayerCookArgsRsp());
|
||||
}
|
||||
|
||||
/********************
|
||||
* Notify unlocked recipies.
|
||||
|
@ -852,6 +852,11 @@ public class InventoryManager {
|
||||
// Unlock.
|
||||
useSuccess = player.getServer().getCombineManger().unlockCombineDiagram(player, useItem);
|
||||
}
|
||||
// Handle cooking recipies.
|
||||
if (useItem.getItemData().getItemUse().get(0).getUseOp().equals("ITEM_USE_UNLOCK_COOK_RECIPE")) {
|
||||
// Unlock.
|
||||
useSuccess = player.getCookingManager().unlockRecipe(useItem);
|
||||
}
|
||||
break;
|
||||
case MATERIAL_FURNITURE_FORMULA:
|
||||
case MATERIAL_FURNITURE_SUITE_FORMULA:
|
||||
|
@ -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.PlayerCookArgsReqOuterClass;
|
||||
import emu.grasscutter.server.game.GameSession;
|
||||
|
||||
@Opcodes(PacketOpcodes.PlayerCookArgsReq)
|
||||
public class HandlerPlayerCookArgsReq extends PacketHandler {
|
||||
@Override
|
||||
public void handle(GameSession session, byte[] header, byte[] payload) throws Exception {
|
||||
PlayerCookArgsReqOuterClass.PlayerCookArgsReq req = PlayerCookArgsReqOuterClass.PlayerCookArgsReq.parseFrom(payload);
|
||||
session.getPlayer().getCookingManager().handleCookArgsReq(req);
|
||||
}
|
||||
}
|
@ -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.PlayerCookReqOuterClass;
|
||||
import emu.grasscutter.server.game.GameSession;
|
||||
|
||||
@Opcodes(PacketOpcodes.PlayerCookReq)
|
||||
public class HandlerPlayerCookReq extends PacketHandler {
|
||||
@Override
|
||||
public void handle(GameSession session, byte[] header, byte[] payload) throws Exception {
|
||||
PlayerCookReqOuterClass.PlayerCookReq req = PlayerCookReqOuterClass.PlayerCookReq.parseFrom(payload);
|
||||
session.getPlayer().getCookingManager().handlePlayerCookReq(req);
|
||||
}
|
||||
}
|
@ -0,0 +1,28 @@
|
||||
package emu.grasscutter.server.packet.send;
|
||||
|
||||
import emu.grasscutter.net.packet.BasePacket;
|
||||
import emu.grasscutter.net.packet.PacketOpcodes;
|
||||
import emu.grasscutter.net.proto.CookRecipeDataNotifyOuterClass.CookRecipeDataNotify;
|
||||
import emu.grasscutter.net.proto.CookRecipeDataOuterClass.CookRecipeData;
|
||||
|
||||
public class PacketCookRecipeDataNotify extends BasePacket {
|
||||
public PacketCookRecipeDataNotify(CookRecipeData recipe) {
|
||||
super(PacketOpcodes.CookRecipeDataNotify);
|
||||
|
||||
CookRecipeDataNotify proto = CookRecipeDataNotify.newBuilder()
|
||||
.setRecipeData(recipe)
|
||||
.build();
|
||||
|
||||
this.setData(proto);
|
||||
}
|
||||
|
||||
public PacketCookRecipeDataNotify(int recipeId) {
|
||||
super(PacketOpcodes.CookRecipeDataNotify);
|
||||
|
||||
CookRecipeDataNotify proto = CookRecipeDataNotify.newBuilder()
|
||||
.setRecipeData(CookRecipeData.newBuilder().setRecipeId(recipeId))
|
||||
.build();
|
||||
|
||||
this.setData(proto);
|
||||
}
|
||||
}
|
@ -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.PlayerCookArgsRspOuterClass.PlayerCookArgsRsp;
|
||||
|
||||
public class PacketPlayerCookArgsRsp extends BasePacket {
|
||||
|
||||
public PacketPlayerCookArgsRsp() {
|
||||
super(PacketOpcodes.PlayerCookArgsRsp);
|
||||
|
||||
PlayerCookArgsRsp proto = PlayerCookArgsRsp.newBuilder()
|
||||
.build();
|
||||
|
||||
this.setData(proto);
|
||||
}
|
||||
}
|
@ -0,0 +1,42 @@
|
||||
package emu.grasscutter.server.packet.send;
|
||||
|
||||
import emu.grasscutter.game.inventory.GameItem;
|
||||
import emu.grasscutter.net.packet.BasePacket;
|
||||
import emu.grasscutter.net.packet.PacketOpcodes;
|
||||
import emu.grasscutter.net.proto.CookRecipeDataOuterClass.CookRecipeData;
|
||||
import emu.grasscutter.net.proto.ItemParamOuterClass.ItemParam;
|
||||
import emu.grasscutter.net.proto.PlayerCookRspOuterClass.PlayerCookRsp;
|
||||
import emu.grasscutter.net.proto.RetcodeOuterClass.Retcode;
|
||||
|
||||
public class PacketPlayerCookRsp extends BasePacket {
|
||||
public PacketPlayerCookRsp(Retcode retcode) {
|
||||
super(PacketOpcodes.PlayerCookRsp);
|
||||
|
||||
PlayerCookRsp proto = PlayerCookRsp.newBuilder()
|
||||
.setRetcode(retcode.getNumber())
|
||||
.build();
|
||||
|
||||
this.setData(proto);
|
||||
}
|
||||
|
||||
public PacketPlayerCookRsp(GameItem output, int quality, int count, int recipeId, int proficiency) {
|
||||
super(PacketOpcodes.PlayerCookRsp);
|
||||
|
||||
PlayerCookRsp proto = PlayerCookRsp.newBuilder()
|
||||
.setRecipeData(
|
||||
CookRecipeData.newBuilder()
|
||||
.setRecipeId(recipeId)
|
||||
.setProficiency(proficiency)
|
||||
)
|
||||
.setQteQuality(quality)
|
||||
.addItemList(
|
||||
ItemParam.newBuilder()
|
||||
.setItemId(output.getItemId())
|
||||
.setCount(output.getCount())
|
||||
)
|
||||
.setCookCount(count)
|
||||
.build();
|
||||
|
||||
this.setData(proto);
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user