Fixed NPE in Blood Altar and added some WIP blocks
Also included is a fix for the Blood Altar not receiving piped in fluids, as well as standardizing the Blood Altar's capabilities.
This commit is contained in:
parent
e36f8f4e24
commit
d719b85958
23 changed files with 883 additions and 6 deletions
|
@ -64,12 +64,14 @@ import wayoftime.bloodmagic.tile.TileAlchemicalReactionChamber;
|
|||
import wayoftime.bloodmagic.tile.TileAlchemyArray;
|
||||
import wayoftime.bloodmagic.tile.TileAlchemyTable;
|
||||
import wayoftime.bloodmagic.tile.TileAltar;
|
||||
import wayoftime.bloodmagic.tile.TileDeforesterCharge;
|
||||
import wayoftime.bloodmagic.tile.TileDemonCrucible;
|
||||
import wayoftime.bloodmagic.tile.TileDemonCrystal;
|
||||
import wayoftime.bloodmagic.tile.TileDemonCrystallizer;
|
||||
import wayoftime.bloodmagic.tile.TileIncenseAltar;
|
||||
import wayoftime.bloodmagic.tile.TileMasterRitualStone;
|
||||
import wayoftime.bloodmagic.tile.TileMimic;
|
||||
import wayoftime.bloodmagic.tile.TileShapedExplosive;
|
||||
import wayoftime.bloodmagic.tile.TileSoulForge;
|
||||
import wayoftime.bloodmagic.util.handler.event.GenericHandler;
|
||||
import wayoftime.bloodmagic.util.handler.event.WillHandler;
|
||||
|
@ -186,6 +188,8 @@ public class BloodMagic
|
|||
event.getRegistry().register(TileEntityType.Builder.create(TileDemonCrystallizer::new, BloodMagicBlocks.DEMON_CRYSTALLIZER.get()).build(null).setRegistryName("demoncrystallizer"));
|
||||
event.getRegistry().register(TileEntityType.Builder.create(TileIncenseAltar::new, BloodMagicBlocks.INCENSE_ALTAR.get()).build(null).setRegistryName("incensealtar"));
|
||||
event.getRegistry().register(TileEntityType.Builder.create(TileMimic::new, BloodMagicBlocks.MIMIC.get(), BloodMagicBlocks.ETHEREAL_MIMIC.get()).build(null).setRegistryName("mimic"));
|
||||
event.getRegistry().register(TileEntityType.Builder.create(TileShapedExplosive::new, BloodMagicBlocks.SHAPED_CHARGE.get()).build(null).setRegistryName("shaped_explosive"));
|
||||
event.getRegistry().register(TileEntityType.Builder.create(TileDeforesterCharge::new, BloodMagicBlocks.DEFORESTER_CHARGE.get()).build(null).setRegistryName("deforester_charge"));
|
||||
}
|
||||
|
||||
@SubscribeEvent
|
||||
|
|
|
@ -684,7 +684,7 @@ public class BloodAltar// implements IFluidHandler
|
|||
return Math.min(bufferCapacity - fluidInput.getAmount(), resource.getAmount());
|
||||
}
|
||||
|
||||
if (fluidInput == null)
|
||||
if (fluidInput == null || fluidInput.isEmpty())
|
||||
{
|
||||
fluidInput = new FluidStack(resource, Math.min(bufferCapacity, resource.getAmount()));
|
||||
|
||||
|
@ -713,7 +713,7 @@ public class BloodAltar// implements IFluidHandler
|
|||
{
|
||||
if (resource == null || !resource.isFluidEqual(fluidOutput))
|
||||
{
|
||||
return null;
|
||||
return FluidStack.EMPTY;
|
||||
}
|
||||
return drain(resource.getAmount(), doDrain);
|
||||
}
|
||||
|
@ -722,7 +722,7 @@ public class BloodAltar// implements IFluidHandler
|
|||
{
|
||||
if (fluidOutput == null)
|
||||
{
|
||||
return null;
|
||||
return FluidStack.EMPTY;
|
||||
}
|
||||
|
||||
int drained = maxDrain;
|
||||
|
|
|
@ -0,0 +1,20 @@
|
|||
package wayoftime.bloodmagic.common.block;
|
||||
|
||||
import net.minecraft.block.BlockState;
|
||||
import net.minecraft.tileentity.TileEntity;
|
||||
import net.minecraft.world.IBlockReader;
|
||||
import wayoftime.bloodmagic.tile.TileDeforesterCharge;
|
||||
|
||||
public class BlockDeforesterCharge extends BlockShapedExplosive
|
||||
{
|
||||
public BlockDeforesterCharge(int explosionSize, Properties properties)
|
||||
{
|
||||
super(explosionSize, properties);
|
||||
}
|
||||
|
||||
@Override
|
||||
public TileEntity createTileEntity(BlockState state, IBlockReader world)
|
||||
{
|
||||
return new TileDeforesterCharge();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,107 @@
|
|||
package wayoftime.bloodmagic.common.block;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.block.BlockState;
|
||||
import net.minecraft.block.Blocks;
|
||||
import net.minecraft.item.BlockItemUseContext;
|
||||
import net.minecraft.state.EnumProperty;
|
||||
import net.minecraft.state.StateContainer;
|
||||
import net.minecraft.tileentity.TileEntity;
|
||||
import net.minecraft.util.Direction;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.util.math.shapes.ISelectionContext;
|
||||
import net.minecraft.util.math.shapes.VoxelShape;
|
||||
import net.minecraft.world.IBlockReader;
|
||||
import net.minecraft.world.IWorld;
|
||||
import net.minecraft.world.IWorldReader;
|
||||
import wayoftime.bloodmagic.tile.TileShapedExplosive;
|
||||
|
||||
public class BlockShapedExplosive extends Block
|
||||
{
|
||||
private static final VoxelShape UP = Block.makeCuboidShape(2, 0, 2, 14, 7, 14);
|
||||
private static final VoxelShape DOWN = Block.makeCuboidShape(2, 9, 2, 14, 16, 14);
|
||||
private static final VoxelShape NORTH = Block.makeCuboidShape(2, 2, 7, 14, 14, 16);
|
||||
private static final VoxelShape SOUTH = Block.makeCuboidShape(2, 2, 0, 14, 14, 7);
|
||||
private static final VoxelShape EAST = Block.makeCuboidShape(0, 2, 2, 7, 14, 14);
|
||||
private static final VoxelShape WEST = Block.makeCuboidShape(16, 2, 2, 9, 14, 14);
|
||||
|
||||
public static final EnumProperty<Direction> ATTACHED = EnumProperty.create("attached", Direction.class);
|
||||
protected final int explosionSize;
|
||||
|
||||
public BlockShapedExplosive(int explosionSize, Properties properties)
|
||||
{
|
||||
super(properties);
|
||||
this.explosionSize = explosionSize;
|
||||
|
||||
this.setDefaultState(this.stateContainer.getBaseState().with(ATTACHED, Direction.UP));
|
||||
}
|
||||
|
||||
public BlockState updatePostPlacement(BlockState stateIn, Direction facing, BlockState facingState, IWorld worldIn, BlockPos currentPos, BlockPos facingPos)
|
||||
{
|
||||
return facing.getOpposite() == stateIn.get(ATTACHED) && !stateIn.isValidPosition(worldIn, currentPos)
|
||||
? Blocks.AIR.getDefaultState()
|
||||
: stateIn;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public BlockState getStateForPlacement(BlockItemUseContext context)
|
||||
{
|
||||
BlockState blockstate = this.getDefaultState();
|
||||
IWorldReader iworldreader = context.getWorld();
|
||||
BlockPos blockpos = context.getPos();
|
||||
Direction[] adirection = context.getNearestLookingDirections();
|
||||
|
||||
for (Direction direction : adirection)
|
||||
{
|
||||
Direction direction1 = direction.getOpposite();
|
||||
blockstate = blockstate.with(ATTACHED, direction1);
|
||||
if (blockstate.isValidPosition(iworldreader, blockpos))
|
||||
{
|
||||
return blockstate;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void fillStateContainer(StateContainer.Builder<Block, BlockState> builder)
|
||||
{
|
||||
builder.add(ATTACHED);
|
||||
}
|
||||
|
||||
@Override
|
||||
public VoxelShape getShape(BlockState state, IBlockReader worldIn, BlockPos pos, ISelectionContext context)
|
||||
{
|
||||
switch (state.get(ATTACHED))
|
||||
{
|
||||
case DOWN:
|
||||
return DOWN;
|
||||
case NORTH:
|
||||
return NORTH;
|
||||
case SOUTH:
|
||||
return SOUTH;
|
||||
case EAST:
|
||||
return EAST;
|
||||
case WEST:
|
||||
return WEST;
|
||||
case UP:
|
||||
default:
|
||||
return UP;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasTileEntity(BlockState state)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public TileEntity createTileEntity(BlockState state, IBlockReader world)
|
||||
{
|
||||
return new TileShapedExplosive();
|
||||
}
|
||||
}
|
|
@ -29,6 +29,7 @@ import net.minecraftforge.fml.RegistryObject;
|
|||
import net.minecraftforge.registries.DeferredRegister;
|
||||
import net.minecraftforge.registries.ForgeRegistries;
|
||||
import wayoftime.bloodmagic.BloodMagic;
|
||||
import wayoftime.bloodmagic.api.compat.EnumDemonWillType;
|
||||
import wayoftime.bloodmagic.block.enums.BloodRuneType;
|
||||
import wayoftime.bloodmagic.common.block.base.BlockPillarCap;
|
||||
import wayoftime.bloodmagic.common.item.BloodMagicItems;
|
||||
|
@ -36,7 +37,6 @@ import wayoftime.bloodmagic.ritual.EnumRuneType;
|
|||
import wayoftime.bloodmagic.tile.container.ContainerAlchemicalReactionChamber;
|
||||
import wayoftime.bloodmagic.tile.container.ContainerAlchemyTable;
|
||||
import wayoftime.bloodmagic.tile.container.ContainerSoulForge;
|
||||
import wayoftime.bloodmagic.api.compat.EnumDemonWillType;
|
||||
|
||||
public class BloodMagicBlocks
|
||||
{
|
||||
|
@ -171,6 +171,10 @@ public class BloodMagicBlocks
|
|||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
public static final RegistryObject<Block> SHAPED_CHARGE = BLOCKS.register("shaped_charge", () -> new BlockShapedExplosive(3, Properties.create(Material.IRON).hardnessAndResistance(5.0F, 6.0F).sound(SoundType.METAL).harvestTool(ToolType.PICKAXE).harvestLevel(1).setRequiresTool()));
|
||||
public static final RegistryObject<Block> DEFORESTER_CHARGE = BLOCKS.register("deforester_charge", () -> new BlockDeforesterCharge(3, Properties.create(Material.IRON).hardnessAndResistance(5.0F, 6.0F).sound(SoundType.METAL).harvestTool(ToolType.PICKAXE).harvestLevel(1).setRequiresTool()));
|
||||
|
||||
//
|
||||
//// private static <T extends Block> RegistryObject<T> register(String name, Supplier<? extends T> sup, Function<RegistryObject<T>, Supplier<? extends Item>> itemCreator)
|
||||
//// {
|
||||
|
|
|
@ -25,6 +25,7 @@ import net.minecraftforge.fml.RegistryObject;
|
|||
import wayoftime.bloodmagic.BloodMagic;
|
||||
import wayoftime.bloodmagic.common.block.BlockAlchemicalReactionChamber;
|
||||
import wayoftime.bloodmagic.common.block.BlockDemonCrystal;
|
||||
import wayoftime.bloodmagic.common.block.BlockShapedExplosive;
|
||||
import wayoftime.bloodmagic.common.block.BloodMagicBlocks;
|
||||
import wayoftime.bloodmagic.common.block.base.BlockPillarCap;
|
||||
|
||||
|
@ -90,6 +91,25 @@ public class GeneratorBlockStates extends BlockStateProvider
|
|||
buildCubeAllWithTextureName("solidopaquemimic");
|
||||
|
||||
buildCrop(BloodMagicBlocks.GROWING_DOUBT.get(), CropsBlock.AGE, 7, BloodMagic.rl("block/creeping_doubt_1"), BloodMagic.rl("block/creeping_doubt_2"), BloodMagic.rl("block/creeping_doubt_3"), BloodMagic.rl("block/creeping_doubt_4"), BloodMagic.rl("block/creeping_doubt_5"), BloodMagic.rl("block/creeping_doubt_6"), BloodMagic.rl("block/creeping_doubt_7"), BloodMagic.rl("block/creeping_doubt_8"));
|
||||
|
||||
buildOrientable(BloodMagicBlocks.SHAPED_CHARGE.get(), "shaped_charge", modLoc("block/sub/shaped_charge"), modLoc("block/dungeon/dungeon_stone"), modLoc("block/dungeon/dungeon_tile"), modLoc("block/blankrune"), modLoc("block/largebloodstonebrick"), modLoc("models/defaultcrystal"));
|
||||
buildOrientable(BloodMagicBlocks.DEFORESTER_CHARGE.get(), "deforester_charge", modLoc("block/sub/shaped_charge"), new ResourceLocation("block/oak_log_top"), new ResourceLocation("block/oak_log_top"), modLoc("block/blankrune"), new ResourceLocation("block/oak_planks"), modLoc("models/defaultcrystal"));
|
||||
}
|
||||
|
||||
private void buildOrientable(Block block, String name, ResourceLocation modelPath, ResourceLocation base, ResourceLocation edges, ResourceLocation centerCap, ResourceLocation binding, ResourceLocation core)
|
||||
{
|
||||
// ModelFile furnace_off = models().orientableWithBottom("alchemicalreactionchamber", BloodMagic.rl("block/arc_side"), BloodMagic.rl("block/arc_front"), BloodMagic.rl("block/arc_bottom"), BloodMagic.rl("block/arc_top"));
|
||||
// getVariantBuilder(block).addModels(block.getDefaultState().with(BlockAlchemicalReactionChamber.FACING, Direction.NORTH).with(BlockAlchemicalReactionChamber.LIT, false), furnaceModel);
|
||||
ModelFile model = models().withExistingParent(name, modelPath).texture("1", edges).texture("3", base).texture("4", centerCap).texture("5", binding).texture("6", core).texture("particle", core);
|
||||
|
||||
VariantBlockStateBuilder builder = getVariantBuilder(block);
|
||||
|
||||
builder.partialState().with(BlockShapedExplosive.ATTACHED, Direction.UP).modelForState().modelFile(model).addModel();
|
||||
builder.partialState().with(BlockShapedExplosive.ATTACHED, Direction.DOWN).modelForState().modelFile(model).rotationX(180).addModel();
|
||||
builder.partialState().with(BlockShapedExplosive.ATTACHED, Direction.EAST).modelForState().modelFile(model).rotationX(90).rotationY(90).addModel();
|
||||
builder.partialState().with(BlockShapedExplosive.ATTACHED, Direction.WEST).modelForState().modelFile(model).rotationX(90).rotationY(270).addModel();
|
||||
builder.partialState().with(BlockShapedExplosive.ATTACHED, Direction.NORTH).modelForState().modelFile(model).rotationX(90).addModel();
|
||||
builder.partialState().with(BlockShapedExplosive.ATTACHED, Direction.SOUTH).modelForState().modelFile(model).rotationX(270).addModel();
|
||||
}
|
||||
|
||||
private void buildCrop(Block block, IntegerProperty prop, int maxAge, ResourceLocation... textures)
|
||||
|
|
|
@ -9,9 +9,9 @@ import net.minecraftforge.client.model.generators.ModelFile;
|
|||
import net.minecraftforge.common.data.ExistingFileHelper;
|
||||
import net.minecraftforge.fml.RegistryObject;
|
||||
import wayoftime.bloodmagic.BloodMagic;
|
||||
import wayoftime.bloodmagic.api.compat.EnumDemonWillType;
|
||||
import wayoftime.bloodmagic.common.block.BloodMagicBlocks;
|
||||
import wayoftime.bloodmagic.common.item.BloodMagicItems;
|
||||
import wayoftime.bloodmagic.api.compat.EnumDemonWillType;
|
||||
|
||||
public class GeneratorItemModels extends ItemModelProvider
|
||||
{
|
||||
|
@ -87,6 +87,9 @@ public class GeneratorItemModels extends ItemModelProvider
|
|||
registerCustomFullTexture(BloodMagicBlocks.MIMIC.get(), "solidopaquemimic");
|
||||
registerCustomFullTexture(BloodMagicBlocks.ETHEREAL_MIMIC.get(), "etherealopaquemimic");
|
||||
this.crop(BloodMagicBlocks.GROWING_DOUBT.get().getRegistryName().getPath(), modLoc("block/creeping_doubt_8"));
|
||||
|
||||
registerBlockModel(BloodMagicBlocks.SHAPED_CHARGE.get());
|
||||
registerBlockModel(BloodMagicBlocks.DEFORESTER_CHARGE.get());
|
||||
}
|
||||
|
||||
private void registerCustomFullTexture(Block block, String texturePath)
|
||||
|
|
|
@ -131,6 +131,9 @@ public class GeneratorLootTable extends LootTableProvider
|
|||
registerDropSelfLootTable(BloodMagicBlocks.ETHEREAL_MIMIC.get());
|
||||
|
||||
registerCropDropLootTable(BloodMagicBlocks.GROWING_DOUBT.get(), BloodMagicItems.WEAK_BLOOD_SHARD.get());
|
||||
|
||||
registerDropSelfLootTable(BloodMagicBlocks.SHAPED_CHARGE.get());
|
||||
registerDropSelfLootTable(BloodMagicBlocks.DEFORESTER_CHARGE.get());
|
||||
}
|
||||
|
||||
private void registerNoDropLootTable(Block block)
|
||||
|
|
|
@ -96,6 +96,9 @@ public class BloodMagicItems
|
|||
|
||||
public static final RegistryObject<Item> NETHE_SOIL_ITEM = ITEMS.register("nether_soil", () -> new BlockItem(BloodMagicBlocks.NETHER_SOIL.get(), new Item.Properties().group(BloodMagic.TAB)));
|
||||
public static final RegistryObject<Item> GROWING_DOUBT_ITEM = ITEMS.register("growing_doubt", () -> new BlockItem(BloodMagicBlocks.GROWING_DOUBT.get(), new Item.Properties().group(BloodMagic.TAB)));
|
||||
|
||||
public static final RegistryObject<Item> SHAPED_CHARGE_ITEM = ITEMS.register("shaped_charge", () -> new BlockItem(BloodMagicBlocks.SHAPED_CHARGE.get(), new Item.Properties().group(BloodMagic.TAB)));
|
||||
public static final RegistryObject<Item> DEFORESTER_CHARGE_ITEM = ITEMS.register("deforester_charge", () -> new BlockItem(BloodMagicBlocks.DEFORESTER_CHARGE.get(), new Item.Properties().group(BloodMagic.TAB)));
|
||||
// TODO: Need to rework the above instantiations for the ItemBlocks so that it's
|
||||
// done with the Blocks.
|
||||
|
||||
|
|
|
@ -22,6 +22,8 @@ public class TileAltar extends TileInventory implements IBloodAltar, ITickableTi
|
|||
public static TileEntityType<TileAltar> TYPE;
|
||||
private BloodAltar bloodAltar;
|
||||
|
||||
private LazyOptional fluidOptional;
|
||||
|
||||
public TileAltar(TileEntityType<?> type)
|
||||
{
|
||||
super(type, 1, "altar");
|
||||
|
@ -220,13 +222,25 @@ public class TileAltar extends TileInventory implements IBloodAltar, ITickableTi
|
|||
// return super.hasCapability(capability, facing);
|
||||
// }
|
||||
|
||||
@Override
|
||||
protected void invalidateCaps()
|
||||
{
|
||||
super.invalidateCaps();
|
||||
fluidOptional.invalidate();
|
||||
fluidOptional = null;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Override
|
||||
public <T> LazyOptional<T> getCapability(@Nonnull Capability<T> capability, @Nullable Direction facing)
|
||||
{
|
||||
if (capability == CapabilityFluidHandler.FLUID_HANDLER_CAPABILITY)
|
||||
{
|
||||
return LazyOptional.of(() -> new BloodAltar.VariableSizeFluidHandler(bloodAltar)).cast();
|
||||
if (fluidOptional == null)
|
||||
{
|
||||
fluidOptional = LazyOptional.of(() -> new BloodAltar.VariableSizeFluidHandler(bloodAltar));
|
||||
}
|
||||
return fluidOptional.cast();
|
||||
// return (T) bloodAltar;
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,233 @@
|
|||
package wayoftime.bloodmagic.tile;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import com.mojang.datafixers.util.Pair;
|
||||
|
||||
import it.unimi.dsi.fastutil.objects.ObjectArrayList;
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.block.BlockState;
|
||||
import net.minecraft.block.Blocks;
|
||||
import net.minecraft.entity.item.ItemEntity;
|
||||
import net.minecraft.entity.player.PlayerEntity;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.loot.LootContext;
|
||||
import net.minecraft.loot.LootParameters;
|
||||
import net.minecraft.nbt.CompoundNBT;
|
||||
import net.minecraft.particles.ParticleTypes;
|
||||
import net.minecraft.tags.BlockTags;
|
||||
import net.minecraft.tileentity.TileEntity;
|
||||
import net.minecraft.tileentity.TileEntityType;
|
||||
import net.minecraft.util.Direction;
|
||||
import net.minecraft.util.SoundCategory;
|
||||
import net.minecraft.util.SoundEvents;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.util.math.vector.Vector3d;
|
||||
import net.minecraft.world.server.ServerWorld;
|
||||
import net.minecraftforge.registries.ObjectHolder;
|
||||
import wayoftime.bloodmagic.common.block.BlockShapedExplosive;
|
||||
import wayoftime.bloodmagic.tile.base.TileTicking;
|
||||
|
||||
public class TileDeforesterCharge extends TileTicking
|
||||
{
|
||||
@ObjectHolder("bloodmagic:deforester_charge")
|
||||
public static TileEntityType<TileDeforesterCharge> TYPE;
|
||||
|
||||
private Map<BlockPos, Boolean> treePartsMap;
|
||||
private List<BlockPos> treePartsCache;
|
||||
private boolean finishedAnalysis;
|
||||
// private Iterator<BlockPos> blockPosIterator;
|
||||
|
||||
// private boolean cached = false;
|
||||
|
||||
public double internalCounter = 0;
|
||||
public int explosionRadius;
|
||||
public int explosionDepth;
|
||||
|
||||
public int maxLogs = 64;
|
||||
|
||||
public TileDeforesterCharge(TileEntityType<?> type, int explosionRadius, int explosionDepth)
|
||||
{
|
||||
super(type);
|
||||
this.explosionRadius = explosionRadius;
|
||||
this.explosionDepth = explosionDepth;
|
||||
}
|
||||
|
||||
public TileDeforesterCharge()
|
||||
{
|
||||
this(TYPE, 1, 3);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onUpdate()
|
||||
{
|
||||
if (world.isRemote)
|
||||
{
|
||||
return;
|
||||
}
|
||||
// System.out.println("Counter: " + internalCounter);
|
||||
|
||||
Direction explosiveDirection = this.getBlockState().get(BlockShapedExplosive.ATTACHED).getOpposite();
|
||||
BlockState attachedState = world.getBlockState(pos.offset(explosiveDirection));
|
||||
if (!BlockTags.LOGS.contains(attachedState.getBlock()) && !BlockTags.LEAVES.contains(attachedState.getBlock()))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (treePartsMap == null)
|
||||
{
|
||||
treePartsMap = new HashMap<BlockPos, Boolean>();
|
||||
treePartsMap.put(pos.offset(explosiveDirection), false);
|
||||
treePartsCache = new LinkedList<BlockPos>();
|
||||
treePartsCache.add(pos.offset(explosiveDirection));
|
||||
// treePartsMap.add(pos.offset(explosiveDirection));
|
||||
}
|
||||
|
||||
boolean foundNew = false;
|
||||
List<BlockPos> newPositions = new LinkedList<BlockPos>();
|
||||
for (BlockPos currentPos : treePartsCache)
|
||||
{
|
||||
if (!treePartsMap.getOrDefault(currentPos, false)) // If the BlockPos wasn't checked yet
|
||||
{
|
||||
// BlockPos currentPos = entry.getKey();
|
||||
for (Direction dir : Direction.values())
|
||||
{
|
||||
BlockPos checkPos = currentPos.offset(dir);
|
||||
if (treePartsMap.containsKey(checkPos))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
BlockState checkState = world.getBlockState(checkPos);
|
||||
|
||||
if (BlockTags.LOGS.contains(checkState.getBlock()) || BlockTags.LEAVES.contains(checkState.getBlock()))
|
||||
{
|
||||
treePartsMap.put(checkPos, false);
|
||||
newPositions.add(checkPos);
|
||||
foundNew = true;
|
||||
}
|
||||
}
|
||||
|
||||
treePartsMap.put(currentPos, true);
|
||||
}
|
||||
}
|
||||
|
||||
treePartsCache.addAll(newPositions);
|
||||
|
||||
System.out.println("Found blocks: " + treePartsMap.size());
|
||||
|
||||
if (foundNew)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
internalCounter++;
|
||||
if (internalCounter == 20)
|
||||
{
|
||||
// worldIn.playSound((PlayerEntity)null, tntentity.getPosX(), tntentity.getPosY(), tntentity.getPosZ(), SoundEvents.ENTITY_TNT_PRIMED, SoundCategory.BLOCKS, 1.0F, 1.0F);
|
||||
world.playSound((PlayerEntity) null, this.getPos().getX() + 0.5, this.getPos().getY() + 0.5, this.getPos().getZ() + 0.5, SoundEvents.ITEM_FLINTANDSTEEL_USE, SoundCategory.BLOCKS, 1.0F, world.rand.nextFloat() * 0.4F + 0.8F);
|
||||
((ServerWorld) this.world).spawnParticle(ParticleTypes.FLAME, pos.getX() + 0.5, pos.getY() + 0.5, pos.getZ() + 0.5, 5, 0.02, 0.03, 0.02, 0);
|
||||
}
|
||||
|
||||
if (internalCounter == 30)
|
||||
{
|
||||
world.playSound((PlayerEntity) null, this.getPos().getX() + 0.5, this.getPos().getY() + 0.5, this.getPos().getZ() + 0.5, SoundEvents.ENTITY_TNT_PRIMED, SoundCategory.BLOCKS, 1.0F, 1.0F);
|
||||
}
|
||||
|
||||
if (internalCounter < 30)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (world.rand.nextDouble() < 0.3)
|
||||
{
|
||||
((ServerWorld) this.world).spawnParticle(ParticleTypes.SMOKE, pos.getX() + 0.5, pos.getY() + 0.5, pos.getZ() + 0.5, 1, 0.0D, 0.0D, 0.0D, 0);
|
||||
}
|
||||
|
||||
if (internalCounter == 100)
|
||||
{
|
||||
world.playSound((PlayerEntity) null, this.getPos().getX() + 0.5, this.getPos().getY() + 0.5, this.getPos().getZ() + 0.5, SoundEvents.ENTITY_GENERIC_EXPLODE, SoundCategory.BLOCKS, 4.0F, (1.0F + (world.rand.nextFloat() - world.rand.nextFloat()) * 0.2F) * 0.7F);
|
||||
|
||||
int numParticles = explosionDepth * (explosionRadius + 1);
|
||||
|
||||
((ServerWorld) this.world).spawnParticle(ParticleTypes.EXPLOSION, pos.getX() + 0.5 + explosiveDirection.getXOffset(), pos.getY() + 0.5 + explosiveDirection.getYOffset(), pos.getZ() + 0.5 + explosiveDirection.getZOffset(), numParticles, 1.0D, 1.0D, 1.0D, 0);
|
||||
|
||||
ObjectArrayList<Pair<ItemStack, BlockPos>> objectarraylist = new ObjectArrayList<>();
|
||||
|
||||
for (BlockPos blockPos : treePartsCache)
|
||||
{
|
||||
// BlockPos blockpos = initialPos.offset(explosiveDirection, i).offset(sweepDir1, j).offset(sweepDir2, k);
|
||||
|
||||
BlockState blockstate = this.world.getBlockState(blockPos);
|
||||
Block block = blockstate.getBlock();
|
||||
if (!blockstate.isAir(this.world, blockPos))
|
||||
{
|
||||
BlockPos blockpos1 = blockPos.toImmutable();
|
||||
// this.world.getProfiler().startSection("explosion_blocks");
|
||||
if (this.world instanceof ServerWorld)
|
||||
{
|
||||
TileEntity tileentity = blockstate.hasTileEntity() ? this.world.getTileEntity(blockPos) : null;
|
||||
LootContext.Builder lootcontext$builder = (new LootContext.Builder((ServerWorld) this.world)).withRandom(this.world.rand).withParameter(LootParameters.field_237457_g_, Vector3d.copyCentered(blockPos)).withParameter(LootParameters.TOOL, ItemStack.EMPTY).withNullableParameter(LootParameters.BLOCK_ENTITY, tileentity);
|
||||
// if (this.mode == Explosion.Mode.DESTROY) {
|
||||
// lootcontext$builder.withParameter(LootParameters.EXPLOSION_RADIUS, this.size);
|
||||
// }
|
||||
|
||||
blockstate.getDrops(lootcontext$builder).forEach((stack) -> {
|
||||
handleExplosionDrops(objectarraylist, stack, blockpos1);
|
||||
});
|
||||
|
||||
world.setBlockState(blockPos, Blocks.AIR.getDefaultState(), 3);
|
||||
|
||||
// blockstate.onBlockExploded(this.world, blockpos, null);
|
||||
// this.world.getProfiler().endSection();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (Pair<ItemStack, BlockPos> pair : objectarraylist)
|
||||
{
|
||||
Block.spawnAsEntity(this.world, pair.getSecond(), pair.getFirst());
|
||||
}
|
||||
|
||||
world.setBlockState(getPos(), Blocks.AIR.getDefaultState());
|
||||
}
|
||||
}
|
||||
|
||||
private static void handleExplosionDrops(ObjectArrayList<Pair<ItemStack, BlockPos>> dropPositionArray, ItemStack stack, BlockPos pos)
|
||||
{
|
||||
int i = dropPositionArray.size();
|
||||
|
||||
for (int j = 0; j < i; ++j)
|
||||
{
|
||||
Pair<ItemStack, BlockPos> pair = dropPositionArray.get(j);
|
||||
ItemStack itemstack = pair.getFirst();
|
||||
if (ItemEntity.canMergeStacks(itemstack, stack))
|
||||
{
|
||||
ItemStack itemstack1 = ItemEntity.mergeStacks(itemstack, stack, 16);
|
||||
dropPositionArray.set(j, Pair.of(itemstack1, pair.getSecond()));
|
||||
if (stack.isEmpty())
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
dropPositionArray.add(Pair.of(stack, pos));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void deserialize(CompoundNBT tag)
|
||||
{
|
||||
internalCounter = tag.getDouble("internalCounter");
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompoundNBT serialize(CompoundNBT tag)
|
||||
{
|
||||
tag.putDouble("internalCounter", internalCounter);
|
||||
return tag;
|
||||
}
|
||||
}
|
195
src/main/java/wayoftime/bloodmagic/tile/TileShapedExplosive.java
Normal file
195
src/main/java/wayoftime/bloodmagic/tile/TileShapedExplosive.java
Normal file
|
@ -0,0 +1,195 @@
|
|||
package wayoftime.bloodmagic.tile;
|
||||
|
||||
import com.mojang.datafixers.util.Pair;
|
||||
|
||||
import it.unimi.dsi.fastutil.objects.ObjectArrayList;
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.block.BlockState;
|
||||
import net.minecraft.block.Blocks;
|
||||
import net.minecraft.entity.item.ItemEntity;
|
||||
import net.minecraft.entity.player.PlayerEntity;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.loot.LootContext;
|
||||
import net.minecraft.loot.LootParameters;
|
||||
import net.minecraft.nbt.CompoundNBT;
|
||||
import net.minecraft.particles.ParticleTypes;
|
||||
import net.minecraft.tileentity.TileEntity;
|
||||
import net.minecraft.tileentity.TileEntityType;
|
||||
import net.minecraft.util.Direction;
|
||||
import net.minecraft.util.SoundCategory;
|
||||
import net.minecraft.util.SoundEvents;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.util.math.vector.Vector3d;
|
||||
import net.minecraft.world.server.ServerWorld;
|
||||
import net.minecraftforge.registries.ObjectHolder;
|
||||
import wayoftime.bloodmagic.common.block.BlockShapedExplosive;
|
||||
import wayoftime.bloodmagic.tile.base.TileTicking;
|
||||
|
||||
public class TileShapedExplosive extends TileTicking
|
||||
{
|
||||
@ObjectHolder("bloodmagic:shaped_explosive")
|
||||
public static TileEntityType<TileShapedExplosive> TYPE;
|
||||
|
||||
public double internalCounter = 0;
|
||||
public int explosionRadius;
|
||||
public int explosionDepth;
|
||||
|
||||
public TileShapedExplosive(TileEntityType<?> type, int explosionRadius, int explosionDepth)
|
||||
{
|
||||
super(type);
|
||||
this.explosionRadius = explosionRadius;
|
||||
this.explosionDepth = explosionDepth;
|
||||
}
|
||||
|
||||
public TileShapedExplosive()
|
||||
{
|
||||
this(TYPE, 1, 3);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onUpdate()
|
||||
{
|
||||
if (world.isRemote)
|
||||
{
|
||||
return;
|
||||
}
|
||||
// System.out.println("Counter: " + internalCounter);
|
||||
|
||||
internalCounter++;
|
||||
if (internalCounter == 20)
|
||||
{
|
||||
// worldIn.playSound((PlayerEntity)null, tntentity.getPosX(), tntentity.getPosY(), tntentity.getPosZ(), SoundEvents.ENTITY_TNT_PRIMED, SoundCategory.BLOCKS, 1.0F, 1.0F);
|
||||
world.playSound((PlayerEntity) null, this.getPos().getX() + 0.5, this.getPos().getY() + 0.5, this.getPos().getZ() + 0.5, SoundEvents.ITEM_FLINTANDSTEEL_USE, SoundCategory.BLOCKS, 1.0F, world.rand.nextFloat() * 0.4F + 0.8F);
|
||||
((ServerWorld) this.world).spawnParticle(ParticleTypes.FLAME, pos.getX() + 0.5, pos.getY() + 0.5, pos.getZ() + 0.5, 5, 0.02, 0.03, 0.02, 0);
|
||||
}
|
||||
|
||||
if (internalCounter == 30)
|
||||
{
|
||||
world.playSound((PlayerEntity) null, this.getPos().getX() + 0.5, this.getPos().getY() + 0.5, this.getPos().getZ() + 0.5, SoundEvents.ENTITY_TNT_PRIMED, SoundCategory.BLOCKS, 1.0F, 1.0F);
|
||||
}
|
||||
|
||||
if (internalCounter < 30)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (world.rand.nextDouble() < 0.3)
|
||||
{
|
||||
((ServerWorld) this.world).spawnParticle(ParticleTypes.SMOKE, pos.getX() + 0.5, pos.getY() + 0.5, pos.getZ() + 0.5, 1, 0.0D, 0.0D, 0.0D, 0);
|
||||
}
|
||||
|
||||
if (internalCounter == 100)
|
||||
{
|
||||
world.playSound((PlayerEntity) null, this.getPos().getX() + 0.5, this.getPos().getY() + 0.5, this.getPos().getZ() + 0.5, SoundEvents.ENTITY_GENERIC_EXPLODE, SoundCategory.BLOCKS, 4.0F, (1.0F + (world.rand.nextFloat() - world.rand.nextFloat()) * 0.2F) * 0.7F);
|
||||
|
||||
Direction explosiveDirection = this.getBlockState().get(BlockShapedExplosive.ATTACHED).getOpposite();
|
||||
Direction sweepDir1 = Direction.UP;
|
||||
Direction sweepDir2 = Direction.UP;
|
||||
|
||||
int numParticles = explosionDepth * (explosionRadius + 1);
|
||||
|
||||
((ServerWorld) this.world).spawnParticle(ParticleTypes.EXPLOSION, pos.getX() + 0.5 + explosiveDirection.getXOffset() * explosionDepth / 2d, pos.getY() + 0.5 + explosiveDirection.getYOffset() * explosionDepth / 2d, pos.getZ() + 0.5 + explosiveDirection.getZOffset() * explosionDepth / 2d, numParticles, 1.0D, 1.0D, 1.0D, 0);
|
||||
|
||||
switch (explosiveDirection)
|
||||
{
|
||||
case UP:
|
||||
case DOWN:
|
||||
sweepDir1 = Direction.NORTH;
|
||||
sweepDir2 = Direction.EAST;
|
||||
break;
|
||||
case EAST:
|
||||
case WEST:
|
||||
sweepDir1 = Direction.NORTH;
|
||||
sweepDir2 = Direction.UP;
|
||||
break;
|
||||
case NORTH:
|
||||
case SOUTH:
|
||||
sweepDir1 = Direction.EAST;
|
||||
sweepDir2 = Direction.UP;
|
||||
break;
|
||||
}
|
||||
|
||||
ObjectArrayList<Pair<ItemStack, BlockPos>> objectarraylist = new ObjectArrayList<>();
|
||||
|
||||
BlockPos initialPos = getPos();
|
||||
for (int i = 1; i <= explosionDepth; i++)
|
||||
{
|
||||
for (int j = -explosionRadius; j <= explosionRadius; j++)
|
||||
{
|
||||
for (int k = -explosionRadius; k <= explosionRadius; k++)
|
||||
{
|
||||
BlockPos blockpos = initialPos.offset(explosiveDirection, i).offset(sweepDir1, j).offset(sweepDir2, k);
|
||||
|
||||
BlockState blockstate = this.world.getBlockState(blockpos);
|
||||
Block block = blockstate.getBlock();
|
||||
if (!blockstate.isAir(this.world, blockpos))
|
||||
{
|
||||
BlockPos blockpos1 = blockpos.toImmutable();
|
||||
// this.world.getProfiler().startSection("explosion_blocks");
|
||||
if (this.world instanceof ServerWorld)
|
||||
{
|
||||
TileEntity tileentity = blockstate.hasTileEntity() ? this.world.getTileEntity(blockpos)
|
||||
: null;
|
||||
LootContext.Builder lootcontext$builder = (new LootContext.Builder((ServerWorld) this.world)).withRandom(this.world.rand).withParameter(LootParameters.field_237457_g_, Vector3d.copyCentered(blockpos)).withParameter(LootParameters.TOOL, ItemStack.EMPTY).withNullableParameter(LootParameters.BLOCK_ENTITY, tileentity);
|
||||
// if (this.mode == Explosion.Mode.DESTROY) {
|
||||
// lootcontext$builder.withParameter(LootParameters.EXPLOSION_RADIUS, this.size);
|
||||
// }
|
||||
|
||||
blockstate.getDrops(lootcontext$builder).forEach((stack) -> {
|
||||
handleExplosionDrops(objectarraylist, stack, blockpos1);
|
||||
});
|
||||
|
||||
world.setBlockState(blockpos, Blocks.AIR.getDefaultState(), 3);
|
||||
|
||||
// blockstate.onBlockExploded(this.world, blockpos, null);
|
||||
// this.world.getProfiler().endSection();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (Pair<ItemStack, BlockPos> pair : objectarraylist)
|
||||
{
|
||||
Block.spawnAsEntity(this.world, pair.getSecond(), pair.getFirst());
|
||||
}
|
||||
|
||||
world.setBlockState(getPos(), Blocks.AIR.getDefaultState());
|
||||
}
|
||||
}
|
||||
|
||||
private static void handleExplosionDrops(ObjectArrayList<Pair<ItemStack, BlockPos>> dropPositionArray, ItemStack stack, BlockPos pos)
|
||||
{
|
||||
int i = dropPositionArray.size();
|
||||
|
||||
for (int j = 0; j < i; ++j)
|
||||
{
|
||||
Pair<ItemStack, BlockPos> pair = dropPositionArray.get(j);
|
||||
ItemStack itemstack = pair.getFirst();
|
||||
if (ItemEntity.canMergeStacks(itemstack, stack))
|
||||
{
|
||||
ItemStack itemstack1 = ItemEntity.mergeStacks(itemstack, stack, 16);
|
||||
dropPositionArray.set(j, Pair.of(itemstack1, pair.getSecond()));
|
||||
if (stack.isEmpty())
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
dropPositionArray.add(Pair.of(stack, pos));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void deserialize(CompoundNBT tag)
|
||||
{
|
||||
internalCounter = tag.getDouble("internalCounter");
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompoundNBT serialize(CompoundNBT tag)
|
||||
{
|
||||
tag.putDouble("internalCounter", internalCounter);
|
||||
return tag;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,136 @@
|
|||
{
|
||||
"parent": "block/block",
|
||||
"credit": "Made with Blockbench",
|
||||
"textures": {
|
||||
"1": "dungeon_tile",
|
||||
"3": "dungeon_stone",
|
||||
"4": "blankrune",
|
||||
"5": "largebloodstonebrick",
|
||||
"6": "defaultcrystal",
|
||||
"particle": "dungeon_stone"
|
||||
},
|
||||
"elements": [
|
||||
{
|
||||
"name": "base",
|
||||
"from": [2, 0, 2],
|
||||
"to": [14, 2, 14],
|
||||
"faces": {
|
||||
"north": {"uv": [0, 6, 10, 8], "texture": "#3"},
|
||||
"east": {"uv": [0, 6, 10, 8], "texture": "#3"},
|
||||
"south": {"uv": [0, 6, 10, 8], "texture": "#3"},
|
||||
"west": {"uv": [8, 14, 18, 16], "texture": "#3"},
|
||||
"up": {"uv": [10, 10, 0, 0], "texture": "#3"},
|
||||
"down": {"uv": [10, 0, 0, 10], "texture": "#3"}
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "core",
|
||||
"from": [4, 2, 4],
|
||||
"to": [12, 5, 12],
|
||||
"rotation": {"angle": 0, "axis": "y", "origin": [12, 9, 13]},
|
||||
"faces": {
|
||||
"north": {"uv": [4, 5, 12, 8], "texture": "#6"},
|
||||
"east": {"uv": [4, 5, 12, 8], "texture": "#6"},
|
||||
"south": {"uv": [4, 5, 12, 8], "texture": "#6"},
|
||||
"west": {"uv": [4, 5, 12, 8], "texture": "#6"},
|
||||
"up": {"uv": [4, 4, 12, 12], "texture": "#6"},
|
||||
"down": {"uv": [0, 0, 8, 8], "texture": "#6"}
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "casing1",
|
||||
"from": [7, 2, 3],
|
||||
"to": [9, 6, 13],
|
||||
"rotation": {"angle": 0, "axis": "y", "origin": [15, 10, 11]},
|
||||
"faces": {
|
||||
"north": {"uv": [0, 0, 2, 4], "texture": "#5"},
|
||||
"east": {"uv": [0, 0, 10, 4], "texture": "#5"},
|
||||
"south": {"uv": [0, 0, 2, 4], "texture": "#5"},
|
||||
"west": {"uv": [0, 0, 10, 4], "texture": "#5"},
|
||||
"up": {"uv": [0, 0, 2, 10], "texture": "#5"},
|
||||
"down": {"uv": [0, 0, 2, 10], "texture": "#5"}
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "casing2",
|
||||
"from": [3, 2, 7],
|
||||
"to": [13, 6, 9],
|
||||
"rotation": {"angle": 0, "axis": "y", "origin": [11, 10, 15]},
|
||||
"faces": {
|
||||
"north": {"uv": [0, 0, 10, 4], "texture": "#5"},
|
||||
"east": {"uv": [0, 0, 2, 4], "texture": "#5"},
|
||||
"south": {"uv": [0, 0, 10, 4], "texture": "#5"},
|
||||
"west": {"uv": [0, 0, 2, 4], "texture": "#5"},
|
||||
"up": {"uv": [0, 0, 10, 2], "texture": "#5"},
|
||||
"down": {"uv": [0, 0, 10, 2], "texture": "#5"}
|
||||
}
|
||||
},
|
||||
{
|
||||
"from": [6, 5, 6],
|
||||
"to": [10, 7, 10],
|
||||
"rotation": {"angle": 0, "axis": "y", "origin": [14, 13, 14]},
|
||||
"faces": {
|
||||
"north": {"uv": [0, 0, 4, 2], "texture": "#4"},
|
||||
"east": {"uv": [0, 0, 4, 2], "texture": "#4"},
|
||||
"south": {"uv": [0, 0, 4, 2], "texture": "#4"},
|
||||
"west": {"uv": [0, 0, 4, 2], "texture": "#4"},
|
||||
"up": {"uv": [0, 0, 4, 4], "texture": "#4"},
|
||||
"down": {"uv": [0, 0, 4, 4], "texture": "#4"}
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "edge1",
|
||||
"from": [3, 2, 3],
|
||||
"to": [6, 3, 6],
|
||||
"rotation": {"angle": 0, "axis": "y", "origin": [14, 8, 9]},
|
||||
"faces": {
|
||||
"north": {"uv": [5, 7, 8, 8], "texture": "#1"},
|
||||
"east": {"uv": [5, 7, 8, 8], "texture": "#1"},
|
||||
"south": {"uv": [5, 7, 8, 8], "texture": "#1"},
|
||||
"west": {"uv": [5, 7, 8, 8], "texture": "#1"},
|
||||
"up": {"uv": [5, 5, 8, 8], "rotation": 180, "texture": "#1"},
|
||||
"down": {"uv": [5, 5, 8, 8], "rotation": 180, "texture": "#1"}
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "edge2",
|
||||
"from": [3, 2, 10],
|
||||
"to": [6, 3, 13],
|
||||
"rotation": {"angle": 0, "axis": "y", "origin": [14, 8, 16]},
|
||||
"faces": {
|
||||
"north": {"uv": [5, 7, 8, 8], "texture": "#1"},
|
||||
"east": {"uv": [5, 7, 8, 8], "texture": "#1"},
|
||||
"south": {"uv": [5, 7, 8, 8], "texture": "#1"},
|
||||
"west": {"uv": [5, 7, 8, 8], "texture": "#1"},
|
||||
"up": {"uv": [5, 5, 8, 8], "rotation": 90, "texture": "#1"},
|
||||
"down": {"uv": [5, 5, 8, 8], "rotation": 90, "texture": "#1"}
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "edge3",
|
||||
"from": [10, 2, 3],
|
||||
"to": [13, 3, 6],
|
||||
"faces": {
|
||||
"north": {"uv": [5, 7, 8, 8], "texture": "#1"},
|
||||
"east": {"uv": [5, 7, 8, 8], "texture": "#1"},
|
||||
"south": {"uv": [5, 7, 8, 8], "texture": "#1"},
|
||||
"west": {"uv": [5, 7, 8, 8], "texture": "#1"},
|
||||
"up": {"uv": [5, 5, 8, 8], "rotation": 270, "texture": "#1"},
|
||||
"down": {"uv": [5, 5, 8, 8], "rotation": 270, "texture": "#1"}
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "edge4",
|
||||
"from": [10, 2, 10],
|
||||
"to": [13, 3, 13],
|
||||
"faces": {
|
||||
"north": {"uv": [5, 7, 8, 8], "texture": "#1"},
|
||||
"east": {"uv": [5, 7, 8, 8], "texture": "#1"},
|
||||
"south": {"uv": [5, 7, 8, 8], "texture": "#1"},
|
||||
"west": {"uv": [5, 7, 8, 8], "texture": "#1"},
|
||||
"up": {"uv": [5, 5, 8, 8], "texture": "#1"},
|
||||
"down": {"uv": [5, 6, 8, 9], "texture": "#1"}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue