mirror of
https://github.com/Sollace/Unicopia.git
synced 2024-11-25 14:28:00 +01:00
172 lines
6 KiB
Java
172 lines
6 KiB
Java
package com.minelittlepony.unicopia.spell;
|
|
|
|
import javax.annotation.Nullable;
|
|
|
|
import com.minelittlepony.unicopia.init.UMaterials;
|
|
import com.minelittlepony.util.MagicalDamageSource;
|
|
import com.minelittlepony.util.PosHelper;
|
|
import com.minelittlepony.util.collection.IStateMapping;
|
|
import com.minelittlepony.util.collection.StateMapList;
|
|
import com.minelittlepony.util.shape.IShape;
|
|
import com.minelittlepony.util.shape.Sphere;
|
|
import com.minelittlepony.util.vector.VecHelper;
|
|
|
|
import net.minecraft.block.Block;
|
|
import net.minecraft.block.BlockBush;
|
|
import net.minecraft.block.BlockLeaves;
|
|
import net.minecraft.block.BlockRedstoneWire;
|
|
import net.minecraft.block.BlockSnow;
|
|
import net.minecraft.block.material.Material;
|
|
import net.minecraft.block.state.IBlockState;
|
|
import net.minecraft.dispenser.IBlockSource;
|
|
import net.minecraft.entity.Entity;
|
|
import net.minecraft.entity.item.EntityTNTPrimed;
|
|
import net.minecraft.entity.player.EntityPlayer;
|
|
import net.minecraft.init.Blocks;
|
|
import net.minecraft.item.ItemStack;
|
|
import net.minecraft.util.math.BlockPos;
|
|
import net.minecraft.util.EnumFacing;
|
|
import net.minecraft.util.EnumParticleTypes;
|
|
import net.minecraft.world.World;
|
|
|
|
public class SpellIce extends AbstractSpell.RangedAreaSpell implements IUseAction, IDispenceable {
|
|
|
|
public final StateMapList affected = new StateMapList();
|
|
|
|
public SpellIce() {
|
|
affected.add(IStateMapping.build(
|
|
s -> s.getMaterial() == Material.WATER,
|
|
s -> Blocks.ICE.getDefaultState()));
|
|
affected.add(IStateMapping.build(
|
|
s -> s.getMaterial() == Material.LAVA,
|
|
s -> Blocks.OBSIDIAN.getDefaultState()));
|
|
affected.add(IStateMapping.build(
|
|
s -> s.getBlock() == Blocks.SNOW_LAYER,
|
|
s -> {
|
|
s = s.cycleProperty(BlockSnow.LAYERS);
|
|
if (s.getValue(BlockSnow.LAYERS) >= 7) {
|
|
return Blocks.SNOW.getDefaultState();
|
|
}
|
|
|
|
return s;
|
|
}));
|
|
affected.replaceBlock(Blocks.FIRE, Blocks.AIR);
|
|
affected.setProperty(Blocks.REDSTONE_WIRE, BlockRedstoneWire.POWER, 0);
|
|
}
|
|
|
|
private final int rad = 3;
|
|
private final IShape effect_range = new Sphere(false, rad);
|
|
|
|
@Override
|
|
public String getName() {
|
|
return "ice";
|
|
}
|
|
|
|
@Override
|
|
public SpellAffinity getAffinity() {
|
|
return SpellAffinity.GOOD;
|
|
}
|
|
|
|
@Override
|
|
public int getTint() {
|
|
return 0xBDBDF9;
|
|
}
|
|
|
|
@Override
|
|
public boolean update(ICaster<?> source) {
|
|
return false;
|
|
}
|
|
|
|
@Override
|
|
public void render(ICaster<?> source) {
|
|
}
|
|
|
|
@Override
|
|
public SpellCastResult onDispenced(BlockPos pos, EnumFacing facing, IBlockSource source, SpellAffinity affinity) {
|
|
return applyBlocks(null, source.getWorld(), pos.offset(facing, rad)) ? SpellCastResult.NONE : SpellCastResult.DEFAULT;
|
|
}
|
|
|
|
@Override
|
|
public SpellCastResult onUse(ItemStack stack, SpellAffinity affinity, EntityPlayer player, World world, BlockPos pos, EnumFacing side, float hitX, float hitY, float hitZ) {
|
|
if (player != null && player.isSneaking()) {
|
|
applyBlockSingle(world, pos);
|
|
} else {
|
|
applyBlocks(player, world, pos);
|
|
}
|
|
|
|
return SpellCastResult.DEFAULT;
|
|
}
|
|
|
|
@Override
|
|
public SpellCastResult onUse(ItemStack stack, SpellAffinity affinity, EntityPlayer player, World world, @Nullable Entity hitEntity) {
|
|
if (hitEntity != null && applyEntitySingle(player, hitEntity)) {
|
|
return SpellCastResult.DEFAULT;
|
|
}
|
|
|
|
return SpellCastResult.NONE;
|
|
}
|
|
|
|
private boolean applyBlocks(EntityPlayer owner, World world, BlockPos pos) {
|
|
|
|
for (BlockPos i : PosHelper.getAllInRegionMutable(pos, effect_range)) {
|
|
applyBlockSingle(world, i);
|
|
}
|
|
|
|
return applyEntities(owner, world, pos);
|
|
}
|
|
|
|
protected boolean applyEntities(EntityPlayer owner, World world, BlockPos pos) {
|
|
return VecHelper.findAllEntitiesInRange(owner, world, pos, 3).filter(i ->
|
|
applyEntitySingle(owner, i)
|
|
).count() > 0;
|
|
}
|
|
|
|
protected boolean applyEntitySingle(EntityPlayer owner, Entity e) {
|
|
if (e instanceof EntityTNTPrimed) {
|
|
e.setDead();
|
|
e.getEntityWorld().setBlockState(e.getPosition(), Blocks.TNT.getDefaultState());
|
|
} else if (e.isBurning()) {
|
|
e.extinguish();
|
|
} else {
|
|
e.attackEntityFrom(MagicalDamageSource.causePlayerDamage("cold", owner), 2);
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
private void applyBlockSingle(World world, BlockPos pos) {
|
|
IBlockState state = world.getBlockState(pos);
|
|
Block id = state.getBlock();
|
|
|
|
IBlockState converted = affected.getConverted(state);
|
|
|
|
if (!state.equals(converted)) {
|
|
world.setBlockState(pos, converted, 3);
|
|
} else if (state.getMaterial() != UMaterials.cloud && state.isSideSolid(world, pos, EnumFacing.UP)
|
|
|| (id == Blocks.SNOW)
|
|
|| (id instanceof BlockLeaves)) {
|
|
incrementIce(world, pos.up());
|
|
} else if (state.getMaterial() == Material.ICE && world.rand.nextInt(10) == 0) {
|
|
if (isSurroundedByIce(world, pos)) {
|
|
world.setBlockState(pos, Blocks.PACKED_ICE.getDefaultState());
|
|
}
|
|
}
|
|
|
|
world.spawnParticle(EnumParticleTypes.WATER_SPLASH, pos.getX() + world.rand.nextFloat(), pos.getY() + 1, pos.getZ() + world.rand.nextFloat(), 0, 0, 0);
|
|
}
|
|
|
|
public static boolean isSurroundedByIce(World w, BlockPos pos) {
|
|
return !PosHelper.adjacentNeighbours(pos).stream().anyMatch(i ->
|
|
w.getBlockState(i).getMaterial() == Material.ICE
|
|
);
|
|
}
|
|
|
|
private void incrementIce(World world, BlockPos pos) {
|
|
IBlockState state = world.getBlockState(pos);
|
|
Block id = state.getBlock();
|
|
|
|
if (id == Blocks.AIR || (id instanceof BlockBush)) {
|
|
world.setBlockState(pos, Blocks.SNOW_LAYER.getDefaultState(), 3);
|
|
}
|
|
}
|
|
}
|