Unverified Commit cf67c44f authored by dragon's avatar dragon Committed by GitHub
Browse files

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: default avatarLuke H-W <Birdulon@users.noreply.github.com>

* Update Inventory.java

* Update Inventory.java
Co-authored-by: default avatarLuke H-W <Birdulon@users.noreply.github.com>
parent 1ecc3f43
// Generated by the protocol buffer compiler. DO NOT EDIT!
// source: GetCompoundDataReq.proto
package emu.grasscutter.net.proto;
public final class GetCompoundDataReqOuterClass {
private GetCompoundDataReqOuterClass() {}
public static void registerAllExtensions(
com.google.protobuf.ExtensionRegistryLite registry) {
}
public static void registerAllExtensions(
com.google.protobuf.ExtensionRegistry registry) {
registerAllExtensions(
(com.google.protobuf.ExtensionRegistryLite) registry);
}
public interface GetCompoundDataReqOrBuilder extends
// @@protoc_insertion_point(interface_extends:GetCompoundDataReq)
com.google.protobuf.MessageOrBuilder {
}
/**
* <pre>
* CmdId: 141
* EnetChannelId: 0
* EnetIsReliable: true
* IsAllowClient: true
* </pre>
*
* Protobuf type {@code GetCompoundDataReq}
*/
public static final class GetCompoundDataReq extends
com.google.protobuf.GeneratedMessageV3 implements
// @@protoc_insertion_point(message_implements:GetCompoundDataReq)
GetCompoundDataReqOrBuilder {
private static final long serialVersionUID = 0L;
// Use GetCompoundDataReq.newBuilder() to construct.
private GetCompoundDataReq(com.google.protobuf.GeneratedMessageV3.Builder<?> builder) {
super(builder);
}
private GetCompoundDataReq() {
}
@java.lang.Override
@SuppressWarnings({"unused"})
protected java.lang.Object newInstance(
UnusedPrivateParameter unused) {
return new GetCompoundDataReq();
}
@java.lang.Override
public final com.google.protobuf.UnknownFieldSet
getUnknownFields() {
return this.unknownFields;
}
private GetCompoundDataReq(
com.google.protobuf.CodedInputStream input,
com.google.protobuf.ExtensionRegistryLite extensionRegistry)
throws com.google.protobuf.InvalidProtocolBufferException {
this();
if (extensionRegistry == null) {
throw new java.lang.NullPointerException();
}
com.google.protobuf.UnknownFieldSet.Builder unknownFields =
com.google.protobuf.UnknownFieldSet.newBuilder();
try {
boolean done = false;
while (!done) {
int tag = input.readTag();
switch (tag) {
case 0:
done = true;
break;
default: {
if (!parseUnknownField(
input, unknownFields, extensionRegistry, tag)) {
done = true;
}
break;
}
}
}
} catch (com.google.protobuf.InvalidProtocolBufferException e) {
throw e.setUnfinishedMessage(this);
} catch (java.io.IOException e) {
throw new com.google.protobuf.InvalidProtocolBufferException(
e).setUnfinishedMessage(this);
} finally {
this.unknownFields = unknownFields.build();
makeExtensionsImmutable();
}
}
public static final com.google.protobuf.Descriptors.Descriptor
getDescriptor() {
return emu.grasscutter.net.proto.GetCompoundDataReqOuterClass.internal_static_GetCompoundDataReq_descriptor;
}
@java.lang.Override
protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
internalGetFieldAccessorTable() {
return emu.grasscutter.net.proto.GetCompoundDataReqOuterClass.internal_static_GetCompoundDataReq_fieldAccessorTable
.ensureFieldAccessorsInitialized(
emu.grasscutter.net.proto.GetCompoundDataReqOuterClass.GetCompoundDataReq.class, emu.grasscutter.net.proto.GetCompoundDataReqOuterClass.GetCompoundDataReq.Builder.class);
}
private byte memoizedIsInitialized = -1;
@java.lang.Override
public final boolean isInitialized() {
byte isInitialized = memoizedIsInitialized;
if (isInitialized == 1) return true;
if (isInitialized == 0) return false;
memoizedIsInitialized = 1;
return true;
}
@java.lang.Override
public void writeTo(com.google.protobuf.CodedOutputStream output)
throws java.io.IOException {
unknownFields.writeTo(output);
}
@java.lang.Override
public int getSerializedSize() {
int size = memoizedSize;
if (size != -1) return size;
size = 0;
size += unknownFields.getSerializedSize();
memoizedSize = size;
return size;
}
@java.lang.Override
public boolean equals(final java.lang.Object obj) {
if (obj == this) {
return true;
}
if (!(obj instanceof emu.grasscutter.net.proto.GetCompoundDataReqOuterClass.GetCompoundDataReq)) {
return super.equals(obj);
}
emu.grasscutter.net.proto.GetCompoundDataReqOuterClass.GetCompoundDataReq other = (emu.grasscutter.net.proto.GetCompoundDataReqOuterClass.GetCompoundDataReq) obj;
if (!unknownFields.equals(other.unknownFields)) return false;
return true;
}
@java.lang.Override
public int hashCode() {
if (memoizedHashCode != 0) {
return memoizedHashCode;
}
int hash = 41;
hash = (19 * hash) + getDescriptor().hashCode();
hash = (29 * hash) + unknownFields.hashCode();
memoizedHashCode = hash;
return hash;
}
public static emu.grasscutter.net.proto.GetCompoundDataReqOuterClass.GetCompoundDataReq parseFrom(
java.nio.ByteBuffer data)
throws com.google.protobuf.InvalidProtocolBufferException {
return PARSER.parseFrom(data);
}
public static emu.grasscutter.net.proto.GetCompoundDataReqOuterClass.GetCompoundDataReq parseFrom(
java.nio.ByteBuffer data,
com.google.protobuf.ExtensionRegistryLite extensionRegistry)
throws com.google.protobuf.InvalidProtocolBufferException {
return PARSER.parseFrom(data, extensionRegistry);
}
public static emu.grasscutter.net.proto.GetCompoundDataReqOuterClass.GetCompoundDataReq parseFrom(
com.google.protobuf.ByteString data)
throws com.google.protobuf.InvalidProtocolBufferException {
return PARSER.parseFrom(data);
}
public static emu.grasscutter.net.proto.GetCompoundDataReqOuterClass.GetCompoundDataReq parseFrom(
com.google.protobuf.ByteString data,
com.google.protobuf.ExtensionRegistryLite extensionRegistry)
throws com.google.protobuf.InvalidProtocolBufferException {
return PARSER.parseFrom(data, extensionRegistry);
}
public static emu.grasscutter.net.proto.GetCompoundDataReqOuterClass.GetCompoundDataReq parseFrom(byte[] data)
throws com.google.protobuf.InvalidProtocolBufferException {
return PARSER.parseFrom(data);
}
public static emu.grasscutter.net.proto.GetCompoundDataReqOuterClass.GetCompoundDataReq parseFrom(
byte[] data,
com.google.protobuf.ExtensionRegistryLite extensionRegistry)
throws com.google.protobuf.InvalidProtocolBufferException {
return PARSER.parseFrom(data, extensionRegistry);
}
public static emu.grasscutter.net.proto.GetCompoundDataReqOuterClass.GetCompoundDataReq parseFrom(java.io.InputStream input)
throws java.io.IOException {
return com.google.protobuf.GeneratedMessageV3
.parseWithIOException(PARSER, input);
}
public static emu.grasscutter.net.proto.GetCompoundDataReqOuterClass.GetCompoundDataReq parseFrom(
java.io.InputStream input,
com.google.protobuf.ExtensionRegistryLite extensionRegistry)
throws java.io.IOException {
return com.google.protobuf.GeneratedMessageV3
.parseWithIOException(PARSER, input, extensionRegistry);
}
public static emu.grasscutter.net.proto.GetCompoundDataReqOuterClass.GetCompoundDataReq parseDelimitedFrom(java.io.InputStream input)
throws java.io.IOException {
return com.google.protobuf.GeneratedMessageV3
.parseDelimitedWithIOException(PARSER, input);
}
public static emu.grasscutter.net.proto.GetCompoundDataReqOuterClass.GetCompoundDataReq parseDelimitedFrom(
java.io.InputStream input,
com.google.protobuf.ExtensionRegistryLite extensionRegistry)
throws java.io.IOException {
return com.google.protobuf.GeneratedMessageV3
.parseDelimitedWithIOException(PARSER, input, extensionRegistry);
}
public static emu.grasscutter.net.proto.GetCompoundDataReqOuterClass.GetCompoundDataReq parseFrom(
com.google.protobuf.CodedInputStream input)
throws java.io.IOException {
return com.google.protobuf.GeneratedMessageV3
.parseWithIOException(PARSER, input);
}
public static emu.grasscutter.net.proto.GetCompoundDataReqOuterClass.GetCompoundDataReq parseFrom(
com.google.protobuf.CodedInputStream input,
com.google.protobuf.ExtensionRegistryLite extensionRegistry)
throws java.io.IOException {
return com.google.protobuf.GeneratedMessageV3
.parseWithIOException(PARSER, input, extensionRegistry);
}
@java.lang.Override
public Builder newBuilderForType() { return newBuilder(); }
public static Builder newBuilder() {
return DEFAULT_INSTANCE.toBuilder();
}
public static Builder newBuilder(emu.grasscutter.net.proto.GetCompoundDataReqOuterClass.GetCompoundDataReq prototype) {
return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype);
}
@java.lang.Override
public Builder toBuilder() {
return this == DEFAULT_INSTANCE
? new Builder() : new Builder().mergeFrom(this);
}
@java.lang.Override
protected Builder newBuilderForType(
com.google.protobuf.GeneratedMessageV3.BuilderParent parent) {
Builder builder = new Builder(parent);
return builder;
}
/**
* <pre>
* CmdId: 141
* EnetChannelId: 0
* EnetIsReliable: true
* IsAllowClient: true
* </pre>
*
* Protobuf type {@code GetCompoundDataReq}
*/
public static final class Builder extends
com.google.protobuf.GeneratedMessageV3.Builder<Builder> implements
// @@protoc_insertion_point(builder_implements:GetCompoundDataReq)
emu.grasscutter.net.proto.GetCompoundDataReqOuterClass.GetCompoundDataReqOrBuilder {
public static final com.google.protobuf.Descriptors.Descriptor
getDescriptor() {
return emu.grasscutter.net.proto.GetCompoundDataReqOuterClass.internal_static_GetCompoundDataReq_descriptor;
}
@java.lang.Override
protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
internalGetFieldAccessorTable() {
return emu.grasscutter.net.proto.GetCompoundDataReqOuterClass.internal_static_GetCompoundDataReq_fieldAccessorTable
.ensureFieldAccessorsInitialized(
emu.grasscutter.net.proto.GetCompoundDataReqOuterClass.GetCompoundDataReq.class, emu.grasscutter.net.proto.GetCompoundDataReqOuterClass.GetCompoundDataReq.Builder.class);
}
// Construct using emu.grasscutter.net.proto.GetCompoundDataReqOuterClass.GetCompoundDataReq.newBuilder()
private Builder() {
maybeForceBuilderInitialization();
}
private Builder(
com.google.protobuf.GeneratedMessageV3.BuilderParent parent) {
super(parent);
maybeForceBuilderInitialization();
}
private void maybeForceBuilderInitialization() {
if (com.google.protobuf.GeneratedMessageV3
.alwaysUseFieldBuilders) {
}
}
@java.lang.Override
public Builder clear() {
super.clear();
return this;
}
@java.lang.Override
public com.google.protobuf.Descriptors.Descriptor
getDescriptorForType() {
return emu.grasscutter.net.proto.GetCompoundDataReqOuterClass.internal_static_GetCompoundDataReq_descriptor;
}
@java.lang.Override
public emu.grasscutter.net.proto.GetCompoundDataReqOuterClass.GetCompoundDataReq getDefaultInstanceForType() {
return emu.grasscutter.net.proto.GetCompoundDataReqOuterClass.GetCompoundDataReq.getDefaultInstance();
}
@java.lang.Override
public emu.grasscutter.net.proto.GetCompoundDataReqOuterClass.GetCompoundDataReq build() {
emu.grasscutter.net.proto.GetCompoundDataReqOuterClass.GetCompoundDataReq result = buildPartial();
if (!result.isInitialized()) {
throw newUninitializedMessageException(result);
}
return result;
}
@java.lang.Override
public emu.grasscutter.net.proto.GetCompoundDataReqOuterClass.GetCompoundDataReq buildPartial() {
emu.grasscutter.net.proto.GetCompoundDataReqOuterClass.GetCompoundDataReq result = new emu.grasscutter.net.proto.GetCompoundDataReqOuterClass.GetCompoundDataReq(this);
onBuilt();
return result;
}
@java.lang.Override
public Builder clone() {
return super.clone();
}
@java.lang.Override
public Builder setField(
com.google.protobuf.Descriptors.FieldDescriptor field,
java.lang.Object value) {
return super.setField(field, value);
}
@java.lang.Override
public Builder clearField(
com.google.protobuf.Descriptors.FieldDescriptor field) {
return super.clearField(field);
}
@java.lang.Override
public Builder clearOneof(
com.google.protobuf.Descriptors.OneofDescriptor oneof) {
return super.clearOneof(oneof);
}
@java.lang.Override
public Builder setRepeatedField(
com.google.protobuf.Descriptors.FieldDescriptor field,
int index, java.lang.Object value) {
return super.setRepeatedField(field, index, value);
}
@java.lang.Override
public Builder addRepeatedField(
com.google.protobuf.Descriptors.FieldDescriptor field,
java.lang.Object value) {
return super.addRepeatedField(field, value);
}
@java.lang.Override
public Builder mergeFrom(com.google.protobuf.Message other) {
if (other instanceof emu.grasscutter.net.proto.GetCompoundDataReqOuterClass.GetCompoundDataReq) {
return mergeFrom((emu.grasscutter.net.proto.GetCompoundDataReqOuterClass.GetCompoundDataReq)other);
} else {
super.mergeFrom(other);
return this;
}
}
public Builder mergeFrom(emu.grasscutter.net.proto.GetCompoundDataReqOuterClass.GetCompoundDataReq other) {
if (other == emu.grasscutter.net.proto.GetCompoundDataReqOuterClass.GetCompoundDataReq.getDefaultInstance()) return this;
this.mergeUnknownFields(other.unknownFields);
onChanged();
return this;
}
@java.lang.Override
public final boolean isInitialized() {
return true;
}
@java.lang.Override
public Builder mergeFrom(
com.google.protobuf.CodedInputStream input,
com.google.protobuf.ExtensionRegistryLite extensionRegistry)
throws java.io.IOException {
emu.grasscutter.net.proto.GetCompoundDataReqOuterClass.GetCompoundDataReq parsedMessage = null;
try {
parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
} catch (com.google.protobuf.InvalidProtocolBufferException e) {
parsedMessage = (emu.grasscutter.net.proto.GetCompoundDataReqOuterClass.GetCompoundDataReq) e.getUnfinishedMessage();
throw e.unwrapIOException();
} finally {
if (parsedMessage != null) {
mergeFrom(parsedMessage);
}
}
return this;
}
@java.lang.Override
public final Builder setUnknownFields(
final com.google.protobuf.UnknownFieldSet unknownFields) {
return super.setUnknownFields(unknownFields);
}
@java.lang.Override
public final Builder mergeUnknownFields(
final com.google.protobuf.UnknownFieldSet unknownFields) {
return super.mergeUnknownFields(unknownFields);
}
// @@protoc_insertion_point(builder_scope:GetCompoundDataReq)
}
// @@protoc_insertion_point(class_scope:GetCompoundDataReq)
private static final emu.grasscutter.net.proto.GetCompoundDataReqOuterClass.GetCompoundDataReq DEFAULT_INSTANCE;
static {
DEFAULT_INSTANCE = new emu.grasscutter.net.proto.GetCompoundDataReqOuterClass.GetCompoundDataReq();
}
public static emu.grasscutter.net.proto.GetCompoundDataReqOuterClass.GetCompoundDataReq getDefaultInstance() {
return DEFAULT_INSTANCE;
}
private static final com.google.protobuf.Parser<GetCompoundDataReq>
PARSER = new com.google.protobuf.AbstractParser<GetCompoundDataReq>() {
@java.lang.Override
public GetCompoundDataReq parsePartialFrom(
com.google.protobuf.CodedInputStream input,
com.google.protobuf.ExtensionRegistryLite extensionRegistry)
throws com.google.protobuf.InvalidProtocolBufferException {
return new GetCompoundDataReq(input, extensionRegistry);
}
};
public static com.google.protobuf.Parser<GetCompoundDataReq> parser() {
return PARSER;
}
@java.lang.Override
public com.google.protobuf.Parser<GetCompoundDataReq> getParserForType() {
return PARSER;
}
@java.lang.Override
public emu.grasscutter.net.proto.GetCompoundDataReqOuterClass.GetCompoundDataReq getDefaultInstanceForType() {
return DEFAULT_INSTANCE;
}
}
private static final com.google.protobuf.Descriptors.Descriptor
internal_static_GetCompoundDataReq_descriptor;
private static final
com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
internal_static_GetCompoundDataReq_fieldAccessorTable;
public static com.google.protobuf.Descriptors.FileDescriptor
getDescriptor() {
return descriptor;
}
private static com.google.protobuf.Descriptors.FileDescriptor
descriptor;
static {
java.lang.String[] descriptorData = {
"\n\030GetCompoundDataReq.proto\"\024\n\022GetCompoun" +
"dDataReqB\033\n\031emu.grasscutter.net.protob\006p" +
"roto3"
};
descriptor = com.google.protobuf.Descriptors.FileDescriptor
.internalBuildGeneratedFileFrom(descriptorData,
new com.google.protobuf.Descriptors.FileDescriptor[] {
});
internal_static_GetCompoundDataReq_descriptor =
getDescriptor().getMessageTypes().get(0);
internal_static_GetCompoundDataReq_fieldAccessorTable = new
com.google.protobuf.GeneratedMessageV3.FieldAccessorTable(
internal_static_GetCompoundDataReq_descriptor,
new java.lang.String[] { });
}
// @@protoc_insertion_point(outer_class_scope)
}
...@@ -68,6 +68,7 @@ public class GameData { ...@@ -68,6 +68,7 @@ public class GameData {
@Getter private static final Int2ObjectMap<CombineData> combineDataMap = new Int2ObjectOpenHashMap<>(); @Getter private static final Int2ObjectMap<CombineData> combineDataMap = new Int2ObjectOpenHashMap<>();
@Getter private static final Int2ObjectMap<CookBonusData> cookBonusDataMap = 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<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<DailyDungeonData> dailyDungeonDataMap = new Int2ObjectOpenHashMap<>();
@Getter private static final Int2ObjectMap<DungeonData> dungeonDataMap = new Int2ObjectOpenHashMap<>(); @Getter private static final Int2ObjectMap<DungeonData> dungeonDataMap = new Int2ObjectOpenHashMap<>();
@Getter private static final Int2ObjectMap<DungeonEntryData> dungeonEntryDataMap = new Int2ObjectOpenHashMap<>(); @Getter private static final Int2ObjectMap<DungeonEntryData> dungeonEntryDataMap = new Int2ObjectOpenHashMap<>();
......
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(){}
}
...@@ -6,44 +6,23 @@ import emu.grasscutter.data.GameResource; ...@@ -6,44 +6,23 @@ import emu.grasscutter.data.GameResource;
import emu.grasscutter.data.ResourceType; import emu.grasscutter.data.ResourceType;
import emu.grasscutter.data.ResourceType.LoadPriority; import emu.grasscutter.data.ResourceType.LoadPriority;
import emu.grasscutter.data.common.ItemParamData; import emu.grasscutter.data.common.ItemParamData;
import emu.grasscutter.net.proto.ItemParamOuterClass.ItemParam; import lombok.Getter;
@ResourceType(name = {"CookRecipeExcelConfigData.json"}, loadPriority = LoadPriority.LOW) @ResourceType(name = {"CookRecipeExcelConfigData.json"}, loadPriority = LoadPriority.LOW)
public class CookRecipeData extends GameResource { public class CookRecipeData extends GameResource {
private int id; private int id;
private int rankLevel; @Getter private int rankLevel;
private boolean isDefaultUnlocked; @Getter boolean isDefaultUnlocked;
private int maxProficiency; @Getter int maxProficiency;
private List<ItemParamData> qualityOutputVec; @Getter List<ItemParamData> qualityOutputVec;
private List<ItemParamData> inputVec; @Getter List<ItemParamData> inputVec;
@Override @Override
public int getId() { public int getId() {
return this.id; 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 @Override
public void onLoad() { public void onLoad() {
} }
......
package emu.grasscutter.game.inventory; 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.GameConstants;
import emu.grasscutter.data.GameData; import emu.grasscutter.data.GameData;
import emu.grasscutter.data.common.ItemParamData; import emu.grasscutter.data.common.ItemParamData;
...@@ -15,14 +8,14 @@ import emu.grasscutter.data.excels.AvatarData; ...@@ -15,14 +8,14 @@ import emu.grasscutter.data.excels.AvatarData;
import emu.grasscutter.data.excels.AvatarFlycloakData; import emu.grasscutter.data.excels.AvatarFlycloakData;
import emu.grasscutter.data.excels.ItemData; import emu.grasscutter.data.excels.ItemData;
import emu.grasscutter.database.DatabaseHelper; import emu.grasscutter.database.DatabaseHelper;
import emu.grasscutter.game.avatar.AvatarStorage;
import emu.grasscutter.game.avatar.Avatar; import emu.grasscutter.game.avatar.Avatar;
import emu.grasscutter.game.avatar.AvatarStorage;
import emu.grasscutter.game.player.BasePlayerManager; import emu.grasscutter.game.player.BasePlayerManager;
import emu.grasscutter.game.player.Player; import emu.grasscutter.game.player.Player;
import emu.grasscutter.game.props.ActionReason; import emu.grasscutter.game.props.ActionReason;
import emu.grasscutter.game.props.ItemUseAction.UseItemParams;
import emu.grasscutter.game.props.PlayerProperty; import emu.grasscutter.game.props.PlayerProperty;
import emu.grasscutter.game.props.WatcherTriggerType; import emu.grasscutter.game.props.WatcherTriggerType;
import emu.grasscutter.game.props.ItemUseAction.UseItemParams;
import emu.grasscutter.net.proto.ItemParamOuterClass.ItemParam; import emu.grasscutter.net.proto.ItemParamOuterClass.ItemParam;
import emu.grasscutter.server.packet.send.PacketAvatarEquipChangeNotify; import emu.grasscutter.server.packet.send.PacketAvatarEquipChangeNotify;
import emu.grasscutter.server.packet.send.PacketItemAddHintNotify; import emu.grasscutter.server.packet.send.PacketItemAddHintNotify;
...@@ -33,6 +26,13 @@ import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap; ...@@ -33,6 +26,13 @@ import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap;
import it.unimi.dsi.fastutil.longs.Long2ObjectMap; import it.unimi.dsi.fastutil.longs.Long2ObjectMap;
import it.unimi.dsi.fastutil.longs.Long2ObjectOpenHashMap; 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> { public class Inventory extends BasePlayerManager implements Iterable<GameItem> {
private final Long2ObjectMap<GameItem> store; private final Long2ObjectMap<GameItem> store;
private final Int2ObjectMap<InventoryTab> inventoryTypes; private final Int2ObjectMap<InventoryTab> inventoryTypes;
...@@ -138,26 +138,23 @@ public class Inventory extends BasePlayerManager implements Iterable<GameItem> { ...@@ -138,26 +138,23 @@ public class Inventory extends BasePlayerManager implements Iterable<GameItem> {
this.addItems(items, null); this.addItems(items, null);
} }
public void addItems(Collection<GameItem> items, ActionReason reason) {
List<GameItem> changedItems = new LinkedList<>();
for (GameItem item : items) { public void addItems(Collection<GameItem> items, ActionReason reason) {
List<GameItem> changedItems = new ArrayList<>();
for (var item : items) {
if (item.getItemId() == 0) continue;
GameItem result = putItem(item); GameItem result = putItem(item);
if (result != null) { if (result != null) {
getPlayer().getBattlePassManager().triggerMission(WatcherTriggerType.TRIGGER_OBTAIN_MATERIAL_NUM, result.getItemId(), result.getCount()); getPlayer().getBattlePassManager().triggerMission(WatcherTriggerType.TRIGGER_OBTAIN_MATERIAL_NUM, result.getItemId(), result.getCount());
changedItems.add(result); changedItems.add(result);
} }
} }
if (changedItems.size() == 0) { if (changedItems.size() == 0) {
return; return;
} }
if (reason != null) { if (reason != null) {
getPlayer().sendPacket(new PacketItemAddHintNotify(changedItems, reason)); getPlayer().sendPacket(new PacketItemAddHintNotify(changedItems, reason));
} }
getPlayer().sendPacket(new PacketStoreItemChangeNotify(changedItems)); getPlayer().sendPacket(new PacketStoreItemChangeNotify(changedItems));
} }
...@@ -394,6 +391,7 @@ public class Inventory extends BasePlayerManager implements Iterable<GameItem> { ...@@ -394,6 +391,7 @@ public class Inventory extends BasePlayerManager implements Iterable<GameItem> {
return false; return false;
// All costs are satisfied, now remove them all // All costs are satisfied, now remove them all
costItems.forEach(cost -> this.payVirtualItem(cost.getId(), cost.getCount() * quantity)); costItems.forEach(cost -> this.payVirtualItem(cost.getId(), cost.getCount() * quantity));
//TODO:handle the reason(need to send certain package)
return true; return true;
} }
......
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;
}
}
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));
}
}
}
package emu.grasscutter.game.managers; package emu.grasscutter.game.managers.cooking;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.HashSet; import java.util.HashSet;
......
package emu.grasscutter.game.managers.forging; package emu.grasscutter.game.managers.forging;
import dev.morphia.annotations.Entity; import dev.morphia.annotations.Entity;
import emu.grasscutter.utils.Utils;
@Entity @Entity
public class ActiveForgeData { public class ActiveForgeData {
...@@ -17,7 +16,7 @@ public class ActiveForgeData { ...@@ -17,7 +16,7 @@ public class ActiveForgeData {
public int getFinishedCount(int currentTime) { public int getFinishedCount(int currentTime) {
int timeDelta = currentTime - this.startTime; int timeDelta = currentTime - this.startTime;
int finishedCount = (int)Math.floor(timeDelta / this.forgeTime); int finishedCount = timeDelta / this.forgeTime;
return Math.min(finishedCount, this.count); return Math.min(finishedCount, this.count);
} }
......
...@@ -146,7 +146,8 @@ public class ForgingManager extends BasePlayerManager { ...@@ -146,7 +146,8 @@ public class ForgingManager extends BasePlayerManager {
boolean success = player.getInventory().payItems(material, req.getForgeCount(), ActionReason.ForgeCost); boolean success = player.getInventory().payItems(material, req.getForgeCount(), ActionReason.ForgeCost);
if (!success) { 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. // Consume forge points.
...@@ -171,7 +172,7 @@ public class ForgingManager extends BasePlayerManager { ...@@ -171,7 +172,7 @@ public class ForgingManager extends BasePlayerManager {
Forge queue manipulation (obtaining results and cancelling forges). Forge queue manipulation (obtaining results and cancelling forges).
**********/ **********/
private synchronized void obtainItems(int queueId) { private synchronized void obtainItems(int queueId) {
// Determin how many items are finished. // Determine how many items are finished.
int currentTime = Utils.getCurrentSeconds(); int currentTime = Utils.getCurrentSeconds();
ActiveForgeData forge = this.player.getActiveForges().get(queueId - 1); ActiveForgeData forge = this.player.getActiveForges().get(queueId - 1);
...@@ -271,14 +272,10 @@ public class ForgingManager extends BasePlayerManager { ...@@ -271,14 +272,10 @@ public class ForgingManager extends BasePlayerManager {
// Handle according to the manipulation type. // Handle according to the manipulation type.
switch (manipulateType) { switch (manipulateType) {
case FORGE_QUEUE_MANIPULATE_TYPE_RECEIVE_OUTPUT: case FORGE_QUEUE_MANIPULATE_TYPE_RECEIVE_OUTPUT -> this.obtainItems(queueId);
this.obtainItems(queueId); case FORGE_QUEUE_MANIPULATE_TYPE_STOP_FORGE -> this.cancelForge(queueId);
break; default -> {
case FORGE_QUEUE_MANIPULATE_TYPE_STOP_FORGE: } //Should never happen.
this.cancelForge(queueId);
break;
default:
break; //Should never happen.
} }
} }
...@@ -296,9 +293,7 @@ public class ForgingManager extends BasePlayerManager { ...@@ -296,9 +293,7 @@ public class ForgingManager extends BasePlayerManager {
} }
boolean hasChanges = this.player.getActiveForges().stream() boolean hasChanges = this.player.getActiveForges().stream()
.filter(forge -> forge.updateChanged(currentTime)) .anyMatch(forge -> forge.updateChanged(currentTime));
.findAny()
.isPresent();
if (!hasChanges) { if (!hasChanges) {
return; return;
......
Markdown is supported
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