Added granny smith apple trees and more related log blocks for zap apple trees

* Earth ponies can now kick zap and granny smith trees
* Kicking these types of trees will dislodge their fruit rather than spawn apples
This commit is contained in:
Sollace 2022-09-25 00:14:29 +02:00
parent def7e37712
commit 9476b5634c
50 changed files with 1078 additions and 93 deletions

View file

@ -29,6 +29,7 @@ import net.minecraft.entity.passive.BeeEntity;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.item.ItemStack;
import net.minecraft.predicate.entity.EntityPredicates;
import net.minecraft.server.world.ServerWorld;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.Box;
import net.minecraft.util.math.Vec3d;
@ -200,7 +201,9 @@ public class EarthPonyKickAbility implements Ability<Pos> {
}, (world, state, position, recurse) -> {
affectBlockChange(player, position);
if (world.getBlockState(position.down()).isAir()) {
BlockState below = world.getBlockState(position.down());
if (below.isAir()) {
ItemStack stack = tree.pickRandomStack(state);
if (!stack.isEmpty()) {
world.syncWorldEvent(WorldEvents.BLOCK_BROKEN, position, Block.getRawIdFromState(state));
@ -212,6 +215,19 @@ public class EarthPonyKickAbility implements Ability<Pos> {
stack
));
}
} else if (below.getBlock() instanceof Buckable buckable) {
List<ItemStack> stacks = buckable.onBucked((ServerWorld)world, state, pos);
if (!stacks.isEmpty()) {
world.syncWorldEvent(WorldEvents.BLOCK_BROKEN, position, Block.getRawIdFromState(state));
stacks.forEach(stack -> {
capturedDrops.add(new ItemEntity(world,
position.getX() + world.random.nextFloat(),
position.getY() - 0.5,
position.getZ() + world.random.nextFloat(),
stack
));
});
}
}
});
@ -254,4 +270,8 @@ public class EarthPonyKickAbility implements Ability<Pos> {
}
}, PosHelper.HORIZONTAL);
}
public interface Buckable {
List<ItemStack> onBucked(ServerWorld world, BlockState state, BlockPos pos);
}
}

View file

@ -0,0 +1,142 @@
package com.minelittlepony.unicopia.block;
import java.util.*;
import java.util.function.Supplier;
import org.jetbrains.annotations.Nullable;
import com.minelittlepony.unicopia.USounds;
import net.minecraft.block.*;
import net.minecraft.item.ItemStack;
import net.minecraft.server.world.ServerWorld;
import net.minecraft.sound.BlockSoundGroup;
import net.minecraft.sound.SoundCategory;
import net.minecraft.state.StateManager;
import net.minecraft.state.property.*;
import net.minecraft.state.property.Properties;
import net.minecraft.util.StringIdentifiable;
import net.minecraft.util.math.*;
import net.minecraft.util.math.random.Random;
import net.minecraft.world.*;
import net.minecraft.world.event.GameEvent;
public class FruitBearingBlock extends LeavesBlock implements TintedBlock {
public static final IntProperty AGE = Properties.AGE_25;
public static final int WITHER_AGE = 15;
public static final EnumProperty<Stage> STAGE = EnumProperty.of("stage", Stage.class);
public static final List<FruitBearingBlock> REGISTRY = new ArrayList<>();
private final Supplier<Block> fruit;
private final Supplier<ItemStack> rottenFruitSupplier;
private final int overlay;
public FruitBearingBlock(Settings settings, int overlay, Supplier<Block> fruit, Supplier<ItemStack> rottenFruitSupplier) {
super(settings
.ticksRandomly()
.nonOpaque()
.allowsSpawning(UBlocks::canSpawnOnLeaves)
.suffocates(UBlocks::never)
.blockVision(UBlocks::never));
setDefaultState(getDefaultState().with(STAGE, Stage.IDLE));
this.overlay = overlay;
this.fruit = fruit;
this.rottenFruitSupplier = rottenFruitSupplier;
REGISTRY.add(this);
}
@Override
protected void appendProperties(StateManager.Builder<Block, BlockState> builder) {
super.appendProperties(builder);
builder.add(STAGE).add(AGE);
}
@Override
public boolean hasRandomTicks(BlockState state) {
return true;
}
@Override
public void randomTick(BlockState state, ServerWorld world, BlockPos pos, Random random) {
super.randomTick(state, world, pos, random);
if (shouldDecay(state)) {
return;
}
if (world.isDay()) {
BlockSoundGroup group = getSoundGroup(state);
if (state.get(STAGE) == Stage.FRUITING) {
state = state.cycle(AGE);
if (state.get(AGE) > 20) {
state = state.with(AGE, 0).cycle(STAGE);
}
} else {
state = state.with(AGE, 0).cycle(STAGE);
}
world.setBlockState(pos, state, Block.NOTIFY_ALL);
BlockPos fruitPosition = pos.down();
Stage stage = state.get(STAGE);
if (stage == Stage.FRUITING && isPositionValidForFruit(state, pos)) {
if (world.isAir(fruitPosition)) {
world.setBlockState(fruitPosition, fruit.get().getDefaultState(), Block.NOTIFY_ALL);
}
}
BlockState fruitState = world.getBlockState(fruitPosition);
if (stage == Stage.WITHERING && fruitState.isOf(fruit.get())) {
if (world.random.nextInt(2) == 0) {
Block.dropStack(world, fruitPosition, rottenFruitSupplier.get());
} else {
Block.dropStacks(fruitState, world, fruitPosition, fruitState.hasBlockEntity() ? world.getBlockEntity(fruitPosition) : null, null, ItemStack.EMPTY);
}
if (world.removeBlock(fruitPosition, false)) {
world.emitGameEvent(GameEvent.BLOCK_DESTROY, pos, GameEvent.Emitter.of(fruitState));
}
world.playSound(null, pos, USounds.ITEM_APPLE_ROT, SoundCategory.BLOCKS, group.getVolume(), group.getPitch());
}
}
}
@Override
public BlockState getStateForNeighborUpdate(BlockState state, Direction direction, BlockState neighborState, WorldAccess world, BlockPos pos, BlockPos neighborPos) {
BlockState newState = super.getStateForNeighborUpdate(state, direction, neighborState, world, pos, neighborPos);
return newState;
}
@Override
public int getTint(BlockState state, @Nullable BlockRenderView world, @Nullable BlockPos pos, int foliageColor) {
return TintedBlock.blend(foliageColor, overlay);
}
private boolean isPositionValidForFruit(BlockState state, BlockPos pos) {
return state.getRenderingSeed(pos) % 3 == 1;
}
public enum Stage implements StringIdentifiable {
IDLE,
FLOWERING,
FRUITING,
WITHERING;
private static final Stage[] VALUES = values();
public Stage getNext() {
return VALUES[(ordinal() + 1) % VALUES.length];
}
@Override
public String asString() {
return name().toLowerCase(Locale.ROOT);
}
}
}

View file

@ -1,19 +1,26 @@
package com.minelittlepony.unicopia.block;
import java.util.ArrayList;
import java.util.List;
import com.minelittlepony.unicopia.ability.EarthPonyKickAbility.Buckable;
import net.minecraft.block.*;
import net.minecraft.item.ItemStack;
import net.minecraft.server.world.ServerWorld;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.Direction;
import net.minecraft.util.math.random.Random;
import net.minecraft.util.shape.VoxelShape;
import net.minecraft.util.shape.VoxelShapes;
import net.minecraft.world.BlockView;
import net.minecraft.world.WorldView;
import net.minecraft.world.*;
public class FruitBlock extends Block {
public class FruitBlock extends Block implements Buckable {
public static final int DEFAULT_FRUIT_SIZE = 8;
public static final VoxelShape DEFAULT_SHAPE = createFruitShape(DEFAULT_FRUIT_SIZE);
public static final List<FruitBlock> REGISTRY = new ArrayList<>();
private final Direction attachmentFace;
private final Block stem;
private final VoxelShape shape;
@ -30,6 +37,7 @@ public class FruitBlock extends Block {
this.attachmentFace = attachmentFace;
this.stem = stem;
this.shape = shape;
REGISTRY.add(this);
}
@Override
@ -41,7 +49,16 @@ public class FruitBlock extends Block {
public boolean canPlaceAt(BlockState state, WorldView world, BlockPos pos) {
BlockPos attachedPos = pos.offset(attachmentFace.getOpposite());
BlockState attachedState = world.getBlockState(attachedPos);
return canAttachTo(attachedState) && attachedState.isSideSolidFullSquare(world, attachedPos, attachmentFace);
return canAttachTo(attachedState);
}
@Deprecated
@Override
public BlockState getStateForNeighborUpdate(BlockState state, Direction direction, BlockState neighborState, WorldAccess world, BlockPos pos, BlockPos neighborPos) {
if (!state.canPlaceAt(world, pos)) {
return Blocks.AIR.getDefaultState();
}
return super.getStateForNeighborUpdate(state, direction, neighborState, world, pos, neighborPos);
}
@Override
@ -54,4 +71,11 @@ public class FruitBlock extends Block {
protected boolean canAttachTo(BlockState state) {
return state.isOf(stem);
}
@Override
public List<ItemStack> onBucked(ServerWorld world, BlockState state, BlockPos pos) {
List<ItemStack> stacks = Block.getDroppedStacks(state, world, pos, null);
world.breakBlock(pos, false);
return stacks;
}
}

View file

@ -0,0 +1,53 @@
package com.minelittlepony.unicopia.block;
import java.util.ArrayList;
import java.util.List;
import org.jetbrains.annotations.Nullable;
import net.minecraft.block.Block;
import net.minecraft.block.BlockState;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.MathHelper;
import net.minecraft.world.BlockRenderView;
public interface TintedBlock {
List<Block> REGISTRY = new ArrayList<>();
int MAX_BIT_SHIFT = 8 * 3;
int WHITE = 0xFFFFFF;
int getTint(BlockState state, @Nullable BlockRenderView world, @Nullable BlockPos pos, int foliageColor);
/**
* Rotates a color's components by a given number of bytes.
*/
static int rotate(int color, int bitShift) {
bitShift = MathHelper.clamp(bitShift, -MAX_BIT_SHIFT, MAX_BIT_SHIFT);
return WHITE & (
(color << bitShift)
| ((color >> (MAX_BIT_SHIFT - bitShift)) & ~(WHITE << bitShift))
);
}
/**
* Blends two colors together using the overlay color's opacity value
*/
static int blend(int color, int overlay) {
return blend(color, overlay & WHITE, ((overlay >> MAX_BIT_SHIFT) & 0xFF) / 255F);
}
/**
* Blends two colors an alpha ratio to determine the opacity of the overlay.
*/
static int blend(int color, int overlay, float blend) {
return blendComponent(color & 0xFF, overlay & 0xFF, blend)
| (blendComponent((color >> 8) & 0xFF, (overlay >> 8) & 0xFF, blend) << 8)
| (blendComponent((color >> 16) & 0xFF, (overlay >> 16) & 0xFF, blend) << 16);
}
private static int blendComponent(int color, int overlay, float blend) {
return (int)((color * (1F - blend)) + (overlay * blend));
}
}

View file

@ -0,0 +1,118 @@
package com.minelittlepony.unicopia.block;
import java.util.*;
import java.util.function.Predicate;
import java.util.function.Supplier;
import net.fabricmc.fabric.api.biome.v1.*;
import net.fabricmc.fabric.api.object.builder.v1.block.FabricBlockSettings;
import net.minecraft.block.*;
import net.minecraft.block.sapling.SaplingGenerator;
import net.minecraft.item.*;
import net.minecraft.tag.BiomeTags;
import net.minecraft.util.Identifier;
import net.minecraft.util.math.random.Random;
import net.minecraft.util.registry.*;
import net.minecraft.world.gen.GenerationStep;
import net.minecraft.world.gen.feature.*;
import net.minecraft.world.gen.feature.size.TwoLayersFeatureSize;
import net.minecraft.world.gen.foliage.FoliagePlacer;
import net.minecraft.world.gen.placementmodifier.PlacementModifier;
import net.minecraft.world.gen.stateprovider.BlockStateProvider;
import net.minecraft.world.gen.trunk.TrunkPlacer;
public record Tree (
RegistryEntry<ConfiguredFeature<TreeFeatureConfig, ?>> configuredFeature,
Optional<RegistryEntry<PlacedFeature>> placedFeature,
Optional<Block> sapling
) {
public static final List<Tree> REGISTRY = new ArrayList<>();
public static class Builder {
public static final Predicate<BiomeSelectionContext> IS_FOREST = BiomeSelectors.foundInOverworld().and(BiomeSelectors.tag(BiomeTags.IS_FOREST));
public static Builder create(Identifier id, TrunkPlacer trunkPlacer, FoliagePlacer foliagePlacer) {
return new Builder(id, trunkPlacer, foliagePlacer);
}
private Block logType = Blocks.OAK_LOG;
private Block leavesType = Blocks.OAK_LEAVES;
private Optional<Identifier> saplingId = Optional.empty();
private final TrunkPlacer trunkPlacer;
private final FoliagePlacer foliagePlacer;
private final Identifier id;
private Optional<Predicate<BiomeSelectionContext>> selector = Optional.empty();
private Optional<PlacementModifier> countModifier = Optional.empty();
private Optional<Supplier<TreeFeatureConfig.Builder>> configSupplier = Optional.empty();
private Builder(Identifier id, TrunkPlacer trunkPlacer, FoliagePlacer foliagePlacer) {
this.id = id;
this.trunkPlacer = trunkPlacer;
this.foliagePlacer = foliagePlacer;
}
public Builder log(Block log) {
this.logType = log;
return this;
}
public Builder leaves(Block leaves) {
this.leavesType = leaves;
return this;
}
public Builder sapling(Identifier saplingId) {
this.saplingId = Optional.of(saplingId);
return this;
}
public Builder count(int count, float extraChance, int extraCount) {
countModifier = Optional.of(PlacedFeatures.createCountExtraModifier(count, extraChance, extraCount));
return this;
}
public Builder biomes(Predicate<BiomeSelectionContext> selector) {
this.selector = Optional.of(selector);
return this;
}
public Builder shape(Supplier<TreeFeatureConfig.Builder> shape) {
this.configSupplier = Optional.of(shape);
return this;
}
public Tree build() {
RegistryEntry<ConfiguredFeature<TreeFeatureConfig, ?>> configuredFeature = ConfiguredFeatures.register(id.toString(), Feature.TREE, configSupplier.map(Supplier::get)
.orElseGet(() -> new TreeFeatureConfig.Builder(
BlockStateProvider.of(logType),
trunkPlacer,
BlockStateProvider.of(leavesType),
foliagePlacer,
new TwoLayersFeatureSize(6, 0, 16)
).forceDirt()).build());
Optional<Block> sapling = saplingId.map(id -> UBlocks.register(id, new SaplingBlock(new SaplingGenerator() {
@Override
protected RegistryEntry<? extends ConfiguredFeature<?, ?>> getTreeFeature(Random rng, boolean flowersNearby) {
return configuredFeature;
}
}, FabricBlockSettings.copy(Blocks.OAK_SAPLING)), ItemGroup.DECORATIONS));
Optional<RegistryEntry<PlacedFeature>> placedFeature = selector.map(selector -> {
var pf = PlacedFeatures.register(id.toString() + "_checked", configuredFeature,
VegetationPlacedFeatures.modifiersWithWouldSurvive(countModifier.orElseThrow(), sapling.orElse(Blocks.OAK_SAPLING))
);
BiomeModifications.addFeature(selector, GenerationStep.Feature.VEGETAL_DECORATION, pf.getKey().get());
return pf;
});
Tree tree = new Tree(configuredFeature, placedFeature, sapling);
REGISTRY.add(tree);
return tree;
}
}
}

View file

@ -1,20 +1,21 @@
package com.minelittlepony.unicopia.block;
import com.minelittlepony.unicopia.Unicopia;
import com.minelittlepony.unicopia.item.UItems;
import net.fabricmc.fabric.api.object.builder.v1.block.FabricBlockSettings;
import net.fabricmc.fabric.api.object.builder.v1.block.FabricMaterialBuilder;
import net.fabricmc.fabric.api.registry.FlammableBlockRegistry;
import net.fabricmc.fabric.api.registry.StrippableBlockRegistry;
import net.minecraft.block.*;
import net.minecraft.block.sapling.SaplingGenerator;
import net.minecraft.entity.EntityType;
import net.minecraft.item.*;
import net.minecraft.sound.BlockSoundGroup;
import net.minecraft.util.Identifier;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.Direction;
import net.minecraft.util.math.random.Random;
import net.minecraft.util.registry.Registry;
import net.minecraft.util.registry.RegistryEntry;
import net.minecraft.world.BlockView;
import net.minecraft.world.gen.feature.ConfiguredFeature;
public interface UBlocks {
Block ROCKS = register("rocks", new RockCropBlock(FabricBlockSettings.of(
@ -27,24 +28,49 @@ public interface UBlocks {
Block FROSTED_OBSIDIAN = register("frosted_obsidian", new FrostedObsidianBlock(FabricBlockSettings.copy(Blocks.OBSIDIAN).ticksRandomly()));
Block ZAPLING = register("zapling", new SaplingBlock(new SaplingGenerator() {
@Override
protected RegistryEntry<? extends ConfiguredFeature<?, ?>> getTreeFeature(Random rng, boolean flowersNearby) {
return UTreeGen.ZAP_APPLE_TREE;
}
}, FabricBlockSettings.copy(Blocks.OAK_SAPLING)));
Block ZAP_LOG = register("zap_log", new ZapAppleLogBlock(Blocks.OAK_LOG, MapColor.GRAY, MapColor.DEEPSLATE_GRAY), ItemGroup.MATERIALS);
Block ZAP_WOOD = register("zap_wood", new ZapBlock(AbstractBlock.Settings.of(Material.WOOD, MapColor.DEEPSLATE_GRAY).sounds(BlockSoundGroup.WOOD), Blocks.OAK_WOOD), ItemGroup.MATERIALS);
Block ZAP_LOG = register("zap_log", new ZapAppleLogBlock(MapColor.GRAY, MapColor.DEEPSLATE_GRAY));
Block ZAP_LEAVES = register("zap_leaves", new ZapAppleLeavesBlock());
Block STRIPPED_ZAP_LOG = register("stripped_zap_log", new ZapAppleLogBlock(Blocks.STRIPPED_OAK_LOG, MapColor.LIGHT_GRAY, MapColor.GRAY), ItemGroup.MATERIALS);
Block STRIPPED_ZAP_WOOD = register("stripped_zap_wood", new ZapBlock(AbstractBlock.Settings.of(Material.WOOD, MapColor.DEEPSLATE_GRAY).sounds(BlockSoundGroup.WOOD), Blocks.STRIPPED_OAK_WOOD), ItemGroup.MATERIALS);
Block ZAP_LEAVES = register("zap_leaves", new ZapAppleLeavesBlock(), ItemGroup.DECORATIONS);
Block ZAP_BULB = register("zap_bulb", new FruitBlock(FabricBlockSettings.of(Material.GOURD, MapColor.GRAY).strength(500, 1200).sounds(BlockSoundGroup.AZALEA_LEAVES), Direction.DOWN, ZAP_LEAVES, FruitBlock.DEFAULT_SHAPE));
Block ZAP_APPLE = register("zap_apple", new FruitBlock(FabricBlockSettings.of(Material.GOURD, MapColor.GRAY).sounds(BlockSoundGroup.AZALEA_LEAVES), Direction.DOWN, ZAP_LEAVES, FruitBlock.DEFAULT_SHAPE));
private static <T extends Block> T register(String name, T item) {
return Registry.register(Registry.BLOCK, Unicopia.id(name), item);
Block GREEN_APPLE_LEAVES = register("green_apple_leaves", new FruitBearingBlock(FabricBlockSettings.copy(Blocks.OAK_LEAVES),
0xE5FFFF88,
() -> UBlocks.GREEN_APPLE,
() -> UItems.GREEN_APPLE.getDefaultStack()
), ItemGroup.DECORATIONS);
Block GREEN_APPLE = register("green_apple", new FruitBlock(FabricBlockSettings.of(Material.GOURD, MapColor.GREEN).sounds(BlockSoundGroup.WOOD), Direction.DOWN, GREEN_APPLE_LEAVES, FruitBlock.DEFAULT_SHAPE));
static <T extends Block> T register(String name, T item) {
return register(Unicopia.id(name), item);
}
static void bootstrap() {}
static <T extends Block> T register(String name, T block, ItemGroup group) {
return register(Unicopia.id(name), block, group);
}
static <T extends Block> T register(Identifier id, T block, ItemGroup group) {
UItems.register(id, new BlockItem(block, new Item.Settings().group(group)));
return register(id, block);
}
static <T extends Block> T register(Identifier id, T block) {
if (block instanceof TintedBlock) {
TintedBlock.REGISTRY.add(block);
}
return Registry.register(Registry.BLOCK, id, block);
}
static void bootstrap() {
StrippableBlockRegistry.register(ZAP_LOG, STRIPPED_ZAP_LOG);
StrippableBlockRegistry.register(ZAP_WOOD, STRIPPED_ZAP_WOOD);
FlammableBlockRegistry.getDefaultInstance().add(GREEN_APPLE_LEAVES, 30, 60);
FlammableBlockRegistry.getDefaultInstance().add(GREEN_APPLE, 20, 50);
}
static boolean never(BlockState state, BlockView world, BlockPos pos) {
return false;

View file

@ -1,41 +1,48 @@
package com.minelittlepony.unicopia.block;
import net.fabricmc.fabric.api.biome.v1.*;
import net.minecraft.tag.BiomeTags;
import com.minelittlepony.unicopia.Unicopia;
import net.minecraft.block.*;
import net.minecraft.tag.BlockTags;
import net.minecraft.util.math.intprovider.ConstantIntProvider;
import net.minecraft.util.math.intprovider.UniformIntProvider;
import net.minecraft.util.registry.*;
import net.minecraft.world.gen.GenerationStep;
import net.minecraft.world.gen.feature.*;
import net.minecraft.world.gen.feature.size.TwoLayersFeatureSize;
import net.minecraft.util.registry.Registry;
import net.minecraft.world.gen.foliage.BlobFoliagePlacer;
import net.minecraft.world.gen.foliage.JungleFoliagePlacer;
import net.minecraft.world.gen.stateprovider.BlockStateProvider;
import net.minecraft.world.gen.trunk.StraightTrunkPlacer;
import net.minecraft.world.gen.trunk.UpwardsBranchingTrunkPlacer;
public interface UTreeGen {
RegistryEntry<ConfiguredFeature<TreeFeatureConfig, ?>> ZAP_APPLE_TREE = ConfiguredFeatures.register("unicopia:zap_apple_tree", Feature.TREE, new TreeFeatureConfig.Builder(
BlockStateProvider.of(UBlocks.ZAP_LOG),
new UpwardsBranchingTrunkPlacer(7, 2, 3,
UniformIntProvider.create(3, 6), 0.3f,
Tree ZAP_APPLE_TREE = Tree.Builder.create(Unicopia.id("zap_apple_tree"), new UpwardsBranchingTrunkPlacer(
7, 2, 3,
UniformIntProvider.create(3, 6),
0.3f,
UniformIntProvider.create(1, 3),
Registry.BLOCK.getOrCreateEntryList(BlockTags.MANGROVE_LOGS_CAN_GROW_THROUGH)
),
BlockStateProvider.of(UBlocks.ZAP_LEAVES),
new JungleFoliagePlacer(
), new JungleFoliagePlacer(
ConstantIntProvider.create(3),
ConstantIntProvider.create(2),
3
),
new TwoLayersFeatureSize(6, 0, 16)
).forceDirt()
.build()
);
RegistryEntry<PlacedFeature> TREES_ZAP = PlacedFeatures.register("unicopia:trees_zap", ZAP_APPLE_TREE,
VegetationPlacedFeatures.modifiersWithWouldSurvive(PlacedFeatures.createCountExtraModifier(0, 0.01F, 1), UBlocks.ZAPLING)
);
)
)
.log(UBlocks.ZAP_LOG)
.leaves(UBlocks.ZAP_LEAVES)
.sapling(Unicopia.id("zapling"))
.biomes(Tree.Builder.IS_FOREST)
.count(0, 0.01F, 1)
.build();
Tree GREEN_APPLE_TREE = createAppleTree("green_apple", UBlocks.GREEN_APPLE_LEAVES);
static void bootstrap() {
BiomeModifications.addFeature(BiomeSelectors.foundInOverworld().and(BiomeSelectors.tag(BiomeTags.IS_FOREST)), GenerationStep.Feature.VEGETAL_DECORATION, TREES_ZAP.getKey().get());
static Tree createAppleTree(String name, Block leaves) {
return Tree.Builder.create(Unicopia.id(name + "_tree"),
new StraightTrunkPlacer(4, 6, 2),
new BlobFoliagePlacer(ConstantIntProvider.create(3), ConstantIntProvider.create(0), 3)
)
.log(Blocks.OAK_LOG)
.leaves(leaves)
.sapling(Unicopia.id(name + "_sapling"))
.build();
}
static void bootstrap() { }
}

View file

@ -1,29 +1,24 @@
package com.minelittlepony.unicopia.block;
import org.jetbrains.annotations.Nullable;
import com.minelittlepony.unicopia.block.data.ZapAppleStageStore;
import com.minelittlepony.unicopia.entity.player.Pony;
import com.minelittlepony.unicopia.particle.ParticleUtils;
import com.minelittlepony.unicopia.particle.UParticles;
import net.minecraft.block.*;
import net.minecraft.entity.*;
import net.minecraft.entity.damage.DamageSource;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.fluid.Fluid;
import net.minecraft.item.ItemPlacementContext;
import net.minecraft.server.world.ServerWorld;
import net.minecraft.sound.BlockSoundGroup;
import net.minecraft.state.StateManager;
import net.minecraft.state.property.EnumProperty;
import net.minecraft.state.property.*;
import net.minecraft.util.math.*;
import net.minecraft.util.math.random.Random;
import net.minecraft.util.shape.VoxelShape;
import net.minecraft.util.shape.VoxelShapes;
import net.minecraft.world.BlockView;
import net.minecraft.world.World;
import net.minecraft.world.event.GameEvent;
import net.minecraft.world.*;
public class ZapAppleLeavesBlock extends LeavesBlock {
public class ZapAppleLeavesBlock extends LeavesBlock implements TintedBlock {
public static final EnumProperty<ZapAppleStageStore.Stage> STAGE = EnumProperty.of("stage", ZapAppleStageStore.Stage.class);
ZapAppleLeavesBlock() {
@ -118,7 +113,7 @@ public class ZapAppleLeavesBlock extends LeavesBlock {
@Override
public void onBlockBreakStart(BlockState state, World world, BlockPos pos, PlayerEntity player) {
triggerLightning(state, world, pos, player);
ZapBlock.triggerLightning(state, world, pos, player);
}
@Deprecated
@ -149,9 +144,23 @@ public class ZapAppleLeavesBlock extends LeavesBlock {
return state.get(STAGE) == ZapAppleStageStore.Stage.HIBERNATING;
}
@Override
public int getTint(BlockState state, @Nullable BlockRenderView world, @Nullable BlockPos pos, int foliageColor) {
if (pos == null) {
return 0x4C7EFA;
}
return TintedBlock.blend(TintedBlock.rotate(foliageColor, 2), 0x0000FF, 0.3F);
}
@Deprecated
@Override
public float calcBlockBreakingDelta(BlockState state, PlayerEntity player, BlockView world, BlockPos pos) {
if (state.get(PERSISTENT)) {
return Blocks.OAK_LEAVES.calcBlockBreakingDelta(Blocks.OAK_LEAVES.getDefaultState(), player, world, pos);
}
float delta = super.calcBlockBreakingDelta(state, player, world, pos);
if (Pony.of(player).getSpecies().canUseEarth()) {
@ -164,25 +173,4 @@ public class ZapAppleLeavesBlock extends LeavesBlock {
return MathHelper.clamp(delta, 0, 0.9F);
}
public static void triggerLightning(BlockState state, World world, BlockPos pos, PlayerEntity player) {
if (world instanceof ServerWorld serverWorld) {
Vec3d center = Vec3d.ofCenter(pos);
LightningEntity lightning = EntityType.LIGHTNING_BOLT.create(world);
world.getOtherEntities(null, Box.from(center).expand(7)).forEach(other -> {
float dist = (float)other.getPos().distanceTo(center);
if (dist < 4) {
other.onStruckByLightning(serverWorld, lightning);
} else {
float damage = 3 / dist;
if (damage > 1) {
other.damage(DamageSource.LIGHTNING_BOLT, damage);
}
}
});
}
world.emitGameEvent(GameEvent.LIGHTNING_STRIKE, pos, GameEvent.Emitter.of(state));
ParticleUtils.spawnParticle(world, UParticles.LIGHTNING_BOLT, Vec3d.ofCenter(pos), Vec3d.ZERO);
}
}

View file

@ -4,25 +4,54 @@ import com.minelittlepony.unicopia.entity.player.Pony;
import net.minecraft.block.*;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.item.ItemPlacementContext;
import net.minecraft.sound.BlockSoundGroup;
import net.minecraft.state.StateManager;
import net.minecraft.state.property.BooleanProperty;
import net.minecraft.state.property.Properties;
import net.minecraft.util.math.*;
import net.minecraft.world.BlockView;
import net.minecraft.world.World;
public class ZapAppleLogBlock extends PillarBlock {
ZapAppleLogBlock(MapColor topMapColor, MapColor sideMapColor) {
super(AbstractBlock.Settings.of(Material.WOOD, state -> state.get(PillarBlock.AXIS) == Direction.Axis.Y ? topMapColor : sideMapColor).strength(2.0f).sounds(BlockSoundGroup.WOOD).strength(500, 1200));
public static final BooleanProperty NATURAL = Properties.PERSISTENT;
private final Block artifialModelBlock;
ZapAppleLogBlock(Block artifialModelBlock, MapColor topMapColor, MapColor sideMapColor) {
super(AbstractBlock.Settings.of(Material.WOOD,
state -> state.get(PillarBlock.AXIS) == Direction.Axis.Y ? topMapColor : sideMapColor
)
.sounds(BlockSoundGroup.WOOD)
.strength(500, 1200));
setDefaultState(getDefaultState().with(NATURAL, true));
this.artifialModelBlock = artifialModelBlock;
}
@Override
protected void appendProperties(StateManager.Builder<Block, BlockState> builder) {
super.appendProperties(builder);
builder.add(NATURAL);
}
@Override
public BlockState getPlacementState(ItemPlacementContext ctx) {
return getDefaultState().with(NATURAL, false);
}
@Deprecated
@Override
public void onBlockBreakStart(BlockState state, World world, BlockPos pos, PlayerEntity player) {
ZapAppleLeavesBlock.triggerLightning(state, world, pos, player);
ZapBlock.triggerLightning(state, world, pos, player);
}
@Deprecated
@Override
public float calcBlockBreakingDelta(BlockState state, PlayerEntity player, BlockView world, BlockPos pos) {
if (!state.get(NATURAL)) {
return artifialModelBlock.calcBlockBreakingDelta(artifialModelBlock.getDefaultState(), player, world, pos);
}
float delta = super.calcBlockBreakingDelta(state, player, world, pos);
if (Pony.of(player).getSpecies().canUseEarth()) {

View file

@ -0,0 +1,86 @@
package com.minelittlepony.unicopia.block;
import com.minelittlepony.unicopia.entity.player.Pony;
import com.minelittlepony.unicopia.particle.ParticleUtils;
import com.minelittlepony.unicopia.particle.UParticles;
import net.minecraft.block.*;
import net.minecraft.entity.EntityType;
import net.minecraft.entity.LightningEntity;
import net.minecraft.entity.damage.DamageSource;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.item.ItemPlacementContext;
import net.minecraft.server.world.ServerWorld;
import net.minecraft.state.StateManager;
import net.minecraft.state.property.BooleanProperty;
import net.minecraft.state.property.Properties;
import net.minecraft.util.math.*;
import net.minecraft.world.BlockView;
import net.minecraft.world.World;
import net.minecraft.world.event.GameEvent;
public class ZapBlock extends Block {
public static final BooleanProperty NATURAL = Properties.PERSISTENT;
private final Block artificialModelBlock;
ZapBlock(Settings settings, Block artificialModelBlock) {
super(settings.strength(500, 1200));
setDefaultState(getDefaultState().with(NATURAL, true));
this.artificialModelBlock = artificialModelBlock;
}
@Override
protected void appendProperties(StateManager.Builder<Block, BlockState> builder) {
super.appendProperties(builder);
builder.add(NATURAL);
}
@Override
public BlockState getPlacementState(ItemPlacementContext ctx) {
return getDefaultState().with(NATURAL, false);
}
@Deprecated
@Override
public void onBlockBreakStart(BlockState state, World world, BlockPos pos, PlayerEntity player) {
triggerLightning(state, world, pos, player);
}
@Deprecated
@Override
public float calcBlockBreakingDelta(BlockState state, PlayerEntity player, BlockView world, BlockPos pos) {
if (!state.get(NATURAL)) {
return artificialModelBlock.calcBlockBreakingDelta(artificialModelBlock.getDefaultState(), player, world, pos);
}
float delta = super.calcBlockBreakingDelta(state, player, world, pos);
if (Pony.of(player).getSpecies().canUseEarth()) {
delta *= 50;
}
return MathHelper.clamp(delta, 0, 0.9F);
}
public static void triggerLightning(BlockState state, World world, BlockPos pos, PlayerEntity player) {
if (world instanceof ServerWorld serverWorld) {
Vec3d center = Vec3d.ofCenter(pos);
LightningEntity lightning = EntityType.LIGHTNING_BOLT.create(world);
world.getOtherEntities(null, Box.from(center).expand(7)).forEach(other -> {
float dist = (float)other.getPos().distanceTo(center);
if (dist < 4) {
other.onStruckByLightning(serverWorld, lightning);
} else {
float damage = 3 / dist;
if (damage > 1) {
other.damage(DamageSource.LIGHTNING_BOLT, damage);
}
}
});
}
world.emitGameEvent(GameEvent.LIGHTNING_STRIKE, pos, GameEvent.Emitter.of(state));
ParticleUtils.spawnParticle(world, UParticles.LIGHTNING_BOLT, Vec3d.ofCenter(pos), Vec3d.ZERO);
}
}

View file

@ -1,6 +1,6 @@
package com.minelittlepony.unicopia.client;
import com.minelittlepony.unicopia.block.UBlocks;
import com.minelittlepony.unicopia.block.*;
import com.minelittlepony.unicopia.client.particle.ChangelingMagicParticle;
import com.minelittlepony.unicopia.client.particle.CloudsEscapingParticle;
import com.minelittlepony.unicopia.client.particle.DiskParticle;
@ -27,7 +27,9 @@ import net.fabricmc.fabric.api.client.particle.v1.ParticleFactoryRegistry.Pendin
import net.fabricmc.fabric.api.client.rendering.v1.EntityRendererRegistry;
import net.fabricmc.fabric.api.client.rendering.v1.BuiltinItemRendererRegistry;
import net.fabricmc.fabric.api.client.rendering.v1.ColorProviderRegistry;
import net.minecraft.block.Block;
import net.minecraft.client.MinecraftClient;
import net.minecraft.client.color.block.BlockColorProvider;
import net.minecraft.client.color.world.BiomeColors;
import net.minecraft.client.color.world.FoliageColors;
import net.minecraft.client.item.ModelPredicateProviderRegistry;
@ -41,7 +43,7 @@ import net.minecraft.client.render.item.ItemRenderer;
import net.minecraft.client.render.model.json.ModelTransformation;
import net.minecraft.client.world.ClientWorld;
import net.minecraft.fluid.Fluids;
import net.minecraft.item.DyeableItem;
import net.minecraft.item.*;
import net.minecraft.particle.ParticleEffect;
import net.minecraft.util.Identifier;
@ -120,20 +122,27 @@ public interface URenderers {
ColorProviderRegistry.ITEM.register((stack, i) -> {
return i > 0 || !GemstoneItem.isEnchanted(stack) ? -1 : GemstoneItem.getSpellKey(stack).getColor();
}, UItems.GEMSTONE);
ColorProviderRegistry.BLOCK.register((state, view, pos, color) -> {
BlockColorProvider tintedProvider = (state, view, pos, color) -> {
if (view == null || pos == null) {
color = FoliageColors.getDefaultColor();
} else {
color = BiomeColors.getFoliageColor(view, pos);
}
return (color << 2) | ((color >> 4) & 0xFF);
}, UBlocks.ZAP_LEAVES);
return ((TintedBlock)state.getBlock()).getTint(state, view, pos, color);
};
ColorProviderRegistry.BLOCK.register(tintedProvider, TintedBlock.REGISTRY.stream().toArray(Block[]::new));
ColorProviderRegistry.ITEM.register((stack, i) -> {
Block block = Block.getBlockFromItem(stack.getItem());
return block instanceof TintedBlock ? tintedProvider.getColor(block.getDefaultState(), null, null, i) : FoliageColors.getDefaultColor();
}, TintedBlock.REGISTRY.stream().map(Block::asItem).filter(i -> i != Items.AIR).toArray(Item[]::new));
BlockRenderLayerMap.INSTANCE.putBlocks(RenderLayers.getTranslucent(), FruitBlock.REGISTRY.stream().toArray(FruitBlock[]::new));
BlockRenderLayerMap.INSTANCE.putBlocks(RenderLayers.getTranslucent(), Tree.REGISTRY.stream().flatMap(tree -> tree.sapling().stream()).toArray(Block[]::new));
// for lava boats
BlockRenderLayerMap.INSTANCE.putFluids(RenderLayers.getTranslucent(), Fluids.LAVA, Fluids.FLOWING_LAVA);
BlockRenderLayerMap.INSTANCE.putBlocks(RenderLayers.getTranslucent(), UBlocks.ZAP_BULB, UBlocks.ZAP_APPLE, UBlocks.ZAPLING);
}
static <T extends ParticleEffect> PendingParticleFactory<T> createFactory(ParticleSupplier<T> supplier) {

View file

@ -16,6 +16,7 @@ import net.minecraft.item.Item.Settings;
import net.fabricmc.fabric.api.item.v1.FabricItemSettings;
import net.fabricmc.fabric.api.registry.FuelRegistry;
import net.minecraft.sound.SoundEvent;
import net.minecraft.util.Identifier;
import net.minecraft.util.Rarity;
import net.minecraft.util.registry.Registry;
@ -100,8 +101,6 @@ public interface UItems {
Item SPELLBOOK = register("spellbook", new SpellbookItem(new Item.Settings().maxCount(1).rarity(Rarity.UNCOMMON).group(ItemGroup.TOOLS)));
Item ZAPLING = register("zapling", new BlockItem(UBlocks.ZAPLING, new Item.Settings().group(ItemGroup.DECORATIONS)));
AmuletItem PEGASUS_AMULET = register("pegasus_amulet", new AmuletItem(new FabricItemSettings()
.maxCount(1)
.maxDamage(890)
@ -114,11 +113,15 @@ public interface UItems {
.group(ItemGroup.DECORATIONS)));
static <T extends Item> T register(String name, T item) {
return register(Unicopia.id(name), item);
}
static <T extends Item> T register(Identifier id, T item) {
ITEMS.add(item);
if (item instanceof BlockItem) {
((BlockItem)item).appendBlocks(Item.BLOCK_ITEMS, item);
}
return Registry.register(Registry.ITEM, Unicopia.id(name), item);
return Registry.register(Registry.ITEM, id, item);
}
static MusicDiscItem register(String name, SoundEvent sound, int seconds) {

View file

@ -0,0 +1,7 @@
{
"variants": {
"": {
"model": "unicopia:block/green_apple"
}
}
}

View file

@ -0,0 +1,7 @@
{
"variants": {
"": {
"model": "unicopia:block/green_apple_leaves"
}
}
}

View file

@ -0,0 +1,7 @@
{
"variants": {
"": {
"model": "unicopia:block/green_apple_sapling"
}
}
}

View file

@ -0,0 +1,16 @@
{
"variants": {
"axis=x": {
"model": "unicopia:block/stripped_zap_log_horizontal",
"x": 90,
"y": 90
},
"axis=y": {
"model": "unicopia:block/stripped_zap_log"
},
"axis=z": {
"model": "unicopia:block/stripped_zap_log_horizontal",
"x": 90
}
}
}

View file

@ -0,0 +1,7 @@
{
"variants": {
"": {
"model": "unicopia:block/stripped_zap_wood"
}
}
}

View file

@ -0,0 +1,7 @@
{
"variants": {
"": {
"model": "unicopia:block/zap_wood"
}
}
}

View file

@ -89,10 +89,15 @@
"block.unicopia.rocks": "Rocks",
"block.unicopia.zapling": "Zapling",
"block.unicopia.zap_log": "Zap Log",
"block.unicopia.zap_leaves": "Zap Leaves",
"block.unicopia.zap_log": "Zap Apple Log",
"block.unicopia.zap_wood": "Zap Apple Wood",
"block.unicopia.stripped_zap_log": "Stripped Zap Apple Log",
"block.unicopia.stripped_zap_wood": "Stripped Zap Apple Wood",
"block.unicopia.zap_leaves": "Zap Apple Leaves",
"block.unicopia.zap_apple": "Zap Apple",
"block.unicopia.zap_bulb": "Unripened Zap Apple",
"block.unicopia.green_apple_leaves": "Granny Smith Leaves",
"block.unicopia.green_apple_sapling": "Granny Smith Sapling",
"entity.unicopia.butterfly": "Butterfly",
"entity.unicopia.twittermite": "Twittermite",

View file

@ -0,0 +1,6 @@
{
"parent": "minecraft:block/cross",
"textures": {
"cross": "unicopia:item/green_apple"
}
}

View file

@ -0,0 +1,6 @@
{
"parent": "minecraft:block/leaves",
"textures": {
"all": "unicopia:block/green_apple_leaves"
}
}

View file

@ -0,0 +1,6 @@
{
"parent": "minecraft:block/cross",
"textures": {
"cross": "unicopia:item/green_apple_sapling"
}
}

View file

@ -0,0 +1,7 @@
{
"parent": "minecraft:block/cube_column",
"textures": {
"end": "unicopia:block/stripped_zap_log_top",
"side": "unicopia:block/stripped_zap_log"
}
}

View file

@ -0,0 +1,7 @@
{
"parent": "minecraft:block/cube_column_horizontal",
"textures": {
"end": "unicopia:block/stripped_zap_log_top",
"side": "unicopia:block/stripped_zap_log"
}
}

View file

@ -0,0 +1,6 @@
{
"parent": "minecraft:block/cube_all",
"textures": {
"all": "unicopia:block/stripped_zap_log"
}
}

View file

@ -0,0 +1,6 @@
{
"parent": "minecraft:block/cube_all",
"textures": {
"all": "unicopia:block/zap_log"
}
}

View file

@ -0,0 +1,3 @@
{
"parent": "unicopia:block/green_apple_leaves"
}

View file

@ -0,0 +1,6 @@
{
"parent": "item/generated",
"textures": {
"layer0": "unicopia:item/green_apple_sapling"
}
}

View file

@ -0,0 +1,3 @@
{
"parent": "unicopia:block/stripped_zap_log"
}

View file

@ -0,0 +1,3 @@
{
"parent": "unicopia:block/stripped_zap_wood"
}

View file

@ -0,0 +1,3 @@
{
"parent": "unicopia:block/zap_leaves"
}

View file

@ -0,0 +1,3 @@
{
"parent": "unicopia:block/zap_log"
}

View file

@ -0,0 +1,3 @@
{
"parent": "unicopia:block/zap_wood"
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

View file

@ -0,0 +1,7 @@
{
"replace": false,
"values": [
"unicopia:zap_leaves",
"unicopia:green_apple_leaves"
]
}

View file

@ -0,0 +1,9 @@
{
"replace": false,
"values": [
"unicopia:zap_log",
"unicopia:zap_wood",
"unicopia:stripped_zap_log",
"unicopia:stripped_zap_wood"
]
}

View file

@ -0,0 +1,7 @@
{
"replace": false,
"values": [
"unicopia:zap_leaves",
"unicopia:green_apple_leaves"
]
}

View file

@ -0,0 +1,9 @@
{
"replace": false,
"values": [
"unicopia:zap_log",
"unicopia:zap_wood",
"unicopia:stripped_zap_log",
"unicopia:stripped_zap_wood"
]
}

View file

@ -0,0 +1,20 @@
{
"type": "minecraft:block",
"pools": [
{
"rolls": 1.0,
"bonus_rolls": 0.0,
"entries": [
{
"type": "minecraft:item",
"name": "unicopia:green_apple"
}
],
"conditions": [
{
"condition": "minecraft:survives_explosion"
}
]
}
]
}

View file

@ -0,0 +1,116 @@
{
"type": "minecraft:block",
"pools": [
{
"bonus_rolls": 0.0,
"entries": [
{
"type": "minecraft:alternatives",
"children": [
{
"type": "minecraft:item",
"conditions": [
{
"condition": "minecraft:alternative",
"terms": [
{
"condition": "minecraft:match_tool",
"predicate": {
"items": [
"minecraft:shears"
]
}
},
{
"condition": "minecraft:match_tool",
"predicate": {
"enchantments": [
{
"enchantment": "minecraft:silk_touch",
"levels": {
"min": 1
}
}
]
}
}
]
}
],
"name": "unicopia:green_apple_leaves"
}
]
}
],
"rolls": 1.0
},
{
"bonus_rolls": 0.0,
"conditions": [
{
"condition": "minecraft:inverted",
"term": {
"condition": "minecraft:alternative",
"terms": [
{
"condition": "minecraft:match_tool",
"predicate": {
"items": [
"minecraft:shears"
]
}
},
{
"condition": "minecraft:match_tool",
"predicate": {
"enchantments": [
{
"enchantment": "minecraft:silk_touch",
"levels": {
"min": 1
}
}
]
}
}
]
}
}
],
"entries": [
{
"type": "minecraft:item",
"conditions": [
{
"chances": [
0.02,
0.022222223,
0.025,
0.033333335,
0.1
],
"condition": "minecraft:table_bonus",
"enchantment": "minecraft:fortune"
}
],
"functions": [
{
"add": false,
"count": {
"type": "minecraft:uniform",
"max": 2.0,
"min": 1.0
},
"function": "minecraft:set_count"
},
{
"function": "minecraft:explosion_decay"
}
],
"name": "minecraft:stick"
}
],
"rolls": 1.0
}
]
}

View file

@ -0,0 +1,20 @@
{
"type": "minecraft:block",
"pools": [
{
"rolls": 1.0,
"bonus_rolls": 0.0,
"entries": [
{
"type": "minecraft:item",
"name": "unicopia:green_apple_sapling"
}
],
"conditions": [
{
"condition": "minecraft:survives_explosion"
}
]
}
]
}

View file

@ -0,0 +1,116 @@
{
"type": "minecraft:block",
"pools": [
{
"bonus_rolls": 0.0,
"entries": [
{
"type": "minecraft:alternatives",
"children": [
{
"type": "minecraft:item",
"conditions": [
{
"condition": "minecraft:alternative",
"terms": [
{
"condition": "minecraft:match_tool",
"predicate": {
"items": [
"minecraft:shears"
]
}
},
{
"condition": "minecraft:match_tool",
"predicate": {
"enchantments": [
{
"enchantment": "minecraft:silk_touch",
"levels": {
"min": 1
}
}
]
}
}
]
}
],
"name": "unicopia:zap_leaves"
}
]
}
],
"rolls": 1.0
},
{
"bonus_rolls": 0.0,
"conditions": [
{
"condition": "minecraft:inverted",
"term": {
"condition": "minecraft:alternative",
"terms": [
{
"condition": "minecraft:match_tool",
"predicate": {
"items": [
"minecraft:shears"
]
}
},
{
"condition": "minecraft:match_tool",
"predicate": {
"enchantments": [
{
"enchantment": "minecraft:silk_touch",
"levels": {
"min": 1
}
}
]
}
}
]
}
}
],
"entries": [
{
"type": "minecraft:item",
"conditions": [
{
"chances": [
0.02,
0.022222223,
0.025,
0.033333335,
0.1
],
"condition": "minecraft:table_bonus",
"enchantment": "minecraft:fortune"
}
],
"functions": [
{
"add": false,
"count": {
"type": "minecraft:uniform",
"max": 2.0,
"min": 1.0
},
"function": "minecraft:set_count"
},
{
"function": "minecraft:explosion_decay"
}
],
"name": "minecraft:stick"
}
],
"rolls": 1.0
}
]
}

View file

@ -0,0 +1,20 @@
{
"type": "minecraft:block",
"pools": [
{
"rolls": 1.0,
"bonus_rolls": 0.0,
"entries": [
{
"type": "minecraft:item",
"name": "unicopia:zap_log"
}
],
"conditions": [
{
"condition": "minecraft:survives_explosion"
}
]
}
]
}

View file

@ -0,0 +1,20 @@
{
"type": "minecraft:block",
"pools": [
{
"rolls": 1.0,
"bonus_rolls": 0.0,
"entries": [
{
"type": "minecraft:item",
"name": "unicopia:zap_wood"
}
],
"conditions": [
{
"condition": "minecraft:survives_explosion"
}
]
}
]
}

View file

@ -3,8 +3,8 @@
"leaves": [ "minecraft:dark_oak_leaves" ],
"wideTrunk": true,
"drops": [
{ "weight": 1, "item": "unicopia:rottenn_apple" },
{ "weight": 1, "item": "unicopia:rotten_apple" },
{ "weight": 2, "item": "unicopia:sweet_apple" },
{ "weight": 5, "item": "unicopia:zap_apple" }
{ "weight": 5, "item": "minecraft:apple" }
]
}

View file

@ -0,0 +1,6 @@
{
"logs": [ "minecraft:oak_log", "minecraft:oak_wood" ],
"leaves": [ "unicopia:green_apple_leaves" ],
"wideTrunk": false,
"drops": []
}

View file

@ -0,0 +1,6 @@
{
"logs": [ "unicopia:zap_log" ],
"leaves": [ "unicopia:zap_leaves" ],
"wideTrunk": false,
"drops": []
}