From afd437d9cf38a88da7cef9f2fc0a7f81f4b43d4d Mon Sep 17 00:00:00 2001 From: Sollace Date: Wed, 3 Mar 2021 20:06:57 +0200 Subject: [PATCH] Polish up the inferno spell and refactor block state mapping a little --- .../ability/magic/spell/FireSpell.java | 23 ++++----- .../ability/magic/spell/IceSpell.java | 2 +- .../ability/magic/spell/InfernoSpell.java | 23 +++++++-- .../ability/magic/spell/ScorchSpell.java | 2 +- .../block/state/BlockStateConverter.java | 3 +- .../unicopia/block/state/BlockStateMap.java | 15 +++++- .../unicopia/block/state/StateMapping.java | 50 +++++++++++++++---- .../unicopia/block/state/StateMaps.java | 46 ++++++++++++----- 8 files changed, 122 insertions(+), 42 deletions(-) diff --git a/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/FireSpell.java b/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/FireSpell.java index 3bbba357..571c43cc 100644 --- a/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/FireSpell.java +++ b/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/FireSpell.java @@ -6,6 +6,7 @@ import com.minelittlepony.unicopia.ability.magic.Caster; import com.minelittlepony.unicopia.ability.magic.Magical; import com.minelittlepony.unicopia.ability.magic.Thrown; import com.minelittlepony.unicopia.block.state.StateMaps; +import com.minelittlepony.unicopia.particle.ParticleUtils; import com.minelittlepony.unicopia.projectile.MagicProjectileEntity; import com.minelittlepony.unicopia.util.MagicalDamageSource; import com.minelittlepony.unicopia.util.PosHelper; @@ -37,7 +38,6 @@ import net.minecraft.world.explosion.Explosion.DestructionType; */ public class FireSpell extends AbstractSpell implements Thrown, Attached { - private static final Shape VISUAL_EFFECT_RANGE = new Sphere(false, 0.5); private static final Shape EFFECT_RANGE = new Sphere(false, 4); protected FireSpell(SpellType type) { @@ -69,7 +69,7 @@ public class FireSpell extends AbstractSpell implements Thrown, Attached { } protected void generateParticles(Caster source) { - source.spawnParticles(VISUAL_EFFECT_RANGE, source.getLevel().get() * 6, pos -> { + source.spawnParticles(EFFECT_RANGE, (1 + source.getLevel().get()) * 6, pos -> { source.addParticle(ParticleTypes.LARGE_SMOKE, pos, Vec3d.ZERO); }); } @@ -79,13 +79,8 @@ public class FireSpell extends AbstractSpell implements Thrown, Attached { Block id = state.getBlock(); if (id != Blocks.AIR) { - if (id == Blocks.ICE || id == Blocks.PACKED_ICE) { - world.setBlockState(pos, (world.getDimension().isUltrawarm() ? Blocks.AIR : Blocks.WATER).getDefaultState()); - playEffect(world, pos); - - return true; - } else if (id == Blocks.NETHERRACK) { - if (world.getBlockState(pos.up()).getMaterial() == Material.AIR) { + if (id == Blocks.NETHERRACK) { + if (world.isAir(pos.up())) { if (world.random.nextInt(300) == 0) { world.setBlockState(pos.up(), Blocks.FIRE.getDefaultState()); @@ -114,7 +109,7 @@ public class FireSpell extends AbstractSpell implements Thrown, Attached { return true; } } else { - BlockState newState = StateMaps.FIRE_AFFECTED.getConverted(state); + BlockState newState = StateMaps.FIRE_AFFECTED.getConverted(world, state); if (!state.equals(newState)) { world.setBlockState(pos, newState, 3); @@ -175,10 +170,14 @@ public class FireSpell extends AbstractSpell implements Thrown, Attached { int y = pos.getY(); int z = pos.getZ(); - world.playSound(x + 0.5F, y + 0.5F, z + 0.5F, SoundEvents.BLOCK_FURNACE_FIRE_CRACKLE, SoundCategory.AMBIENT, 0.5F, 2.6F + (world.random.nextFloat() - world.random.nextFloat()) * 0.8F, true); + world.playSound(null, pos, SoundEvents.BLOCK_FURNACE_FIRE_CRACKLE, SoundCategory.AMBIENT, 0.5F, 2.6F + (world.random.nextFloat() - world.random.nextFloat()) * 0.8F); for (int i = 0; i < 8; ++i) { - world.addParticle(ParticleTypes.LARGE_SMOKE, x + Math.random(), y + Math.random(), z + Math.random(), 0, 0, 0); + ParticleUtils.spawnParticle(ParticleTypes.LARGE_SMOKE, world, new Vec3d( + x + Math.random(), + y + Math.random(), + z + Math.random() + ), Vec3d.ZERO); } } diff --git a/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/IceSpell.java b/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/IceSpell.java index 74e53f1e..f35eab78 100644 --- a/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/IceSpell.java +++ b/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/IceSpell.java @@ -69,7 +69,7 @@ public class IceSpell extends AbstractSpell implements Thrown, Attached { BlockState state = world.getBlockState(pos); Block id = state.getBlock(); - BlockState converted = StateMaps.ICE_AFFECTED.getConverted(state); + BlockState converted = StateMaps.ICE_AFFECTED.getConverted(world, state); if (!state.equals(converted)) { world.setBlockState(pos, converted, 3); diff --git a/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/InfernoSpell.java b/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/InfernoSpell.java index 31c4716d..bf6d0ebf 100644 --- a/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/InfernoSpell.java +++ b/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/InfernoSpell.java @@ -1,12 +1,15 @@ package com.minelittlepony.unicopia.ability.magic.spell; import com.minelittlepony.unicopia.ability.magic.Caster; +import com.minelittlepony.unicopia.block.state.BlockStateConverter; import com.minelittlepony.unicopia.block.state.StateMaps; import com.minelittlepony.unicopia.util.MagicalDamageSource; import com.minelittlepony.unicopia.util.shape.Shape; import com.minelittlepony.unicopia.util.shape.Sphere; import net.minecraft.block.BlockState; +import net.minecraft.block.DoorBlock; +import net.minecraft.block.enums.DoubleBlockHalf; import net.minecraft.entity.Entity; import net.minecraft.entity.LivingEntity; import net.minecraft.entity.damage.DamageSource; @@ -22,6 +25,10 @@ public class InfernoSpell extends FireSpell { @Override public boolean onThrownTick(Caster source) { + if (source.isClient()) { + generateParticles(source); + } + World w = source.getWorld(); if (!w.isClient) { @@ -30,14 +37,24 @@ public class InfernoSpell extends FireSpell { Vec3d origin = source.getOriginVector(); + BlockStateConverter converter = w.getDimension().isUltrawarm() ? StateMaps.HELLFIRE_AFFECTED.getInverse() : StateMaps.HELLFIRE_AFFECTED; + for (int i = 0; i < radius; i++) { BlockPos pos = new BlockPos(shape.computePoint(w.random).add(origin)); BlockState state = w.getBlockState(pos); - BlockState newState = StateMaps.HELLFIRE_AFFECTED.getConverted(state); + BlockState newState = converter.getConverted(w, state); if (!state.equals(newState)) { - w.setBlockState(pos, newState, 3); + + if (newState.getBlock() instanceof DoorBlock) { + boolean lower = newState.get(DoorBlock.HALF) == DoubleBlockHalf.LOWER; + BlockPos other = lower ? pos.up() : pos.down(); + + w.setBlockState(other, newState.with(DoorBlock.HALF, lower ? DoubleBlockHalf.UPPER : DoubleBlockHalf.LOWER), 16 | 2); + } + + w.setBlockState(pos, newState, 16 | 2); playEffect(w, pos); } @@ -54,7 +71,7 @@ public class InfernoSpell extends FireSpell { } } } - return false; + return true; } @Override diff --git a/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/ScorchSpell.java b/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/ScorchSpell.java index 4eb16a41..fda2218f 100644 --- a/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/ScorchSpell.java +++ b/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/ScorchSpell.java @@ -27,7 +27,7 @@ public class ScorchSpell extends FireSpell { BlockState state = source.getWorld().getBlockState(pos); - BlockState newState = StateMaps.FIRE_AFFECTED.getConverted(state); + BlockState newState = StateMaps.FIRE_AFFECTED.getConverted(source.getWorld(), state); if (!state.equals(newState)) { source.getWorld().setBlockState(pos, newState, 3); diff --git a/src/main/java/com/minelittlepony/unicopia/block/state/BlockStateConverter.java b/src/main/java/com/minelittlepony/unicopia/block/state/BlockStateConverter.java index 6705a0e0..15538ba6 100644 --- a/src/main/java/com/minelittlepony/unicopia/block/state/BlockStateConverter.java +++ b/src/main/java/com/minelittlepony/unicopia/block/state/BlockStateConverter.java @@ -4,6 +4,7 @@ import javax.annotation.Nonnull; import javax.annotation.Nullable; import net.minecraft.block.BlockState; +import net.minecraft.world.World; public interface BlockStateConverter { /** @@ -23,5 +24,5 @@ public interface BlockStateConverter { * @return The converted state if there is one, otherwise null */ @Nonnull - BlockState getConverted(@Nonnull BlockState state); + BlockState getConverted(World world, @Nonnull BlockState state); } diff --git a/src/main/java/com/minelittlepony/unicopia/block/state/BlockStateMap.java b/src/main/java/com/minelittlepony/unicopia/block/state/BlockStateMap.java index 0f5720d7..f6ec0900 100644 --- a/src/main/java/com/minelittlepony/unicopia/block/state/BlockStateMap.java +++ b/src/main/java/com/minelittlepony/unicopia/block/state/BlockStateMap.java @@ -9,6 +9,8 @@ import javax.annotation.Nullable; import net.minecraft.block.Block; import net.minecraft.block.BlockState; import net.minecraft.state.property.Property; +import net.minecraft.tag.Tag; +import net.minecraft.world.World; /** * A collection of block-state mappings. @@ -21,10 +23,19 @@ class BlockStateMap extends ArrayList implements BlockStateConvert add(StateMapping.removeBlock(mapper)); } + public void removeBlock(Block from) { + add(StateMapping.removeBlock(from)); + } + + public void replaceBlock(Block from, Block to) { add(StateMapping.replaceBlock(from, to)); } + public void replaceBlock(Tag from, Block to) { + add(StateMapping.replaceBlock(from, to)); + } + public > void replaceProperty(Block block, Property property, T from, T to) { add(StateMapping.replaceProperty(block, property, from, to)); } @@ -40,10 +51,10 @@ class BlockStateMap extends ArrayList implements BlockStateConvert @Override @Nonnull - public BlockState getConverted(@Nonnull BlockState state) { + public BlockState getConverted(World world, @Nonnull BlockState state) { for (StateMapping i : this) { if (i.test(state)) { - return i.apply(state); + return i.apply(world, state); } } diff --git a/src/main/java/com/minelittlepony/unicopia/block/state/StateMapping.java b/src/main/java/com/minelittlepony/unicopia/block/state/StateMapping.java index c92371c0..6bb4bd32 100644 --- a/src/main/java/com/minelittlepony/unicopia/block/state/StateMapping.java +++ b/src/main/java/com/minelittlepony/unicopia/block/state/StateMapping.java @@ -1,5 +1,7 @@ package com.minelittlepony.unicopia.block.state; +import java.util.Random; +import java.util.function.BiFunction; import java.util.function.Function; import java.util.function.Predicate; @@ -9,40 +11,68 @@ import net.minecraft.block.Block; import net.minecraft.block.BlockState; import net.minecraft.block.Blocks; import net.minecraft.state.property.Property; +import net.minecraft.tag.Tag; +import net.minecraft.world.World; -interface StateMapping extends Predicate, Function { +interface StateMapping extends Predicate, BiFunction { + + Random RNG = new Random(); static StateMapping removeBlock(Predicate mapper) { return build( mapper, - s -> Blocks.AIR.getDefaultState()); + (w, s) -> Blocks.AIR.getDefaultState()); } + static StateMapping removeBlock(Block from) { + return removeBlock(s -> s.isOf(from)); + } + + static StateMapping replaceBlock(Tag tag, Block to) { + return build( + s -> s.isIn(tag), + (w, s) -> to.getDefaultState(), + s -> build( + p -> p.isOf(to), + (w, p) -> tag.getRandom(w.random).getDefaultState() + ) + ); + } + + @SuppressWarnings("unchecked") static StateMapping replaceBlock(Block from, Block to) { return build( s -> s.getBlock() == from, - s -> to.getDefaultState(), + (w, s) -> { + BlockState newState = to.getDefaultState(); + for (@SuppressWarnings("rawtypes") Property i : s.getProperties()) { + if (newState.contains(i)) { + newState = newState.with(i, s.get(i)); + } + } + return newState; + }, s -> replaceBlock(to, from)); } static > StateMapping replaceProperty(Block block, Property property, T from, T to) { return build( s -> s.getBlock() == block && s.get(property) == from, - s -> s.with(property, to), + (w, s) -> s.with(property, to), s -> replaceProperty(block, property, to, from)); } static > StateMapping setProperty(Block block, Property property, T to) { return build( s -> s.getBlock() == block, - s -> s.with(property, to)); + (w, s) -> s.with(property, to)); } - static StateMapping build(Predicate predicate, Function converter) { + static StateMapping build(Predicate predicate, BiFunction converter) { return build(predicate, converter, s -> s); } - static StateMapping build(Predicate predicate, Function converter, Function inverter) { + static StateMapping build(Predicate predicate, BiFunction converter, Function inverter) { return new StateMapping() { private StateMapping inverse; @@ -52,8 +82,8 @@ interface StateMapping extends Predicate, Function, Function { a.add(StateMapping.build( s -> s.getMaterial() == Material.WATER, - s -> Blocks.ICE.getDefaultState())); + (w, s) -> Blocks.ICE.getDefaultState())); a.add(StateMapping.build( s -> s.getMaterial() == Material.LAVA, - s -> Blocks.OBSIDIAN.getDefaultState())); + (w, s) -> Blocks.OBSIDIAN.getDefaultState())); a.add(StateMapping.build( s -> s.getBlock() == Blocks.SNOW, - s -> { + (w, s) -> { s = s.cycle(SnowBlock.LAYERS); if (s.get(SnowBlock.LAYERS) >= 7) { return Blocks.SNOW_BLOCK.getDefaultState(); @@ -53,8 +54,11 @@ public class StateMaps { }), "infestation"); public static final BlockStateConverter FIRE_AFFECTED = register(Util.make(new BlockStateMap(), a -> { - a.removeBlock(s -> s.getBlock() == Blocks.SNOW || s.getBlock() == Blocks.SNOW_BLOCK); + a.removeBlock(Blocks.SNOW); + a.removeBlock(Blocks.SNOW_BLOCK); a.removeBlock(s -> s.getBlock() instanceof PlantBlock); + a.replaceBlock(Blocks.ICE, Blocks.WATER); + a.replaceBlock(Blocks.PACKED_ICE, Blocks.WATER); a.replaceBlock(Blocks.CLAY, Blocks.BROWN_CONCRETE); a.replaceBlock(Blocks.OBSIDIAN, Blocks.LAVA); a.replaceBlock(Blocks.GRASS_BLOCK, Blocks.DIRT); @@ -66,24 +70,42 @@ public class StateMaps { a.setProperty(Blocks.FARMLAND, FarmlandBlock.MOISTURE, 0); a.add(StateMapping.build( s -> s.getBlock() == Blocks.DIRT, - s -> (Math.random() <= 0.15 ? Blocks.COARSE_DIRT.getDefaultState() : s))); + (w, s) -> (w.random.nextFloat() <= 0.15 ? Blocks.COARSE_DIRT.getDefaultState() : s))); }), "fire"); - public static final BlockStateConverter HELLFIRE_AFFECTED = register(Util.make(new BlockStateMap(), a -> { - a.add(StateMapping.build( - s -> s.getBlock() == Blocks.GRASS_BLOCK || s.getBlock() == Blocks.DIRT || s.getBlock() == Blocks.STONE, - s -> Blocks.NETHERRACK.getDefaultState())); + public static final ReversableBlockStateConverter HELLFIRE_AFFECTED = register(Util.make(new ReversableBlockStateMap(), a -> { + a.replaceBlock(Blocks.GRASS_BLOCK, Blocks.WARPED_NYLIUM); + a.replaceBlock(Blocks.STONE, Blocks.NETHERRACK); a.replaceBlock(Blocks.SAND, Blocks.SOUL_SAND); a.replaceBlock(Blocks.GRAVEL, Blocks.SOUL_SAND); + a.replaceBlock(Blocks.DIRT, Blocks.SOUL_SOIL); + a.replaceBlock(Blocks.COARSE_DIRT, Blocks.SOUL_SOIL); + a.replaceBlock(Blocks.TORCH, Blocks.SOUL_TORCH); + a.replaceBlock(Blocks.WALL_TORCH, Blocks.SOUL_WALL_TORCH); + a.replaceBlock(Blocks.OAK_LOG, Blocks.WARPED_STEM); + a.replaceBlock(Blocks.STRIPPED_OAK_LOG, Blocks.STRIPPED_WARPED_STEM); + a.replaceBlock(Blocks.STRIPPED_OAK_WOOD, Blocks.STRIPPED_WARPED_HYPHAE); + a.replaceBlock(Blocks.OAK_PLANKS, Blocks.WARPED_PLANKS); + a.replaceBlock(Blocks.OAK_DOOR, Blocks.WARPED_DOOR); + a.replaceBlock(Blocks.OAK_STAIRS, Blocks.WARPED_STAIRS); + a.replaceBlock(Blocks.OAK_TRAPDOOR, Blocks.WARPED_TRAPDOOR); + a.replaceBlock(Blocks.OAK_PRESSURE_PLATE, Blocks.WARPED_PRESSURE_PLATE); + a.replaceBlock(Blocks.OAK_BUTTON, Blocks.WARPED_BUTTON); + a.replaceBlock(Blocks.OAK_FENCE, Blocks.WARPED_FENCE); + a.replaceBlock(Blocks.OAK_FENCE_GATE, Blocks.WARPED_FENCE_GATE); + a.replaceBlock(BlockTags.LEAVES, Blocks.WARPED_HYPHAE); a.add(StateMapping.build( s -> s.getMaterial() == Material.WATER, - s -> Blocks.OBSIDIAN.getDefaultState())); + (w, s) -> Blocks.OBSIDIAN.getDefaultState(), + s -> StateMapping.replaceBlock(Blocks.OBSIDIAN, Blocks.WATER))); a.add(StateMapping.build( s -> s.getBlock() instanceof PlantBlock, - s -> Blocks.NETHER_WART.getDefaultState())); + (w, s) -> Blocks.NETHER_WART.getDefaultState(), + s -> StateMapping.replaceBlock(Blocks.NETHER_WART, Blocks.GRASS))); a.add(StateMapping.build( s -> (s.getBlock() != Blocks.NETHER_QUARTZ_ORE) && (s.getBlock() instanceof OreBlock), - s -> Blocks.NETHER_QUARTZ_ORE.getDefaultState())); + (w, s) -> Blocks.NETHER_QUARTZ_ORE.getDefaultState(), + s -> StateMapping.replaceBlock(Blocks.NETHER_QUARTZ_ORE, Blocks.COAL_ORE))); }), "hellfire"); private static T register(T value, String name) {