fix double-use of getHeldItemToOperateOn

This commit is contained in:
yrsegal@gmail.com 2022-08-22 22:28:55 -04:00
parent 473a5a9834
commit ed2abee735
12 changed files with 51 additions and 83 deletions

View file

@ -14,8 +14,8 @@ import net.minecraft.server.level.ServerLevel
import net.minecraft.server.level.ServerPlayer
import net.minecraft.world.InteractionHand
import net.minecraft.world.entity.Entity
import net.minecraft.world.entity.item.ItemEntity
import net.minecraft.world.entity.player.Player
import net.minecraft.world.item.Item
import net.minecraft.world.item.ItemStack
import net.minecraft.world.level.GameType
import net.minecraft.world.phys.Vec3
@ -150,14 +150,14 @@ data class CastingContext(
* Return whether the withdrawal was successful.
*/
// https://github.com/VazkiiMods/Psi/blob/master/src/main/java/vazkii/psi/common/spell/trick/block/PieceTrickPlaceBlock.java#L143
fun withdrawItem(item: Item, count: Int, actuallyRemove: Boolean): Boolean {
fun withdrawItem(item: ItemStack, count: Int, actuallyRemove: Boolean): Boolean {
if (this.caster.isCreative) return true
// TODO: withdraw from ender chest given a specific ender charm?
val stacksToExamine = DiscoveryHandlers.collectItemSlots(this)
fun matches(stack: ItemStack): Boolean =
!stack.isEmpty && stack.`is`(item)
!stack.isEmpty && ItemEntity.areMergable(stack, item)
val presentCount = stacksToExamine.fold(0) { acc, stack ->
acc + if (matches(stack)) stack.count else 0

View file

@ -1,5 +1,6 @@
package at.petrak.hexcasting.common.casting.operators
import at.petrak.hexcasting.api.addldata.DataHolder
import at.petrak.hexcasting.api.spell.ParticleSpray
import at.petrak.hexcasting.api.spell.RenderedSpell
import at.petrak.hexcasting.api.spell.SpellDatum
@ -35,22 +36,15 @@ object OpWrite : SpellOperator {
throw MishapOthersName(trueName)
return Triple(
Spell(datum),
Spell(datum, datumHolder),
0,
listOf()
)
}
private data class Spell(val datum: SpellDatum<*>) : RenderedSpell {
private data class Spell(val datum: SpellDatum<*>, val datumHolder: DataHolder) : RenderedSpell {
override fun cast(ctx: CastingContext) {
val (handStack) = ctx.getHeldItemToOperateOn {
val datumHolder = IXplatAbstractions.INSTANCE.findDataHolder(it)
datumHolder != null && datumHolder.writeDatum(datum, true)
}
val datumHolder = IXplatAbstractions.INSTANCE.findDataHolder(handStack)
datumHolder?.writeDatum(datum, false)
datumHolder.writeDatum(datum, false)
}
}
}

View file

@ -15,22 +15,21 @@ object OpBreakBlock : SpellOperator {
override fun execute(
args: List<SpellDatum<*>>,
ctx: CastingContext
): Triple<RenderedSpell, Int, List<ParticleSpray>> {
): Triple<RenderedSpell, Int, List<ParticleSpray>>? {
val pos = args.getChecked<Vec3>(0, argc)
ctx.assertVecInRange(pos)
val centered = Vec3.atCenterOf(BlockPos(pos))
val bpos = BlockPos(pos)
val centered = Vec3.atCenterOf(bpos)
return Triple(
Spell(pos),
Spell(bpos),
(ManaConstants.DUST_UNIT * 1.125).toInt(),
listOf(ParticleSpray.burst(centered, 1.0))
)
}
private data class Spell(val v: Vec3) : RenderedSpell {
private data class Spell(val pos: BlockPos) : RenderedSpell {
override fun cast(ctx: CastingContext) {
val pos = BlockPos(v)
if (!ctx.canEditBlockAt(pos))
return

View file

@ -9,6 +9,7 @@ import at.petrak.hexcasting.api.spell.SpellOperator
import at.petrak.hexcasting.api.spell.casting.CastingContext
import at.petrak.hexcasting.api.spell.mishaps.MishapBadOffhandItem
import at.petrak.hexcasting.xplat.IXplatAbstractions
import net.minecraft.world.item.ItemStack
object OpColorize : SpellOperator {
override val argc = 0
@ -26,23 +27,20 @@ object OpColorize : SpellOperator {
)
}
return Triple(
Spell,
Spell(handStack),
ManaConstants.DUST_UNIT,
listOf()
)
}
private object Spell : RenderedSpell {
private data class Spell(val stack: ItemStack) : RenderedSpell {
override fun cast(ctx: CastingContext) {
val handStack = ctx.getHeldItemToOperateOn(IXplatAbstractions.INSTANCE::isColorizer).first.copy()
if (IXplatAbstractions.INSTANCE.isColorizer(handStack)) {
if (ctx.withdrawItem(handStack.item, 1, true)) {
if (ctx.withdrawItem(stack, 1, true)) {
IXplatAbstractions.INSTANCE.setColorizer(
ctx.caster,
FrozenColorizer(handStack, ctx.caster.uuid)
FrozenColorizer(stack, ctx.caster.uuid)
)
}
}
}
}
}

View file

@ -52,8 +52,6 @@ object OpDestroyWater : SpellOperator {
var successes = 0
while (todo.isNotEmpty() && successes <= MAX_DESTROY_COUNT) {
val here = todo.removeFirst()
val distFromFocus =
ctx.caster.position().distanceToSqr(Vec3.atCenterOf(here))
if (ctx.canEditBlockAt(here) && seen.add(here)) {
// never seen this pos in my life
val fluid = ctx.world.getFluidState(here)

View file

@ -8,6 +8,7 @@ import at.petrak.hexcasting.api.spell.SpellOperator
import at.petrak.hexcasting.api.spell.casting.CastingContext
import at.petrak.hexcasting.api.spell.mishaps.MishapBadOffhandItem
import at.petrak.hexcasting.xplat.IXplatAbstractions
import net.minecraft.world.item.ItemStack
class OpErase : SpellOperator {
override val argc = 0
@ -33,22 +34,15 @@ class OpErase : SpellOperator {
}
return Triple(
Spell,
Spell(handStack),
ManaConstants.DUST_UNIT, listOf()
)
}
private object Spell : RenderedSpell {
private data class Spell(val stack: ItemStack) : RenderedSpell {
override fun cast(ctx: CastingContext) {
val (handStack) = ctx.getHeldItemToOperateOn {
val hexHolder = IXplatAbstractions.INSTANCE.findHexHolder(it)
val datumHolder = IXplatAbstractions.INSTANCE.findDataHolder(it)
(hexHolder?.hasHex() == true) ||
(datumHolder?.writeDatum(null, true) == true)
}
val hexHolder = IXplatAbstractions.INSTANCE.findHexHolder(handStack)
val datumHolder = IXplatAbstractions.INSTANCE.findDataHolder(handStack)
val hexHolder = IXplatAbstractions.INSTANCE.findHexHolder(stack)
val datumHolder = IXplatAbstractions.INSTANCE.findDataHolder(stack)
if (hexHolder?.hasHex() == true)
hexHolder.clearHex()

View file

@ -2,11 +2,7 @@ package at.petrak.hexcasting.common.casting.operators.spells
import at.petrak.hexcasting.api.misc.ManaConstants
import at.petrak.hexcasting.api.mod.HexItemTags
import at.petrak.hexcasting.api.spell.getChecked
import at.petrak.hexcasting.api.spell.ParticleSpray
import at.petrak.hexcasting.api.spell.RenderedSpell
import at.petrak.hexcasting.api.spell.SpellDatum
import at.petrak.hexcasting.api.spell.SpellOperator
import at.petrak.hexcasting.api.spell.*
import at.petrak.hexcasting.api.spell.casting.CastingContext
import at.petrak.hexcasting.api.spell.mishaps.MishapBadItem
import at.petrak.hexcasting.api.spell.mishaps.MishapBadOffhandItem
@ -14,6 +10,7 @@ import at.petrak.hexcasting.api.utils.extractMana
import at.petrak.hexcasting.api.utils.isManaItem
import at.petrak.hexcasting.common.items.magic.ItemManaHolder
import at.petrak.hexcasting.common.lib.HexItems
import net.minecraft.world.InteractionHand
import net.minecraft.world.entity.item.ItemEntity
import net.minecraft.world.item.ItemStack
@ -59,14 +56,13 @@ object OpMakeBattery : SpellOperator {
)
}
return Triple(Spell(entity),
return Triple(Spell(entity, hand),
ManaConstants.CRYSTAL_UNIT, listOf(ParticleSpray.burst(entity.position(), 0.5)))
}
private data class Spell(val itemEntity: ItemEntity) : RenderedSpell {
private data class Spell(val itemEntity: ItemEntity, val hand: InteractionHand) : RenderedSpell {
override fun cast(ctx: CastingContext) {
val (handStack, hand) = ctx.getHeldItemToOperateOn { it.`is`(HexItemTags.PHIAL_BASE) }
if (handStack.`is`(HexItemTags.PHIAL_BASE) && itemEntity.isAlive) {
if (itemEntity.isAlive) {
val entityStack = itemEntity.item.copy()
val manaAmt = extractMana(entityStack, drainForBatteries = true)
if (manaAmt > 0) {

View file

@ -1,11 +1,6 @@
package at.petrak.hexcasting.common.casting.operators.spells
import at.petrak.hexcasting.api.spell.getChecked
import at.petrak.hexcasting.api.spell.ParticleSpray
import at.petrak.hexcasting.api.spell.RenderedSpell
import at.petrak.hexcasting.api.spell.SpellDatum
import at.petrak.hexcasting.api.spell.SpellList
import at.petrak.hexcasting.api.spell.SpellOperator
import at.petrak.hexcasting.api.spell.*
import at.petrak.hexcasting.api.spell.casting.CastingContext
import at.petrak.hexcasting.api.spell.mishaps.MishapBadItem
import at.petrak.hexcasting.api.spell.mishaps.MishapBadOffhandItem
@ -15,6 +10,7 @@ import at.petrak.hexcasting.api.utils.isManaItem
import at.petrak.hexcasting.common.items.magic.ItemPackagedHex
import at.petrak.hexcasting.xplat.IXplatAbstractions
import net.minecraft.world.entity.item.ItemEntity
import net.minecraft.world.item.ItemStack
class OpMakePackagedSpell<T : ItemPackagedHex>(val itemType: T, val cost: Int) : SpellOperator {
override val argc = 2
@ -53,13 +49,12 @@ class OpMakePackagedSpell<T : ItemPackagedHex>(val itemType: T, val cost: Int) :
if (trueName != null)
throw MishapOthersName(trueName)
return Triple(Spell(entity, patterns), cost, listOf(ParticleSpray.burst(entity.position(), 0.5)))
return Triple(Spell(entity, patterns, handStack), cost, listOf(ParticleSpray.burst(entity.position(), 0.5)))
}
private inner class Spell(val itemEntity: ItemEntity, val patterns: List<SpellDatum<*>>) : RenderedSpell {
private inner class Spell(val itemEntity: ItemEntity, val patterns: List<SpellDatum<*>>, val stack: ItemStack) : RenderedSpell {
override fun cast(ctx: CastingContext) {
val (handStack) = ctx.getHeldItemToOperateOn { it.`is`(itemType) }
val hexHolder = IXplatAbstractions.INSTANCE.findHexHolder(handStack)
val hexHolder = IXplatAbstractions.INSTANCE.findHexHolder(stack)
if (hexHolder != null
&& !hexHolder.hasHex()
&& itemEntity.isAlive

View file

@ -29,13 +29,8 @@ object OpPlaceBlock : SpellOperator {
val pos = BlockPos(target)
// TODO: does this even work?? why are we returning null?? what does that *do*?
if (!ctx.canEditBlockAt(pos))
return null
val blockHit = BlockHitResult(
Vec3.ZERO, ctx.caster.direction, pos, false
target, ctx.caster.direction, pos, false
)
val itemUseCtx = UseOnContext(ctx.caster, ctx.castingHand, blockHit)
val placeContext = BlockPlaceContext(itemUseCtx)
@ -59,7 +54,7 @@ object OpPlaceBlock : SpellOperator {
return
val blockHit = BlockHitResult(
Vec3.ZERO, ctx.caster.direction, pos, false
vec, ctx.caster.direction, pos, false
)
val bstate = ctx.world.getBlockState(pos)
@ -80,13 +75,12 @@ object OpPlaceBlock : SpellOperator {
val itemUseCtx = UseOnContext(ctx.caster, ctx.castingHand, blockHit)
val placeContext = BlockPlaceContext(itemUseCtx)
if (bstate.canBeReplaced(placeContext)) {
val placee = placeeStack.item as BlockItem
if (ctx.withdrawItem(placee, 1, false)) {
if (ctx.withdrawItem(placeeStack, 1, false)) {
val res = spoofedStack.useOn(placeContext)
ctx.caster.setItemInHand(ctx.castingHand, oldStack)
if (res != InteractionResult.FAIL) {
ctx.withdrawItem(placee, 1, true)
ctx.withdrawItem(placeeStack, 1, true)
ctx.world.playSound(
ctx.caster,

View file

@ -9,6 +9,7 @@ import at.petrak.hexcasting.api.utils.extractMana
import at.petrak.hexcasting.api.utils.isManaItem
import at.petrak.hexcasting.xplat.IXplatAbstractions
import net.minecraft.world.entity.item.ItemEntity
import net.minecraft.world.item.ItemStack
object OpRecharge : SpellOperator {
override val argc = 1
@ -44,19 +45,15 @@ object OpRecharge : SpellOperator {
return null
return Triple(
Spell(entity),
Spell(entity, handStack),
ManaConstants.SHARD_UNIT,
listOf(ParticleSpray.burst(entity.position(), 0.5))
)
}
private data class Spell(val itemEntity: ItemEntity) : RenderedSpell {
private data class Spell(val itemEntity: ItemEntity, val stack: ItemStack) : RenderedSpell {
override fun cast(ctx: CastingContext) {
val (handStack) = ctx.getHeldItemToOperateOn {
val mana = IXplatAbstractions.INSTANCE.findManaHolder(it)
mana != null && mana.canRecharge() && mana.insertMana(-1, true) != 0
}
val mana = IXplatAbstractions.INSTANCE.findManaHolder(handStack)
val mana = IXplatAbstractions.INSTANCE.findManaHolder(stack)
if (mana != null && itemEntity.isAlive) {
val entityStack = itemEntity.item.copy()

View file

@ -25,7 +25,7 @@ object OpBrainsweep : SpellOperator {
override fun execute(
args: List<SpellDatum<*>>,
ctx: CastingContext
): Triple<RenderedSpell, Int, List<ParticleSpray>> {
): Triple<RenderedSpell, Int, List<ParticleSpray>>? {
val sacrifice = args.getChecked<Villager>(0, argc)
val pos = args.getChecked<Vec3>(1, argc)
ctx.assertVecInRange(pos)
@ -35,6 +35,10 @@ object OpBrainsweep : SpellOperator {
throw MishapAlreadyBrainswept(sacrifice)
val bpos = BlockPos(pos)
if (!ctx.canEditBlockAt(bpos))
return null
val state = ctx.world.getBlockState(bpos)
val recman = ctx.world.recipeManager
@ -56,9 +60,8 @@ object OpBrainsweep : SpellOperator {
val recipe: BrainsweepRecipe
) : RenderedSpell {
override fun cast(ctx: CastingContext) {
if (ctx.canEditBlockAt(pos)) {
ctx.world.setBlockAndUpdate(pos, BrainsweepRecipe.copyProperties(state, recipe.result))
}
Brainsweeping.brainsweep(sacrifice)
if (HexConfig.server().doVillagersTakeOffenseAtMindMurder()) {
sacrifice.tellWitnessesThatIWasMurdered(ctx.caster)

View file

@ -46,7 +46,7 @@ object OpTeleport : SpellOperator {
override fun cast(ctx: CastingContext) {
val distance = delta.length()
if (distance < 32768.0) {
OpTeleport.teleportRespectSticky(teleportee, delta)
teleportRespectSticky(teleportee, delta)
}
if (teleportee is ServerPlayer && teleportee == ctx.caster) {