From def7e37712345870a5a34bf834e7cb5c050afff2 Mon Sep 17 00:00:00 2001 From: Sollace Date: Fri, 23 Sep 2022 23:25:00 +0200 Subject: [PATCH] Added zap apple trees --- .../com/minelittlepony/unicopia/UTags.java | 4 + .../com/minelittlepony/unicopia/Unicopia.java | 4 + .../unicopia/block/FruitBlock.java | 57 ++++++ .../unicopia/block/UBlocks.java | 33 ++- .../unicopia/block/UTreeGen.java | 41 ++++ .../unicopia/block/ZapAppleLeavesBlock.java | 188 ++++++++++++++++++ .../unicopia/block/ZapAppleLogBlock.java | 34 ++++ .../block/data/BlockDestructionManager.java | 5 +- .../unicopia/block/data/WorldOverlay.java | 4 +- .../block/data/ZapAppleStageStore.java | 164 +++++++++++++++ .../unicopia/client/URenderers.java | 14 ++ .../unicopia/entity/FairyEntity.java | 4 +- .../unicopia/item/PolearmItem.java | 3 +- .../minelittlepony/unicopia/item/UItems.java | 12 ++ .../unicopia/blockstates/zap_apple.json | 7 + .../assets/unicopia/blockstates/zap_bulb.json | 7 + .../unicopia/blockstates/zap_leaves.json | 19 ++ .../assets/unicopia/blockstates/zap_log.json | 16 ++ .../assets/unicopia/blockstates/zapling.json | 7 + .../resources/assets/unicopia/lang/en_us.json | 6 + .../models/block/flowering_zap_leaves.json | 6 + .../unicopia/models/block/zap_apple.json | 6 + .../unicopia/models/block/zap_bulb.json | 6 + .../unicopia/models/block/zap_leaves.json | 6 + .../assets/unicopia/models/block/zap_log.json | 7 + .../models/block/zap_log_horizontal.json | 7 + .../assets/unicopia/models/block/zapling.json | 6 + .../assets/unicopia/models/item/zap_bulb.json | 6 + .../assets/unicopia/models/item/zapling.json | 6 + .../textures/block/flowering_zap_leaves.png | Bin 0 -> 1851 bytes .../unicopia/textures/block/zap_leaves.png | Bin 0 -> 256 bytes .../unicopia/textures/block/zap_log.png | Bin 0 -> 1697 bytes .../unicopia/textures/block/zap_log_top.png | Bin 0 -> 1765 bytes .../unicopia/textures/item/zap_bulb.png | Bin 0 -> 1617 bytes .../assets/unicopia/textures/item/zapling.png | Bin 0 -> 1786 bytes .../loot_tables/blocks/zap_apple.json | 20 ++ .../unicopia/loot_tables/blocks/zap_bulb.json | 20 ++ .../unicopia/loot_tables/blocks/zapling.json | 20 ++ .../tags/blocks/mineable/polearm.json | 7 + .../data/unicopia/tags/items/polearms.json | 11 + 40 files changed, 755 insertions(+), 8 deletions(-) create mode 100644 src/main/java/com/minelittlepony/unicopia/block/FruitBlock.java create mode 100644 src/main/java/com/minelittlepony/unicopia/block/UTreeGen.java create mode 100644 src/main/java/com/minelittlepony/unicopia/block/ZapAppleLeavesBlock.java create mode 100644 src/main/java/com/minelittlepony/unicopia/block/ZapAppleLogBlock.java create mode 100644 src/main/java/com/minelittlepony/unicopia/block/data/ZapAppleStageStore.java create mode 100644 src/main/resources/assets/unicopia/blockstates/zap_apple.json create mode 100644 src/main/resources/assets/unicopia/blockstates/zap_bulb.json create mode 100644 src/main/resources/assets/unicopia/blockstates/zap_leaves.json create mode 100644 src/main/resources/assets/unicopia/blockstates/zap_log.json create mode 100644 src/main/resources/assets/unicopia/blockstates/zapling.json create mode 100644 src/main/resources/assets/unicopia/models/block/flowering_zap_leaves.json create mode 100644 src/main/resources/assets/unicopia/models/block/zap_apple.json create mode 100644 src/main/resources/assets/unicopia/models/block/zap_bulb.json create mode 100644 src/main/resources/assets/unicopia/models/block/zap_leaves.json create mode 100644 src/main/resources/assets/unicopia/models/block/zap_log.json create mode 100644 src/main/resources/assets/unicopia/models/block/zap_log_horizontal.json create mode 100644 src/main/resources/assets/unicopia/models/block/zapling.json create mode 100644 src/main/resources/assets/unicopia/models/item/zap_bulb.json create mode 100644 src/main/resources/assets/unicopia/models/item/zapling.json create mode 100644 src/main/resources/assets/unicopia/textures/block/flowering_zap_leaves.png create mode 100644 src/main/resources/assets/unicopia/textures/block/zap_leaves.png create mode 100644 src/main/resources/assets/unicopia/textures/block/zap_log.png create mode 100644 src/main/resources/assets/unicopia/textures/block/zap_log_top.png create mode 100644 src/main/resources/assets/unicopia/textures/item/zap_bulb.png create mode 100644 src/main/resources/assets/unicopia/textures/item/zapling.png create mode 100644 src/main/resources/data/unicopia/loot_tables/blocks/zap_apple.json create mode 100644 src/main/resources/data/unicopia/loot_tables/blocks/zap_bulb.json create mode 100644 src/main/resources/data/unicopia/loot_tables/blocks/zapling.json create mode 100644 src/main/resources/data/unicopia/tags/blocks/mineable/polearm.json create mode 100644 src/main/resources/data/unicopia/tags/items/polearms.json diff --git a/src/main/java/com/minelittlepony/unicopia/UTags.java b/src/main/java/com/minelittlepony/unicopia/UTags.java index 70de0898..cab336b1 100644 --- a/src/main/java/com/minelittlepony/unicopia/UTags.java +++ b/src/main/java/com/minelittlepony/unicopia/UTags.java @@ -18,12 +18,16 @@ public interface UTags { TagKey SHADES = item("shades"); + TagKey POLEARMS = item("polearms"); + TagKey FRAGILE = block("fragile"); TagKey INTERESTING = block("interesting"); TagKey CRYSTAL_HEART_BASE = block("crystal_heart_base"); TagKey CRYSTAL_HEART_ORNAMENT = block("crystal_heart_ornament"); + TagKey POLEARM_MINEABLE = block("mineable/polearm"); + TagKey> TRANSFORMABLE_ENTITIES = entity("transformable"); static TagKey item(String name) { diff --git a/src/main/java/com/minelittlepony/unicopia/Unicopia.java b/src/main/java/com/minelittlepony/unicopia/Unicopia.java index 1a3a6ec2..1e67cff6 100644 --- a/src/main/java/com/minelittlepony/unicopia/Unicopia.java +++ b/src/main/java/com/minelittlepony/unicopia/Unicopia.java @@ -17,7 +17,9 @@ import com.minelittlepony.unicopia.ability.magic.spell.effect.SpellType; import com.minelittlepony.unicopia.ability.magic.spell.trait.TraitLoader; import com.minelittlepony.unicopia.advancement.UCriteria; import com.minelittlepony.unicopia.block.UBlocks; +import com.minelittlepony.unicopia.block.UTreeGen; import com.minelittlepony.unicopia.block.data.BlockDestructionManager; +import com.minelittlepony.unicopia.block.data.ZapAppleStageStore; import com.minelittlepony.unicopia.block.state.StateMapLoader; import com.minelittlepony.unicopia.command.Commands; import com.minelittlepony.unicopia.container.SpellbookChapterLoader; @@ -59,6 +61,7 @@ public class Unicopia implements ModInitializer { ServerTickEvents.END_WORLD_TICK.register(w -> { ((BlockDestructionManager.Source)w).getDestructionManager().tick(); + ZapAppleStageStore.get(w).tick(); if (SpellbookChapterLoader.DEBUG) { SpellbookChapterLoader.INSTANCE.sendUpdate(w.getServer()); } @@ -78,6 +81,7 @@ public class Unicopia implements ModInitializer { SpellType.bootstrap(); Abilities.bootstrap(); UScreenHandlers.bootstrap(); + UTreeGen.bootstrap(); } public interface SidedAccess { diff --git a/src/main/java/com/minelittlepony/unicopia/block/FruitBlock.java b/src/main/java/com/minelittlepony/unicopia/block/FruitBlock.java new file mode 100644 index 00000000..65b4fdba --- /dev/null +++ b/src/main/java/com/minelittlepony/unicopia/block/FruitBlock.java @@ -0,0 +1,57 @@ +package com.minelittlepony.unicopia.block; + +import net.minecraft.block.*; +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; + +public class FruitBlock extends Block { + public static final int DEFAULT_FRUIT_SIZE = 8; + public static final VoxelShape DEFAULT_SHAPE = createFruitShape(DEFAULT_FRUIT_SIZE); + + private final Direction attachmentFace; + private final Block stem; + private final VoxelShape shape; + + public static VoxelShape createFruitShape(int fruitSize) { + int min = (16 - fruitSize) / 2; + int max = 16 - min; + + return VoxelShapes.cuboid(min / 16D, (max - fruitSize) / 16D, min / 16D, max / 16D, 1, max / 16D); + } + + public FruitBlock(Settings settings, Direction attachmentFace, Block stem, VoxelShape shape) { + super(settings.nonOpaque().suffocates(UBlocks::never).blockVision(UBlocks::never)); + this.attachmentFace = attachmentFace; + this.stem = stem; + this.shape = shape; + } + + @Override + public VoxelShape getOutlineShape(BlockState state, BlockView world, BlockPos pos, ShapeContext context) { + return shape; + } + + @Override + 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); + } + + @Override + public void scheduledTick(BlockState state, ServerWorld world, BlockPos pos, Random random) { + if (!state.canPlaceAt(world, pos)) { + world.breakBlock(pos, true); + } + } + + protected boolean canAttachTo(BlockState state) { + return state.isOf(stem); + } +} diff --git a/src/main/java/com/minelittlepony/unicopia/block/UBlocks.java b/src/main/java/com/minelittlepony/unicopia/block/UBlocks.java index f9efda90..53b3987e 100644 --- a/src/main/java/com/minelittlepony/unicopia/block/UBlocks.java +++ b/src/main/java/com/minelittlepony/unicopia/block/UBlocks.java @@ -4,11 +4,17 @@ import com.minelittlepony.unicopia.Unicopia; import net.fabricmc.fabric.api.object.builder.v1.block.FabricBlockSettings; import net.fabricmc.fabric.api.object.builder.v1.block.FabricMaterialBuilder; -import net.minecraft.block.Block; -import net.minecraft.block.Blocks; -import net.minecraft.block.MapColor; +import net.minecraft.block.*; +import net.minecraft.block.sapling.SaplingGenerator; +import net.minecraft.entity.EntityType; import net.minecraft.sound.BlockSoundGroup; +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( @@ -21,9 +27,30 @@ 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> getTreeFeature(Random rng, boolean flowersNearby) { + return UTreeGen.ZAP_APPLE_TREE; + } + }, FabricBlockSettings.copy(Blocks.OAK_SAPLING))); + + Block ZAP_LOG = register("zap_log", new ZapAppleLogBlock(MapColor.GRAY, MapColor.DEEPSLATE_GRAY)); + Block ZAP_LEAVES = register("zap_leaves", new ZapAppleLeavesBlock()); + 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 register(String name, T item) { return Registry.register(Registry.BLOCK, Unicopia.id(name), item); } static void bootstrap() {} + + + static boolean never(BlockState state, BlockView world, BlockPos pos) { + return false; + } + + static Boolean canSpawnOnLeaves(BlockState state, BlockView world, BlockPos pos, EntityType type) { + return type == EntityType.OCELOT || type == EntityType.PARROT; + } } diff --git a/src/main/java/com/minelittlepony/unicopia/block/UTreeGen.java b/src/main/java/com/minelittlepony/unicopia/block/UTreeGen.java new file mode 100644 index 00000000..13b021a9 --- /dev/null +++ b/src/main/java/com/minelittlepony/unicopia/block/UTreeGen.java @@ -0,0 +1,41 @@ +package com.minelittlepony.unicopia.block; + +import net.fabricmc.fabric.api.biome.v1.*; +import net.minecraft.tag.BiomeTags; +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.world.gen.foliage.JungleFoliagePlacer; +import net.minecraft.world.gen.stateprovider.BlockStateProvider; +import net.minecraft.world.gen.trunk.UpwardsBranchingTrunkPlacer; + +public interface UTreeGen { + RegistryEntry> 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, + UniformIntProvider.create(1, 3), + Registry.BLOCK.getOrCreateEntryList(BlockTags.MANGROVE_LOGS_CAN_GROW_THROUGH) + ), + BlockStateProvider.of(UBlocks.ZAP_LEAVES), + new JungleFoliagePlacer( + ConstantIntProvider.create(3), + ConstantIntProvider.create(2), + 3 + ), + new TwoLayersFeatureSize(6, 0, 16) + ).forceDirt() + .build() + ); + RegistryEntry TREES_ZAP = PlacedFeatures.register("unicopia:trees_zap", ZAP_APPLE_TREE, + VegetationPlacedFeatures.modifiersWithWouldSurvive(PlacedFeatures.createCountExtraModifier(0, 0.01F, 1), UBlocks.ZAPLING) + ); + + static void bootstrap() { + BiomeModifications.addFeature(BiomeSelectors.foundInOverworld().and(BiomeSelectors.tag(BiomeTags.IS_FOREST)), GenerationStep.Feature.VEGETAL_DECORATION, TREES_ZAP.getKey().get()); + } +} diff --git a/src/main/java/com/minelittlepony/unicopia/block/ZapAppleLeavesBlock.java b/src/main/java/com/minelittlepony/unicopia/block/ZapAppleLeavesBlock.java new file mode 100644 index 00000000..df76bcf0 --- /dev/null +++ b/src/main/java/com/minelittlepony/unicopia/block/ZapAppleLeavesBlock.java @@ -0,0 +1,188 @@ +package com.minelittlepony.unicopia.block; + +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.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; + +public class ZapAppleLeavesBlock extends LeavesBlock { + public static final EnumProperty STAGE = EnumProperty.of("stage", ZapAppleStageStore.Stage.class); + + ZapAppleLeavesBlock() { + super(Settings.of(Material.LEAVES) + .strength(500, 1200) + .ticksRandomly() + .sounds(BlockSoundGroup.AZALEA_LEAVES) + .nonOpaque() + .allowsSpawning(UBlocks::canSpawnOnLeaves) + .suffocates(UBlocks::never) + .blockVision(UBlocks::never) + ); + setDefaultState(getDefaultState().with(STAGE, ZapAppleStageStore.Stage.HIBERNATING)); + } + + @Override + protected void appendProperties(StateManager.Builder builder) { + super.appendProperties(builder); + builder.add(STAGE); + } + + @Override + public void randomTick(BlockState state, ServerWorld world, BlockPos pos, Random random) { + super.randomTick(state, world, pos, random); + + ZapAppleStageStore store = ZapAppleStageStore.get(world); + ZapAppleStageStore.Stage newStage = store.getStage(); + if (!world.isDay() && state.get(STAGE).mustChangeInto(newStage)) { + world.setBlockState(pos, state.with(STAGE, newStage)); + onStageChanged(store, newStage, world, state, pos, random); + } + } + + @Override + public void scheduledTick(BlockState state, ServerWorld world, BlockPos pos, Random random) { + super.scheduledTick(state, world, pos, random); + + ZapAppleStageStore store = ZapAppleStageStore.get(world); + ZapAppleStageStore.Stage newStage = store.getStage(); + if (!world.isDay() && state.get(STAGE).mustChangeIntoInstantly(newStage)) { + world.setBlockState(pos, state.with(STAGE, newStage)); + onStageChanged(store, newStage, world, state, pos, random); + } + + world.createAndScheduleBlockTick(pos, this, 1); + } + + @Override + protected boolean shouldDecay(BlockState state) { + return false; + } + + @Override + public BlockState getPlacementState(ItemPlacementContext ctx) { + if (!ctx.getWorld().isClient) { + ctx.getWorld().createAndScheduleBlockTick(ctx.getBlockPos(), this, 1); + return super.getPlacementState(ctx).with(STAGE, ZapAppleStageStore.get(ctx.getWorld()).getStage()); + } + return super.getPlacementState(ctx); + } + + private void onStageChanged(ZapAppleStageStore store, ZapAppleStageStore.Stage stage, ServerWorld world, BlockState state, BlockPos pos, Random random) { + boolean mustFruit = Random.create(state.getRenderingSeed(pos)).nextInt(5) < 2; + BlockState below = world.getBlockState(pos.down()); + + if (world.isAir(pos.down())) { + if (stage == ZapAppleStageStore.Stage.FRUITING && mustFruit) { + world.setBlockState(pos.down(), UBlocks.ZAP_BULB.getDefaultState(), Block.NOTIFY_ALL); + store.triggerLightningStrike(pos); + } + } + + if (stage != ZapAppleStageStore.Stage.HIBERNATING && world.getRandom().nextInt(10) == 0) { + store.triggerLightningStrike(pos); + } + + if (stage == ZapAppleStageStore.Stage.RIPE) { + store.playMoonEffect(pos); + + if (below.isOf(UBlocks.ZAP_BULB)) { + world.setBlockState(pos.down(), UBlocks.ZAP_APPLE.getDefaultState(), Block.NOTIFY_ALL); + store.triggerLightningStrike(pos); + } + } + + if (mustFruit && stage == ZapAppleStageStore.Stage.HIBERNATING) { + if (below.isOf(UBlocks.ZAP_APPLE) || below.isOf(UBlocks.ZAP_BULB)) { + world.setBlockState(pos.down(), Blocks.AIR.getDefaultState()); + } + } + } + + @Override + public void onBlockBreakStart(BlockState state, World world, BlockPos pos, PlayerEntity player) { + triggerLightning(state, world, pos, player); + } + + @Deprecated + @Override + public BlockRenderType getRenderType(BlockState state) { + return isAir(state) ? BlockRenderType.INVISIBLE : super.getRenderType(state); + } + + @Deprecated + @Override + public VoxelShape getOutlineShape(BlockState state, BlockView world, BlockPos pos, ShapeContext context) { + return isAir(state) ? VoxelShapes.empty() : super.getOutlineShape(state, world, pos, context); + } + + @Deprecated + @Override + public boolean canReplace(BlockState state, ItemPlacementContext context) { + return isAir(state) || super.canReplace(state, context); + } + + @Deprecated + @Override + public boolean canBucketPlace(BlockState state, Fluid fluid) { + return isAir(state) || super.canBucketPlace(state, fluid); + } + + protected boolean isAir(BlockState state) { + return state.get(STAGE) == ZapAppleStageStore.Stage.HIBERNATING; + } + + @Deprecated + @Override + public float calcBlockBreakingDelta(BlockState state, PlayerEntity player, BlockView world, BlockPos pos) { + float delta = super.calcBlockBreakingDelta(state, player, world, pos); + + if (Pony.of(player).getSpecies().canUseEarth()) { + delta *= 50; + } + + if (state.get(STAGE) == ZapAppleStageStore.Stage.RIPE) { + delta *= 5; + } + + 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); + } + +} diff --git a/src/main/java/com/minelittlepony/unicopia/block/ZapAppleLogBlock.java b/src/main/java/com/minelittlepony/unicopia/block/ZapAppleLogBlock.java new file mode 100644 index 00000000..25f16e79 --- /dev/null +++ b/src/main/java/com/minelittlepony/unicopia/block/ZapAppleLogBlock.java @@ -0,0 +1,34 @@ +package com.minelittlepony.unicopia.block; + +import com.minelittlepony.unicopia.entity.player.Pony; + +import net.minecraft.block.*; +import net.minecraft.entity.player.PlayerEntity; +import net.minecraft.sound.BlockSoundGroup; +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)); + } + + @Deprecated + @Override + public void onBlockBreakStart(BlockState state, World world, BlockPos pos, PlayerEntity player) { + ZapAppleLeavesBlock.triggerLightning(state, world, pos, player); + } + + @Deprecated + @Override + public float calcBlockBreakingDelta(BlockState state, PlayerEntity player, BlockView world, BlockPos pos) { + float delta = super.calcBlockBreakingDelta(state, player, world, pos); + + if (Pony.of(player).getSpecies().canUseEarth()) { + delta *= 50; + } + + return MathHelper.clamp(delta, 0, 0.9F); + } +} diff --git a/src/main/java/com/minelittlepony/unicopia/block/data/BlockDestructionManager.java b/src/main/java/com/minelittlepony/unicopia/block/data/BlockDestructionManager.java index 5b68ba64..f05db351 100644 --- a/src/main/java/com/minelittlepony/unicopia/block/data/BlockDestructionManager.java +++ b/src/main/java/com/minelittlepony/unicopia/block/data/BlockDestructionManager.java @@ -8,6 +8,8 @@ import com.google.common.base.Suppliers; import com.minelittlepony.unicopia.Unicopia; import com.minelittlepony.unicopia.network.Channel; import com.minelittlepony.unicopia.network.MsgBlockDestruction; +import com.minelittlepony.unicopia.util.Tickable; + import it.unimi.dsi.fastutil.longs.Long2ObjectMap; import it.unimi.dsi.fastutil.longs.Long2ObjectOpenHashMap; import net.minecraft.block.BlockState; @@ -17,7 +19,7 @@ import net.minecraft.util.Identifier; import net.minecraft.util.math.BlockPos; import net.minecraft.world.World; -public class BlockDestructionManager { +public class BlockDestructionManager implements Tickable { private static final Identifier ID = Unicopia.id("destruction_manager"); public static final int DESTRUCTION_COOLDOWN = 50; @@ -63,6 +65,7 @@ public class BlockDestructionManager { } } + @Override public void tick() { chunks.tick(); } diff --git a/src/main/java/com/minelittlepony/unicopia/block/data/WorldOverlay.java b/src/main/java/com/minelittlepony/unicopia/block/data/WorldOverlay.java index d5464117..7b34aed9 100644 --- a/src/main/java/com/minelittlepony/unicopia/block/data/WorldOverlay.java +++ b/src/main/java/com/minelittlepony/unicopia/block/data/WorldOverlay.java @@ -6,6 +6,7 @@ import java.util.function.*; import org.jetbrains.annotations.Nullable; import com.minelittlepony.unicopia.util.NbtSerialisable; +import com.minelittlepony.unicopia.util.Tickable; import it.unimi.dsi.fastutil.longs.Long2ObjectMap; import it.unimi.dsi.fastutil.longs.Long2ObjectOpenHashMap; @@ -19,7 +20,7 @@ import net.minecraft.util.math.ChunkPos; import net.minecraft.world.PersistentState; import net.minecraft.world.World; -public class WorldOverlay extends PersistentState { +public class WorldOverlay extends PersistentState implements Tickable { private final World world; private final Long2ObjectMap chunks = new Long2ObjectOpenHashMap<>(); @@ -98,6 +99,7 @@ public class WorldOverlay extends PersistentState } } + @Override public void tick() { synchronized (locker) { chunks.long2ObjectEntrySet().removeIf(entry -> entry.getValue().tick()); diff --git a/src/main/java/com/minelittlepony/unicopia/block/data/ZapAppleStageStore.java b/src/main/java/com/minelittlepony/unicopia/block/data/ZapAppleStageStore.java new file mode 100644 index 00000000..33b16fd0 --- /dev/null +++ b/src/main/java/com/minelittlepony/unicopia/block/data/ZapAppleStageStore.java @@ -0,0 +1,164 @@ +package com.minelittlepony.unicopia.block.data; + +import java.util.Locale; +import java.util.stream.StreamSupport; + +import com.minelittlepony.unicopia.Unicopia; +import com.minelittlepony.unicopia.particle.ParticleUtils; +import com.minelittlepony.unicopia.particle.UParticles; +import com.minelittlepony.unicopia.util.Tickable; + +import net.minecraft.entity.EntityType; +import net.minecraft.entity.LightningEntity; +import net.minecraft.nbt.*; +import net.minecraft.sound.SoundCategory; +import net.minecraft.sound.SoundEvents; +import net.minecraft.util.Identifier; +import net.minecraft.util.StringIdentifiable; +import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.Vec3d; +import net.minecraft.world.PersistentState; +import net.minecraft.world.World; +import net.minecraft.world.event.GameEvent; + +public class ZapAppleStageStore extends PersistentState implements Tickable { + private static final Identifier ID = Unicopia.id("zap_apple_stage"); + + public static ZapAppleStageStore get(World world) { + return WorldOverlay.getPersistableStorage(world, ID, ZapAppleStageStore::new, ZapAppleStageStore::new); + } + + private final World world; + + private Stage lastStage = Stage.HIBERNATING; + private int countdown; + private boolean stageChanged; + private boolean playedMoonEffect; + private int nextLightningEvent = 1200; + + ZapAppleStageStore(World world, NbtCompound compound) { + this(world); + lastStage = Stage.VALUES[Math.max(0, compound.getInt("stage")) % Stage.VALUES.length]; + stageChanged = compound.getBoolean("stageChanged"); + countdown = compound.getInt("countdown"); + playedMoonEffect = compound.getBoolean("playedMoonEffect"); + nextLightningEvent = compound.getInt("nextLightningEvent"); + } + + ZapAppleStageStore(World world) { + this.world = world; + } + + @Override + public void tick() { + if (!world.isDay()) { + if (nextLightningEvent > 0) { + nextLightningEvent--; + markDirty(); + } + + if (!stageChanged && (lastStage != Stage.HIBERNATING || (world.getMoonPhase() == 0))) { + stageChanged = true; + if (countDay()) { + lastStage = lastStage.getNext(); + countdown = 1; + playedMoonEffect = false; + markDirty(); + onStageChanged(); + } + } + } else if (stageChanged) { + stageChanged = false; + markDirty(); + } + } + + private boolean countDay() { + markDirty(); + return countdown-- <= 0; + } + + protected void onStageChanged() { + world.setRainGradient(0.5F); + } + + public void playMoonEffect(BlockPos pos) { + if (!playedMoonEffect) { + playedMoonEffect = true; + markDirty(); + world.playSound(pos.getX(), pos.getY(), pos.getZ(), SoundEvents.ENTITY_WOLF_HOWL, SoundCategory.BLOCKS, 1.5F, 0.9F, true); + } + } + + public void triggerLightningStrike(BlockPos pos) { + world.emitGameEvent(GameEvent.LIGHTNING_STRIKE, pos, GameEvent.Emitter.of(world.getBlockState(pos))); + ParticleUtils.spawnParticle(world, UParticles.LIGHTNING_BOLT, Vec3d.ofCenter(pos), Vec3d.ZERO); + + if (nextLightningEvent <= 0) { + StreamSupport.stream(BlockPos.iterateRandomly(world.random, 20, pos, 10).spliterator(), false) + .filter(p -> world.isAir(p) && !world.isAir(p.down()) && world.isSkyVisible(p)) + .findFirst().ifPresent(p -> { + LightningEntity bolt = EntityType.LIGHTNING_BOLT.create(world); + bolt.refreshPositionAfterTeleport(Vec3d.ofBottomCenter(pos)); + bolt.setCosmetic(true); + world.spawnEntity(bolt); + nextLightningEvent = world.getRandom().nextBetween(1200, 8000); + markDirty(); + }); + } + } + + /** + * Returns true during nights that the zap apples must change their states. + * @return + */ + public boolean hasStageChanged() { + return stageChanged; + } + + /** + * Returns the current zap apple ripening stage. + */ + public Stage getStage() { + return lastStage; + } + + @Override + public NbtCompound writeNbt(NbtCompound compound) { + compound.putInt("stage", lastStage.ordinal()); + compound.putBoolean("stageChanged", stageChanged); + compound.putInt("countdown", countdown); + compound.putBoolean("playedMoonEffect", playedMoonEffect); + compound.putInt("nextLightningEvent", nextLightningEvent); + return compound; + } + + public enum Stage implements StringIdentifiable { + HIBERNATING, + GREENING, + FLOWERING, + FRUITING, + RIPE; + + static final long DAY_LENGTH = 24000; + static final Stage[] VALUES = values(); + + public Stage getNext() { + return VALUES[(ordinal() + 1) % VALUES.length]; + } + + public boolean mustChangeInto(Stage to) { + return this != to && (getNext() == to || this == HIBERNATING || to == HIBERNATING); + } + + public boolean mustChangeIntoInstantly(Stage to) { + return this != to && (this == HIBERNATING || to == HIBERNATING); + } + + @Override + public String asString() { + return name().toLowerCase(Locale.ROOT); + } + } + +} diff --git a/src/main/java/com/minelittlepony/unicopia/client/URenderers.java b/src/main/java/com/minelittlepony/unicopia/client/URenderers.java index d4da7abe..78cb633a 100644 --- a/src/main/java/com/minelittlepony/unicopia/client/URenderers.java +++ b/src/main/java/com/minelittlepony/unicopia/client/URenderers.java @@ -1,5 +1,6 @@ package com.minelittlepony.unicopia.client; +import com.minelittlepony.unicopia.block.UBlocks; import com.minelittlepony.unicopia.client.particle.ChangelingMagicParticle; import com.minelittlepony.unicopia.client.particle.CloudsEscapingParticle; import com.minelittlepony.unicopia.client.particle.DiskParticle; @@ -27,6 +28,8 @@ 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.client.MinecraftClient; +import net.minecraft.client.color.world.BiomeColors; +import net.minecraft.client.color.world.FoliageColors; import net.minecraft.client.item.ModelPredicateProviderRegistry; import net.minecraft.client.particle.Particle; import net.minecraft.client.particle.SpriteProvider; @@ -117,9 +120,20 @@ 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) -> { + if (view == null || pos == null) { + color = FoliageColors.getDefaultColor(); + } else { + color = BiomeColors.getFoliageColor(view, pos); + } + + return (color << 2) | ((color >> 4) & 0xFF); + }, UBlocks.ZAP_LEAVES); // 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 PendingParticleFactory createFactory(ParticleSupplier supplier) { diff --git a/src/main/java/com/minelittlepony/unicopia/entity/FairyEntity.java b/src/main/java/com/minelittlepony/unicopia/entity/FairyEntity.java index 6739b66a..ef2bbd2e 100644 --- a/src/main/java/com/minelittlepony/unicopia/entity/FairyEntity.java +++ b/src/main/java/com/minelittlepony/unicopia/entity/FairyEntity.java @@ -198,10 +198,10 @@ public class FairyEntity extends PathAwareEntity implements DynamicLightSource, @Override public boolean handleAttack(Entity attacker) { - if (world instanceof ServerWorld) { + if (world instanceof ServerWorld serverWorld) { LightningEntity lightning = EntityType.LIGHTNING_BOLT.create(world); lightning.refreshPositionAfterTeleport(getX(), getY(), getZ()); - attacker.onStruckByLightning((ServerWorld)world, lightning); + attacker.onStruckByLightning(serverWorld, lightning); } emitGameEvent(GameEvent.LIGHTNING_STRIKE); ParticleUtils.spawnParticle(world, UParticles.LIGHTNING_BOLT, getPos(), Vec3d.ZERO); diff --git a/src/main/java/com/minelittlepony/unicopia/item/PolearmItem.java b/src/main/java/com/minelittlepony/unicopia/item/PolearmItem.java index 31ac019a..031c3e21 100644 --- a/src/main/java/com/minelittlepony/unicopia/item/PolearmItem.java +++ b/src/main/java/com/minelittlepony/unicopia/item/PolearmItem.java @@ -4,6 +4,7 @@ import java.util.UUID; import com.google.common.collect.ImmutableMultimap; import com.google.common.collect.Multimap; +import com.minelittlepony.unicopia.UTags; import com.minelittlepony.unicopia.entity.UEntityAttributes; import net.minecraft.block.*; @@ -40,7 +41,7 @@ public class PolearmItem extends SwordItem { @Override public boolean isSuitableFor(BlockState state) { - return false; + return state.isIn(UTags.POLEARM_MINEABLE); } @Override diff --git a/src/main/java/com/minelittlepony/unicopia/item/UItems.java b/src/main/java/com/minelittlepony/unicopia/item/UItems.java index 367e053f..ab2b18f8 100644 --- a/src/main/java/com/minelittlepony/unicopia/item/UItems.java +++ b/src/main/java/com/minelittlepony/unicopia/item/UItems.java @@ -9,6 +9,8 @@ import com.minelittlepony.unicopia.entity.UEntities; import com.minelittlepony.unicopia.item.enchantment.UEnchantments; import com.minelittlepony.unicopia.item.toxin.UFoodComponents; +import net.minecraft.entity.effect.StatusEffectInstance; +import net.minecraft.entity.effect.StatusEffects; import net.minecraft.item.*; import net.minecraft.item.Item.Settings; import net.fabricmc.fabric.api.item.v1.FabricItemSettings; @@ -26,6 +28,14 @@ public interface UItems { Item SOUR_APPLE = register("sour_apple", AppleItem.registerTickCallback(new Item(new Item.Settings().group(ItemGroup.FOOD).food(FoodComponents.APPLE)))); ZapAppleItem ZAP_APPLE = register("zap_apple", AppleItem.registerTickCallback(new ZapAppleItem(new Item.Settings().group(ItemGroup.FOOD).food(UFoodComponents.ZAP_APPLE)))); + Item ZAP_BULB = register("zap_bulb", new Item(new Item.Settings().group(ItemGroup.FOOD).food(new FoodComponent.Builder() + .hunger(-2) + .saturationModifier(-0.8f) + .alwaysEdible() + .statusEffect(new StatusEffectInstance(StatusEffects.POISON, 100, 0), 0.6F) + .statusEffect(new StatusEffectInstance(StatusEffects.BLINDNESS, 100, 0), 0.6F) + .statusEffect(new StatusEffectInstance(StatusEffects.BAD_OMEN, 100, 0), 0.6F) + .build()))); Item ROTTEN_APPLE = register("rotten_apple", new RottenAppleItem(new Item.Settings().group(ItemGroup.FOOD).food(FoodComponents.APPLE))); Item COOKED_ZAP_APPLE = register("cooked_zap_apple", new Item(new Item.Settings().group(ItemGroup.FOOD).food(FoodComponents.APPLE))); @@ -90,6 +100,8 @@ 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) diff --git a/src/main/resources/assets/unicopia/blockstates/zap_apple.json b/src/main/resources/assets/unicopia/blockstates/zap_apple.json new file mode 100644 index 00000000..26404112 --- /dev/null +++ b/src/main/resources/assets/unicopia/blockstates/zap_apple.json @@ -0,0 +1,7 @@ +{ + "variants": { + "": { + "model": "unicopia:block/zap_apple" + } + } +} \ No newline at end of file diff --git a/src/main/resources/assets/unicopia/blockstates/zap_bulb.json b/src/main/resources/assets/unicopia/blockstates/zap_bulb.json new file mode 100644 index 00000000..65df6348 --- /dev/null +++ b/src/main/resources/assets/unicopia/blockstates/zap_bulb.json @@ -0,0 +1,7 @@ +{ + "variants": { + "": { + "model": "unicopia:block/zap_bulb" + } + } +} \ No newline at end of file diff --git a/src/main/resources/assets/unicopia/blockstates/zap_leaves.json b/src/main/resources/assets/unicopia/blockstates/zap_leaves.json new file mode 100644 index 00000000..6d93be93 --- /dev/null +++ b/src/main/resources/assets/unicopia/blockstates/zap_leaves.json @@ -0,0 +1,19 @@ +{ + "variants": { + "stage=hibernating": { + "model": "unicopia:block/zap_leaves" + }, + "stage=greening": { + "model": "unicopia:block/zap_leaves" + }, + "stage=flowering": { + "model": "unicopia:block/flowering_zap_leaves" + }, + "stage=fruiting": { + "model": "unicopia:block/zap_leaves" + }, + "stage=ripe": { + "model": "unicopia:block/zap_leaves" + } + } +} diff --git a/src/main/resources/assets/unicopia/blockstates/zap_log.json b/src/main/resources/assets/unicopia/blockstates/zap_log.json new file mode 100644 index 00000000..c3b64c19 --- /dev/null +++ b/src/main/resources/assets/unicopia/blockstates/zap_log.json @@ -0,0 +1,16 @@ +{ + "variants": { + "axis=x": { + "model": "unicopia:block/zap_log_horizontal", + "x": 90, + "y": 90 + }, + "axis=y": { + "model": "unicopia:block/zap_log" + }, + "axis=z": { + "model": "unicopia:block/zap_log_horizontal", + "x": 90 + } + } +} diff --git a/src/main/resources/assets/unicopia/blockstates/zapling.json b/src/main/resources/assets/unicopia/blockstates/zapling.json new file mode 100644 index 00000000..02ed0968 --- /dev/null +++ b/src/main/resources/assets/unicopia/blockstates/zapling.json @@ -0,0 +1,7 @@ +{ + "variants": { + "": { + "model": "unicopia:block/zapling" + } + } +} \ No newline at end of file diff --git a/src/main/resources/assets/unicopia/lang/en_us.json b/src/main/resources/assets/unicopia/lang/en_us.json index b9f22726..2484bc1c 100644 --- a/src/main/resources/assets/unicopia/lang/en_us.json +++ b/src/main/resources/assets/unicopia/lang/en_us.json @@ -26,6 +26,7 @@ "item.unicopia.rotten_apple": "Rotten Apple", "item.unicopia.cooked_zap_apple": "Cooked Zap Apple", "item.unicopia.zap_apple": "Zap Apple", + "item.unicopia.zap_bulb": "Unripened Zap Apple", "item.unicopia.empty_jar": "Glass Jar", "item.unicopia.filled_jar": "%s in a Jar", @@ -87,6 +88,11 @@ "item.unicopia.music_disc_funk.desc": "funk, just funk", "block.unicopia.rocks": "Rocks", + "block.unicopia.zapling": "Zapling", + "block.unicopia.zap_log": "Zap Log", + "block.unicopia.zap_leaves": "Zap Leaves", + "block.unicopia.zap_apple": "Zap Apple", + "block.unicopia.zap_bulb": "Unripened Zap Apple", "entity.unicopia.butterfly": "Butterfly", "entity.unicopia.twittermite": "Twittermite", diff --git a/src/main/resources/assets/unicopia/models/block/flowering_zap_leaves.json b/src/main/resources/assets/unicopia/models/block/flowering_zap_leaves.json new file mode 100644 index 00000000..d4d79822 --- /dev/null +++ b/src/main/resources/assets/unicopia/models/block/flowering_zap_leaves.json @@ -0,0 +1,6 @@ +{ + "parent": "minecraft:block/leaves", + "textures": { + "all": "unicopia:block/flowering_zap_leaves" + } +} \ No newline at end of file diff --git a/src/main/resources/assets/unicopia/models/block/zap_apple.json b/src/main/resources/assets/unicopia/models/block/zap_apple.json new file mode 100644 index 00000000..c5b0e7a4 --- /dev/null +++ b/src/main/resources/assets/unicopia/models/block/zap_apple.json @@ -0,0 +1,6 @@ +{ + "parent": "minecraft:block/cross", + "textures": { + "cross": "unicopia:item/zap_apple" + } +} \ No newline at end of file diff --git a/src/main/resources/assets/unicopia/models/block/zap_bulb.json b/src/main/resources/assets/unicopia/models/block/zap_bulb.json new file mode 100644 index 00000000..2ada77fe --- /dev/null +++ b/src/main/resources/assets/unicopia/models/block/zap_bulb.json @@ -0,0 +1,6 @@ +{ + "parent": "minecraft:block/cross", + "textures": { + "cross": "unicopia:item/zap_bulb" + } +} \ No newline at end of file diff --git a/src/main/resources/assets/unicopia/models/block/zap_leaves.json b/src/main/resources/assets/unicopia/models/block/zap_leaves.json new file mode 100644 index 00000000..e8066248 --- /dev/null +++ b/src/main/resources/assets/unicopia/models/block/zap_leaves.json @@ -0,0 +1,6 @@ +{ + "parent": "minecraft:block/leaves", + "textures": { + "all": "unicopia:block/zap_leaves" + } +} \ No newline at end of file diff --git a/src/main/resources/assets/unicopia/models/block/zap_log.json b/src/main/resources/assets/unicopia/models/block/zap_log.json new file mode 100644 index 00000000..e787c248 --- /dev/null +++ b/src/main/resources/assets/unicopia/models/block/zap_log.json @@ -0,0 +1,7 @@ +{ + "parent": "minecraft:block/cube_column", + "textures": { + "end": "unicopia:block/zap_log_top", + "side": "unicopia:block/zap_log" + } +} \ No newline at end of file diff --git a/src/main/resources/assets/unicopia/models/block/zap_log_horizontal.json b/src/main/resources/assets/unicopia/models/block/zap_log_horizontal.json new file mode 100644 index 00000000..67f2f50c --- /dev/null +++ b/src/main/resources/assets/unicopia/models/block/zap_log_horizontal.json @@ -0,0 +1,7 @@ +{ + "parent": "minecraft:block/cube_column_horizontal", + "textures": { + "end": "unicopia:block/zap_log_top", + "side": "unicopia:block/zap_log" + } +} \ No newline at end of file diff --git a/src/main/resources/assets/unicopia/models/block/zapling.json b/src/main/resources/assets/unicopia/models/block/zapling.json new file mode 100644 index 00000000..e630495b --- /dev/null +++ b/src/main/resources/assets/unicopia/models/block/zapling.json @@ -0,0 +1,6 @@ +{ + "parent": "minecraft:block/cross", + "textures": { + "cross": "unicopia:item/zapling" + } +} \ No newline at end of file diff --git a/src/main/resources/assets/unicopia/models/item/zap_bulb.json b/src/main/resources/assets/unicopia/models/item/zap_bulb.json new file mode 100644 index 00000000..0fce5058 --- /dev/null +++ b/src/main/resources/assets/unicopia/models/item/zap_bulb.json @@ -0,0 +1,6 @@ +{ + "parent": "item/generated", + "textures": { + "layer0": "unicopia:item/zap_bulb" + } +} diff --git a/src/main/resources/assets/unicopia/models/item/zapling.json b/src/main/resources/assets/unicopia/models/item/zapling.json new file mode 100644 index 00000000..3c4bffea --- /dev/null +++ b/src/main/resources/assets/unicopia/models/item/zapling.json @@ -0,0 +1,6 @@ +{ + "parent": "item/generated", + "textures": { + "layer0": "unicopia:item/zapling" + } +} diff --git a/src/main/resources/assets/unicopia/textures/block/flowering_zap_leaves.png b/src/main/resources/assets/unicopia/textures/block/flowering_zap_leaves.png new file mode 100644 index 0000000000000000000000000000000000000000..ca5c516d7f3688a8604749284018c18d4909a164 GIT binary patch literal 1851 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 r>zIMcw(_! literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/unicopia/textures/block/zap_log_top.png b/src/main/resources/assets/unicopia/textures/block/zap_log_top.png new file mode 100644 index 0000000000000000000000000000000000000000..baa390f4f26b7ff6b77eeaafeef6d5fb1d0ca86a GIT binary patch literal 1765 zcmV zaB^>EX>4U6ba`-PAZ2)IW&i+q+O1bvvfMTd{O2ih1OniC9EwX-Zjj@rxk(z$%(Kgh zWSM*rL;~GdII8~hcT<1iVl6=#>w}BVXQ;XEgi#;RU zpX7{DFv=93`$=C&ZXdXFq)&3P54oJ%@QX!ZFT}WSa+kE%_bXgaYb7-Jth%;I#sMF< zoZ7C8859oyBjYoN+vBmA`*BCyK_{IR8C`VN2kuOfm_#=+R47rSI>t;HCK|5nF*0YC zAq(O;auzKlMu`zajlD!E5`-ml6@ipbTWIVX$99;QP*&kMw25d*CbbAW?MA9IPr(iK~x2GIgVi_y%F zeOU_tBJ6Ep3<(&}j>M89?U_9ha17ul!EzR5_y7fDEf-kHM#O=fz21saKs~JgikivW|w^qIp(Aa z7b&LL;)*Y!#F8pigi@ zLSvqg0e;T%!MTvJ1Q6hS=+ek|kATF}^PvtQ^mt4_u0S7{5ipwHMhd7|W9oonpBUXU zu}icv^!8Fel~6FlR4TzIGu~PR$bD3{7r`L`KhBgn1rs-^UH-aGz|ufXJvWrG5ZOdY zKa4qbvY%FE=VLN$x*MIhc1*pAr8<<}u~3LPZ!>M0umYwr33>x<2B!FzZlaAS2el`2 zJazXnVkZqH)GP?;;bH{4Co44#_Ef4-4p=l*NMfh}sQ*=i9AT@w=^?w%P=mEEP(Rh3 zT`>>?rMT6q=VM|eit?!pM<#e(u0-WAF zl2bjWhuC=j7J-&Gf|~1;9|Xv^w-NTM<-j}HUy0;4gN*K&I&}llPwSCps7{mTjLLQ< zY>(?9wvuw19Km?M=*P)m#|+JwiD=ty*&%kneU3bxN87YD&49du>)Pfc#orj#E7wre zy<747Lh;jlSiftOd7`RPxV_wXK;|YK2v?4iOBCf@a!}TC*;Oi!=v5!>`~x%9GG!SR z^f4*bx7hy7_k(V=_&%m5EO7@87O$yZ>AS=z(Z>YeWmm66RY>cJ8ehhQZ)NUs`vhz2 z;#B+Y0S>E+@R<2l7Jo`=^~~xM%hL?&mQQGpD@Dy(9YL_Q)J3RFyHUZ(Og_*@ccV(2 z(JZGlRC6Z7nKcS&^9vZ=mzwzAj-D@mAo)AT3MA)Mqq7vghw&{S&zf?9d8>3IMSiM^ zt5+MBgwMLbb+2^`UYsFU|Eu_+bN237>=YLq-r^1U51nm`l>Sz4es_F{qq<_HItlvG z`DWvLdi~Z<)JuQ(&~Dc82B$K!Pej?E-S29&%ME_7z1fNnX2lNmDy$z4T`wQ1Unt#9 zXtAxnvw<6p062r@HN7!-+Afe*wXU&@S3?5R(7^0cJ@=K~y-)g_A!| z!!QuVe~m3SP)89({1pNrF|ac*AThJ>X<7Inh#et70#qr)p>0&B491RA+H#9?m-G3( zcXz$(qpNvo4Vlnn{fu&2;(dUupYi(r7X0`hfGn-y_T+}xs>U!#G*x5Ro$v6z{QsATVFdtWhR_h^~6$1SEQ&5 zPKU?s^SUh>Bgup&@i{6LfoBkMW-v3;L9<99;UDwx{kixpOKVnM)>4C}gTTM+hbqiL zJ+Yx}UdW;@$W_NhQtBsm}00000NkvXX Hu0mjf0D4QO literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/unicopia/textures/item/zap_bulb.png b/src/main/resources/assets/unicopia/textures/item/zap_bulb.png new file mode 100644 index 0000000000000000000000000000000000000000..679a55ad90ea5a777e08998d9c6fe248b8db8955 GIT binary patch literal 1617 zcmV-X2Cn&uP) zaB^>EX>4U6ba`-PAZ2)IW&i+q+O=0%mMbR={bvCqs4(|Hd9-&1mq_i z4|P7uT0yZOF}%zIhT`L~)-@7FwAofeVw|Axc zWRcY+SJ^VL7#0>9PC0So$d0S)%#gYZ3$3_mg{u@1xDhlR!5P6~4RbF3>v-#Ej5jh%rM4&a(9PxnJmhGZ=y7v~FMKnXvW0q~K z?Qnn;A+`q?VlZF>v8O;*ol_#@F@m2AFSEs@7Oj&8E4=O`30^ zX^Snj+^J(Lb?Lr`u08hD^T1XcJY@J0hK@MW$QNsiRrAEzSLVKFjSkj8m|2_&lup(l zRy|$NY$twl2F9Ea7}v=FHnf|Z*+?R8GG``dHaS#+8RZA1>>~cG{l(eX-!%N8 zBksTF%S_wSmZ&IKQ0n#%%PoE~r9b%U<=y{z-8T~eX23I ztzc)9IBo;A`2rg-e*xu%&TM#3sLq%vwYYJkUmo*pN^^x{MpksO1E;8YxN#~!fPYH$ zw^+?*up4X0+pB=Ud=P83$SYJ6!d5J)yZD-m+D>dC#d1Q&0q*u_wT+n;^XTwj8^%-1hO*uXnriA6rq_hRqrr7?a-?4x9RHOKG+x*;uO#0od=Gl=%kj0{hF& z{|5Pc7|rL59%?;vSLtcHD0oZ1H8F2|w7l^M$J+gYAr6te%gN!qQH~u@cpffhhb)AH zI`?)oJm&WKZE?R~xE(FJ5AG}=cs*LSt+uU$6U1v1!eN8%&U2Jrq8^jNZAGg$^vs?EL@CKfAL+ zO3A-WO39%lncA(4;>8XX$kcA7XWNnS*fA=dZcjwT#74dl+n7S5F8%48kLMQ>y3VB8 z65$s1CMY!O5+GGIu)GJ5iX8=>X+@F~`P?rq@T^)` zQkZzilmdS`j|3(1Ih@xnOK0)-99%sskEi3_y{On#9waYk5{F12B8)0FX9T{-%0xkhF-omjIt@a7?cJeShKy5>>DS?Yae^ P00000NkvXXu0mjfAF&Ka literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/unicopia/textures/item/zapling.png b/src/main/resources/assets/unicopia/textures/item/zapling.png new file mode 100644 index 0000000000000000000000000000000000000000..466698989b5b57bc3d2a0649cd37f9905a4f6ecb GIT binary patch literal 1786 zcmV zaB^>EX>4U6ba`-PAZ2)IW&i+q+QnCGlI$i7{Ld+J1cU@g$H9D5g$CS8v{rITrlrlF_Y2?!$*Y zBD8n%fS%Fw65i|aG{jF6(%sWLImJ(MzLyCf5a~7)(4ORJ`0Sq_ef-8~I?78V*IvvFhPz%_JcNW+bV&UNivu99NmM$ildV}u!Jb9?Y_+gn3p z)afF^?zgXiD}+e{O)v8N3oQ^rW5-cE9lYD;2gJgNKx?{LvBBbxW#WkRh%I&}(G10i zUe@H?E(358){X!}3E0HM4Nft#6mB>+Ij49@*(PBxQB*m0cPBRxv<}5kplylZ>xhSh> z)TCKeO^dT&j9iVDESs8HDOj|?a>4AP1%e|Se8>@xbmT)1J4!|PRH?D1nyXf;#kJ75 zNsBGD+_YIMojO9POOHME+_hUT1EDr}$cQ72JapJ7H)|)W?gMA9%ze)qU95pHcXB3B z+N?pG^EN@VoW#i)7z;vRJWmD?&|z}sl|;g1&P~p|1!P4GKp7`FjV5DYP&$P;=;rRh z+zW3GdH=h-g=gm6r0&09&Q0pxF!##a8`j#a?{(&(M`4?3IGySl=?8_bB`7q)&wBUM z3IBtk-qz-N;?`NuaX5+$FW=d6zXM`OTIQ{e!d!bo($2M&dww9Ya3jL`aK3m3-5c2~ z`@e~(wF`g_sWsdt`N4;^+ajmNF0teQzg?_Gp*)8$FW|RTt}|w^>zp< z%wFn&@Y2zanqX}a=S7K6*G?IF)P+HUjadbl|E7Y+`D%l-ovoCF{iQsrTD<+ zCb$>@ZQw+x}$5JB~KjN9UnL#*RWP)y3(H5^h2K7ReqbGhA$oC zns%xCgHn9FNJbiDo`t6#<}+ zdf2_Qr@W%*7E}ozHuhC?ek{X$iL1z2*uv4~k$I&}^tD_(t3G50@5t3PN=c|(p8+zs z6Lpa@Xl4|8z2;=|Iqy95I8BM}V&(6UXvgwEbu}OLh56?>)@bRrp5t9Uu9{iyD05E% z8`sfeTFcmFN_XB_tvQW5vc{uqoicK+pKRn6C<*tXaJi>c95GJ`|5OF8s@{dVEA~6D|BUr#T=!Xe=R)1Nrl>Pt)smOmGH`b^+!_A{BH_fgc7S8R z0004@Nklz4 zw7r|X54?50CX>Gt?3Gt@rzQ7y6d%9TVXdQ04S>uRg|&`0@6z{oQgu8&-i!b!S6*qA zDyAw1U=a0WPQlUkE_FE-0J~(9uI=mBpU(lX+*Z~cJe){7P_nc_ci6|bUFvcwDplAe zo2DP?4>vzDg@dRkJ5QbwsW`ij{O*8eovZ5+m5oh$U*5>#al6BQKEZ*vPI7;T<+ik4 zviWp*!C7)Fd*xM}qQ%?Ew|p0xeyGD*M~@2)?G!Dpu19mEmfOu~O z!--5)%p==nTxjUZ#%4y4uI=loiusw|^3=KzV{>8F^Qz-9h@sKvN+K2WesY_sXa`EV!#<{dPQfA~7316PQfwAx=t>@eNjCj3i!BoV(`Pcf c8_)Cb3x98>>XHp1ssI2007*qoM6N<$f=BXkF#rGn literal 0 HcmV?d00001 diff --git a/src/main/resources/data/unicopia/loot_tables/blocks/zap_apple.json b/src/main/resources/data/unicopia/loot_tables/blocks/zap_apple.json new file mode 100644 index 00000000..3400bb32 --- /dev/null +++ b/src/main/resources/data/unicopia/loot_tables/blocks/zap_apple.json @@ -0,0 +1,20 @@ +{ + "type": "minecraft:block", + "pools": [ + { + "rolls": 1.0, + "bonus_rolls": 0.0, + "entries": [ + { + "type": "minecraft:item", + "name": "unicopia:zap_apple" + } + ], + "conditions": [ + { + "condition": "minecraft:survives_explosion" + } + ] + } + ] +} \ No newline at end of file diff --git a/src/main/resources/data/unicopia/loot_tables/blocks/zap_bulb.json b/src/main/resources/data/unicopia/loot_tables/blocks/zap_bulb.json new file mode 100644 index 00000000..2944030f --- /dev/null +++ b/src/main/resources/data/unicopia/loot_tables/blocks/zap_bulb.json @@ -0,0 +1,20 @@ +{ + "type": "minecraft:block", + "pools": [ + { + "rolls": 1.0, + "bonus_rolls": 0.0, + "entries": [ + { + "type": "minecraft:item", + "name": "unicopia:zap_bulb" + } + ], + "conditions": [ + { + "condition": "minecraft:survives_explosion" + } + ] + } + ] +} \ No newline at end of file diff --git a/src/main/resources/data/unicopia/loot_tables/blocks/zapling.json b/src/main/resources/data/unicopia/loot_tables/blocks/zapling.json new file mode 100644 index 00000000..508f8ba3 --- /dev/null +++ b/src/main/resources/data/unicopia/loot_tables/blocks/zapling.json @@ -0,0 +1,20 @@ +{ + "type": "minecraft:block", + "pools": [ + { + "rolls": 1.0, + "bonus_rolls": 0.0, + "entries": [ + { + "type": "minecraft:item", + "name": "unicopia:zapling" + } + ], + "conditions": [ + { + "condition": "minecraft:survives_explosion" + } + ] + } + ] +} \ No newline at end of file diff --git a/src/main/resources/data/unicopia/tags/blocks/mineable/polearm.json b/src/main/resources/data/unicopia/tags/blocks/mineable/polearm.json new file mode 100644 index 00000000..11c84d4c --- /dev/null +++ b/src/main/resources/data/unicopia/tags/blocks/mineable/polearm.json @@ -0,0 +1,7 @@ +{ + "replace": false, + "values": [ + "unicopia:zap_leaves", + "unicopia:zap_log" + ] +} diff --git a/src/main/resources/data/unicopia/tags/items/polearms.json b/src/main/resources/data/unicopia/tags/items/polearms.json new file mode 100644 index 00000000..54736807 --- /dev/null +++ b/src/main/resources/data/unicopia/tags/items/polearms.json @@ -0,0 +1,11 @@ +{ + "replace": false, + "values": [ + "unicopia:wooden_polearm", + "unicopia:stone_polearm", + "unicopia:iron_polearm", + "unicopia:golden_polearm", + "unicopia:diamond_polearm", + "unicopia:netherite_polearm" + ] +}