
emu.grasscutter.game.managers.cooking.CookingCompoundManager Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of grasscutter Show documentation
Show all versions of grasscutter Show documentation
A server software reimplementation for an anime game.
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.PacketCompoundDataNotify;
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 defaultUnlockedCompounds;
private static Map> compoundGroups;
//TODO:bind it to player
private static Set unlocked;
public CookingCompoundManager(Player player) {
super(player);
}
public static void initialize() {
defaultUnlockedCompounds = new HashSet<>();
compoundGroups = new HashMap<>();
GameData.getCompoundDataMap().forEach((id, compound) -> {
if (compound.isDefaultUnlocked()) {
defaultUnlockedCompounds.add(id);
}
compoundGroups.computeIfAbsent(compound.getGroupID(), gid -> new HashSet<>()).add(id);
});
//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);
if (compoundGroups.containsKey(3)) // Avoid NPE from Resources error
unlocked.addAll(compoundGroups.get(3));
}
private synchronized List getCompoundQueueData() {
List 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 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 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));
}
}
public void onPlayerLogin() {
player.sendPacket(new PacketCompoundDataNotify(unlocked,getCompoundQueueData()));
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy