Implement consumables

This commit is contained in:
Melledy
2023-12-05 04:53:27 -08:00
parent c649e94f87
commit 3eed08012c
23 changed files with 341 additions and 117 deletions

View File

@@ -6,7 +6,7 @@ import emu.lunarcore.LunarCore;
import emu.lunarcore.data.GameData; import emu.lunarcore.data.GameData;
import emu.lunarcore.game.avatar.GameAvatar; import emu.lunarcore.game.avatar.GameAvatar;
import emu.lunarcore.game.inventory.GameItem; import emu.lunarcore.game.inventory.GameItem;
import emu.lunarcore.game.inventory.ItemSubAffix; import emu.lunarcore.game.inventory.GameItemSubAffix;
import emu.lunarcore.game.player.Player; import emu.lunarcore.game.player.Player;
import emu.lunarcore.util.Utils; import emu.lunarcore.util.Utils;
import it.unimi.dsi.fastutil.ints.Int2IntMap; import it.unimi.dsi.fastutil.ints.Int2IntMap;
@@ -205,7 +205,7 @@ public class CommandArgs {
var subAffix = GameData.getRelicSubAffixExcel(item.getExcel().getRelicExcel().getSubAffixGroup(), entry.getIntKey()); var subAffix = GameData.getRelicSubAffixExcel(item.getExcel().getRelicExcel().getSubAffixGroup(), entry.getIntKey());
if (subAffix == null) continue; if (subAffix == null) continue;
item.getSubAffixes().add(new ItemSubAffix(subAffix, entry.getIntValue())); item.getSubAffixes().add(new GameItemSubAffix(subAffix, entry.getIntValue()));
} }
} }

View File

@@ -53,7 +53,7 @@ public class GiveAllCommand implements CommandHandler {
} }
case "lc", "lightcones" -> { case "lc", "lightcones" -> {
// Make sure we dont go over the inventory limit // Make sure we dont go over the inventory limit
var tab = args.getTarget().getInventory().getInventoryTab(ItemMainType.Equipment); var tab = args.getTarget().getInventory().getTabByItemType(ItemMainType.Equipment);
if (tab.getSize() >= tab.getMaxCapacity()) { if (tab.getSize() >= tab.getMaxCapacity()) {
args.sendMessage(target.getName() + " has too many of this item type"); args.sendMessage(target.getName() + " has too many of this item type");
return; return;
@@ -76,19 +76,9 @@ public class GiveAllCommand implements CommandHandler {
// Send message // Send message
args.sendMessage("Giving " + target.getName() + " " + items.size() + " light cones"); args.sendMessage("Giving " + target.getName() + " " + items.size() + " light cones");
} }
case "ic", "icons" -> {
// Get UnlockedHeads
for (var iconhead : GameData.getPlayerIconExcelMap().values()) {
// This function will handle any duplicate head icons
target.addHeadIcon(iconhead.getId());
}
// Send message
args.sendMessage("Added all icons to " + target.getName());
}
case "r", "relics" -> { case "r", "relics" -> {
// Make sure we dont go over the inventory limit // Make sure we dont go over the inventory limit
var tab = args.getTarget().getInventory().getInventoryTab(ItemMainType.Relic); var tab = args.getTarget().getInventory().getTabByItemType(ItemMainType.Relic);
if (tab.getSize() >= tab.getMaxCapacity()) { if (tab.getSize() >= tab.getMaxCapacity()) {
args.sendMessage(target.getName() + " has too many of this item type"); args.sendMessage(target.getName() + " has too many of this item type");
return; return;
@@ -137,6 +127,30 @@ public class GiveAllCommand implements CommandHandler {
// Send message // Send message
args.sendMessage("Giving " + target.getName() + " all avatars"); args.sendMessage("Giving " + target.getName() + " all avatars");
} }
case "ic", "icons" -> {
// Get UnlockedHeads
for (var iconhead : GameData.getPlayerIconExcelMap().values()) {
// This function will handle any duplicate head icons
target.addHeadIcon(iconhead.getId());
}
// Send message
args.sendMessage("Added all icons to " + target.getName());
}
case "consumables", "food" -> {
// Get consumables
List<GameItem> items = GameData.getItemExcelMap().values()
.stream()
.filter(excel -> excel.getItemSubType() == ItemSubType.Food)
.map(excel -> new GameItem(excel, 1000))
.toList();
// Add to target's inventory
target.getInventory().addItems(items, true);
// Send message
args.sendMessage("Added all consumables to " + target.getName());
}
} }
} }

View File

@@ -49,7 +49,7 @@ public class GiveCommand implements CommandHandler {
args.getTarget().addAvatar(avatar); args.getTarget().addAvatar(avatar);
} else if (itemData.isEquippable()) { } else if (itemData.isEquippable()) {
// Make sure we dont go over the inventory limit // Make sure we dont go over the inventory limit
var tab = args.getTarget().getInventory().getInventoryTab(itemData.getItemMainType()); var tab = args.getTarget().getInventory().getTabByItemType(itemData.getItemMainType());
amount = Math.min(amount, tab.getAvailableCapacity()); amount = Math.min(amount, tab.getAvailableCapacity());
// Add items // Add items

View File

@@ -19,6 +19,7 @@ public class GameData {
// Excels // Excels
@Getter private static Int2ObjectMap<AvatarExcel> avatarExcelMap = new Int2ObjectOpenHashMap<>(); @Getter private static Int2ObjectMap<AvatarExcel> avatarExcelMap = new Int2ObjectOpenHashMap<>();
@Getter private static Int2ObjectMap<ItemExcel> itemExcelMap = new Int2ObjectOpenHashMap<>(); @Getter private static Int2ObjectMap<ItemExcel> itemExcelMap = new Int2ObjectOpenHashMap<>();
@Getter private static Int2ObjectMap<ItemUseExcel> itemUseExcelMap = new Int2ObjectOpenHashMap<>();
@Getter private static Int2ObjectMap<EquipmentExcel> equipExcelMap = new Int2ObjectOpenHashMap<>(); @Getter private static Int2ObjectMap<EquipmentExcel> equipExcelMap = new Int2ObjectOpenHashMap<>();
@Getter private static Int2ObjectMap<RelicExcel> relicExcelMap = new Int2ObjectOpenHashMap<>(); @Getter private static Int2ObjectMap<RelicExcel> relicExcelMap = new Int2ObjectOpenHashMap<>();
@Getter private static Int2ObjectMap<PropExcel> propExcelMap = new Int2ObjectOpenHashMap<>(); @Getter private static Int2ObjectMap<PropExcel> propExcelMap = new Int2ObjectOpenHashMap<>();

View File

@@ -8,6 +8,7 @@ import emu.lunarcore.data.common.ItemParam;
import emu.lunarcore.game.enums.ItemMainType; import emu.lunarcore.game.enums.ItemMainType;
import emu.lunarcore.game.enums.ItemRarity; import emu.lunarcore.game.enums.ItemRarity;
import emu.lunarcore.game.enums.ItemSubType; import emu.lunarcore.game.enums.ItemSubType;
import emu.lunarcore.game.enums.ItemUseMethod;
import lombok.Getter; import lombok.Getter;
import lombok.Setter; import lombok.Setter;
@@ -18,12 +19,15 @@ public class ItemExcel extends GameResource {
// General item data // General item data
private int ID; private int ID;
private long ItemName; private long ItemName;
private ItemMainType ItemMainType; private ItemMainType ItemMainType = emu.lunarcore.game.enums.ItemMainType.Unknown;
private ItemSubType ItemSubType; private ItemSubType ItemSubType = emu.lunarcore.game.enums.ItemSubType.Unknown;
private ItemRarity Rarity; private ItemRarity Rarity;
private int PileLimit; private int PileLimit;
private int PurposeType; private int PurposeType;
private int UseDataID;
private ItemUseMethod UseMethod;
private List<ItemParam> ReturnItemIDList; private List<ItemParam> ReturnItemIDList;
// Transient cache // Transient cache
@@ -56,6 +60,10 @@ public class ItemExcel extends GameResource {
return ItemMainType == emu.lunarcore.game.enums.ItemMainType.Relic || ItemMainType == emu.lunarcore.game.enums.ItemMainType.Equipment; return ItemMainType == emu.lunarcore.game.enums.ItemMainType.Relic || ItemMainType == emu.lunarcore.game.enums.ItemMainType.Equipment;
} }
public int getRarityNum() {
return this.getRarity().getVal();
}
public int getRelicExp() { public int getRelicExp() {
if (this.relicExcel != null) { if (this.relicExcel != null) {
return this.relicExcel.getExpProvide(); return this.relicExcel.getExpProvide();
@@ -63,28 +71,6 @@ public class ItemExcel extends GameResource {
return this.relicExp; return this.relicExp;
} }
public int getRarityNum() {
if (this.getRarity() == ItemRarity.Unknown) {
return 0;
}
if (this.getRarity() == ItemRarity.Normal) {
return 1;
}
if (this.getRarity() == ItemRarity.NotNormal) {
return 2;
}
if (this.getRarity() == ItemRarity.Rare) {
return 3;
}
if (this.getRarity() == ItemRarity.VeryRare) {
return 4;
}
if (this.getRarity() == ItemRarity.SuperRare) {
return 5;
}
return 0;
}
public int getRelicExpCost() { public int getRelicExpCost() {
if (this.relicExcel != null) { if (this.relicExcel != null) {
return this.relicExcel.getCoinCost(); return this.relicExcel.getCoinCost();

View File

@@ -0,0 +1,29 @@
package emu.lunarcore.data.excel;
import emu.lunarcore.data.GameResource;
import emu.lunarcore.data.ResourceType;
import emu.lunarcore.game.enums.ItemFoodTargetType;
import it.unimi.dsi.fastutil.ints.IntArrayList;
import lombok.Getter;
@Getter
@ResourceType(name = {"ItemUseData.json", "ItemUseBuffData.json"})
public class ItemUseExcel extends GameResource {
private int UseDataID;
private int ConsumeType;
private int MazeBuffID;
private double PreviewHPRecoveryPercent;
private int PreviewHPRecoveryValue;
private double PreviewPowerPercent;
private int PreviewSkillPoint;
private ItemFoodTargetType UseTargetType;
private IntArrayList UseParam;
@Override
public int getId() {
return UseDataID;
}
}

View File

@@ -189,6 +189,13 @@ public class Battle {
} }
} }
// Apply food buffs to battle
if (player.getFoodBuffs().size() > 0) {
for (int buffId : player.getFoodBuffs().values()) {
this.addBuff(buffId, -1);
}
}
// Buffs // Buffs
for (MazeBuff buff : this.getBuffs()) { for (MazeBuff buff : this.getBuffs()) {
proto.addBuffList(buff.toProto()); proto.addBuffList(buff.toProto());

View File

@@ -300,6 +300,11 @@ public class BattleService extends BaseGameService {
} }
} }
// Clear food buffs for player
if (player.getFoodBuffs().size() > 0) {
player.getFoodBuffs().clear();
}
// Challenge // Challenge
if (player.getChallengeInstance() != null) { if (player.getChallengeInstance() != null) {
player.getChallengeInstance().onBattleFinish(battle, result, stats); player.getChallengeInstance().onBattleFinish(battle, result, stats);

View File

@@ -0,0 +1,16 @@
package emu.lunarcore.game.enums;
import lombok.Getter;
@Getter
public enum ItemFoodTargetType {
All (0),
Alive (101),
Dead (102);
private int val;
private ItemFoodTargetType(int value) {
this.val = value;
}
}

View File

@@ -1,5 +1,6 @@
package emu.lunarcore.game.enums; package emu.lunarcore.game.enums;
import emu.lunarcore.game.inventory.tabs.InventoryTabType;
import lombok.Getter; import lombok.Getter;
@Getter @Getter
@@ -7,16 +8,22 @@ public enum ItemMainType {
Unknown (0), Unknown (0),
Virtual (1), Virtual (1),
AvatarCard (2), AvatarCard (2),
Equipment (3), Equipment (3, InventoryTabType.EQUIPMENT),
Relic (4), Relic (4, InventoryTabType.RELIC),
Usable (5), Usable (5),
Material (6), Material (6),
Mission (7), Mission (7),
Display (8); Display (8);
private int val; private int val;
private InventoryTabType tabType = InventoryTabType.MATERIAL;
private ItemMainType(int value) { private ItemMainType(int value) {
this.val = value; this.val = value;
} }
private ItemMainType(int value, InventoryTabType tabType) {
this.val = value;
this.tabType = tabType;
}
} }

View File

@@ -0,0 +1,29 @@
package emu.lunarcore.game.enums;
import lombok.Getter;
@Getter
public enum ItemUseMethod {
Unknown (0),
FixedRewardGift (101),
RandomRewardGift (102),
PlayerSelectedReward (103),
TeamFoodBenefit (201),
TeamSpecificFoodBenefit (202),
ExternalSystemFoodBenefit (203),
PlayerSelectedDropGift (301),
TreasureMap (401),
Recipe (501),
PerformanceProp (601),
MonthlyCard (701),
BPUnlock68 (702),
BPUnlock128 (703),
BPUpgradeFrom68To128 (704),
AutoConversionItem (801);
private int val;
private ItemUseMethod(int value) {
this.val = value;
}
}

View File

@@ -74,7 +74,7 @@ public class GachaService extends BaseGameService {
if (times != 10 && times != 1) return; if (times != 10 && times != 1) return;
// Prevent player from using gacha if they are at max light cones // Prevent player from using gacha if they are at max light cones
if (player.getInventory().getInventoryTab(ItemMainType.Equipment).getSize() >= player.getInventory().getInventoryTab(ItemMainType.Equipment).getMaxCapacity()) { if (player.getInventory().getTabByItemType(ItemMainType.Equipment).getSize() >= player.getInventory().getTabByItemType(ItemMainType.Equipment).getMaxCapacity()) {
player.sendPacket(new PacketDoGachaScRsp()); player.sendPacket(new PacketDoGachaScRsp());
return; return;
} }
@@ -88,7 +88,7 @@ public class GachaService extends BaseGameService {
// Spend currency // Spend currency
if (banner.getGachaType().getCostItem() > 0) { if (banner.getGachaType().getCostItem() > 0) {
GameItem costItem = player.getInventory().getInventoryTab(ItemMainType.Material).getItemById(banner.getGachaType().getCostItem()); GameItem costItem = player.getInventory().getMaterialByItemId(banner.getGachaType().getCostItem());
if (costItem == null || costItem.getCount() < times) { if (costItem == null || costItem.getCount() < times) {
return; return;
} }
@@ -195,7 +195,7 @@ public class GachaService extends BaseGameService {
if (avatar != null) { if (avatar != null) {
int dupeLevel = avatar.getRank(); int dupeLevel = avatar.getRank();
int dupeItemId = avatarId + 10000; // Hacky fix so we dont have to fetch data from an excel int dupeItemId = avatarId + 10000; // Hacky fix so we dont have to fetch data from an excel
GameItem dupeItem = player.getInventory().getInventoryTab(ItemMainType.Material).getItemById(dupeItemId); GameItem dupeItem = player.getInventory().getTabByItemType(ItemMainType.Material).getItemById(dupeItemId);
if (dupeItem != null) { if (dupeItem != null) {
dupeLevel += dupeItem.getCount(); dupeLevel += dupeItem.getCount();
} }

View File

@@ -49,7 +49,7 @@ public class GameItem {
@Setter private boolean locked; @Setter private boolean locked;
@Setter private int mainAffix; @Setter private int mainAffix;
private List<ItemSubAffix> subAffixes; private List<GameItemSubAffix> subAffixes;
private int equipAvatar; private int equipAvatar;
@@ -188,7 +188,7 @@ public class GameItem {
} }
IntSet blacklist = new IntOpenHashSet(); IntSet blacklist = new IntOpenHashSet();
for (ItemSubAffix subAffix : this.getSubAffixes()) { for (GameItemSubAffix subAffix : this.getSubAffixes()) {
blacklist.add(subAffix.getId()); blacklist.add(subAffix.getId());
} }
@@ -207,11 +207,11 @@ public class GameItem {
// Add random stat // Add random stat
RelicSubAffixExcel subAffix = randomList.next(); RelicSubAffixExcel subAffix = randomList.next();
this.subAffixes.add(new ItemSubAffix(subAffix)); this.subAffixes.add(new GameItemSubAffix(subAffix));
} }
private void upgradeRandomSubAffix() { private void upgradeRandomSubAffix() {
ItemSubAffix subAffix = Utils.randomElement(this.subAffixes); GameItemSubAffix subAffix = Utils.randomElement(this.subAffixes);
var subAffixExcel = GameData.getRelicSubAffixExcel(this.getExcel().getRelicExcel().getSubAffixGroup(), subAffix.getId()); var subAffixExcel = GameData.getRelicSubAffixExcel(this.getExcel().getRelicExcel().getSubAffixGroup(), subAffix.getId());
subAffix.incrementCount(subAffixExcel.getStepNum()); subAffix.incrementCount(subAffixExcel.getStepNum());
} }

View File

@@ -8,21 +8,21 @@ import lombok.Getter;
@Getter @Getter
@Entity(useDiscriminator = false) @Entity(useDiscriminator = false)
public class ItemSubAffix { public class GameItemSubAffix {
private int id; // Affix id private int id; // Affix id
private int count; private int count;
private int step; private int step;
@Deprecated @Deprecated
public ItemSubAffix() { public GameItemSubAffix() {
// Morphia only! // Morphia only!
} }
public ItemSubAffix(RelicSubAffixExcel subAffix) { public GameItemSubAffix(RelicSubAffixExcel subAffix) {
this(subAffix, 1); this(subAffix, 1);
} }
public ItemSubAffix(RelicSubAffixExcel subAffix, int count) { public GameItemSubAffix(RelicSubAffixExcel subAffix, int count) {
this.id = subAffix.getAffixID(); this.id = subAffix.getAffixID();
this.count = count; this.count = count;
this.step = Utils.randomRange(0, count * subAffix.getStepNum()); this.step = Utils.randomRange(0, count * subAffix.getStepNum());

View File

@@ -16,63 +16,73 @@ import emu.lunarcore.game.avatar.AvatarStorage;
import emu.lunarcore.game.avatar.GameAvatar; import emu.lunarcore.game.avatar.GameAvatar;
import emu.lunarcore.game.enums.ItemMainType; import emu.lunarcore.game.enums.ItemMainType;
import emu.lunarcore.game.enums.ItemSubType; import emu.lunarcore.game.enums.ItemSubType;
import emu.lunarcore.game.inventory.tabs.EquipInventoryTab;
import emu.lunarcore.game.inventory.tabs.InventoryTab;
import emu.lunarcore.game.inventory.tabs.InventoryTabType;
import emu.lunarcore.game.inventory.tabs.MaterialInventoryTab;
import emu.lunarcore.game.player.BasePlayerManager; import emu.lunarcore.game.player.BasePlayerManager;
import emu.lunarcore.game.player.Player; import emu.lunarcore.game.player.Player;
import emu.lunarcore.server.packet.send.PacketPlayerSyncScNotify; import emu.lunarcore.server.packet.send.PacketPlayerSyncScNotify;
import emu.lunarcore.server.packet.send.PacketScenePlaneEventScNotify; import emu.lunarcore.server.packet.send.PacketScenePlaneEventScNotify;
import it.unimi.dsi.fastutil.ints.Int2ObjectMap; import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap; import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap;
import it.unimi.dsi.fastutil.longs.Long2ObjectMap;
import it.unimi.dsi.fastutil.longs.Long2ObjectOpenHashMap;
public class Inventory extends BasePlayerManager { public class Inventory extends BasePlayerManager {
private final Long2ObjectMap<GameItem> store; private final Int2ObjectMap<GameItem> store;
private final Int2ObjectMap<InventoryTab> inventoryTypes; private final Int2ObjectMap<InventoryTab> inventoryTypes;
private int nextInternalUid; private int nextInternalUid;
public Inventory(Player player) { public Inventory(Player player) {
super(player); super(player);
this.store = new Long2ObjectOpenHashMap<>(); this.store = new Int2ObjectOpenHashMap<>();
this.inventoryTypes = new Int2ObjectOpenHashMap<>(); this.inventoryTypes = new Int2ObjectOpenHashMap<>();
this.createInventoryTab(ItemMainType.Equipment, new EquipInventoryTab(GameConstants.INVENTORY_MAX_EQUIPMENT)); this.createTab(InventoryTabType.EQUIPMENT, new EquipInventoryTab(GameConstants.INVENTORY_MAX_EQUIPMENT));
this.createInventoryTab(ItemMainType.Relic, new EquipInventoryTab(GameConstants.INVENTORY_MAX_RELIC)); this.createTab(InventoryTabType.RELIC, new EquipInventoryTab(GameConstants.INVENTORY_MAX_RELIC));
this.createInventoryTab(ItemMainType.Material, new MaterialInventoryTab(GameConstants.INVENTORY_MAX_MATERIAL)); this.createTab(InventoryTabType.MATERIAL, new MaterialInventoryTab(GameConstants.INVENTORY_MAX_MATERIAL));
} }
public AvatarStorage getAvatarStorage() { public AvatarStorage getAvatarStorage() {
return this.getPlayer().getAvatars(); return this.getPlayer().getAvatars();
} }
public Long2ObjectMap<GameItem> getItems() { public Int2ObjectMap<GameItem> getItems() {
return store; return store;
} }
public Int2ObjectMap<InventoryTab> getInventoryTypes() {
return inventoryTypes;
}
public InventoryTab getInventoryTab(ItemMainType type) {
return getInventoryTypes().get(type.getVal());
}
public void createInventoryTab(ItemMainType type, InventoryTab tab) {
this.getInventoryTypes().put(type.getVal(), tab);
}
public int getNextItemInternalUid() { public int getNextItemInternalUid() {
return ++nextInternalUid; return ++nextInternalUid;
} }
/* Returns an item using its internal uid // Inventory tabs
* */
public InventoryTab getTabByItemType(ItemMainType type) {
if (type == null) return null;
return getTab(type.getTabType());
}
public InventoryTab getTab(InventoryTabType type) {
return this.inventoryTypes.get(type.getVal());
}
public void createTab(InventoryTabType type, InventoryTab tab) {
this.inventoryTypes.put(type.getVal(), tab);
}
// Items
/**
* Returns an item using its internal uid
* @param uid
* @return
*/
public synchronized GameItem getItemByUid(int uid) { public synchronized GameItem getItemByUid(int uid) {
return this.getItems().get(uid); return this.getItems().get(uid);
} }
public synchronized GameItem getMaterialByItemId(int id) { public synchronized GameItem getMaterialByItemId(int id) {
return this.getInventoryTab(ItemMainType.Material).getItemById(id); return this.getTab(InventoryTabType.MATERIAL).getItemById(id);
} }
public GameItem getItemByParam(ItemParam param) { public GameItem getItemByParam(ItemParam param) {
@@ -146,8 +156,12 @@ public class Inventory extends BasePlayerManager {
} }
public List<GameItem> addItemParams(Collection<ItemParam> params) { public List<GameItem> addItemParams(Collection<ItemParam> params) {
return addItemParams(params, 1);
}
public List<GameItem> addItemParams(Collection<ItemParam> params, int modifier) {
// TODO handle params if they are equipment or relics // TODO handle params if they are equipment or relics
List<GameItem> items = params.stream().map(param -> new GameItem(param.getId(), param.getCount())).toList(); List<GameItem> items = params.stream().map(param -> new GameItem(param.getId(), param.getCount() * modifier)).toList();
return addItems(items, false); return addItems(items, false);
} }
@@ -160,7 +174,7 @@ public class Inventory extends BasePlayerManager {
// Add item to inventory store // Add item to inventory store
ItemMainType type = item.getExcel().getItemMainType(); ItemMainType type = item.getExcel().getItemMainType();
ItemSubType subType = item.getExcel().getItemSubType(); ItemSubType subType = item.getExcel().getItemSubType();
InventoryTab tab = getInventoryTab(type); InventoryTab tab = getTabByItemType(type);
// Add // Add
switch (type) { switch (type) {
@@ -188,12 +202,12 @@ public class Inventory extends BasePlayerManager {
} }
return null; return null;
case Usable: case Usable:
// Add head icon
if (subType == ItemSubType.HeadIcon) { if (subType == ItemSubType.HeadIcon) {
getPlayer().addHeadIcon(item.getItemId()); getPlayer().addHeadIcon(item.getItemId());
return item; return item;
} }
return null; default:
case Material:
if (tab == null) { if (tab == null) {
return null; return null;
} }
@@ -216,8 +230,6 @@ public class Inventory extends BasePlayerManager {
existingItem.save(); existingItem.save();
return existingItem; return existingItem;
} }
default:
return null;
} }
} }
@@ -368,7 +380,7 @@ public class Inventory extends BasePlayerManager {
// Remove from inventory tab too // Remove from inventory tab too
InventoryTab tab = null; InventoryTab tab = null;
if (item.getExcel() != null) { if (item.getExcel() != null) {
tab = getInventoryTab(item.getExcel().getItemMainType()); tab = getTabByItemType(item.getExcel().getItemMainType());
if (tab != null) { if (tab != null) {
tab.onRemoveItem(item); tab.onRemoveItem(item);
@@ -428,20 +440,37 @@ public class Inventory extends BasePlayerManager {
// Use item // Use item
public List<GameItem> useItem(int itemId, int count, int baseAvatarId) { public List<GameItem> useItem(int itemId, int count, int avatarId) {
// Verify that the player actually has the item // Sanity
GameItem useItem = this.getMaterialByItemId(itemId); if (count <= 0) {
if (useItem == null || useItem.getCount() < count) {
return null; return null;
} }
// Remove item from inventory // Verify that the player actually has the item
this.removeItem(useItem, count); GameItem useItem = this.getMaterialByItemId(itemId);
if (useItem == null || useItem.getCount() < count || useItem.getExcel().getUseMethod() == null) {
return null;
}
// Use the item now // Get use excel
var itemUseExcel = GameData.getItemUseExcelMap().get(useItem.getExcel().getUseDataID());
if (itemUseExcel == null) return null;
// Setup variables
boolean usedItem = false;
// Handle item useMethod
// TODO write better handler for this later // TODO write better handler for this later
if (itemId == 201) { usedItem = switch (useItem.getExcel().getUseMethod()) {
this.getPlayer().addStamina(60 * count); case FixedRewardGift -> ItemUseHandler.handleFixedRewardGift(getPlayer(), itemUseExcel, avatarId, count);
case TeamSpecificFoodBenefit -> ItemUseHandler.handleTeamSpecificFoodBenefit(getPlayer(), itemUseExcel, avatarId, count);
case ExternalSystemFoodBenefit -> ItemUseHandler.handleExternalSystemFoodBenefit(getPlayer(), itemUseExcel, avatarId, count);
default -> false;
};
// Remove item from inventory if we used it
if (usedItem) {
this.removeItem(useItem, count);
} }
return null; return null;
@@ -498,7 +527,7 @@ public class Inventory extends BasePlayerManager {
item.setExcel(excel); item.setExcel(excel);
// Put in inventory // Put in inventory
InventoryTab tab = getInventoryTab(item.getExcel().getItemMainType()); InventoryTab tab = getTabByItemType(item.getExcel().getItemMainType());
putItem(item, tab); putItem(item, tab);
// Equip to a character if possible // Equip to a character if possible

View File

@@ -0,0 +1,78 @@
package emu.lunarcore.game.inventory;
import emu.lunarcore.data.GameData;
import emu.lunarcore.data.excel.ItemUseExcel;
import emu.lunarcore.game.avatar.GameAvatar;
import emu.lunarcore.game.player.Player;
public class ItemUseHandler {
public static boolean handleFixedRewardGift(Player player, ItemUseExcel excel, int avatarId, int count) {
// Sanity check
if (excel.getUseParam() == null) {
return false;
}
// Add reward items
for (int rewardId : excel.getUseParam()) {
var rewardExcel = GameData.getRewardExcelMap().get(rewardId);
if (rewardExcel == null) continue;
player.getInventory().addItemParams(rewardExcel.getRewards(), count);
}
return true;
}
public static boolean handleTeamSpecificFoodBenefit(Player player, ItemUseExcel excel, int avatarId, int count) {
// Get lineup
var lineup = player.getCurrentLineup();
// TODO check if we can give dead avatars food
// Add hp
if (excel.getPreviewHPRecoveryPercent() != 0) {
GameAvatar avatar = player.getAvatarById(avatarId);
if (avatar == null) return false;
int amount = (int) (excel.getPreviewHPRecoveryPercent() * 10000);
avatar.setCurrentHp(lineup, avatar.getCurrentHp(lineup) + amount);
// Clamp so our avatar doesnt die
if (avatar.getCurrentHp(lineup) <= 0) {
avatar.setCurrentHp(lineup, 100);
}
avatar.save();
}
// Add avatar energy
if (excel.getPreviewPowerPercent() != 0) {
GameAvatar avatar = player.getAvatarById(avatarId);
if (avatar == null) return false;
int amount = (int) (excel.getPreviewHPRecoveryPercent() * 10000);
avatar.setCurrentSp(lineup, avatar.getCurrentHp(lineup) + amount);
avatar.save();
}
// Add lineup technique points
if (excel.getPreviewSkillPoint() > 0) {
lineup.addMp(excel.getPreviewSkillPoint());
}
// Refresh
lineup.refreshLineup();
return true;
}
public static boolean handleExternalSystemFoodBenefit(Player player, ItemUseExcel excel, int avatarId, int count) {
// Add food buffs
player.getFoodBuffs().put(excel.getConsumeType(), excel.getMazeBuffID());
player.save();
// TODO send buff refresh packet
return true;
}
}

View File

@@ -1,9 +1,11 @@
package emu.lunarcore.game.inventory; package emu.lunarcore.game.inventory.tabs;
import java.util.HashSet; import java.util.HashSet;
import java.util.Iterator; import java.util.Iterator;
import java.util.Set; import java.util.Set;
import emu.lunarcore.game.inventory.GameItem;
public class EquipInventoryTab extends InventoryTab { public class EquipInventoryTab extends InventoryTab {
private final Set<GameItem> items; private final Set<GameItem> items;
private final int maxCapacity; private final int maxCapacity;

View File

@@ -1,4 +1,6 @@
package emu.lunarcore.game.inventory; package emu.lunarcore.game.inventory.tabs;
import emu.lunarcore.game.inventory.GameItem;
public abstract class InventoryTab implements Iterable<GameItem> { public abstract class InventoryTab implements Iterable<GameItem> {
public abstract GameItem getItemById(int id); public abstract GameItem getItemById(int id);

View File

@@ -0,0 +1,16 @@
package emu.lunarcore.game.inventory.tabs;
import lombok.Getter;
@Getter
public enum InventoryTabType {
MATERIAL (0),
EQUIPMENT (1),
RELIC (2);
private int val;
private InventoryTabType(int value) {
this.val = value;
}
}

View File

@@ -1,7 +1,8 @@
package emu.lunarcore.game.inventory; package emu.lunarcore.game.inventory.tabs;
import java.util.Iterator; import java.util.Iterator;
import emu.lunarcore.game.inventory.GameItem;
import it.unimi.dsi.fastutil.ints.Int2ObjectMap; import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap; import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap;

View File

@@ -63,6 +63,8 @@ import emu.lunarcore.server.packet.BasePacket;
import emu.lunarcore.server.packet.CmdId; import emu.lunarcore.server.packet.CmdId;
import emu.lunarcore.server.packet.send.*; import emu.lunarcore.server.packet.send.*;
import emu.lunarcore.util.Position; import emu.lunarcore.util.Position;
import it.unimi.dsi.fastutil.ints.Int2IntMap;
import it.unimi.dsi.fastutil.ints.Int2IntOpenHashMap;
import it.unimi.dsi.fastutil.ints.IntOpenHashSet; import it.unimi.dsi.fastutil.ints.IntOpenHashSet;
import it.unimi.dsi.fastutil.ints.IntSet; import it.unimi.dsi.fastutil.ints.IntSet;
import lombok.Getter; import lombok.Getter;
@@ -130,6 +132,7 @@ public class Player {
private transient boolean loggedIn; private transient boolean loggedIn;
private transient boolean inAnchorRange; private transient boolean inAnchorRange;
private transient int nextBattleId; private transient int nextBattleId;
private transient Int2IntMap foodBuffs; // TODO
@Setter private transient boolean paused; @Setter private transient boolean paused;
@@ -137,6 +140,8 @@ public class Player {
public Player() { public Player() {
this.curBasicType = GameConstants.TRAILBLAZER_AVATAR_ID; this.curBasicType = GameConstants.TRAILBLAZER_AVATAR_ID;
this.gender = PlayerGender.GENDER_MAN; this.gender = PlayerGender.GENDER_MAN;
this.foodBuffs = new Int2IntOpenHashMap();
this.avatars = new AvatarStorage(this); this.avatars = new AvatarStorage(this);
this.inventory = new Inventory(this); this.inventory = new Inventory(this);
this.chatManager = new ChatManager(this); this.chatManager = new ChatManager(this);

View File

@@ -1,8 +1,8 @@
package emu.lunarcore.server.packet.send; package emu.lunarcore.server.packet.send;
import emu.lunarcore.game.enums.ItemMainType;
import emu.lunarcore.game.inventory.GameItem; import emu.lunarcore.game.inventory.GameItem;
import emu.lunarcore.game.inventory.InventoryTab; import emu.lunarcore.game.inventory.tabs.InventoryTab;
import emu.lunarcore.game.inventory.tabs.InventoryTabType;
import emu.lunarcore.proto.GetBagScRspOuterClass.GetBagScRsp; import emu.lunarcore.proto.GetBagScRspOuterClass.GetBagScRsp;
import emu.lunarcore.server.game.GameSession; import emu.lunarcore.server.game.GameSession;
import emu.lunarcore.server.packet.BasePacket; import emu.lunarcore.server.packet.BasePacket;
@@ -15,17 +15,17 @@ public class PacketGetBagScRsp extends BasePacket {
var data = GetBagScRsp.newInstance(); var data = GetBagScRsp.newInstance();
InventoryTab tabMaterial = session.getPlayer().getInventory().getInventoryTab(ItemMainType.Material); InventoryTab tabMaterial = session.getPlayer().getInventory().getTab(InventoryTabType.MATERIAL);
for (GameItem item : tabMaterial) { for (GameItem item : tabMaterial) {
data.addMaterialList(item.toMaterialProto()); data.addMaterialList(item.toMaterialProto());
} }
InventoryTab tabRelic = session.getPlayer().getInventory().getInventoryTab(ItemMainType.Relic); InventoryTab tabRelic = session.getPlayer().getInventory().getTab(InventoryTabType.RELIC);
for (GameItem item : tabRelic) { for (GameItem item : tabRelic) {
data.addRelicList(item.toRelicProto()); data.addRelicList(item.toRelicProto());
} }
InventoryTab tabEquipment = session.getPlayer().getInventory().getInventoryTab(ItemMainType.Equipment); InventoryTab tabEquipment = session.getPlayer().getInventory().getTab(InventoryTabType.EQUIPMENT);
for (GameItem item : tabEquipment) { for (GameItem item : tabEquipment) {
data.addEquipmentList(item.toEquipmentProto()); data.addEquipmentList(item.toEquipmentProto());
} }

View File

@@ -102,18 +102,15 @@ public class PacketPlayerSyncScNotify extends BasePacket {
} }
private void addItemToProto(PlayerSyncScNotify data, GameItem item) { private void addItemToProto(PlayerSyncScNotify data, GameItem item) {
switch (item.getExcel().getItemMainType()) { switch (item.getExcel().getItemMainType().getTabType()) {
case Material -> { case RELIC -> {
data.addMaterialList(item.toMaterialProto());
}
case Relic -> {
if (item.getCount() > 0) { if (item.getCount() > 0) {
data.addRelicList(item.toRelicProto()); data.addRelicList(item.toRelicProto());
} else { } else {
data.addDelRelicList(item.getInternalUid()); data.addDelRelicList(item.getInternalUid());
} }
} }
case Equipment -> { case EQUIPMENT -> {
if (item.getCount() > 0) { if (item.getCount() > 0) {
data.addEquipmentList(item.toEquipmentProto()); data.addEquipmentList(item.toEquipmentProto());
} else { } else {
@@ -121,7 +118,7 @@ public class PacketPlayerSyncScNotify extends BasePacket {
} }
} }
default -> { default -> {
data.addMaterialList(item.toMaterialProto());
} }
} }
} }