From aacf013c065db9b2daa14be83e475a66dab9be0a Mon Sep 17 00:00:00 2001 From: AnimeGitB Date: Tue, 18 Oct 2022 15:11:10 +1030 Subject: [PATCH] Fix gacha avatars (fixes #1870) --- .../data/excels/AvatarSkillDepotData.java | 9 +++++ .../emu/grasscutter/data/excels/ItemData.java | 2 + .../grasscutter/game/gacha/GachaSystem.java | 8 ++-- .../ItemUseAction/ItemUseGainAvatar.java | 7 +++- .../game/systems/InventorySystem.java | 37 ++++++++++++++----- 5 files changed, 49 insertions(+), 14 deletions(-) diff --git a/src/main/java/emu/grasscutter/data/excels/AvatarSkillDepotData.java b/src/main/java/emu/grasscutter/data/excels/AvatarSkillDepotData.java index cd4fcd27b..30533d614 100644 --- a/src/main/java/emu/grasscutter/data/excels/AvatarSkillDepotData.java +++ b/src/main/java/emu/grasscutter/data/excels/AvatarSkillDepotData.java @@ -1,6 +1,7 @@ package emu.grasscutter.data.excels; import java.util.List; +import java.util.Optional; import java.util.stream.IntStream; import emu.grasscutter.data.GameData; @@ -36,6 +37,7 @@ public class AvatarSkillDepotData extends GameResource { @Getter private AvatarSkillData energySkillData; @Getter private ElementType elementType; @Getter private IntList abilities; + @Getter private int talentCostItemId; @Override public int getId() { @@ -66,6 +68,13 @@ public class AvatarSkillDepotData extends GameResource { this.setAbilities(new AbilityEmbryoEntry(getSkillDepotAbilityGroup(), config.abilities.stream().map(Object::toString).toArray(String[]::new))); } } + + // Get constellation item from GameData + Optional.ofNullable(this.talents) + .map(talents -> talents.get(0)) + .map(i -> GameData.getAvatarTalentDataMap().get((int) i)) + .map(talentData -> talentData.getMainCostItemId()) + .ifPresent(itemId -> this.talentCostItemId = itemId); } public static class InherentProudSkillOpens { diff --git a/src/main/java/emu/grasscutter/data/excels/ItemData.java b/src/main/java/emu/grasscutter/data/excels/ItemData.java index 7293f8c17..1161e671f 100644 --- a/src/main/java/emu/grasscutter/data/excels/ItemData.java +++ b/src/main/java/emu/grasscutter/data/excels/ItemData.java @@ -2,6 +2,7 @@ package emu.grasscutter.data.excels; import java.util.Arrays; import java.util.List; +import java.util.Objects; import com.google.gson.annotations.SerializedName; import emu.grasscutter.data.GameResource; @@ -133,6 +134,7 @@ public class ItemData extends GameResource { this.itemUseActions = this.itemUse.stream() .filter(x -> x.getUseOp() != ItemUseOp.ITEM_USE_NONE) .map(ItemUseAction::fromItemUseData) + .filter(Objects::nonNull) .toList(); } } diff --git a/src/main/java/emu/grasscutter/game/gacha/GachaSystem.java b/src/main/java/emu/grasscutter/game/gacha/GachaSystem.java index 692466965..6456d4647 100644 --- a/src/main/java/emu/grasscutter/game/gacha/GachaSystem.java +++ b/src/main/java/emu/grasscutter/game/gacha/GachaSystem.java @@ -316,10 +316,10 @@ public class GachaSystem extends BaseGameSystem { pools.removeFromAllPools(new int[] {itemId}); } addStarglitter = (itemData.getRankLevel()==5)? 10 : 2; - int constItemId = itemId + 100; - GameItem constItem = inventory.getInventoryTab(ItemType.ITEM_MATERIAL).getItemById(constItemId); - gachaItem.addTransferItems(GachaTransferItem.newBuilder().setItem(ItemParam.newBuilder().setItemId(constItemId).setCount(1)).setIsTransferItemNew(constItem == null)); - inventory.addItem(constItemId, 1); + int constItemId = itemId + 100; // This may not hold true for future characters. Examples of strictly correct constellation item lookup are elsewhere for now. + boolean haveConstItem = inventory.getInventoryTab(ItemType.ITEM_MATERIAL).getItemById(constItemId) == null; + gachaItem.addTransferItems(GachaTransferItem.newBuilder().setItem(ItemParam.newBuilder().setItemId(constItemId).setCount(1)).setIsTransferItemNew(haveConstItem)); + //inventory.addItem(constItemId, 1); // This is now managed by the avatar card item itself } isTransferItem = true; break; diff --git a/src/main/java/emu/grasscutter/game/props/ItemUseAction/ItemUseGainAvatar.java b/src/main/java/emu/grasscutter/game/props/ItemUseAction/ItemUseGainAvatar.java index fecd509ab..bdfd39bc1 100644 --- a/src/main/java/emu/grasscutter/game/props/ItemUseAction/ItemUseGainAvatar.java +++ b/src/main/java/emu/grasscutter/game/props/ItemUseAction/ItemUseGainAvatar.java @@ -1,5 +1,7 @@ package emu.grasscutter.game.props.ItemUseAction; +import java.util.Optional; + import emu.grasscutter.game.avatar.Avatar; import emu.grasscutter.game.props.ItemUseOp; import emu.grasscutter.game.systems.InventorySystem; @@ -36,7 +38,10 @@ public class ItemUseGainAvatar extends ItemUseInt { params.player.addAvatar(avatar); return true; } else { - int itemId = (this.i % 1000) + 100; + int itemId = Optional.ofNullable(params.player.getAvatars().getAvatarById(this.i)) + .map(Avatar::getSkillDepot) + .map(depot -> depot.getTalentCostItemId()) + .orElse((this.i % 1000) + 100); return params.player.getInventory().addItem(itemId); } } diff --git a/src/main/java/emu/grasscutter/game/systems/InventorySystem.java b/src/main/java/emu/grasscutter/game/systems/InventorySystem.java index baa8ba150..23876aa6d 100644 --- a/src/main/java/emu/grasscutter/game/systems/InventorySystem.java +++ b/src/main/java/emu/grasscutter/game/systems/InventorySystem.java @@ -8,7 +8,6 @@ import java.util.List; import java.util.Map; import java.util.Objects; import java.util.Optional; -import java.util.stream.Collectors; import java.util.stream.Stream; import emu.grasscutter.Grasscutter; @@ -799,18 +798,38 @@ public class InventorySystem extends BaseGameSystem { .reduce(false, (a,b) -> a || b); // Don't short-circuit!!! } - public static synchronized int checkPlayerAvatarConstellationLevel(Player player, int itemId) { - ItemData itemData = GameData.getItemDataMap().get(itemId); - if ((itemData == null) || (itemData.getMaterialType() != MaterialType.MATERIAL_AVATAR)) { + public static synchronized int checkPlayerAvatarConstellationLevel(Player player, int id) { + // Try to accept itemId OR avatarId + int avatarId = 0; + if (GameData.getAvatarDataMap().containsKey(id)) { + avatarId = id; + } else { + avatarId = Optional.ofNullable(GameData.getItemDataMap().get(id)) + .map(itemData -> itemData.getItemUseActions()) + .flatMap(actions -> + actions.stream() + .filter(action -> action.getItemUseOp() == ItemUseOp.ITEM_USE_GAIN_AVATAR) + .map(action -> ((emu.grasscutter.game.props.ItemUseAction.ItemUseGainAvatar) action).getI()) + .findFirst()) + .orElse(0); + } + + if (avatarId == 0) return -2; // Not an Avatar - } - Avatar avatar = player.getAvatars().getAvatarById((itemId % 1000) + 10000000); - if (avatar == null) { + + Avatar avatar = player.getAvatars().getAvatarById(avatarId); + if (avatar == null) return -1; // Doesn't have - } + // Constellation int constLevel = avatar.getCoreProudSkillLevel(); - GameItem constItem = player.getInventory().getInventoryTab(ItemType.ITEM_MATERIAL).getItemById(itemId + 100); + val avatarData = avatar.getSkillDepot(); + if (avatarData == null) { + Grasscutter.getLogger().error("Attempted to check constellation level for UID"+player.getUid()+"'s avatar "+avatarId+" but avatar has no skillDepot!"); + return 0; + } + int constItemId = avatarData.getTalentCostItemId(); + GameItem constItem = player.getInventory().getInventoryTab(ItemType.ITEM_MATERIAL).getItemById(constItemId); constLevel += Optional.ofNullable(constItem).map(GameItem::getCount).orElse(0); return constLevel; }