Use a single implementation for converting blocks

This commit is contained in:
Sollace 2021-03-03 20:31:34 +02:00
parent 8d0552995b
commit c21e492482
6 changed files with 78 additions and 59 deletions

View file

@ -17,7 +17,6 @@ import com.minelittlepony.unicopia.util.shape.Sphere;
import net.minecraft.block.Block;
import net.minecraft.block.BlockState;
import net.minecraft.block.Blocks;
import net.minecraft.block.Material;
import net.minecraft.block.RedstoneWireBlock;
import net.minecraft.entity.Entity;
import net.minecraft.entity.ItemEntity;
@ -76,10 +75,9 @@ public class FireSpell extends AbstractSpell implements Thrown, Attached {
protected boolean applyBlocks(World world, BlockPos pos) {
BlockState state = world.getBlockState(pos);
Block id = state.getBlock();
if (id != Blocks.AIR) {
if (id == Blocks.NETHERRACK) {
if (!state.isAir()) {
if (state.isOf(Blocks.NETHERRACK)) {
if (world.isAir(pos.up())) {
if (world.random.nextInt(300) == 0) {
@ -88,7 +86,7 @@ public class FireSpell extends AbstractSpell implements Thrown, Attached {
return true;
}
} else if (id == Blocks.REDSTONE_WIRE) {
} else if (state.isOf(Blocks.REDSTONE_WIRE)) {
int power = world.random.nextInt(5) == 3 ? 15 : 3;
sendPower(world, pos, power, 3, 0);
@ -102,23 +100,17 @@ public class FireSpell extends AbstractSpell implements Thrown, Attached {
return true;
}
} else if (state.isIn(BlockTags.LEAVES)) {
if (world.getBlockState(pos.up()).getMaterial() == Material.AIR) {
if (world.isAir(pos.up())) {
world.setBlockState(pos.up(), Blocks.FIRE.getDefaultState());
playEffect(world, pos);
return true;
}
} else {
BlockState newState = StateMaps.FIRE_AFFECTED.getConverted(world, state);
if (!state.equals(newState)) {
world.setBlockState(pos, newState, 3);
} else if (StateMaps.FIRE_AFFECTED.convert(world, pos)) {
playEffect(world, pos);
return true;
}
}
}
return false;
}

View file

@ -4,6 +4,7 @@ import com.minelittlepony.unicopia.ability.magic.Attached;
import com.minelittlepony.unicopia.ability.magic.Caster;
import com.minelittlepony.unicopia.ability.magic.Thrown;
import com.minelittlepony.unicopia.block.state.StateMaps;
import com.minelittlepony.unicopia.particle.ParticleUtils;
import com.minelittlepony.unicopia.util.MagicalDamageSource;
import com.minelittlepony.unicopia.util.PosHelper;
import com.minelittlepony.unicopia.util.VecHelper;
@ -43,7 +44,14 @@ public class IceSpell extends AbstractSpell implements Thrown, Attached {
LivingEntity owner = source.getMaster();
PosHelper.getAllInRegionMutable(source.getOrigin(), effect_range)
.forEach(i -> applyBlockSingle(owner, source.getWorld(), i));
.forEach(i -> {
if (applyBlockSingle(owner, source.getWorld(), i)) {
ParticleUtils.spawnParticle(ParticleTypes.SPLASH, source.getWorld(), new Vec3d(
i.getX() + source.getWorld().random.nextFloat(),
i.getY() + 1,
i.getZ() + source.getWorld().random.nextFloat()), Vec3d.ZERO);
}
});
return applyEntities(source.getMaster(), source.getWorld(), source.getOriginVector());
}
@ -65,25 +73,28 @@ public class IceSpell extends AbstractSpell implements Thrown, Attached {
return true;
}
private void applyBlockSingle(Entity owner, World world, BlockPos pos) {
private boolean applyBlockSingle(Entity owner, World world, BlockPos pos) {
BlockState state = world.getBlockState(pos);
Block id = state.getBlock();
BlockState converted = StateMaps.ICE_AFFECTED.getConverted(world, state);
if (StateMaps.ICE_AFFECTED.convert(world, pos)) {
return true;
}
if (!state.equals(converted)) {
world.setBlockState(pos, converted, 3);
} else if (world.isTopSolid(pos, owner)
|| (id == Blocks.SNOW)
if (world.isTopSolid(pos, owner)
|| state.isOf(Blocks.SNOW)
|| state.isIn(BlockTags.LEAVES)) {
incrementIce(world, pos.up());
} else if (state.getMaterial() == Material.ICE && world.random.nextInt(10) == 0) {
if (isSurroundedByIce(world, pos)) {
world.setBlockState(pos, Blocks.PACKED_ICE.getDefaultState());
}
return true;
}
world.addParticle(ParticleTypes.SPLASH, pos.getX() + world.random.nextFloat(), pos.getY() + 1, pos.getZ() + world.random.nextFloat(), 0, 0, 0);
if (state.getMaterial() == Material.ICE
&& world.random.nextInt(10) == 0
&& isSurroundedByIce(world, pos)) {
world.setBlockState(pos, Blocks.PACKED_ICE.getDefaultState());
return true;
}
return false;
}
private static boolean isSurroundedByIce(World w, BlockPos pos) {

View file

@ -7,9 +7,6 @@ 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;
@ -42,20 +39,7 @@ public class InfernoSpell extends FireSpell {
for (int i = 0; i < radius; i++) {
BlockPos pos = new BlockPos(shape.computePoint(w.random).add(origin));
BlockState state = w.getBlockState(pos);
BlockState newState = converter.getConverted(w, state);
if (!state.equals(newState)) {
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);
if (converter.convert(w, pos)) {
playEffect(w, pos);
}
}

View file

@ -9,7 +9,6 @@ import com.minelittlepony.unicopia.projectile.MagicProjectileEntity;
import com.minelittlepony.unicopia.util.PosHelper;
import com.minelittlepony.unicopia.util.shape.Sphere;
import net.minecraft.block.BlockState;
import net.minecraft.particle.ParticleTypes;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.Vec3d;
@ -25,12 +24,7 @@ public class ScorchSpell extends FireSpell {
BlockPos pos = PosHelper.findSolidGroundAt(source.getWorld(), source.getOrigin(), source.getPhysics().getGravitySignum());
BlockState state = source.getWorld().getBlockState(pos);
BlockState newState = StateMaps.FIRE_AFFECTED.getConverted(source.getWorld(), state);
if (!state.equals(newState)) {
source.getWorld().setBlockState(pos, newState, 3);
if (StateMaps.FIRE_AFFECTED.convert(source.getWorld(), pos)) {
source.spawnParticles(new Sphere(false, 1), 5, p -> {
source.addParticle(ParticleTypes.SMOKE, PosHelper.offset(p, pos), Vec3d.ZERO);
});

View file

@ -4,6 +4,9 @@ import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import net.minecraft.block.BlockState;
import net.minecraft.block.enums.DoubleBlockHalf;
import net.minecraft.state.property.Properties;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.World;
public interface BlockStateConverter {
@ -19,10 +22,47 @@ public interface BlockStateConverter {
/**
* Attempts to convert the given state based on the known mappings in this collection.
*
* @param world The world
* @param state State to convert
*
* @return The converted state if there is one, otherwise null
* @return The converted state if there is one, otherwise the original state is returned
*/
@Nonnull
BlockState getConverted(World world, @Nonnull BlockState state);
/**
* Attempts to convert a block state at a position.
* Returns true if the block was changed.
*
*/
default boolean convert(World world, BlockPos pos) {
BlockState state = world.getBlockState(pos);
if (!canConvert(state)) {
return false;
}
BlockState newState = getConverted(world, state);
if (state.equals(newState)) {
return false;
}
if (!newState.contains(Properties.DOUBLE_BLOCK_HALF)) {
world.setBlockState(pos, newState, 16 | 2);
return true;
}
boolean lower = newState.get(Properties.DOUBLE_BLOCK_HALF) == DoubleBlockHalf.LOWER;
BlockPos other = lower ? pos.up() : pos.down();
if (world.getBlockState(other).isOf(state.getBlock())) {
world.setBlockState(other, newState.with(Properties.DOUBLE_BLOCK_HALF, lower ? DoubleBlockHalf.UPPER : DoubleBlockHalf.LOWER), 16 | 2);
world.setBlockState(pos, newState, 16 | 2);
return true;
}
return false;
}
}

View file

@ -16,9 +16,7 @@ public class SilverfishBehaviour extends EntityBehaviour<SilverfishEntity> {
BlockPos pos = entity.getBlockPos().down();
BlockState state = entity.world.getBlockState(pos);
if (StateMaps.SILVERFISH_AFFECTED.canConvert(state)) {
entity.world.setBlockState(pos, StateMaps.SILVERFISH_AFFECTED.getConverted(entity.world, state));
if (StateMaps.SILVERFISH_AFFECTED.convert(entity.world, pos)) {
WorldEvent.play(WorldEvent.DESTROY_BLOCK, entity.world, pos, state);
}
}