mirror of
https://github.com/Grasscutters/Grasscutter.git
synced 2025-01-08 08:12:57 +08:00
Attempt to implement item giving to NPCs (untested)
This commit is contained in:
parent
a4ad781d61
commit
b82567d9d9
@ -4,58 +4,33 @@ import emu.grasscutter.Grasscutter;
|
||||
import emu.grasscutter.data.binout.*;
|
||||
import emu.grasscutter.data.binout.config.*;
|
||||
import emu.grasscutter.data.binout.routes.Route;
|
||||
import emu.grasscutter.data.custom.TrialAvatarActivityCustomData;
|
||||
import emu.grasscutter.data.custom.TrialAvatarCustomData;
|
||||
import emu.grasscutter.data.custom.*;
|
||||
import emu.grasscutter.data.excels.*;
|
||||
import emu.grasscutter.data.excels.achievement.AchievementData;
|
||||
import emu.grasscutter.data.excels.achievement.AchievementGoalData;
|
||||
import emu.grasscutter.data.excels.activity.ActivityCondExcelConfigData;
|
||||
import emu.grasscutter.data.excels.activity.ActivityData;
|
||||
import emu.grasscutter.data.excels.activity.ActivityShopData;
|
||||
import emu.grasscutter.data.excels.activity.ActivityWatcherData;
|
||||
import emu.grasscutter.data.excels.achievement.*;
|
||||
import emu.grasscutter.data.excels.activity.*;
|
||||
import emu.grasscutter.data.excels.avatar.*;
|
||||
import emu.grasscutter.data.excels.codex.*;
|
||||
import emu.grasscutter.data.excels.dungeon.*;
|
||||
import emu.grasscutter.data.excels.monster.MonsterCurveData;
|
||||
import emu.grasscutter.data.excels.monster.MonsterData;
|
||||
import emu.grasscutter.data.excels.monster.MonsterDescribeData;
|
||||
import emu.grasscutter.data.excels.monster.MonsterSpecialNameData;
|
||||
import emu.grasscutter.data.excels.quest.QuestData;
|
||||
import emu.grasscutter.data.excels.quest.QuestGlobalVarData;
|
||||
import emu.grasscutter.data.excels.reliquary.ReliquaryAffixData;
|
||||
import emu.grasscutter.data.excels.reliquary.ReliquaryLevelData;
|
||||
import emu.grasscutter.data.excels.reliquary.ReliquaryMainPropData;
|
||||
import emu.grasscutter.data.excels.reliquary.ReliquarySetData;
|
||||
import emu.grasscutter.data.excels.tower.TowerFloorData;
|
||||
import emu.grasscutter.data.excels.tower.TowerLevelData;
|
||||
import emu.grasscutter.data.excels.tower.TowerScheduleData;
|
||||
import emu.grasscutter.data.excels.giving.*;
|
||||
import emu.grasscutter.data.excels.monster.*;
|
||||
import emu.grasscutter.data.excels.quest.*;
|
||||
import emu.grasscutter.data.excels.reliquary.*;
|
||||
import emu.grasscutter.data.excels.tower.*;
|
||||
import emu.grasscutter.data.excels.trial.*;
|
||||
import emu.grasscutter.data.excels.weapon.WeaponCurveData;
|
||||
import emu.grasscutter.data.excels.weapon.WeaponLevelData;
|
||||
import emu.grasscutter.data.excels.weapon.WeaponPromoteData;
|
||||
import emu.grasscutter.data.excels.world.WeatherData;
|
||||
import emu.grasscutter.data.excels.world.WorldAreaData;
|
||||
import emu.grasscutter.data.excels.world.WorldLevelData;
|
||||
import emu.grasscutter.data.server.ActivityCondGroup;
|
||||
import emu.grasscutter.data.server.DropSubfieldMapping;
|
||||
import emu.grasscutter.data.server.DropTableExcelConfigData;
|
||||
import emu.grasscutter.data.server.GadgetMapping;
|
||||
import emu.grasscutter.data.server.MonsterMapping;
|
||||
import emu.grasscutter.data.server.SubfieldMapping;
|
||||
import emu.grasscutter.data.excels.weapon.*;
|
||||
import emu.grasscutter.data.excels.world.*;
|
||||
import emu.grasscutter.data.server.*;
|
||||
import emu.grasscutter.game.dungeons.DungeonDropEntry;
|
||||
import emu.grasscutter.game.quest.QuestEncryptionKey;
|
||||
import emu.grasscutter.game.quest.RewindData;
|
||||
import emu.grasscutter.game.quest.TeleportData;
|
||||
import emu.grasscutter.game.quest.*;
|
||||
import emu.grasscutter.game.quest.enums.QuestCond;
|
||||
import emu.grasscutter.game.world.GroupReplacementData;
|
||||
import emu.grasscutter.utils.Utils;
|
||||
import it.unimi.dsi.fastutil.ints.*;
|
||||
import lombok.*;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import java.lang.reflect.Field;
|
||||
import java.util.*;
|
||||
import javax.annotation.Nullable;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
import lombok.val;
|
||||
|
||||
@SuppressWarnings({"unused", "MismatchedQueryAndUpdateOfCollection"})
|
||||
public final class GameData {
|
||||
@ -266,6 +241,12 @@ public final class GameData {
|
||||
@Getter
|
||||
private static final Int2ObjectMap<GatherData> gatherDataMap = new Int2ObjectOpenHashMap<>();
|
||||
|
||||
@Getter
|
||||
private static final Int2ObjectMap<GivingData> givingDataMap = new Int2ObjectOpenHashMap<>();
|
||||
|
||||
@Getter
|
||||
private static final Int2ObjectMap<GivingGroupData> givingGroupDataMap = new Int2ObjectOpenHashMap<>();
|
||||
|
||||
@Getter
|
||||
@Deprecated // This is to prevent people from using this map. This is for the resource loader
|
||||
// only!
|
||||
|
@ -0,0 +1,42 @@
|
||||
package emu.grasscutter.data.excels.giving;
|
||||
|
||||
import com.google.gson.annotations.SerializedName;
|
||||
import emu.grasscutter.data.*;
|
||||
import emu.grasscutter.data.common.ItemParamData;
|
||||
import emu.grasscutter.game.inventory.BagTab;
|
||||
import lombok.*;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = false)
|
||||
@ResourceType(name = "GivingExcelConfigData.json")
|
||||
public final class GivingData extends GameResource {
|
||||
@SerializedName(value = "id", alternate = "Id")
|
||||
private int id;
|
||||
private int talkId;
|
||||
private int mistakeTalkId;
|
||||
|
||||
private BagTab tab;
|
||||
private GiveMethod givingMethod;
|
||||
|
||||
private List<ItemParamData> exactItems;
|
||||
private int exactFinishTalkId;
|
||||
|
||||
private List<Integer> givingGroupIds;
|
||||
private int givingGroupCount;
|
||||
|
||||
private boolean isRemoveItem;
|
||||
private GiveType giveType;
|
||||
|
||||
public enum GiveMethod {
|
||||
@SerializedName("GIVING_METHOD_EXACT") EXACT,
|
||||
@SerializedName("GIVING_METHOD_GROUP") GROUP,
|
||||
@SerializedName("GIVING_METHOD_VAGUE_GROUP") GROUP_VAGUE
|
||||
}
|
||||
|
||||
public enum GiveType {
|
||||
@SerializedName("GIVING_TYPE_QUEST") QUEST,
|
||||
@SerializedName("GIVING_TYPE_GROUP") GROUP
|
||||
}
|
||||
}
|
@ -0,0 +1,21 @@
|
||||
package emu.grasscutter.data.excels.giving;
|
||||
|
||||
import com.google.gson.annotations.SerializedName;
|
||||
import emu.grasscutter.data.*;
|
||||
import lombok.*;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = false)
|
||||
@ResourceType(name = "GivingGroupExcelConfigData.json")
|
||||
public final class GivingGroupData extends GameResource {
|
||||
@SerializedName(value = "id", alternate = "Id")
|
||||
private int id;
|
||||
|
||||
@SerializedName(value = "itemIds", alternate = "ItemIds")
|
||||
private List<Integer> itemIds;
|
||||
|
||||
private int finishTalkId;
|
||||
private int mistakeTalkId;
|
||||
}
|
55
src/main/java/emu/grasscutter/game/inventory/BagTab.java
Normal file
55
src/main/java/emu/grasscutter/game/inventory/BagTab.java
Normal file
@ -0,0 +1,55 @@
|
||||
package emu.grasscutter.game.inventory;
|
||||
|
||||
import it.unimi.dsi.fastutil.ints.*;
|
||||
import lombok.*;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
@RequiredArgsConstructor
|
||||
public enum BagTab {
|
||||
TAB_NONE(0),
|
||||
TAB_WEAPON(1),
|
||||
TAB_EQUIP(2),
|
||||
TAB_AVATAR(3),
|
||||
TAB_FOOD(4),
|
||||
TAB_MATERIAL(5),
|
||||
TAB_QUEST(6),
|
||||
TAB_CONSUME(7),
|
||||
TAB_WIDGET(8),
|
||||
TAB_HOMEWORLD(9);
|
||||
|
||||
private static final Int2ObjectMap<BagTab> map = new Int2ObjectOpenHashMap<>();
|
||||
private static final Map<String, BagTab> stringMap = new HashMap<>();
|
||||
|
||||
static {
|
||||
Stream.of(BagTab.values())
|
||||
.forEach(
|
||||
entry -> {
|
||||
map.put(entry.getValue(), entry);
|
||||
stringMap.put(entry.name(), entry);
|
||||
});
|
||||
}
|
||||
|
||||
@Getter private final int value;
|
||||
|
||||
/**
|
||||
* Fetches the bag tab by its value.
|
||||
*
|
||||
* @param value The name of the bag tab.
|
||||
* @return The bag tab.
|
||||
*/
|
||||
public static BagTab getTypeByValue(int value) {
|
||||
return map.getOrDefault(value, TAB_NONE);
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetches the bag tab by its name.
|
||||
*
|
||||
* @param name The name of the bag tab.
|
||||
* @return The bag tab.
|
||||
*/
|
||||
public static BagTab getTypeByName(String name) {
|
||||
return stringMap.getOrDefault(name, TAB_NONE);
|
||||
}
|
||||
}
|
@ -1,7 +1,5 @@
|
||||
package emu.grasscutter.game.inventory;
|
||||
|
||||
import static emu.grasscutter.config.Configuration.INVENTORY_LIMITS;
|
||||
|
||||
import emu.grasscutter.Grasscutter;
|
||||
import emu.grasscutter.data.GameData;
|
||||
import emu.grasscutter.data.common.ItemParamData;
|
||||
@ -17,8 +15,11 @@ import emu.grasscutter.server.packet.send.*;
|
||||
import emu.grasscutter.utils.Utils;
|
||||
import it.unimi.dsi.fastutil.ints.*;
|
||||
import it.unimi.dsi.fastutil.longs.*;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
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;
|
||||
@ -150,6 +151,52 @@ public class Inventory extends BasePlayerManager implements Iterable<GameItem> {
|
||||
getPlayer().sendPacket(new PacketStoreItemChangeNotify(changedItems));
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks to see if the player has the item in their inventory.
|
||||
* This will succeed if the player has at least the minimum count of the item.
|
||||
*
|
||||
* @param itemGuid The item id to check for.
|
||||
* @param minCount The minimum count of the item to check for.
|
||||
* @return True if the player has the item, false otherwise.
|
||||
*/
|
||||
public boolean hasItem(long itemGuid, int minCount) {
|
||||
return hasItem(itemGuid, minCount, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks to see if the player has the item in their inventory.
|
||||
*
|
||||
* @param itemGuid The item id to check for.
|
||||
* @param count The count of the item to check for.
|
||||
* @param enforce If true, the player must have the exact amount.
|
||||
* If false, the player must have at least the amount.
|
||||
* @return True if the player has the item, false otherwise.
|
||||
*/
|
||||
public boolean hasItem(long itemGuid, int count, boolean enforce) {
|
||||
var item = this.getItemByGuid(itemGuid);
|
||||
if (item == null) return false;
|
||||
|
||||
return enforce ?
|
||||
item.getCount() == count :
|
||||
item.getCount() >= count;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks to see if the player has the item in their inventory.
|
||||
* This is exact.
|
||||
*
|
||||
* @param items A map of item game IDs to their count.
|
||||
* @return True if the player has the items, false otherwise.
|
||||
*/
|
||||
public boolean hasAllItems(Map<Long, Integer> items) {
|
||||
for (var item : items.entrySet()) {
|
||||
if (!this.hasItem(item.getKey(), item.getValue(), true))
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private void triggerAddItemEvents(GameItem result) {
|
||||
try {
|
||||
getPlayer()
|
||||
@ -434,6 +481,17 @@ public class Inventory extends BasePlayerManager implements Iterable<GameItem> {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Performs a bulk delete of items.
|
||||
*
|
||||
* @param items A map of item game IDs to the amount of items to remove.
|
||||
*/
|
||||
public void removeItems(Map<Long, Integer> items) {
|
||||
for (var entry : items.entrySet()) {
|
||||
this.removeItem(entry.getKey(), entry.getValue());
|
||||
}
|
||||
}
|
||||
|
||||
public boolean removeItem(long guid) {
|
||||
return removeItem(guid, 1);
|
||||
}
|
||||
|
@ -159,7 +159,7 @@ public class Player implements PlayerHook, FieldFetch {
|
||||
@Getter private transient FriendsList friendsList;
|
||||
@Getter private transient MailHandler mailHandler;
|
||||
@Getter private transient AbilityManager abilityManager;
|
||||
@Getter @Setter private transient QuestManager questManager;
|
||||
@Getter private transient QuestManager questManager;
|
||||
@Getter private transient TowerManager towerManager;
|
||||
@Getter private transient SotSManager sotsManager;
|
||||
@Getter private transient MapMarksManager mapMarksManager;
|
||||
|
@ -1,6 +1,5 @@
|
||||
package emu.grasscutter.game.quest;
|
||||
|
||||
import dev.morphia.annotations.Transient;
|
||||
import emu.grasscutter.Grasscutter;
|
||||
import emu.grasscutter.data.GameData;
|
||||
import emu.grasscutter.data.binout.MainQuestData;
|
||||
@ -31,10 +30,13 @@ import static emu.grasscutter.GameConstants.DEBUG;
|
||||
import static emu.grasscutter.config.Configuration.GAME_OPTIONS;
|
||||
import static emu.grasscutter.config.Configuration.SERVER;
|
||||
|
||||
public class QuestManager extends BasePlayerManager {
|
||||
public final class QuestManager extends BasePlayerManager {
|
||||
@Getter private final Player player;
|
||||
|
||||
@Getter private final Int2ObjectMap<GameMainQuest> mainQuests;
|
||||
@Transient @Getter private final List<Integer> loggedQuests;
|
||||
@Getter private final List<Integer> loggedQuests;
|
||||
|
||||
@Getter private final List<Integer> activeGivings = new ArrayList<>();
|
||||
|
||||
private long lastHourCheck = 0;
|
||||
private long lastDayCheck = 0;
|
||||
@ -45,6 +47,7 @@ public class QuestManager extends BasePlayerManager {
|
||||
60, TimeUnit.SECONDS, new LinkedBlockingDeque<>(1000),
|
||||
FastThreadLocalThread::new, new ThreadPoolExecutor.AbortPolicy());
|
||||
}
|
||||
|
||||
/*
|
||||
On SetPlayerBornDataReq, the server sends FinishedParentQuestNotify, with this exact
|
||||
parentQuestList. Captured on Game version 2.7
|
||||
|
@ -34,7 +34,7 @@ public enum QuestContent implements QuestTrigger {
|
||||
QUEST_CONTENT_ADD_QUEST_PROGRESS(24),
|
||||
QUEST_CONTENT_INTERACT_GADGET(25),
|
||||
QUEST_CONTENT_DAILY_TASK_COMP_FINISH(26), // missing, currently unused
|
||||
QUEST_CONTENT_FINISH_ITEM_GIVING(27), // missing, finish
|
||||
QUEST_CONTENT_FINISH_ITEM_GIVING(27),
|
||||
QUEST_CONTENT_SKILL(107),
|
||||
QUEST_CONTENT_CITY_LEVEL_UP(109), // missing, finish
|
||||
QUEST_CONTENT_PATTERN_GROUP_CLEAR_MONSTER(110), // missing, finish, for random quests
|
||||
|
@ -35,7 +35,7 @@ public enum QuestExec implements QuestTrigger {
|
||||
QUEST_EXEC_CREATE_PATTERN_GROUP(25), // missing, used for random quests
|
||||
QUEST_EXEC_REMOVE_PATTERN_GROUP(26), // missing, used for random quests
|
||||
QUEST_EXEC_REFRESH_GROUP_SUITE_RANDOM(27), // missing
|
||||
QUEST_EXEC_ACTIVE_ITEM_GIVING(28), // missing
|
||||
QUEST_EXEC_ACTIVE_ITEM_GIVING(28),
|
||||
QUEST_EXEC_DEL_ALL_SPECIFIC_PACK_ITEM(29), // missing
|
||||
QUEST_EXEC_ROLLBACK_PARENT_QUEST(30),
|
||||
QUEST_EXEC_LOCK_AVATAR_TEAM(31), // missing
|
||||
@ -71,7 +71,7 @@ public enum QuestExec implements QuestTrigger {
|
||||
QUEST_EXEC_MODIFY_CLIMATE_AREA(60), // missing
|
||||
QUEST_EXEC_GRANT_TRIAL_AVATAR_AND_LOCK_TEAM(61), // missing
|
||||
QUEST_EXEC_CHANGE_MAP_AREA_STATE(62), // missing
|
||||
QUEST_EXEC_DEACTIVE_ITEM_GIVING(63), // missing
|
||||
QUEST_EXEC_DEACTIVE_ITEM_GIVING(63),
|
||||
QUEST_EXEC_CHANGE_SCENE_LEVEL_TAG(64), // missing
|
||||
QUEST_EXEC_UNLOCK_PLAYER_WORLD_SCENE(65), // missing
|
||||
QUEST_EXEC_LOCK_PLAYER_WORLD_SCENE(66), // missing
|
||||
|
@ -0,0 +1,26 @@
|
||||
package emu.grasscutter.game.quest.exec;
|
||||
|
||||
import emu.grasscutter.Grasscutter;
|
||||
import emu.grasscutter.data.excels.quest.QuestData.QuestExecParam;
|
||||
import emu.grasscutter.game.quest.*;
|
||||
import emu.grasscutter.game.quest.enums.QuestExec;
|
||||
import emu.grasscutter.game.quest.handlers.QuestExecHandler;
|
||||
|
||||
@QuestValueExec(QuestExec.QUEST_EXEC_ACTIVE_ITEM_GIVING)
|
||||
public final class ExecActiveItemGiving extends QuestExecHandler {
|
||||
@Override
|
||||
public boolean execute(GameQuest quest, QuestExecParam condition, String... paramStr) {
|
||||
var questManager = quest.getOwner().getQuestManager();
|
||||
var activeGivings = questManager.getActiveGivings();
|
||||
|
||||
var givingId = Integer.parseInt(condition.getParam()[0]);
|
||||
if (activeGivings.contains(givingId)) {
|
||||
Grasscutter.getLogger().debug("Quest {} attempted to add give action {} twice.",
|
||||
quest.getSubQuestId(), givingId);
|
||||
return false;
|
||||
} else {
|
||||
activeGivings.add(givingId);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,26 @@
|
||||
package emu.grasscutter.game.quest.exec;
|
||||
|
||||
import emu.grasscutter.Grasscutter;
|
||||
import emu.grasscutter.data.excels.quest.QuestData;
|
||||
import emu.grasscutter.game.quest.*;
|
||||
import emu.grasscutter.game.quest.enums.QuestExec;
|
||||
import emu.grasscutter.game.quest.handlers.QuestExecHandler;
|
||||
|
||||
@QuestValueExec(QuestExec.QUEST_EXEC_DEACTIVE_ITEM_GIVING)
|
||||
public final class ExecDeactivateItemGiving extends QuestExecHandler {
|
||||
@Override
|
||||
public boolean execute(GameQuest quest, QuestData.QuestExecParam condition, String... paramStr) {
|
||||
var questManager = quest.getOwner().getQuestManager();
|
||||
var activeGivings = questManager.getActiveGivings();
|
||||
|
||||
var givingId = Integer.parseInt(condition.getParam()[0]);
|
||||
if (!activeGivings.contains(givingId)) {
|
||||
Grasscutter.getLogger().debug("Quest {} attempted to remove give action {} when it isn't active.",
|
||||
quest.getSubQuestId(), givingId);
|
||||
return false;
|
||||
} else {
|
||||
activeGivings.remove(givingId);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,63 @@
|
||||
package emu.grasscutter.server.packet.recv;
|
||||
|
||||
import emu.grasscutter.Grasscutter;
|
||||
import emu.grasscutter.data.GameData;
|
||||
import emu.grasscutter.data.excels.giving.GivingData.GiveMethod;
|
||||
import emu.grasscutter.game.quest.enums.QuestContent;
|
||||
import emu.grasscutter.net.packet.*;
|
||||
import emu.grasscutter.net.proto.ItemGivingReqOuterClass.ItemGivingReq;
|
||||
import emu.grasscutter.server.game.GameSession;
|
||||
import emu.grasscutter.server.packet.send.PacketItemGivingRsp;
|
||||
import emu.grasscutter.server.packet.send.PacketItemGivingRsp.Mode;
|
||||
|
||||
@Opcodes(PacketOpcodes.ItemGivingReq)
|
||||
public final class HandlerItemGivingReq extends PacketHandler {
|
||||
@Override
|
||||
public void handle(GameSession session, byte[] header, byte[] payload) throws Exception {
|
||||
var req = ItemGivingReq.parseFrom(payload);
|
||||
|
||||
var player = session.getPlayer();
|
||||
var inventory = player.getInventory();
|
||||
|
||||
var giveId = req.getGivingId();
|
||||
var items = req.getItemGuidCountMapMap();
|
||||
|
||||
switch (req.getItemGivingType()) {
|
||||
case QUEST -> {
|
||||
var questManager = player.getQuestManager();
|
||||
var activeGivings = questManager.getActiveGivings();
|
||||
if (!activeGivings.contains(giveId)) return;
|
||||
|
||||
// Check the items against the resources.
|
||||
var data = GameData.getGivingDataMap().get(giveId);
|
||||
if (data == null) throw new IllegalArgumentException("No giving data found for " + giveId + ".");
|
||||
|
||||
if (data.getGivingMethod() == GiveMethod.EXACT) {
|
||||
if (!inventory.hasAllItems(items)) {
|
||||
player.sendPacket(new PacketItemGivingRsp());
|
||||
return;
|
||||
}
|
||||
|
||||
// Remove the items if the quest specifies.
|
||||
if (data.isRemoveItem()) {
|
||||
inventory.removeItems(items);
|
||||
}
|
||||
|
||||
// Send the response packet.
|
||||
player.sendPacket(new PacketItemGivingRsp(giveId, Mode.EXACT_SUCCESS));
|
||||
// Remove the action from the active givings.
|
||||
activeGivings.remove(giveId);
|
||||
// Queue the content action.
|
||||
questManager.queueEvent(QuestContent.QUEST_CONTENT_FINISH_ITEM_GIVING, giveId);
|
||||
} else {
|
||||
// TODO: Handle group givings.
|
||||
player.sendPacket(new PacketItemGivingRsp());
|
||||
}
|
||||
}
|
||||
case GADGET -> {
|
||||
Grasscutter.getLogger().debug("Unimplemented gadget giving was executed for {}.", giveId);
|
||||
player.sendPacket(new PacketItemGivingRsp());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,30 @@
|
||||
package emu.grasscutter.server.packet.send;
|
||||
|
||||
import emu.grasscutter.net.packet.*;
|
||||
import emu.grasscutter.net.proto.ItemGivingRspOuterClass.ItemGivingRsp;
|
||||
|
||||
public final class PacketItemGivingRsp extends BasePacket {
|
||||
public PacketItemGivingRsp() {
|
||||
this(0, Mode.FAILURE);
|
||||
}
|
||||
|
||||
public PacketItemGivingRsp(int value, Mode mode) {
|
||||
super(PacketOpcodes.ItemGivingRsp);
|
||||
|
||||
var packet = ItemGivingRsp.newBuilder()
|
||||
.setRetcode(mode == Mode.FAILURE ? 1 : 0);
|
||||
if (mode == Mode.EXACT_SUCCESS) {
|
||||
packet.setGivingId(value);
|
||||
} else if (mode == Mode.GROUP_SUCCESS) {
|
||||
packet.setGivingGroupId(value);
|
||||
}
|
||||
|
||||
this.setData(packet);
|
||||
}
|
||||
|
||||
public enum Mode {
|
||||
GROUP_SUCCESS,
|
||||
EXACT_SUCCESS,
|
||||
FAILURE
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user