prevent 0 size batteries; recharge is minimally lossy

This commit is contained in:
yrsegal@gmail.com 2022-04-11 11:35:23 -04:00
parent 963b6c586f
commit 8fd72b9e44
4 changed files with 30 additions and 47 deletions

View file

@ -20,35 +20,12 @@ object ManaHelper {
} }
/** /**
* Try to extract the given amount of mana from this item. * Extract [cost] mana from [stack]. If [cost] is less than zero, extract all mana instead.
* This may mutate the itemstack. * This may mutate [stack] (and may consume it) unless [simulate] is set.
* *
* Return the actual amount of mana extracted, or null if this cannot have mana extracted. * Return the amount of mana extracted. This may be over [cost] if mana is wasted.
*/ */
fun extractMana(stack: ItemStack, cost: Int): Int? { fun extractMana(stack: ItemStack, cost: Int = -1, simulate: Boolean = false): Int {
val base = when (stack.item) {
HexItems.AMETHYST_DUST.get() -> HexConfig.dustManaAmount.get()
Items.AMETHYST_SHARD -> HexConfig.shardManaAmount.get()
HexItems.CHARGED_AMETHYST.get() -> HexConfig.chargedCrystalManaAmount.get()
HexItems.BATTERY.get() -> {
val battery = stack.item as ItemManaBattery
return battery.withdrawMana(stack.orCreateTag, cost)
}
else -> return null
}
val itemsReqd = ceil(cost.toFloat() / base.toFloat()).toInt()
val actualItemsConsumed = min(stack.count, itemsReqd)
stack.shrink(actualItemsConsumed)
return base * actualItemsConsumed
}
/**
* Extract the entirety of the mana out of this.
* This may mutate the itemstack (and will probably consume it).
*
* Return the amount of mana extracted.
*/
fun extractAllMana(stack: ItemStack): Int {
val base = when (stack.item) { val base = when (stack.item) {
HexItems.AMETHYST_DUST.get() -> HexConfig.dustManaAmount.get() HexItems.AMETHYST_DUST.get() -> HexConfig.dustManaAmount.get()
Items.AMETHYST_SHARD -> HexConfig.shardManaAmount.get() Items.AMETHYST_SHARD -> HexConfig.shardManaAmount.get()
@ -58,13 +35,18 @@ object ManaHelper {
val battery = stack.item as ItemManaBattery val battery = stack.item as ItemManaBattery
val tag = stack.orCreateTag val tag = stack.orCreateTag
val manaThere = battery.getManaAmt(tag) val manaThere = battery.getManaAmt(tag)
return battery.withdrawMana(tag, manaThere) val manaToExtract = if (cost < 0) manaThere else min(cost, manaThere)
if (simulate)
return manaToExtract
return battery.withdrawMana(tag, manaToExtract)
} }
else -> return 0 else -> return 0
} }
val count = stack.count val count = stack.count
stack.shrink(count) val countToExtract = if (cost < 0) count else min(count, ceil(cost.toDouble() / base).toInt())
return base * count if (!simulate)
stack.shrink(countToExtract)
return base * countToExtract
} }
/** /**

View file

@ -43,7 +43,7 @@ object OpMakeBattery : SpellOperator {
ctx.assertEntityInRange(entity) ctx.assertEntityInRange(entity)
if (!ManaHelper.isManaItem(entity.item)) { if (!ManaHelper.isManaItem(entity.item) || ManaHelper.extractMana(entity.item, simulate = true) <= 0) {
throw MishapBadItem.of( throw MishapBadItem.of(
entity.item, entity.item,
"mana" "mana"
@ -58,7 +58,7 @@ object OpMakeBattery : SpellOperator {
val (handStack, hand) = ctx.getHeldItemToOperateOn { it.item == Items.GLASS_BOTTLE } val (handStack, hand) = ctx.getHeldItemToOperateOn { it.item == Items.GLASS_BOTTLE }
if (handStack.item == Items.GLASS_BOTTLE && itemEntity.isAlive) { if (handStack.item == Items.GLASS_BOTTLE && itemEntity.isAlive) {
val entityStack = itemEntity.item.copy() val entityStack = itemEntity.item.copy()
val manaAmt = ManaHelper.extractAllMana(entityStack) val manaAmt = ManaHelper.extractMana(entityStack)
if (manaAmt > 0) { if (manaAmt > 0) {
val replaceItem = ItemStack(HexItems.BATTERY.get()) val replaceItem = ItemStack(HexItems.BATTERY.get())
val tag = replaceItem.orCreateTag val tag = replaceItem.orCreateTag

View file

@ -36,7 +36,7 @@ class OpMakePackagedSpell<T : ItemPackagedSpell>(val itemType: T, val cost: Int)
} }
ctx.assertEntityInRange(entity) ctx.assertEntityInRange(entity)
if (!ManaHelper.isManaItem(entity.item)) { if (!ManaHelper.isManaItem(entity.item) || ManaHelper.extractMana(entity.item, simulate = true) <= 0) {
throw MishapBadItem.of( throw MishapBadItem.of(
entity.item, entity.item,
"mana" "mana"
@ -57,7 +57,7 @@ class OpMakePackagedSpell<T : ItemPackagedSpell>(val itemType: T, val cost: Int)
&& itemEntity.isAlive && itemEntity.isAlive
) { ) {
val entityStack = itemEntity.item.copy() val entityStack = itemEntity.item.copy()
val manaAmt = ManaHelper.extractAllMana(entityStack) val manaAmt = ManaHelper.extractMana(entityStack)
if (manaAmt > 0) { if (manaAmt > 0) {
tag.putInt(ItemPackagedSpell.TAG_MANA, manaAmt) tag.putInt(ItemPackagedSpell.TAG_MANA, manaAmt)
tag.putInt(ItemPackagedSpell.TAG_MAX_MANA, manaAmt) tag.putInt(ItemPackagedSpell.TAG_MAX_MANA, manaAmt)

View file

@ -47,19 +47,20 @@ object OpRecharge : SpellOperator {
if (handStack.item is ItemManaHolder && itemEntity.isAlive) { if (handStack.item is ItemManaHolder && itemEntity.isAlive) {
val entityStack = itemEntity.item.copy() val entityStack = itemEntity.item.copy()
val manaAmt = ManaHelper.extractAllMana(entityStack)
if (manaAmt > 0) { val tag = handStack.orCreateTag
val tag = handStack.orCreateTag val maxMana = if (tag.contains(ItemManaHolder.TAG_MAX_MANA))
val maxMana = if (tag.contains(ItemManaHolder.TAG_MAX_MANA)) tag.getInt(ItemManaHolder.TAG_MAX_MANA)
tag.getInt(ItemManaHolder.TAG_MAX_MANA) else
else Int.MAX_VALUE
Int.MAX_VALUE val existingMana = if (tag.contains(ItemManaHolder.TAG_MANA))
val existingMana = if (tag.contains(ItemManaHolder.TAG_MANA)) tag.getInt(ItemManaHolder.TAG_MANA)
tag.getInt(ItemManaHolder.TAG_MANA) else
else 0
0
tag.putInt(ItemManaHolder.TAG_MANA, Mth.clamp(existingMana + manaAmt, 0, maxMana)) val manaAmt = ManaHelper.extractMana(entityStack, maxMana - existingMana)
}
tag.putInt(ItemManaHolder.TAG_MANA, Mth.clamp(existingMana + manaAmt, 0, maxMana))
itemEntity.item = entityStack itemEntity.item = entityStack
if (entityStack.isEmpty) if (entityStack.isEmpty)