Skip to content
Snippets Groups Projects
Commit d95a30a1 authored by GanyusLeftHorn's avatar GanyusLeftHorn Committed by Melledy
Browse files

Cooking and unlocking recipies.

parent a957b8c5
Branches
Tags
No related merge requests found
...@@ -7,11 +7,23 @@ import java.util.List; ...@@ -7,11 +7,23 @@ import java.util.List;
import java.util.Set; import java.util.Set;
import emu.grasscutter.data.GameData; 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.player.Player;
import emu.grasscutter.game.props.ActionReason;
import emu.grasscutter.net.proto.CookRecipeDataOuterClass; 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.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 { public class CookingManager {
private static final int MANUAL_PERFECT_COOK_QUALITY = 3;
private static Set<Integer> defaultUnlockedRecipies; private static Set<Integer> defaultUnlockedRecipies;
private final Player player; private final Player player;
...@@ -30,10 +42,83 @@ public class CookingManager { ...@@ -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. * 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. * Notify unlocked recipies.
......
...@@ -852,6 +852,11 @@ public class InventoryManager { ...@@ -852,6 +852,11 @@ public class InventoryManager {
// Unlock. // Unlock.
useSuccess = player.getServer().getCombineManger().unlockCombineDiagram(player, useItem); 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; break;
case MATERIAL_FURNITURE_FORMULA: case MATERIAL_FURNITURE_FORMULA:
case MATERIAL_FURNITURE_SUITE_FORMULA: case MATERIAL_FURNITURE_SUITE_FORMULA:
......
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);
}
}
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);
}
}
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);
}
}
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);
}
}
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);
}
}
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment