creative unlocker now can show you mana usages

This commit is contained in:
yrsegal@gmail.com 2022-06-04 18:17:10 -04:00
parent 31d40b7555
commit 9b0487688c
5 changed files with 93 additions and 18 deletions

View file

@ -13,6 +13,7 @@ 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
@ -350,10 +351,15 @@ class CastingHarness private constructor(
*/ */
fun withdrawMana(manaCost: Int, allowOvercast: Boolean): Int { fun withdrawMana(manaCost: Int, allowOvercast: Boolean): Int {
// prevent poor impls from gaining you mana // prevent poor impls from gaining you mana
if (this.ctx.caster.isCreative || manaCost <= 0) return 0 if (manaCost <= 0) return 0
var costLeft = manaCost var costLeft = manaCost
val fake = this.ctx.caster.isCreative
if (this.ctx.spellCircle != null) { if (this.ctx.spellCircle != null) {
if (fake)
return 0
val tile = this.ctx.world.getBlockEntity(this.ctx.spellCircle.impetusPos) val tile = this.ctx.world.getBlockEntity(this.ctx.spellCircle.impetusPos)
if (tile is BlockEntityAbstractImpetus) { if (tile is BlockEntityAbstractImpetus) {
val manaAvailable = tile.mana val manaAvailable = tile.mana
@ -365,23 +371,23 @@ class CastingHarness private constructor(
val casterStack = this.ctx.caster.getItemInHand(this.ctx.castingHand) val casterStack = this.ctx.caster.getItemInHand(this.ctx.castingHand)
val casterManaHolder = IXplatAbstractions.INSTANCE.findManaHolder(casterStack) val casterManaHolder = IXplatAbstractions.INSTANCE.findManaHolder(casterStack)
val casterHexHolder = IXplatAbstractions.INSTANCE.findHexHolder(casterStack) val casterHexHolder = IXplatAbstractions.INSTANCE.findHexHolder(casterStack)
val ipsCanDrawFromInv = if (casterHexHolder != null) { val hexHolderDrawsFromInventory = if (casterHexHolder != null) {
if (casterManaHolder != null) { if (casterManaHolder != null) {
val manaAvailable = casterManaHolder.mana val manaAvailable = casterManaHolder.mana
val manaToTake = min(costLeft, manaAvailable) val manaToTake = min(costLeft, manaAvailable)
casterManaHolder.mana = manaAvailable - manaToTake if (!fake) casterManaHolder.mana = manaAvailable - manaToTake
costLeft -= manaToTake costLeft -= manaToTake
} }
casterHexHolder.canDrawManaFromInventory() casterHexHolder.canDrawManaFromInventory()
} else { } else {
false false
} }
if (casterStack.`is`(HexItemTags.WANDS) || ipsCanDrawFromInv) { if (casterStack.`is`(HexItemTags.WANDS) || hexHolderDrawsFromInventory) {
val manableItems = this.ctx.caster.inventory.items val manableItems = this.ctx.caster.inventory.items
.filter(::isManaItem) .filter(::isManaItem)
.sortedWith(Comparator(::compareManaItem).reversed()) .sortedWith(Comparator(::compareManaItem).reversed())
for (stack in manableItems) { for (stack in manableItems) {
costLeft -= extractMana(stack, costLeft) costLeft -= extractMana(stack, costLeft, simulate = fake && !ItemCreativeUnlocker.isDebug(stack))
if (costLeft <= 0) if (costLeft <= 0)
break break
} }
@ -393,15 +399,18 @@ 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) {
HexAdvancementTriggers.OVERCAST_TRIGGER.trigger(this.ctx.caster, manaToActuallyPayFor) HexAdvancementTriggers.OVERCAST_TRIGGER.trigger(this.ctx.caster, manaToActuallyPayFor)
this.ctx.caster.awardStat(HexStatistics.MANA_OVERCASTED, manaCost - costLeft) 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())
}
costLeft -= manaToActuallyPayFor costLeft -= manaToActuallyPayFor
} }
} }
} }
if (!fake) {
// this might be more than the mana cost! for example if we waste a lot of mana from an item // this might be more than the mana cost! for example if we waste a lot of mana from an item
this.ctx.caster.awardStat(HexStatistics.MANA_USED, manaCost - costLeft) this.ctx.caster.awardStat(HexStatistics.MANA_USED, manaCost - costLeft)
HexAdvancementTriggers.SPEND_MANA_TRIGGER.trigger( HexAdvancementTriggers.SPEND_MANA_TRIGGER.trigger(
@ -409,8 +418,9 @@ class CastingHarness private constructor(
manaCost - costLeft, manaCost - costLeft,
if (costLeft < 0) -costLeft else 0 if (costLeft < 0) -costLeft else 0
) )
}
return costLeft return if (fake) 0 else costLeft
} }
fun getColorizer(): FrozenColorizer { fun getColorizer(): FrozenColorizer {

View file

@ -115,7 +115,9 @@ fun CompoundTag.getList(key: String, objType: Byte): ListTag = getList(key, objT
// Get-or-create // Get-or-create
fun CompoundTag.getOrCreateCompound(key: String) = getCompound(key) ?: CompoundTag().also { putCompound(key, this) } fun CompoundTag.getOrCreateCompound(key: String): CompoundTag = getCompound(key) ?: CompoundTag().also { putCompound(key, it) }
fun CompoundTag.getOrCreateList(key: String, objType: Byte) = getOrCreateList(key, objType.toInt())
fun CompoundTag.getOrCreateList(key: String, objType: Int): ListTag = if (hasList(key, objType)) getList(key, objType) else ListTag().also { putList(key, it) }
// ================================================================================================================ Tag // ================================================================================================================ Tag
@ -267,3 +269,5 @@ fun ItemStack.getTag(key: String) = tag.get(key)
// Get-or-create // Get-or-create
fun ItemStack.getOrCreateCompound(key: String): CompoundTag = getOrCreateTagElement(key) fun ItemStack.getOrCreateCompound(key: String): CompoundTag = getOrCreateTagElement(key)
fun ItemStack.getOrCreateList(key: String, objType: Byte) = orCreateTag.getOrCreateList(key, objType)
fun ItemStack.getOrCreateList(key: String, objType: Int) = orCreateTag.getOrCreateList(key, objType)

View file

@ -1,13 +1,18 @@
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.ManaConstants;
import at.petrak.hexcasting.api.utils.NBTHelper;
import at.petrak.hexcasting.common.lib.HexItems;
import net.minecraft.ChatFormatting; import net.minecraft.ChatFormatting;
import net.minecraft.Util;
import net.minecraft.advancements.Advancement; import net.minecraft.advancements.Advancement;
import net.minecraft.locale.Language; import net.minecraft.locale.Language;
import net.minecraft.network.chat.*; import net.minecraft.network.chat.*;
import net.minecraft.server.level.ServerLevel; import net.minecraft.server.level.ServerLevel;
import net.minecraft.server.level.ServerPlayer; import net.minecraft.server.level.ServerPlayer;
import net.minecraft.util.Mth; import net.minecraft.util.Mth;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.LivingEntity; import net.minecraft.world.entity.LivingEntity;
import net.minecraft.world.item.Item; import net.minecraft.world.item.Item;
import net.minecraft.world.item.ItemStack; import net.minecraft.world.item.ItemStack;
@ -16,11 +21,21 @@ import net.minecraft.world.level.Level;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays;
import java.util.List; import java.util.List;
import java.util.Locale;
import static at.petrak.hexcasting.api.HexAPI.modLoc; import static at.petrak.hexcasting.api.HexAPI.modLoc;
public class ItemCreativeUnlocker extends Item implements ManaHolderItem { public class ItemCreativeUnlocker extends Item implements ManaHolderItem {
public static boolean isDebug(ItemStack stack) {
return stack.is(HexItems.CREATIVE_UNLOCKER) &&
stack.getHoverName().getString().toLowerCase(Locale.ROOT).equals("debug");
}
private static final String TAG_EXTRACTIONS = "extractions";
public ItemCreativeUnlocker(Properties properties) { public ItemCreativeUnlocker(Properties properties) {
super(properties); super(properties);
} }
@ -52,9 +67,47 @@ 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) {
if (!simulate && isDebug(stack)) {
int[] arr = NBTHelper.getIntArray(stack, TAG_EXTRACTIONS);
if (arr == null)
arr = new int[0];
int[] newArr = Arrays.copyOf(arr, arr.length + 1);
newArr[newArr.length - 1] = cost;
NBTHelper.putIntArray(stack, TAG_EXTRACTIONS, newArr);
}
return cost < 0 ? 1 : cost; return cost < 0 ? 1 : cost;
} }
@Override
public boolean isFoil(ItemStack stack) {
return super.isFoil(stack) || isDebug(stack);
}
@Override
public void inventoryTick(ItemStack stack, Level level, Entity entity, int slot, boolean selected) {
if (isDebug(stack) && !level.isClientSide) {
int[] arr = NBTHelper.getIntArray(stack, TAG_EXTRACTIONS);
if (arr != null) {
NBTHelper.remove(stack, TAG_EXTRACTIONS);
for (int i : arr) {
if (i < 0) {
entity.sendMessage(new TranslatableComponent("hexcasting.debug.mana_withdrawn",
stack.getDisplayName(),
new TranslatableComponent("hexcasting.debug.all_mana").withStyle(ChatFormatting.GRAY))
.withStyle(ChatFormatting.LIGHT_PURPLE), Util.NIL_UUID);
} else {
entity.sendMessage(new TranslatableComponent("hexcasting.debug.mana_withdrawn.with_dust",
stack.getDisplayName(),
new TextComponent("" + i).withStyle(ChatFormatting.WHITE),
new TextComponent(String.format("%.2f", i * 1.0 / ManaConstants.DUST_UNIT)).withStyle(ChatFormatting.WHITE))
.withStyle(ChatFormatting.LIGHT_PURPLE), Util.NIL_UUID);
}
}
}
}
}
@Override @Override
public ItemStack finishUsingItem(ItemStack stack, Level level, LivingEntity consumer) { public ItemStack finishUsingItem(ItemStack stack, Level level, LivingEntity consumer) {
if (level instanceof ServerLevel slevel && consumer instanceof ServerPlayer player) { if (level instanceof ServerLevel slevel && consumer instanceof ServerPlayer player) {

View file

@ -172,6 +172,9 @@
"command.hexcasting.brainsweep.fail.badtype": "%s is not a villager", "command.hexcasting.brainsweep.fail.badtype": "%s is not a villager",
"command.hexcasting.brainsweep.fail.already": "%s is already empty", "command.hexcasting.brainsweep.fail.already": "%s is already empty",
"hexcasting.pattern.unknown": "Unknown pattern resource location %s", "hexcasting.pattern.unknown": "Unknown pattern resource location %s",
"hexcasting.debug.mana_withdrawn": "%s - Mana withdrawn: %s",
"hexcasting.debug.mana_withdrawn_with_dust": "%s - Mana withdrawn: %s (%s in dust)",
"hexcasting.debug.all_mana": "Entire contents",
"hexcasting.message.cant_overcast": "That Hex needed more media than I had... I should double-check my math.", "hexcasting.message.cant_overcast": "That Hex needed more media than I had... I should double-check my math.",
"hexcasting.message.cant_great_spell": "The spell failed, somehow... am I not skilled enough?", "hexcasting.message.cant_great_spell": "The spell failed, somehow... am I not skilled enough?",

View file

@ -57,6 +57,11 @@ public abstract class CCManaHolder extends ItemComponent implements ManaHolder {
public boolean canConstructBattery() { public boolean canConstructBattery() {
return false; return false;
} }
@Override
public int withdrawMana(int cost, boolean simulate) {
return this.manaHolder.withdrawMana(this.stack, cost, simulate);
}
} }
public static class Static extends CCManaHolder { public static class Static extends CCManaHolder {