mirror of
https://github.com/Sollace/Unicopia.git
synced 2024-11-23 13:37:58 +01:00
Polish up the inferno spell and refactor block state mapping a little
This commit is contained in:
parent
3fda44eba6
commit
afd437d9cf
8 changed files with 122 additions and 42 deletions
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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<StateMapping> 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<Block> from, Block to) {
|
||||
add(StateMapping.replaceBlock(from, to));
|
||||
}
|
||||
|
||||
public <T extends Comparable<T>> void replaceProperty(Block block, Property<T> property, T from, T to) {
|
||||
add(StateMapping.replaceProperty(block, property, from, to));
|
||||
}
|
||||
|
@ -40,10 +51,10 @@ class BlockStateMap extends ArrayList<StateMapping> 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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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<BlockState>, Function<BlockState, BlockState> {
|
||||
interface StateMapping extends Predicate<BlockState>, BiFunction<World, BlockState, BlockState> {
|
||||
|
||||
Random RNG = new Random();
|
||||
|
||||
static StateMapping removeBlock(Predicate<BlockState> 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<Block> 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 <T extends Comparable<T>> StateMapping replaceProperty(Block block, Property<T> 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 <T extends Comparable<T>> StateMapping setProperty(Block block, Property<T> property, T to) {
|
||||
return build(
|
||||
s -> s.getBlock() == block,
|
||||
s -> s.with(property, to));
|
||||
(w, s) -> s.with(property, to));
|
||||
}
|
||||
|
||||
static StateMapping build(Predicate<BlockState> predicate, Function<BlockState, BlockState> converter) {
|
||||
static StateMapping build(Predicate<BlockState> predicate, BiFunction<World, BlockState, BlockState> converter) {
|
||||
return build(predicate, converter, s -> s);
|
||||
}
|
||||
|
||||
static StateMapping build(Predicate<BlockState> predicate, Function<BlockState, BlockState> converter, Function<StateMapping, StateMapping> inverter) {
|
||||
static StateMapping build(Predicate<BlockState> predicate, BiFunction<World, BlockState, BlockState> converter, Function<StateMapping, StateMapping> inverter) {
|
||||
return new StateMapping() {
|
||||
private StateMapping inverse;
|
||||
|
||||
|
@ -52,8 +82,8 @@ interface StateMapping extends Predicate<BlockState>, Function<BlockState, Block
|
|||
}
|
||||
|
||||
@Override
|
||||
public BlockState apply(BlockState state) {
|
||||
return converter.apply(state);
|
||||
public BlockState apply(World world, BlockState state) {
|
||||
return converter.apply(world, state);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -87,7 +117,7 @@ interface StateMapping extends Predicate<BlockState>, Function<BlockState, Block
|
|||
*/
|
||||
@Nonnull
|
||||
@Override
|
||||
default BlockState apply(@Nonnull BlockState state) {
|
||||
default BlockState apply(World world, @Nonnull BlockState state) {
|
||||
return state;
|
||||
}
|
||||
|
||||
|
|
|
@ -7,19 +7,20 @@ import net.minecraft.block.OreBlock;
|
|||
import net.minecraft.block.PlantBlock;
|
||||
import net.minecraft.block.RedstoneWireBlock;
|
||||
import net.minecraft.block.SnowBlock;
|
||||
import net.minecraft.tag.BlockTags;
|
||||
import net.minecraft.util.Util;
|
||||
|
||||
public class StateMaps {
|
||||
public static final BlockStateConverter ICE_AFFECTED = register(Util.make(new BlockStateMap(), a -> {
|
||||
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 extends BlockStateConverter> T register(T value, String name) {
|
||||
|
|
Loading…
Reference in a new issue