diff --git a/build.gradle b/build.gradle index 912d35da..8c8fba82 100755 --- a/build.gradle +++ b/build.gradle @@ -110,7 +110,6 @@ dependencies { runtimeOnly fg.deobf("top.theillusivec4.curios:curios-forge:${curios_version}") compileOnly fg.deobf("curse.maven:jade-324717:${jade_cf_file_id}") runtimeOnly fg.deobf("curse.maven:jade-324717:${jade_cf_file_id}") - runtimeOnly fg.deobf("curse.maven:twilightforest-227639:4337394") // compileOnly fg.deobf("curse.maven:tinkers-74072:3576393") // runtimeOnly fg.deobf("curse.maven:tinkers-74072:3576393") diff --git a/gradle.properties b/gradle.properties index b8044258..328ca6b5 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,7 +1,7 @@ org.gradle.jvmargs=-Xmx2048m minecraft_version=1.20.1 -forge_version=47.1.42 -mod_version=2.0.36 +forge_version=47.1.5 +mod_version=2.0.39 jei_mc_version=1.20.1-forge jei_version=15.1.0.19 curios_version=5.2.0-beta.3+1.20.1 diff --git a/src/main/java/reliquary/compat/curios/CuriosCharmInventoryHandler.java b/src/main/java/reliquary/compat/curios/CuriosCharmInventoryHandler.java index 1b5b7669..2f821284 100644 --- a/src/main/java/reliquary/compat/curios/CuriosCharmInventoryHandler.java +++ b/src/main/java/reliquary/compat/curios/CuriosCharmInventoryHandler.java @@ -9,21 +9,21 @@ import reliquary.items.util.ICuriosItem; import top.theillusivec4.curios.api.CuriosApi; +import java.util.Set; + public class CuriosCharmInventoryHandler extends MobCharmItem.CharmInventoryHandler { @Override - public boolean playerHasMobCharm(Player player, MobCharmDefinition charmDefinition) { - if (super.playerHasMobCharm(player, charmDefinition)) { - return true; - } - return CuriosApi.getCuriosHelper().getCuriosHandler(player).map(handler -> handler.getStacksHandler(ICuriosItem.Type.BELT.getIdentifier()).map(stackHandler -> { + protected Set getCharmRegistryNames(Player player) { + Set ret = super.getCharmRegistryNames(player); + CuriosApi.getCuriosHelper().getCuriosHandler(player).resolve().flatMap(handler -> handler.getStacksHandler(ICuriosItem.Type.BELT.getIdentifier())).ifPresent(stackHandler -> { for (int slot = 0; slot < stackHandler.getSlots(); slot++) { ItemStack baubleStack = stackHandler.getStacks().getStackInSlot(slot); - if (!baubleStack.isEmpty() && baubleStack.getItem() == ModItems.MOB_CHARM_BELT.get() && ModItems.MOB_CHARM_BELT.get().hasCharm(baubleStack, charmDefinition.getRegistryName())) { - return true; + if (!baubleStack.isEmpty() && baubleStack.getItem() == ModItems.MOB_CHARM_BELT.get()) { + ret.addAll(ModItems.MOB_CHARM_BELT.get().getCharmRegistryNames(baubleStack)); } } - return false; - }).orElse(false)).orElse(false); + }); + return ret; } @Override diff --git a/src/main/java/reliquary/items/EnderStaffItem.java b/src/main/java/reliquary/items/EnderStaffItem.java index daded06f..e7a80c50 100644 --- a/src/main/java/reliquary/items/EnderStaffItem.java +++ b/src/main/java/reliquary/items/EnderStaffItem.java @@ -169,7 +169,7 @@ public UseAnim getUseAnimation(ItemStack stack) { @Override public int getUseDuration(ItemStack stack) { - return getNodeWarpCastTime(); + return getMode(stack) == Mode.NODE_WARP ? getNodeWarpCastTime() : 0; } @Override diff --git a/src/main/java/reliquary/items/HeroMedallionItem.java b/src/main/java/reliquary/items/HeroMedallionItem.java index 41042d3c..0b2c5d35 100644 --- a/src/main/java/reliquary/items/HeroMedallionItem.java +++ b/src/main/java/reliquary/items/HeroMedallionItem.java @@ -94,7 +94,7 @@ public void inventoryTick(ItemStack stack, Level world, Entity entity, int itemS } private void drainExperienceLevel(ItemStack stack, Player player) { - int experiencePoints = player.isCreative() ? 100 : player.totalExperience - XpHelper.getExperienceForLevel(Math.max(getStopAtXpLevel(stack), player.experienceLevel - 1)); + int experiencePoints = player.isCreative() ? 100 : XpHelper.getTotalPlayerExperience(player) - XpHelper.getExperienceForLevel(Math.max(getStopAtXpLevel(stack), player.experienceLevel - 1)); if (experiencePoints > 0) { if (!player.isCreative()) { decreasePlayerExperience(player, experiencePoints); @@ -104,12 +104,18 @@ private void drainExperienceLevel(ItemStack stack, Player player) { } private void decreasePlayerExperience(Player player, int pointsToRemove) { + correctTotalExperience(player); player.totalExperience -= pointsToRemove; int newLevel = XpHelper.getLevelForExperience(player.totalExperience); player.experienceLevel = newLevel; player.experienceProgress = (float) (player.totalExperience - XpHelper.getExperienceForLevel(newLevel)) / player.getXpNeededForNextLevel(); } + private static void correctTotalExperience(Player player) { + //even vanilla doesn't seem to update this value properly when removing levels for enchanting / in anvil so fixing before working with it + player.totalExperience = XpHelper.getExperienceForLevel(player.experienceLevel) + (int) (XpHelper.getExperienceLimitOnLevel(player.experienceLevel) * player.experienceProgress); + } + private void decreaseMedallionExperience(ItemStack stack, int experience) { setExperience(stack, getExperience(stack) - experience); } @@ -153,7 +159,7 @@ private void drainExperience(ItemStack stack, Player player, Level level, int xp spawnXpOnGround(stack, level, hitPos, xpLevels); } else { xpLevels += Math.round(player.experienceProgress); - int maxPoints = XpHelper.getExperienceForLevel(player.experienceLevel + xpLevels) - player.totalExperience; + int maxPoints = XpHelper.getExperienceForLevel(player.experienceLevel + xpLevels) - XpHelper.getTotalPlayerExperience(player); int pointsToAdd = player.isCreative() ? maxPoints : Math.min(maxPoints, getExperience(stack)); increasePlayerExperience(player, pointsToAdd); if (!player.isCreative()) { diff --git a/src/main/java/reliquary/items/MobCharmBeltItem.java b/src/main/java/reliquary/items/MobCharmBeltItem.java index 1c3c3867..1a343df6 100644 --- a/src/main/java/reliquary/items/MobCharmBeltItem.java +++ b/src/main/java/reliquary/items/MobCharmBeltItem.java @@ -19,6 +19,9 @@ import reliquary.items.util.ICuriosItem; import reliquary.reference.Settings; +import java.util.HashSet; +import java.util.Set; + public class MobCharmBeltItem extends ItemBase implements ICuriosItem { private static final String SLOTS_TAG = "Slots"; @@ -177,4 +180,14 @@ ItemStack damageCharm(Player player, ItemStack belt, String entityRegistryName) return ItemStack.EMPTY; } + + public Set getCharmRegistryNames(ItemStack slotStack) { + Set ret = new HashSet<>(); + ListTag mobCharms = slotStack.getOrCreateTag().getList(SLOTS_TAG, Tag.TAG_COMPOUND); + for (int i = 0; i < mobCharms.size(); i++) { + ItemStack charmStack = ItemStack.of(mobCharms.getCompound(i)); + ret.add(MobCharmItem.getEntityRegistryName(charmStack)); + } + return ret; + } } diff --git a/src/main/java/reliquary/items/MobCharmDefinition.java b/src/main/java/reliquary/items/MobCharmDefinition.java index c2745658..4dbaf055 100644 --- a/src/main/java/reliquary/items/MobCharmDefinition.java +++ b/src/main/java/reliquary/items/MobCharmDefinition.java @@ -15,21 +15,20 @@ public class MobCharmDefinition { static final MobCharmDefinition WITHER_SKELETON = new MobCharmDefinition("minecraft:wither_skeleton", ModItems.WITHERED_RIB.get(), "minecraft:wither_skeleton"); static final MobCharmDefinition CREEPER = new MobCharmDefinition("minecraft:creeper", ModItems.CATALYZING_GLAND.get(), "minecraft:creeper"); static final MobCharmDefinition WITCH = new MobCharmDefinition("minecraft:witch", ModItems.WITCH_HAT.get(), "minecraft:witch"); - static final MobCharmDefinition ZOMBIFIED_PIGLIN = new MobCharmDefinition("minecraft:zombified_piglin", ModItems.ZOMBIE_HEART.get(), "minecraft:zombified_piglin").setResetTargetInLivingTickEvent(true); + static final MobCharmDefinition ZOMBIFIED_PIGLIN = new MobCharmDefinition("minecraft:zombified_piglin", ModItems.ZOMBIE_HEART.get(), "minecraft:zombified_piglin"); static final MobCharmDefinition CAVE_SPIDER = new MobCharmDefinition("minecraft:cave_spider", ModItems.CHELICERAE.get(), "minecraft:cave_spider"); static final MobCharmDefinition SPIDER = new MobCharmDefinition("minecraft:spider", ModItems.CHELICERAE.get(), "minecraft:spider"); - static final MobCharmDefinition ENDERMAN = new MobCharmDefinition("minecraft:enderman", ModItems.NEBULOUS_HEART.get(), "minecraft:enderman").setResetTargetInLivingTickEvent(true); - static final MobCharmDefinition GHAST = new MobCharmDefinition("minecraft:ghast", ModItems.CATALYZING_GLAND.get(), "minecraft:ghast").setResetTargetInLivingTickEvent(true); - static final MobCharmDefinition SLIME = new MobCharmDefinition("minecraft:slime", ModItems.SLIME_PEARL.get(), "minecraft:slime").setResetTargetInLivingTickEvent(true); - static final MobCharmDefinition MAGMA_CUBE = new MobCharmDefinition("minecraft:magma_cube", ModItems.MOLTEN_CORE.get(), "minecraft:magma_cube").setResetTargetInLivingTickEvent(true); + static final MobCharmDefinition ENDERMAN = new MobCharmDefinition("minecraft:enderman", ModItems.NEBULOUS_HEART.get(), "minecraft:enderman"); + static final MobCharmDefinition GHAST = new MobCharmDefinition("minecraft:ghast", ModItems.CATALYZING_GLAND.get(), "minecraft:ghast"); + static final MobCharmDefinition SLIME = new MobCharmDefinition("minecraft:slime", ModItems.SLIME_PEARL.get(), "minecraft:slime"); + static final MobCharmDefinition MAGMA_CUBE = new MobCharmDefinition("minecraft:magma_cube", ModItems.MOLTEN_CORE.get(), "minecraft:magma_cube"); static final MobCharmDefinition BLAZE = new MobCharmDefinition("minecraft:blaze", ModItems.MOLTEN_CORE.get(), "minecraft:blaze"); static final MobCharmDefinition GUARDIAN = new MobCharmDefinition("minecraft:guardian", ModItems.GUARDIAN_SPIKE.get(), "minecraft:guardian"); - static final MobCharmDefinition PIGLIN = new MobCharmDefinition("minecraft:piglin", null, "minecraft:piglin").setResetTargetInLivingTickEvent(true); - static final MobCharmDefinition PIGLIN_BRUTE = new MobCharmDefinition("minecraft:piglin_brute", null, "minecraft:piglin_brute").setResetTargetInLivingTickEvent(true); - static final MobCharmDefinition HOGLIN = new MobCharmDefinition("minecraft:hoglin", null, "minecraft:hoglin").setResetTargetInLivingTickEvent(true); + static final MobCharmDefinition PIGLIN = new MobCharmDefinition("minecraft:piglin", null, "minecraft:piglin"); + static final MobCharmDefinition PIGLIN_BRUTE = new MobCharmDefinition("minecraft:piglin_brute", null, "minecraft:piglin_brute"); + static final MobCharmDefinition HOGLIN = new MobCharmDefinition("minecraft:hoglin", null, "minecraft:hoglin"); private final Set applicableToEntities = new HashSet<>(); - private boolean resetTargetInLivingTickEvent = false; private final String registryName; private final Item repairItem; private boolean dynamicallyCreated = false; @@ -49,15 +48,6 @@ public String getRegistryName() { return registryName; } - public MobCharmDefinition setResetTargetInLivingTickEvent(boolean resetTargetInLivingTickEvent) { - this.resetTargetInLivingTickEvent = resetTargetInLivingTickEvent; - return this; - } - - public boolean resetTargetInLivingTickEvent() { - return resetTargetInLivingTickEvent; - } - public Set getEntities() { return applicableToEntities; } diff --git a/src/main/java/reliquary/items/MobCharmItem.java b/src/main/java/reliquary/items/MobCharmItem.java index 05e5dca5..487457fc 100644 --- a/src/main/java/reliquary/items/MobCharmItem.java +++ b/src/main/java/reliquary/items/MobCharmItem.java @@ -34,8 +34,7 @@ import reliquary.util.WorldHelper; import javax.annotation.Nullable; -import java.util.List; -import java.util.Optional; +import java.util.*; import java.util.function.Consumer; public class MobCharmItem extends ItemBase { @@ -96,7 +95,7 @@ private void onEntityTargetedEvent(LivingChangeTargetEvent event) { MobCharmRegistry.getCharmDefinitionFor(entity).ifPresent(charmDefinition -> { if (isMobCharmPresent(player, charmDefinition)) { - event.setNewTarget(null); + event.setCanceled(true); } }); } @@ -119,7 +118,7 @@ private void onLivingUpdate(LivingEvent.LivingTickEvent event) { } Player finalPlayer = player; - MobCharmRegistry.getCharmDefinitionFor(entity).filter(MobCharmDefinition::resetTargetInLivingTickEvent).ifPresent(charmDefinition -> { + MobCharmRegistry.getCharmDefinitionFor(entity).ifPresent(charmDefinition -> { if (isMobCharmPresent(finalPlayer, charmDefinition)) { MobHelper.resetTarget(entity, true); } @@ -225,20 +224,37 @@ public void setCharmInventoryHandler(CharmInventoryHandler charmInventoryHandler } public static class CharmInventoryHandler { - public boolean playerHasMobCharm(Player player, MobCharmDefinition charmDefinition) { - String registryName = charmDefinition.getRegistryName(); + private static long lastCharmCacheTime = -1; + private static final Map> charmsInInventoryCache = new HashMap<>(); + protected Set getCharmRegistryNames(Player player) { + Set ret = new HashSet<>(); for (ItemStack slotStack : player.getInventory().items) { if (slotStack.isEmpty()) { continue; } - if (ModItems.MOB_CHARM.get().isCharmOrBeltFor(slotStack, registryName)) { - return true; + if (slotStack.getItem() == ModItems.MOB_CHARM.get()) { + ret.add(getEntityRegistryName(slotStack)); + } + if (slotStack.getItem() == ModItems.MOB_CHARM_BELT.get()) { + ret.addAll(ModItems.MOB_CHARM_BELT.get().getCharmRegistryNames(slotStack)); } } - return false; + return ret; } + public boolean playerHasMobCharm(Player player, MobCharmDefinition charmDefinition) { + String registryName = charmDefinition.getRegistryName(); + + if (lastCharmCacheTime != player.level().getGameTime()) { + lastCharmCacheTime = player.level().getGameTime(); + charmsInInventoryCache.clear(); + charmsInInventoryCache.put(player.getUUID(), getCharmRegistryNames(player)); + } + return charmsInInventoryCache.get(player.getUUID()).contains(registryName); + } + + public boolean damagePlayersMobCharm(Player player, String entityRegistryName) { if (player.isCreative()) { return true; diff --git a/src/main/java/reliquary/items/PotionItemBase.java b/src/main/java/reliquary/items/PotionItemBase.java index dfab531c..ceb51a48 100644 --- a/src/main/java/reliquary/items/PotionItemBase.java +++ b/src/main/java/reliquary/items/PotionItemBase.java @@ -7,6 +7,7 @@ import net.minecraft.world.level.Level; import net.minecraftforge.api.distmarker.Dist; import net.minecraftforge.api.distmarker.OnlyIn; +import reliquary.init.ModItems; import reliquary.items.util.IPotionItem; import reliquary.reference.Settings; import reliquary.util.TooltipBuilder; @@ -30,6 +31,11 @@ public boolean hasCraftingRemainingItem(ItemStack stack) { return !XRPotionHelper.getPotionEffectsFromStack(stack).isEmpty(); } + @Override + public ItemStack getCraftingRemainingItem(ItemStack itemStack) { + return new ItemStack(ModItems.EMPTY_POTION_VIAL.get()); + } + @Override @OnlyIn(Dist.CLIENT) public void appendHoverText(ItemStack potion, @Nullable Level world, List tooltip, TooltipFlag flag) { diff --git a/src/main/java/reliquary/items/TwilightCloakItem.java b/src/main/java/reliquary/items/TwilightCloakItem.java index 0118fce0..9dfd4a42 100644 --- a/src/main/java/reliquary/items/TwilightCloakItem.java +++ b/src/main/java/reliquary/items/TwilightCloakItem.java @@ -69,7 +69,7 @@ public void onWornTick(ItemStack twilightCloak, LivingEntity player) { private void onEntityTargetedEvent(LivingChangeTargetEvent event) { if (shouldResetTarget(event.getNewTarget())) { - event.setNewTarget(null); + event.setCanceled(true); } } diff --git a/src/main/java/reliquary/util/XpHelper.java b/src/main/java/reliquary/util/XpHelper.java index e3c8b1ca..543cbbf4 100644 --- a/src/main/java/reliquary/util/XpHelper.java +++ b/src/main/java/reliquary/util/XpHelper.java @@ -1,5 +1,7 @@ package reliquary.util; +import net.minecraft.world.entity.player.Player; + public class XpHelper { private XpHelper() {} @@ -52,4 +54,8 @@ public static int durabilityToXp(int durability) { public static int xpToDurability(int xp) { return xp * 2; } + + public static int getTotalPlayerExperience(Player player) { + return getExperienceForLevel(player.experienceLevel) + ((int) player.experienceProgress * player.getXpNeededForNextLevel()); + } }