This commit is contained in:
gamma-delta 2022-07-26 13:42:52 -05:00
parent 81e5f8581e
commit 33b50f4a82
12 changed files with 68 additions and 35 deletions

View file

@ -16,6 +16,7 @@ import net.minecraft.world.entity.Entity
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
import java.util.function.Predicate
import kotlin.math.min
@ -83,7 +84,8 @@ data class CastingContext(
return entitiesGivenMotion.contains(target)
}
fun isVecInWorld(vec: Vec3) = world.isInWorldBounds(BlockPos(vec)) && world.worldBorder.isWithinBounds(vec.x, vec.z, 0.5)
fun isVecInWorld(vec: Vec3) =
world.isInWorldBounds(BlockPos(vec)) && world.worldBorder.isWithinBounds(vec.x, vec.z, 0.5)
fun isVecInRange(vec: Vec3): Boolean {
val sentinel = IXplatAbstractions.INSTANCE.getSentinel(caster)
@ -117,6 +119,12 @@ data class CastingContext(
return isVecInRange(entity.position())
}
fun canEditBlockAt(pos: BlockPos): Boolean {
return this.isVecInRange(Vec3.atCenterOf(pos))
&& this.caster.gameMode.gameModeForPlayer != GameType.ADVENTURE
&& this.world.mayInteract(this.caster, pos)
}
/**
* Return the slot from which to take blocks and items.
*/

View file

@ -31,7 +31,7 @@ object OpBreakBlock : SpellOperator {
override fun cast(ctx: CastingContext) {
val pos = BlockPos(v)
if (!ctx.world.mayInteract(ctx.caster, pos))
if (!ctx.canEditBlockAt(pos))
return
val blockstate = ctx.world.getBlockState(pos)

View file

@ -44,7 +44,7 @@ class OpConjure(val light: Boolean) : SpellOperator {
override fun cast(ctx: CastingContext) {
val pos = BlockPos(target)
if (!ctx.world.mayInteract(ctx.caster, pos))
if (!ctx.canEditBlockAt(pos))
return
val placeContext = DirectionalPlaceContext(ctx.world, pos, Direction.DOWN, ItemStack.EMPTY, Direction.UP)

View file

@ -35,7 +35,14 @@ object OpCreateWater : SpellOperator {
override fun cast(ctx: CastingContext) {
val pos = BlockPos(target)
if (!ctx.world.mayInteract(ctx.caster, pos)|| !IXplatAbstractions.INSTANCE.isPlacingAllowed(ctx.world, pos, ItemStack(Items.WATER_BUCKET), ctx.caster))
if (!ctx.canEditBlockAt(pos)
|| !IXplatAbstractions.INSTANCE.isPlacingAllowed(
ctx.world,
pos,
ItemStack(Items.WATER_BUCKET),
ctx.caster
)
)
return
val state = ctx.world.getBlockState(pos)

View file

@ -54,7 +54,7 @@ object OpDestroyWater : SpellOperator {
val here = todo.removeFirst()
val distFromFocus =
ctx.caster.position().distanceToSqr(Vec3.atCenterOf(here))
if (distFromFocus < Operator.MAX_DISTANCE * Operator.MAX_DISTANCE && seen.add(here) && ctx.world.mayInteract(ctx.caster, here)) {
if (ctx.canEditBlockAt(here) && seen.add(here)) {
// never seen this pos in my life
val fluid = ctx.world.getFluidState(here)
if (fluid != Fluids.EMPTY.defaultFluidState()) {
@ -88,25 +88,25 @@ object OpDestroyWater : SpellOperator {
false
}
if (success) {
ctx.world.sendParticles(
ParticleTypes.SMOKE,
here.x + 0.5 + Math.random() * 0.4 - 0.2,
here.y + 0.5 + Math.random() * 0.4 - 0.2,
here.z + 0.5 + Math.random() * 0.4 - 0.2,
2,
0.0,
0.05,
0.0,
0.0
)
successes++
for (dir in Direction.values()) {
todo.add(here.relative(dir))
if (success) {
ctx.world.sendParticles(
ParticleTypes.SMOKE,
here.x + 0.5 + Math.random() * 0.4 - 0.2,
here.y + 0.5 + Math.random() * 0.4 - 0.2,
here.z + 0.5 + Math.random() * 0.4 - 0.2,
2,
0.0,
0.05,
0.0,
0.0
)
successes++
for (dir in Direction.values()) {
todo.add(here.relative(dir))
}
}
}
}
}
}
}

View file

@ -35,8 +35,9 @@ object OpEdifySapling : SpellOperator {
private data class Spell(val pos: BlockPos) : RenderedSpell {
override fun cast(ctx: CastingContext) {
val blockstate = ctx.world.getBlockState(pos)
if (!ctx.world.mayInteract(ctx.caster, pos) ||
!IXplatAbstractions.INSTANCE.isBreakingAllowed(ctx.world, pos, blockstate, ctx.caster))
if (!ctx.canEditBlockAt(pos) ||
!IXplatAbstractions.INSTANCE.isBreakingAllowed(ctx.world, pos, blockstate, ctx.caster)
)
return
val bs = ctx.world.getBlockState(pos)

View file

@ -30,7 +30,8 @@ class OpExplode(val fire: Boolean) : SpellOperator {
private data class Spell(val pos: Vec3, val strength: Double, val fire: Boolean) : RenderedSpell {
override fun cast(ctx: CastingContext) {
if (!ctx.world.mayInteract(ctx.caster, BlockPos(pos)))
// TODO: you can use this to explode things *outside* of the worldborder?
if (!ctx.canEditBlockAt(BlockPos(pos)))
return
ctx.world.explode(

View file

@ -50,11 +50,7 @@ object OpExtinguish : SpellOperator {
ctx.caster.position().distanceToSqr(Vec3.atCenterOf(here))
val distFromTarget =
target.distanceTo(Vec3.atCenterOf(here)) // max distance to prevent runaway shenanigans
if (distFromFocus < Operator.MAX_DISTANCE * Operator.MAX_DISTANCE && seen.add(here) && distFromTarget < 10 && ctx.world.mayInteract(
ctx.caster,
here
)
) {
if (ctx.canEditBlockAt(here) && distFromTarget < 10 && seen.add(here)) {
// never seen this pos in my life
val blockstate = ctx.world.getBlockState(here)
if (IXplatAbstractions.INSTANCE.isBreakingAllowed(ctx.world, here, blockstate, ctx.caster)) {

View file

@ -38,7 +38,13 @@ object OpIgnite : SpellOperator {
// steal petra code that steals bucket code
val maxwell = Items.FIRE_CHARGE
if (!ctx.world.mayInteract(ctx.caster, pos) || !IXplatAbstractions.INSTANCE.isPlacingAllowed(ctx.world, pos, ItemStack(maxwell), ctx.caster))
if (!ctx.canEditBlockAt(pos) || !IXplatAbstractions.INSTANCE.isPlacingAllowed(
ctx.world,
pos,
ItemStack(maxwell),
ctx.caster
)
)
return
if (maxwell is FireChargeItem) {

View file

@ -29,7 +29,8 @@ object OpPlaceBlock : SpellOperator {
val pos = BlockPos(target)
if (!ctx.world.mayInteract(ctx.caster, pos))
// TODO: does this even work?? why are we returning null?? what does that *do*?
if (!ctx.canEditBlockAt(pos))
return null
@ -54,7 +55,7 @@ object OpPlaceBlock : SpellOperator {
override fun cast(ctx: CastingContext) {
val pos = BlockPos(vec)
if (!ctx.world.mayInteract(ctx.caster, pos))
if (!ctx.canEditBlockAt(pos))
return
val blockHit = BlockHitResult(

View file

@ -49,9 +49,16 @@ object OpBrainsweep : SpellOperator {
)
}
private data class Spell(val pos: BlockPos, val state: BlockState, val sacrifice: Villager, val recipe: BrainsweepRecipe) : RenderedSpell {
private data class Spell(
val pos: BlockPos,
val state: BlockState,
val sacrifice: Villager,
val recipe: BrainsweepRecipe
) : RenderedSpell {
override fun cast(ctx: CastingContext) {
ctx.world.setBlockAndUpdate(pos, BrainsweepRecipe.copyProperties(state, recipe.result))
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

@ -35,7 +35,13 @@ object OpCreateLava : SpellOperator {
override fun cast(ctx: CastingContext) {
val pos = BlockPos(target)
if (!ctx.world.mayInteract(ctx.caster, pos)|| !IXplatAbstractions.INSTANCE.isPlacingAllowed(ctx.world, pos, ItemStack(Items.LAVA_BUCKET), ctx.caster))
if (!ctx.canEditBlockAt(pos) || !IXplatAbstractions.INSTANCE.isPlacingAllowed(
ctx.world,
pos,
ItemStack(Items.LAVA_BUCKET),
ctx.caster
)
)
return
val state = ctx.world.getBlockState(pos)