media can now be drawn from trinkets, armor, and offhand
also, armor can no longer keep you safe from the subsuming of your mind
This commit is contained in:
parent
3a1bd29658
commit
8c13fc22dc
15 changed files with 353 additions and 55 deletions
|
@ -0,0 +1,42 @@
|
||||||
|
package at.petrak.hexcasting.api.misc;
|
||||||
|
|
||||||
|
import at.petrak.hexcasting.api.addldata.ManaHolder;
|
||||||
|
import at.petrak.hexcasting.api.spell.casting.CastingHarness;
|
||||||
|
import com.google.common.collect.Lists;
|
||||||
|
import net.minecraft.world.entity.player.Player;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.function.Function;
|
||||||
|
import java.util.function.Predicate;
|
||||||
|
|
||||||
|
public class DiscoveryHandlers {
|
||||||
|
private static final List<Predicate<Player>> HAS_LENS_PREDICATE = new ArrayList<>();
|
||||||
|
private static final List<Function<CastingHarness, List<ManaHolder>>> MANA_HOLDER_DISCOVERY = new ArrayList<>();
|
||||||
|
|
||||||
|
public static boolean hasLens(Player player) {
|
||||||
|
for (var predicate : HAS_LENS_PREDICATE) {
|
||||||
|
if (predicate.test(player)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static List<ManaHolder> collectManaHolders(CastingHarness harness) {
|
||||||
|
List<ManaHolder> holders = Lists.newArrayList();
|
||||||
|
for (var discoverer : MANA_HOLDER_DISCOVERY) {
|
||||||
|
holders.addAll(discoverer.apply(harness));
|
||||||
|
}
|
||||||
|
return holders;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public static void addLensPredicate(Predicate<Player> predicate) {
|
||||||
|
HAS_LENS_PREDICATE.add(predicate);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void addManaHolderDiscoverer(Function<CastingHarness, List<ManaHolder>> discoverer) {
|
||||||
|
MANA_HOLDER_DISCOVERY.add(discoverer);
|
||||||
|
}
|
||||||
|
}
|
|
@ -3,6 +3,7 @@ package at.petrak.hexcasting.api.spell.casting
|
||||||
import at.petrak.hexcasting.api.PatternRegistry
|
import at.petrak.hexcasting.api.PatternRegistry
|
||||||
import at.petrak.hexcasting.api.advancements.HexAdvancementTriggers
|
import at.petrak.hexcasting.api.advancements.HexAdvancementTriggers
|
||||||
import at.petrak.hexcasting.api.block.circle.BlockEntityAbstractImpetus
|
import at.petrak.hexcasting.api.block.circle.BlockEntityAbstractImpetus
|
||||||
|
import at.petrak.hexcasting.api.misc.DiscoveryHandlers
|
||||||
import at.petrak.hexcasting.api.misc.FrozenColorizer
|
import at.petrak.hexcasting.api.misc.FrozenColorizer
|
||||||
import at.petrak.hexcasting.api.misc.HexDamageSources
|
import at.petrak.hexcasting.api.misc.HexDamageSources
|
||||||
import at.petrak.hexcasting.api.mod.HexConfig
|
import at.petrak.hexcasting.api.mod.HexConfig
|
||||||
|
@ -13,7 +14,6 @@ import at.petrak.hexcasting.api.spell.math.HexDir
|
||||||
import at.petrak.hexcasting.api.spell.math.HexPattern
|
import at.petrak.hexcasting.api.spell.math.HexPattern
|
||||||
import at.petrak.hexcasting.api.spell.mishaps.*
|
import at.petrak.hexcasting.api.spell.mishaps.*
|
||||||
import at.petrak.hexcasting.api.utils.*
|
import at.petrak.hexcasting.api.utils.*
|
||||||
import at.petrak.hexcasting.common.items.magic.ItemCreativeUnlocker
|
|
||||||
import at.petrak.hexcasting.xplat.IXplatAbstractions
|
import at.petrak.hexcasting.xplat.IXplatAbstractions
|
||||||
import net.minecraft.nbt.CompoundTag
|
import net.minecraft.nbt.CompoundTag
|
||||||
import net.minecraft.nbt.Tag
|
import net.minecraft.nbt.Tag
|
||||||
|
@ -404,12 +404,12 @@ class CastingHarness private constructor(
|
||||||
} else {
|
} else {
|
||||||
false
|
false
|
||||||
}
|
}
|
||||||
|
|
||||||
if (casterStack.`is`(HexItemTags.WANDS) || hexHolderDrawsFromInventory) {
|
if (casterStack.`is`(HexItemTags.WANDS) || hexHolderDrawsFromInventory) {
|
||||||
val manableItems = this.ctx.caster.inventory.items
|
val manaSources = DiscoveryHandlers.collectManaHolders(this)
|
||||||
.filter(::isManaItem)
|
|
||||||
.sortedWith(Comparator(::compareManaItem).reversed())
|
.sortedWith(Comparator(::compareManaItem).reversed())
|
||||||
for (stack in manableItems) {
|
for (source in manaSources) {
|
||||||
costLeft -= extractMana(stack, costLeft, simulate = fake && !ItemCreativeUnlocker.isDebug(stack))
|
costLeft -= extractMana(source, costLeft, simulate = fake)
|
||||||
if (costLeft <= 0)
|
if (costLeft <= 0)
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
@ -421,13 +421,17 @@ class CastingHarness private constructor(
|
||||||
val manaAbleToCastFromHP = this.ctx.caster.health * manaToHealth
|
val manaAbleToCastFromHP = this.ctx.caster.health * manaToHealth
|
||||||
|
|
||||||
val manaToActuallyPayFor = min(manaAbleToCastFromHP.toInt(), costLeft)
|
val manaToActuallyPayFor = min(manaAbleToCastFromHP.toInt(), costLeft)
|
||||||
if (!fake) {
|
costLeft -= if (!fake) {
|
||||||
HexAdvancementTriggers.OVERCAST_TRIGGER.trigger(this.ctx.caster, manaToActuallyPayFor)
|
|
||||||
this.ctx.caster.awardStat(HexStatistics.MANA_OVERCASTED, manaCost - costLeft)
|
|
||||||
|
|
||||||
Mishap.trulyHurt(this.ctx.caster, HexDamageSources.OVERCAST, healthtoRemove.toFloat())
|
Mishap.trulyHurt(this.ctx.caster, HexDamageSources.OVERCAST, healthtoRemove.toFloat())
|
||||||
|
|
||||||
|
val actuallyTaken = (manaAbleToCastFromHP - (this.ctx.caster.health * manaToHealth)).toInt()
|
||||||
|
|
||||||
|
HexAdvancementTriggers.OVERCAST_TRIGGER.trigger(this.ctx.caster, actuallyTaken)
|
||||||
|
this.ctx.caster.awardStat(HexStatistics.MANA_OVERCASTED, manaCost - costLeft)
|
||||||
|
actuallyTaken
|
||||||
|
} else {
|
||||||
|
manaToActuallyPayFor
|
||||||
}
|
}
|
||||||
costLeft -= manaToActuallyPayFor
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -475,6 +479,24 @@ class CastingHarness private constructor(
|
||||||
const val TAG_ESCAPE_NEXT = "escape_next"
|
const val TAG_ESCAPE_NEXT = "escape_next"
|
||||||
const val TAG_PREPACKAGED_COLORIZER = "prepackaged_colorizer"
|
const val TAG_PREPACKAGED_COLORIZER = "prepackaged_colorizer"
|
||||||
|
|
||||||
|
init {
|
||||||
|
DiscoveryHandlers.addManaHolderDiscoverer {
|
||||||
|
it.ctx.caster.inventory.items
|
||||||
|
.filter(::isManaItem)
|
||||||
|
.mapNotNull(IXplatAbstractions.INSTANCE::findManaHolder)
|
||||||
|
}
|
||||||
|
DiscoveryHandlers.addManaHolderDiscoverer {
|
||||||
|
it.ctx.caster.armorSlots
|
||||||
|
.filter(::isManaItem)
|
||||||
|
.mapNotNull(IXplatAbstractions.INSTANCE::findManaHolder)
|
||||||
|
}
|
||||||
|
DiscoveryHandlers.addManaHolderDiscoverer {
|
||||||
|
listOf(it.ctx.caster.offhandItem)
|
||||||
|
.filter(::isManaItem)
|
||||||
|
.mapNotNull(IXplatAbstractions.INSTANCE::findManaHolder)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@JvmStatic
|
@JvmStatic
|
||||||
fun fromNBT(nbt: CompoundTag, ctx: CastingContext): CastingHarness {
|
fun fromNBT(nbt: CompoundTag, ctx: CastingContext): CastingHarness {
|
||||||
return try {
|
return try {
|
||||||
|
|
|
@ -10,7 +10,7 @@ import at.petrak.hexcasting.api.spell.math.HexPattern
|
||||||
import at.petrak.hexcasting.api.utils.asTranslatedComponent
|
import at.petrak.hexcasting.api.utils.asTranslatedComponent
|
||||||
import at.petrak.hexcasting.api.utils.lightPurple
|
import at.petrak.hexcasting.api.utils.lightPurple
|
||||||
import at.petrak.hexcasting.common.lib.HexItems
|
import at.petrak.hexcasting.common.lib.HexItems
|
||||||
import at.petrak.hexcasting.ktxt.lastHurt
|
import at.petrak.hexcasting.ktxt.*
|
||||||
import net.minecraft.Util
|
import net.minecraft.Util
|
||||||
import net.minecraft.core.BlockPos
|
import net.minecraft.core.BlockPos
|
||||||
import net.minecraft.network.chat.Component
|
import net.minecraft.network.chat.Component
|
||||||
|
@ -109,7 +109,25 @@ sealed class Mishap : Throwable() {
|
||||||
else
|
else
|
||||||
entity.lastHurt -= amount
|
entity.lastHurt -= amount
|
||||||
}
|
}
|
||||||
entity.hurt(source, amount)
|
if (!entity.hurt(source, amount)) {
|
||||||
|
// Ok, if you REALLY don't want to play nice...
|
||||||
|
entity.health -= amount
|
||||||
|
entity.markHurt()
|
||||||
|
|
||||||
|
if (entity.isDeadOrDying) {
|
||||||
|
if (!entity.checkTotemDeathProtection(source)) {
|
||||||
|
val sound = entity.deathSoundAccessor
|
||||||
|
if (sound != null) {
|
||||||
|
entity.playSound(sound, entity.soundVolumeAccessor, entity.voicePitch)
|
||||||
|
}
|
||||||
|
entity.die(source)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
entity.playHurtSound(source)
|
||||||
|
}
|
||||||
|
|
||||||
|
entity.setHurtWithStamp(source, entity.level.gameTime)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
@file:JvmName("ManaHelper")
|
@file:JvmName("ManaHelper")
|
||||||
package at.petrak.hexcasting.api.utils
|
package at.petrak.hexcasting.api.utils
|
||||||
|
|
||||||
|
import at.petrak.hexcasting.api.addldata.ManaHolder
|
||||||
import at.petrak.hexcasting.xplat.IXplatAbstractions
|
import at.petrak.hexcasting.xplat.IXplatAbstractions
|
||||||
import net.minecraft.util.Mth
|
import net.minecraft.util.Mth
|
||||||
import net.minecraft.world.item.ItemStack
|
import net.minecraft.world.item.ItemStack
|
||||||
|
@ -30,26 +31,38 @@ fun extractMana(
|
||||||
): Int {
|
): Int {
|
||||||
val manaHolder = IXplatAbstractions.INSTANCE.findManaHolder(stack) ?: return 0
|
val manaHolder = IXplatAbstractions.INSTANCE.findManaHolder(stack) ?: return 0
|
||||||
|
|
||||||
if (drainForBatteries && !manaHolder.canConstructBattery())
|
return extractMana(manaHolder, cost, drainForBatteries, simulate)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Extract [cost] mana from [holder]. If [cost] is less than zero, extract all mana instead.
|
||||||
|
* This may mutate the stack underlying [holder] (and may consume it) unless [simulate] is set.
|
||||||
|
*
|
||||||
|
* If [drainForBatteries] is false, this will only consider forms of mana that can be used to make new batteries.
|
||||||
|
*
|
||||||
|
* Return the amount of mana extracted. This may be over [cost] if mana is wasted.
|
||||||
|
*/
|
||||||
|
fun extractMana(
|
||||||
|
holder: ManaHolder,
|
||||||
|
cost: Int = -1,
|
||||||
|
drainForBatteries: Boolean = false,
|
||||||
|
simulate: Boolean = false
|
||||||
|
): Int {
|
||||||
|
if (drainForBatteries && !holder.canConstructBattery())
|
||||||
return 0
|
return 0
|
||||||
|
|
||||||
return manaHolder.withdrawMana(cost, simulate)
|
return holder.withdrawMana(cost, simulate)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sorted from least important to most important
|
* Sorted from least important to most important
|
||||||
*/
|
*/
|
||||||
fun compareManaItem(astack: ItemStack, bstack: ItemStack): Int {
|
fun compareManaItem(aMana: ManaHolder, bMana: ManaHolder): Int {
|
||||||
val aMana = IXplatAbstractions.INSTANCE.findManaHolder(astack)
|
val priority = aMana.consumptionPriority - bMana.consumptionPriority
|
||||||
val bMana = IXplatAbstractions.INSTANCE.findManaHolder(bstack)
|
if (priority != 0)
|
||||||
|
return priority
|
||||||
|
|
||||||
return if (astack.item != bstack.item) {
|
return aMana.mana - bMana.mana
|
||||||
(aMana?.consumptionPriority ?: 0) - (bMana?.consumptionPriority ?: 0)
|
|
||||||
} else if (aMana != null && bMana != null) {
|
|
||||||
aMana.mana - bMana.mana
|
|
||||||
} else {
|
|
||||||
astack.count - bstack.count
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fun manaBarColor(mana: Int, maxMana: Int): Int {
|
fun manaBarColor(mana: Int, maxMana: Int): Int {
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
package at.petrak.hexcasting.client;
|
package at.petrak.hexcasting.client;
|
||||||
|
|
||||||
import at.petrak.hexcasting.api.client.ScryingLensOverlayRegistry;
|
import at.petrak.hexcasting.api.client.ScryingLensOverlayRegistry;
|
||||||
|
import at.petrak.hexcasting.api.misc.DiscoveryHandlers;
|
||||||
import at.petrak.hexcasting.api.player.Sentinel;
|
import at.petrak.hexcasting.api.player.Sentinel;
|
||||||
import at.petrak.hexcasting.common.items.ItemLens;
|
|
||||||
import at.petrak.hexcasting.xplat.IXplatAbstractions;
|
import at.petrak.hexcasting.xplat.IXplatAbstractions;
|
||||||
import com.google.common.collect.Lists;
|
import com.google.common.collect.Lists;
|
||||||
import com.mojang.blaze3d.platform.GlStateManager;
|
import com.mojang.blaze3d.platform.GlStateManager;
|
||||||
|
@ -155,7 +155,7 @@ public class HexAdditionalRenderers {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!ItemLens.hasLensHUD(player))
|
if (!DiscoveryHandlers.hasLens(player))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
var hitRes = mc.hitResult;
|
var hitRes = mc.hitResult;
|
||||||
|
|
|
@ -20,7 +20,7 @@ class OpExplode(val fire: Boolean) : SpellOperator {
|
||||||
val strength = args.getChecked<Double>(1, argc)
|
val strength = args.getChecked<Double>(1, argc)
|
||||||
ctx.assertVecInRange(pos)
|
ctx.assertVecInRange(pos)
|
||||||
val clampedStrength = Mth.clamp(strength, 0.0, 10.0)
|
val clampedStrength = Mth.clamp(strength, 0.0, 10.0)
|
||||||
val cost = ManaConstants.DUST_UNIT * (3 * clampedStrength + if (fire) 0.125 else 1.0)
|
val cost = ManaConstants.DUST_UNIT * (3 * clampedStrength + if (fire) 1.0 else 0.125)
|
||||||
return Triple(
|
return Triple(
|
||||||
Spell(pos, clampedStrength, this.fire),
|
Spell(pos, clampedStrength, this.fire),
|
||||||
cost.toInt(),
|
cost.toInt(),
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
package at.petrak.hexcasting.common.items;
|
package at.petrak.hexcasting.common.items;
|
||||||
|
|
||||||
import at.petrak.hexcasting.annotations.SoftImplement;
|
import at.petrak.hexcasting.annotations.SoftImplement;
|
||||||
|
import at.petrak.hexcasting.api.misc.DiscoveryHandlers;
|
||||||
import at.petrak.hexcasting.common.lib.HexItems;
|
import at.petrak.hexcasting.common.lib.HexItems;
|
||||||
import at.petrak.hexcasting.common.network.MsgUpdateComparatorVisualsAck;
|
import at.petrak.hexcasting.common.network.MsgUpdateComparatorVisualsAck;
|
||||||
import at.petrak.hexcasting.xplat.IXplatAbstractions;
|
import at.petrak.hexcasting.xplat.IXplatAbstractions;
|
||||||
|
@ -14,7 +15,6 @@ import net.minecraft.sounds.SoundEvent;
|
||||||
import net.minecraft.sounds.SoundEvents;
|
import net.minecraft.sounds.SoundEvents;
|
||||||
import net.minecraft.world.entity.Entity;
|
import net.minecraft.world.entity.Entity;
|
||||||
import net.minecraft.world.entity.EquipmentSlot;
|
import net.minecraft.world.entity.EquipmentSlot;
|
||||||
import net.minecraft.world.entity.player.Player;
|
|
||||||
import net.minecraft.world.item.ArmorItem;
|
import net.minecraft.world.item.ArmorItem;
|
||||||
import net.minecraft.world.item.Item;
|
import net.minecraft.world.item.Item;
|
||||||
import net.minecraft.world.item.ItemStack;
|
import net.minecraft.world.item.ItemStack;
|
||||||
|
@ -29,32 +29,15 @@ import net.minecraft.world.phys.HitResult;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.WeakHashMap;
|
import java.util.WeakHashMap;
|
||||||
import java.util.function.Predicate;
|
|
||||||
|
|
||||||
public class ItemLens extends Item implements Wearable {
|
public class ItemLens extends Item implements Wearable {
|
||||||
|
|
||||||
private static final List<Predicate<Player>> HAS_HUD_PREDICATE = new ArrayList<>();
|
|
||||||
static {
|
static {
|
||||||
addLensHUDPredicate(player -> player.getItemBySlot(EquipmentSlot.MAINHAND).is(HexItems.SCRYING_LENS));
|
DiscoveryHandlers.addLensPredicate(player -> player.getItemBySlot(EquipmentSlot.MAINHAND).is(HexItems.SCRYING_LENS));
|
||||||
addLensHUDPredicate(player -> player.getItemBySlot(EquipmentSlot.OFFHAND).is(HexItems.SCRYING_LENS));
|
DiscoveryHandlers.addLensPredicate(player -> player.getItemBySlot(EquipmentSlot.OFFHAND).is(HexItems.SCRYING_LENS));
|
||||||
addLensHUDPredicate(player -> player.getItemBySlot(EquipmentSlot.HEAD).is(HexItems.SCRYING_LENS));
|
DiscoveryHandlers.addLensPredicate(player -> player.getItemBySlot(EquipmentSlot.HEAD).is(HexItems.SCRYING_LENS));
|
||||||
}
|
|
||||||
|
|
||||||
public static boolean hasLensHUD(Player player) {
|
|
||||||
for (Predicate<Player> predicate : HAS_HUD_PREDICATE) {
|
|
||||||
if (predicate.test(player)) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void addLensHUDPredicate(Predicate<Player> predicate) {
|
|
||||||
HAS_HUD_PREDICATE.add(predicate);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public ItemLens(Properties pProperties) {
|
public ItemLens(Properties pProperties) {
|
||||||
|
@ -82,7 +65,7 @@ public class ItemLens extends Item implements Wearable {
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void tickLens(Entity pEntity) {
|
public static void tickLens(Entity pEntity) {
|
||||||
if (!pEntity.getLevel().isClientSide() && pEntity instanceof ServerPlayer player && hasLensHUD(player)) {
|
if (!pEntity.getLevel().isClientSide() && pEntity instanceof ServerPlayer player && DiscoveryHandlers.hasLens(player)) {
|
||||||
sendComparatorDataToClient(player);
|
sendComparatorDataToClient(player);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,57 @@
|
||||||
|
package at.petrak.hexcasting.common.items.magic;
|
||||||
|
|
||||||
|
import at.petrak.hexcasting.api.addldata.ManaHolder;
|
||||||
|
import at.petrak.hexcasting.api.utils.NBTHelper;
|
||||||
|
import net.minecraft.world.item.ItemStack;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
|
||||||
|
public record DebugUnlockerHolder(ItemStack creativeUnlocker) implements ManaHolder {
|
||||||
|
@Override
|
||||||
|
public int getMana() {
|
||||||
|
return Integer.MAX_VALUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getMaxMana() {
|
||||||
|
return Integer.MAX_VALUE - 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setMana(int mana) {
|
||||||
|
// NO-OP
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean canRecharge() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean canProvide() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getConsumptionPriority() {
|
||||||
|
return 1000;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean canConstructBattery() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int withdrawMana(int cost, boolean simulate) {
|
||||||
|
int[] arr = NBTHelper.getIntArray(creativeUnlocker, ItemCreativeUnlocker.TAG_EXTRACTIONS);
|
||||||
|
if (arr == null) {
|
||||||
|
arr = new int[0];
|
||||||
|
}
|
||||||
|
int[] newArr = Arrays.copyOf(arr, arr.length + 1);
|
||||||
|
newArr[newArr.length - 1] = cost;
|
||||||
|
NBTHelper.putIntArray(creativeUnlocker, ItemCreativeUnlocker.TAG_EXTRACTIONS, newArr);
|
||||||
|
|
||||||
|
return cost < 0 ? 1 : cost;
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,6 +1,7 @@
|
||||||
package at.petrak.hexcasting.common.items.magic;
|
package at.petrak.hexcasting.common.items.magic;
|
||||||
|
|
||||||
import at.petrak.hexcasting.api.item.ManaHolderItem;
|
import at.petrak.hexcasting.api.item.ManaHolderItem;
|
||||||
|
import at.petrak.hexcasting.api.misc.DiscoveryHandlers;
|
||||||
import at.petrak.hexcasting.api.misc.ManaConstants;
|
import at.petrak.hexcasting.api.misc.ManaConstants;
|
||||||
import at.petrak.hexcasting.api.utils.NBTHelper;
|
import at.petrak.hexcasting.api.utils.NBTHelper;
|
||||||
import at.petrak.hexcasting.common.lib.HexItems;
|
import at.petrak.hexcasting.common.lib.HexItems;
|
||||||
|
@ -29,6 +30,33 @@ import static at.petrak.hexcasting.api.HexAPI.modLoc;
|
||||||
|
|
||||||
public class ItemCreativeUnlocker extends Item implements ManaHolderItem {
|
public class ItemCreativeUnlocker extends Item implements ManaHolderItem {
|
||||||
|
|
||||||
|
static {
|
||||||
|
DiscoveryHandlers.addManaHolderDiscoverer(harness -> {
|
||||||
|
var player = harness.getCtx().getCaster();
|
||||||
|
if (!player.isCreative())
|
||||||
|
return List.of();
|
||||||
|
|
||||||
|
for (ItemStack item : player.inventoryMenu.getItems()) {
|
||||||
|
if (isDebug(item)) {
|
||||||
|
return List.of(new DebugUnlockerHolder(item));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Technically possible with commands!
|
||||||
|
for (ItemStack item : player.getArmorSlots()) {
|
||||||
|
if (isDebug(item)) {
|
||||||
|
return List.of(new DebugUnlockerHolder(item));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isDebug(player.getOffhandItem())) {
|
||||||
|
return List.of(new DebugUnlockerHolder(player.getOffhandItem()));
|
||||||
|
}
|
||||||
|
|
||||||
|
return List.of();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
public static boolean isDebug(ItemStack stack) {
|
public static boolean isDebug(ItemStack stack) {
|
||||||
return stack.is(HexItems.CREATIVE_UNLOCKER)
|
return stack.is(HexItems.CREATIVE_UNLOCKER)
|
||||||
&& stack.hasCustomHoverName()
|
&& stack.hasCustomHoverName()
|
||||||
|
@ -47,7 +75,7 @@ public class ItemCreativeUnlocker extends Item implements ManaHolderItem {
|
||||||
return emphasized;
|
return emphasized;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static final String TAG_EXTRACTIONS = "extractions";
|
public static final String TAG_EXTRACTIONS = "extractions";
|
||||||
|
|
||||||
public ItemCreativeUnlocker(Properties properties) {
|
public ItemCreativeUnlocker(Properties properties) {
|
||||||
super(properties);
|
super(properties);
|
||||||
|
@ -80,6 +108,7 @@ public class ItemCreativeUnlocker extends Item implements ManaHolderItem {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int withdrawMana(ItemStack stack, int cost, boolean simulate) {
|
public int withdrawMana(ItemStack stack, int cost, boolean simulate) {
|
||||||
|
// In case it's withdrawn through other means
|
||||||
if (!simulate && isDebug(stack)) {
|
if (!simulate && isDebug(stack)) {
|
||||||
int[] arr = NBTHelper.getIntArray(stack, TAG_EXTRACTIONS);
|
int[] arr = NBTHelper.getIntArray(stack, TAG_EXTRACTIONS);
|
||||||
if (arr == null) {
|
if (arr == null) {
|
||||||
|
|
|
@ -1,10 +1,13 @@
|
||||||
@file:JvmName("AccessorWrappers")
|
@file:JvmName("AccessorWrappers")
|
||||||
package at.petrak.hexcasting.ktxt
|
package at.petrak.hexcasting.ktxt
|
||||||
|
|
||||||
|
import at.petrak.hexcasting.mixin.accessor.AccessorEntity
|
||||||
import at.petrak.hexcasting.mixin.accessor.AccessorLivingEntity
|
import at.petrak.hexcasting.mixin.accessor.AccessorLivingEntity
|
||||||
import at.petrak.hexcasting.mixin.accessor.AccessorUseOnContext
|
import at.petrak.hexcasting.mixin.accessor.AccessorUseOnContext
|
||||||
import at.petrak.hexcasting.mixin.accessor.AccessorVillager
|
import at.petrak.hexcasting.mixin.accessor.AccessorVillager
|
||||||
|
import net.minecraft.sounds.SoundEvent
|
||||||
import net.minecraft.world.InteractionHand
|
import net.minecraft.world.InteractionHand
|
||||||
|
import net.minecraft.world.damagesource.DamageSource
|
||||||
import net.minecraft.world.entity.Entity
|
import net.minecraft.world.entity.Entity
|
||||||
import net.minecraft.world.entity.LivingEntity
|
import net.minecraft.world.entity.LivingEntity
|
||||||
import net.minecraft.world.entity.npc.Villager
|
import net.minecraft.world.entity.npc.Villager
|
||||||
|
@ -18,6 +21,18 @@ var LivingEntity.lastHurt: Float
|
||||||
get() = (this as AccessorLivingEntity).`hex$getLastHurt`()
|
get() = (this as AccessorLivingEntity).`hex$getLastHurt`()
|
||||||
set(value) = (this as AccessorLivingEntity).`hex$setLastHurt`(value)
|
set(value) = (this as AccessorLivingEntity).`hex$setLastHurt`(value)
|
||||||
|
|
||||||
|
fun LivingEntity.playHurtSound(source: DamageSource) = (this as AccessorLivingEntity).`hex$playHurtSound`(source)
|
||||||
|
fun LivingEntity.checkTotemDeathProtection(source: DamageSource) = (this as AccessorLivingEntity).`hex$checkTotemDeathProtection`(source)
|
||||||
|
val LivingEntity.deathSoundAccessor: SoundEvent? get() = (this as AccessorLivingEntity).`hex$getDeathSound`()
|
||||||
|
val LivingEntity.soundVolumeAccessor get() = (this as AccessorLivingEntity).`hex$getSoundVolume`()
|
||||||
|
|
||||||
|
fun LivingEntity.setHurtWithStamp(source: DamageSource, stamp: Long) = (this as AccessorLivingEntity).apply {
|
||||||
|
`hex$setLastDamageSource`(source)
|
||||||
|
`hex$setLastDamageStamp`(stamp)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun Entity.markHurt() = (this as AccessorEntity).`hex$markHurt`()
|
||||||
|
|
||||||
fun Villager.tellWitnessesThatIWasMurdered(murderer: Entity) = (this as AccessorVillager).`hex$tellWitnessesThatIWasMurdered`(murderer)
|
fun Villager.tellWitnessesThatIWasMurdered(murderer: Entity) = (this as AccessorVillager).`hex$tellWitnessesThatIWasMurdered`(murderer)
|
||||||
|
|
||||||
@Suppress("FunctionName")
|
@Suppress("FunctionName")
|
||||||
|
|
|
@ -0,0 +1,11 @@
|
||||||
|
package at.petrak.hexcasting.mixin.accessor;
|
||||||
|
|
||||||
|
import net.minecraft.world.entity.Entity;
|
||||||
|
import org.spongepowered.asm.mixin.Mixin;
|
||||||
|
import org.spongepowered.asm.mixin.gen.Invoker;
|
||||||
|
|
||||||
|
@Mixin(Entity.class)
|
||||||
|
public interface AccessorEntity {
|
||||||
|
@Invoker("markHurt")
|
||||||
|
void hex$markHurt();
|
||||||
|
}
|
|
@ -1,8 +1,11 @@
|
||||||
package at.petrak.hexcasting.mixin.accessor;
|
package at.petrak.hexcasting.mixin.accessor;
|
||||||
|
|
||||||
|
import net.minecraft.sounds.SoundEvent;
|
||||||
|
import net.minecraft.world.damagesource.DamageSource;
|
||||||
import net.minecraft.world.entity.LivingEntity;
|
import net.minecraft.world.entity.LivingEntity;
|
||||||
import org.spongepowered.asm.mixin.Mixin;
|
import org.spongepowered.asm.mixin.Mixin;
|
||||||
import org.spongepowered.asm.mixin.gen.Accessor;
|
import org.spongepowered.asm.mixin.gen.Accessor;
|
||||||
|
import org.spongepowered.asm.mixin.gen.Invoker;
|
||||||
|
|
||||||
@Mixin(LivingEntity.class)
|
@Mixin(LivingEntity.class)
|
||||||
public interface AccessorLivingEntity {
|
public interface AccessorLivingEntity {
|
||||||
|
@ -11,4 +14,22 @@ public interface AccessorLivingEntity {
|
||||||
|
|
||||||
@Accessor("lastHurt")
|
@Accessor("lastHurt")
|
||||||
void hex$setLastHurt(float lastHurt);
|
void hex$setLastHurt(float lastHurt);
|
||||||
|
|
||||||
|
@Invoker("playHurtSound")
|
||||||
|
void hex$playHurtSound(DamageSource source);
|
||||||
|
|
||||||
|
@Invoker("checkTotemDeathProtection")
|
||||||
|
boolean hex$checkTotemDeathProtection(DamageSource source);
|
||||||
|
|
||||||
|
@Invoker("getDeathSound")
|
||||||
|
SoundEvent hex$getDeathSound();
|
||||||
|
|
||||||
|
@Invoker("getSoundVolume")
|
||||||
|
float hex$getSoundVolume();
|
||||||
|
|
||||||
|
@Accessor("lastDamageSource")
|
||||||
|
void hex$setLastDamageSource(DamageSource source);
|
||||||
|
|
||||||
|
@Accessor("lastDamageStamp")
|
||||||
|
void hex$setLastDamageStamp(long stamp);
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,6 +11,7 @@
|
||||||
"MixinReloadableServerResources",
|
"MixinReloadableServerResources",
|
||||||
"MixinVillager",
|
"MixinVillager",
|
||||||
"MixinWitch",
|
"MixinWitch",
|
||||||
|
"accessor.AccessorEntity",
|
||||||
"accessor.AccessorLivingEntity",
|
"accessor.AccessorLivingEntity",
|
||||||
"accessor.AccessorLootTable",
|
"accessor.AccessorLootTable",
|
||||||
"accessor.AccessorPoiType",
|
"accessor.AccessorPoiType",
|
||||||
|
|
|
@ -1,18 +1,25 @@
|
||||||
package at.petrak.hexcasting.fabric.interop.trinkets;
|
package at.petrak.hexcasting.fabric.interop.trinkets;
|
||||||
|
|
||||||
import at.petrak.hexcasting.common.items.ItemLens;
|
import at.petrak.hexcasting.api.misc.DiscoveryHandlers;
|
||||||
|
import at.petrak.hexcasting.api.utils.ManaHelper;
|
||||||
|
import at.petrak.hexcasting.common.items.magic.DebugUnlockerHolder;
|
||||||
|
import at.petrak.hexcasting.common.items.magic.ItemCreativeUnlocker;
|
||||||
import at.petrak.hexcasting.common.lib.HexItems;
|
import at.petrak.hexcasting.common.lib.HexItems;
|
||||||
|
import at.petrak.hexcasting.xplat.IXplatAbstractions;
|
||||||
import dev.emi.trinkets.api.TrinketComponent;
|
import dev.emi.trinkets.api.TrinketComponent;
|
||||||
import dev.emi.trinkets.api.TrinketsApi;
|
import dev.emi.trinkets.api.TrinketsApi;
|
||||||
import dev.emi.trinkets.api.client.TrinketRendererRegistry;
|
import dev.emi.trinkets.api.client.TrinketRendererRegistry;
|
||||||
import net.fabricmc.api.EnvType;
|
import net.fabricmc.api.EnvType;
|
||||||
import net.fabricmc.api.Environment;
|
import net.fabricmc.api.Environment;
|
||||||
|
import net.minecraft.util.Tuple;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Objects;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
|
|
||||||
public class TrinketsApiInterop {
|
public class TrinketsApiInterop {
|
||||||
public static void init() {
|
public static void init() {
|
||||||
ItemLens.addLensHUDPredicate(player -> {
|
DiscoveryHandlers.addLensPredicate(player -> {
|
||||||
Optional<TrinketComponent> optional = TrinketsApi.getTrinketComponent(player);
|
Optional<TrinketComponent> optional = TrinketsApi.getTrinketComponent(player);
|
||||||
if (optional.isPresent()) {
|
if (optional.isPresent()) {
|
||||||
TrinketComponent component = optional.get();
|
TrinketComponent component = optional.get();
|
||||||
|
@ -20,6 +27,31 @@ public class TrinketsApiInterop {
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
DiscoveryHandlers.addManaHolderDiscoverer(harness -> {
|
||||||
|
Optional<TrinketComponent> optional = TrinketsApi.getTrinketComponent(harness.getCtx().getCaster());
|
||||||
|
if (optional.isPresent()) {
|
||||||
|
TrinketComponent component = optional.get();
|
||||||
|
return component.getEquipped(ManaHelper::isManaItem).stream()
|
||||||
|
.map(Tuple::getB)
|
||||||
|
.map(IXplatAbstractions.INSTANCE::findManaHolder)
|
||||||
|
.filter(Objects::nonNull)
|
||||||
|
.toList();
|
||||||
|
}
|
||||||
|
return List.of();
|
||||||
|
});
|
||||||
|
|
||||||
|
DiscoveryHandlers.addManaHolderDiscoverer(harness -> {
|
||||||
|
Optional<TrinketComponent> optional = TrinketsApi.getTrinketComponent(harness.getCtx().getCaster());
|
||||||
|
if (optional.isPresent()) {
|
||||||
|
TrinketComponent component = optional.get();
|
||||||
|
var equipped = component.getEquipped(ItemCreativeUnlocker::isDebug);
|
||||||
|
if (!equipped.isEmpty()) {
|
||||||
|
return List.of(new DebugUnlockerHolder(equipped.get(0).getB()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return List.of();
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@Environment(EnvType.CLIENT)
|
@Environment(EnvType.CLIENT)
|
||||||
|
|
|
@ -1,8 +1,14 @@
|
||||||
package at.petrak.hexcasting.forge.interop.curios;
|
package at.petrak.hexcasting.forge.interop.curios;
|
||||||
|
|
||||||
import at.petrak.hexcasting.common.items.ItemLens;
|
import at.petrak.hexcasting.api.addldata.ManaHolder;
|
||||||
|
import at.petrak.hexcasting.api.misc.DiscoveryHandlers;
|
||||||
|
import at.petrak.hexcasting.api.utils.ManaHelper;
|
||||||
|
import at.petrak.hexcasting.common.items.magic.DebugUnlockerHolder;
|
||||||
|
import at.petrak.hexcasting.common.items.magic.ItemCreativeUnlocker;
|
||||||
import at.petrak.hexcasting.common.lib.HexItems;
|
import at.petrak.hexcasting.common.lib.HexItems;
|
||||||
import at.petrak.hexcasting.interop.HexInterop;
|
import at.petrak.hexcasting.interop.HexInterop;
|
||||||
|
import at.petrak.hexcasting.xplat.IXplatAbstractions;
|
||||||
|
import com.google.common.collect.Lists;
|
||||||
import net.minecraftforge.fml.InterModComms;
|
import net.minecraftforge.fml.InterModComms;
|
||||||
import net.minecraftforge.fml.event.lifecycle.FMLClientSetupEvent;
|
import net.minecraftforge.fml.event.lifecycle.FMLClientSetupEvent;
|
||||||
import net.minecraftforge.fml.event.lifecycle.InterModEnqueueEvent;
|
import net.minecraftforge.fml.event.lifecycle.InterModEnqueueEvent;
|
||||||
|
@ -11,19 +17,67 @@ import top.theillusivec4.curios.api.SlotTypeMessage;
|
||||||
import top.theillusivec4.curios.api.SlotTypePreset;
|
import top.theillusivec4.curios.api.SlotTypePreset;
|
||||||
import top.theillusivec4.curios.api.type.inventory.ICurioStacksHandler;
|
import top.theillusivec4.curios.api.type.inventory.ICurioStacksHandler;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
import java.util.concurrent.atomic.AtomicBoolean;
|
import java.util.concurrent.atomic.AtomicBoolean;
|
||||||
|
|
||||||
public class CuriosApiInterop {
|
public class CuriosApiInterop {
|
||||||
|
|
||||||
public static void init() {
|
public static void init() {
|
||||||
ItemLens.addLensHUDPredicate(player -> {
|
DiscoveryHandlers.addLensPredicate(player -> {
|
||||||
AtomicBoolean hasLens = new AtomicBoolean(false);
|
AtomicBoolean hasLens = new AtomicBoolean(false);
|
||||||
player.getCapability(CuriosCapability.INVENTORY).ifPresent(handler -> {
|
player.getCapability(CuriosCapability.INVENTORY).ifPresent(handler -> {
|
||||||
ICurioStacksHandler stacksHandler = handler.getCurios().get("head");
|
ICurioStacksHandler stacksHandler = handler.getCurios().get("head");
|
||||||
if(stacksHandler != null) hasLens.set(stacksHandler.getStacks().getStackInSlot(0).is(HexItems.SCRYING_LENS));
|
if(stacksHandler != null) {
|
||||||
|
var stacks = stacksHandler.getStacks();
|
||||||
|
for (int i = 0; i < stacks.getSlots(); i++) {
|
||||||
|
if (stacks.getStackInSlot(i).is(HexItems.SCRYING_LENS)) {
|
||||||
|
hasLens.set(true);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
});
|
});
|
||||||
return hasLens.get();
|
return hasLens.get();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
|
DiscoveryHandlers.addManaHolderDiscoverer(harness -> {
|
||||||
|
List<ManaHolder> holders = Lists.newArrayList();
|
||||||
|
harness.getCtx().getCaster().getCapability(CuriosCapability.INVENTORY).ifPresent(handler -> {
|
||||||
|
for (var stacksHandler : handler.getCurios().values()) {
|
||||||
|
var stacks = stacksHandler.getStacks();
|
||||||
|
for (int i = 0; i < stacks.getSlots(); i++) {
|
||||||
|
var stack = stacks.getStackInSlot(i);
|
||||||
|
if (ManaHelper.isManaItem(stack)) {
|
||||||
|
var holder = IXplatAbstractions.INSTANCE.findManaHolder(stack);
|
||||||
|
if (holder != null) {
|
||||||
|
holders.add(holder);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return holders;
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
DiscoveryHandlers.addManaHolderDiscoverer(harness -> {
|
||||||
|
List<ManaHolder> holders = Lists.newArrayList();
|
||||||
|
harness.getCtx().getCaster().getCapability(CuriosCapability.INVENTORY).ifPresent(handler -> {
|
||||||
|
for (var stacksHandler : handler.getCurios().values()) {
|
||||||
|
var stacks = stacksHandler.getStacks();
|
||||||
|
for (int i = 0; i < stacks.getSlots(); i++) {
|
||||||
|
var stack = stacks.getStackInSlot(i);
|
||||||
|
if (ItemCreativeUnlocker.isDebug(stack)) {
|
||||||
|
holders.add(new DebugUnlockerHolder(stack));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return holders;
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void onInterModEnqueue(final InterModEnqueueEvent event) {
|
public static void onInterModEnqueue(final InterModEnqueueEvent event) {
|
||||||
|
|
Loading…
Reference in a new issue