mirror of
https://github.com/Sollace/Unicopia.git
synced 2024-11-30 16:28:00 +01:00
Added weather vanes
This commit is contained in:
parent
c3032ded26
commit
6db30ff693
16 changed files with 348 additions and 8 deletions
|
@ -18,8 +18,7 @@ import com.minelittlepony.unicopia.ability.magic.spell.trait.TraitLoader;
|
||||||
import com.minelittlepony.unicopia.advancement.UCriteria;
|
import com.minelittlepony.unicopia.advancement.UCriteria;
|
||||||
import com.minelittlepony.unicopia.block.UBlocks;
|
import com.minelittlepony.unicopia.block.UBlocks;
|
||||||
import com.minelittlepony.unicopia.block.UTreeGen;
|
import com.minelittlepony.unicopia.block.UTreeGen;
|
||||||
import com.minelittlepony.unicopia.block.data.BlockDestructionManager;
|
import com.minelittlepony.unicopia.block.data.*;
|
||||||
import com.minelittlepony.unicopia.block.data.ZapAppleStageStore;
|
|
||||||
import com.minelittlepony.unicopia.block.state.StateMapLoader;
|
import com.minelittlepony.unicopia.block.state.StateMapLoader;
|
||||||
import com.minelittlepony.unicopia.command.Commands;
|
import com.minelittlepony.unicopia.command.Commands;
|
||||||
import com.minelittlepony.unicopia.container.SpellbookChapterLoader;
|
import com.minelittlepony.unicopia.container.SpellbookChapterLoader;
|
||||||
|
@ -63,6 +62,7 @@ public class Unicopia implements ModInitializer {
|
||||||
ServerTickEvents.END_WORLD_TICK.register(w -> {
|
ServerTickEvents.END_WORLD_TICK.register(w -> {
|
||||||
((BlockDestructionManager.Source)w).getDestructionManager().tick();
|
((BlockDestructionManager.Source)w).getDestructionManager().tick();
|
||||||
ZapAppleStageStore.get(w).tick();
|
ZapAppleStageStore.get(w).tick();
|
||||||
|
WeatherConditions.get(w).tick();
|
||||||
if (Debug.DEBUG_SPELLBOOK_CHAPTERS) {
|
if (Debug.DEBUG_SPELLBOOK_CHAPTERS) {
|
||||||
SpellbookChapterLoader.INSTANCE.sendUpdate(w.getServer());
|
SpellbookChapterLoader.INSTANCE.sendUpdate(w.getServer());
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,16 @@
|
||||||
|
package com.minelittlepony.unicopia.block;
|
||||||
|
|
||||||
|
import net.minecraft.block.entity.BlockEntity;
|
||||||
|
import net.minecraft.block.entity.BlockEntityType;
|
||||||
|
import net.minecraft.block.entity.BlockEntityType.Builder;
|
||||||
|
import net.minecraft.util.registry.Registry;
|
||||||
|
|
||||||
|
public interface UBlockEntities {
|
||||||
|
BlockEntityType<WeatherVaneBlock.WeatherVane> WEATHER_VANE = create("weather_vane", BlockEntityType.Builder.create(WeatherVaneBlock.WeatherVane::new, UBlocks.WEATHER_VANE));
|
||||||
|
|
||||||
|
static <T extends BlockEntity> BlockEntityType<T> create(String id, Builder<T> builder) {
|
||||||
|
return Registry.register(Registry.BLOCK_ENTITY_TYPE, id, builder.build(null));
|
||||||
|
}
|
||||||
|
|
||||||
|
static void bootstrap() {}
|
||||||
|
}
|
|
@ -42,6 +42,8 @@ public interface UBlocks {
|
||||||
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, false));
|
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, false));
|
||||||
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, false));
|
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, false));
|
||||||
|
|
||||||
|
Block WEATHER_VANE = register("weather_vane", new WeatherVaneBlock(FabricBlockSettings.of(Material.METAL, MapColor.BLACK).requiresTool().strength(3.0f, 6.0f).sounds(BlockSoundGroup.METAL).nonOpaque()), ItemGroup.DECORATIONS);
|
||||||
|
|
||||||
Block GREEN_APPLE_LEAVES = register("green_apple_leaves", new FruitBearingBlock(FabricBlockSettings.copy(Blocks.OAK_LEAVES),
|
Block GREEN_APPLE_LEAVES = register("green_apple_leaves", new FruitBearingBlock(FabricBlockSettings.copy(Blocks.OAK_LEAVES),
|
||||||
0xE5FFFF88,
|
0xE5FFFF88,
|
||||||
() -> UBlocks.GREEN_APPLE,
|
() -> UBlocks.GREEN_APPLE,
|
||||||
|
@ -98,6 +100,9 @@ public interface UBlocks {
|
||||||
static void bootstrap() {
|
static void bootstrap() {
|
||||||
StrippableBlockRegistry.register(ZAP_LOG, STRIPPED_ZAP_LOG);
|
StrippableBlockRegistry.register(ZAP_LOG, STRIPPED_ZAP_LOG);
|
||||||
StrippableBlockRegistry.register(ZAP_WOOD, STRIPPED_ZAP_WOOD);
|
StrippableBlockRegistry.register(ZAP_WOOD, STRIPPED_ZAP_WOOD);
|
||||||
|
TRANSLUCENT_BLOCKS.add(WEATHER_VANE);
|
||||||
|
|
||||||
|
UBlockEntities.bootstrap();
|
||||||
}
|
}
|
||||||
|
|
||||||
static boolean never(BlockState state, BlockView world, BlockPos pos) {
|
static boolean never(BlockState state, BlockView world, BlockPos pos) {
|
||||||
|
|
|
@ -0,0 +1,119 @@
|
||||||
|
package com.minelittlepony.unicopia.block;
|
||||||
|
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
|
import com.minelittlepony.unicopia.USounds;
|
||||||
|
import com.minelittlepony.unicopia.block.data.WeatherConditions;
|
||||||
|
|
||||||
|
import net.minecraft.block.*;
|
||||||
|
import net.minecraft.block.entity.*;
|
||||||
|
import net.minecraft.nbt.NbtCompound;
|
||||||
|
import net.minecraft.network.Packet;
|
||||||
|
import net.minecraft.network.listener.ClientPlayPacketListener;
|
||||||
|
import net.minecraft.network.packet.s2c.play.BlockEntityUpdateS2CPacket;
|
||||||
|
import net.minecraft.server.world.ServerWorld;
|
||||||
|
import net.minecraft.sound.SoundCategory;
|
||||||
|
import net.minecraft.util.math.*;
|
||||||
|
import net.minecraft.util.shape.VoxelShape;
|
||||||
|
import net.minecraft.util.shape.VoxelShapes;
|
||||||
|
import net.minecraft.world.BlockView;
|
||||||
|
import net.minecraft.world.World;
|
||||||
|
|
||||||
|
public class WeatherVaneBlock extends BlockWithEntity {
|
||||||
|
/*private static final VoxelShape SHAPE = VoxelShapes.union(
|
||||||
|
Block.createCuboidShape(7.5F, 0, 7.5F, 8.5F, 14, 8.5F),
|
||||||
|
Block.createCuboidShape(7, 0, 7, 9, 1, 9)
|
||||||
|
);*/
|
||||||
|
|
||||||
|
protected WeatherVaneBlock(Settings settings) {
|
||||||
|
super(settings);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Deprecated
|
||||||
|
@Override
|
||||||
|
public VoxelShape getOutlineShape(BlockState state, BlockView world, BlockPos pos, ShapeContext context) {
|
||||||
|
return VoxelShapes.union(
|
||||||
|
Block.createCuboidShape(7.5F, 0, 7.5F, 8.5F, 14, 8.5F),
|
||||||
|
Block.createCuboidShape(7, 0, 7, 9, 1, 9)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public BlockEntity createBlockEntity(BlockPos pos, BlockState state) {
|
||||||
|
return new WeatherVane(pos, state);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@Nullable
|
||||||
|
public <T extends BlockEntity> BlockEntityTicker<T> getTicker(World world, BlockState state, BlockEntityType<T> type) {
|
||||||
|
return BellBlock.checkType(type, UBlockEntities.WEATHER_VANE, world.isClient ? WeatherVane::clientTick : WeatherVane::serverTick);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class WeatherVane extends BlockEntity {
|
||||||
|
private float angle;
|
||||||
|
|
||||||
|
private float clientAngle;
|
||||||
|
private float prevAngle;
|
||||||
|
|
||||||
|
public WeatherVane(BlockPos pos, BlockState state) {
|
||||||
|
super(UBlockEntities.WEATHER_VANE, pos, state);
|
||||||
|
}
|
||||||
|
|
||||||
|
public float getAngle(float tickDelta) {
|
||||||
|
return MathHelper.lerp(tickDelta, prevAngle, clientAngle);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void readNbt(NbtCompound nbt) {
|
||||||
|
angle = nbt.getFloat("angle");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void writeNbt(NbtCompound nbt) {
|
||||||
|
nbt.putFloat("angle", angle);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Packet<ClientPlayPacketListener> toUpdatePacket() {
|
||||||
|
return BlockEntityUpdateS2CPacket.create(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public NbtCompound toInitialChunkDataNbt() {
|
||||||
|
return createNbt();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void serverTick(World world, BlockPos pos, BlockState state, WeatherVane entity) {
|
||||||
|
Vec3d airflow = WeatherConditions.get(world).getWindDirection();
|
||||||
|
float angle = (float)Math.atan2(airflow.x, airflow.z) + MathHelper.PI;
|
||||||
|
if (Math.signum(entity.angle) != Math.signum(angle)) {
|
||||||
|
angle = MathHelper.PI - angle;
|
||||||
|
}
|
||||||
|
angle %= MathHelper.PI;
|
||||||
|
|
||||||
|
if (angle != entity.angle) {
|
||||||
|
entity.angle = angle;
|
||||||
|
entity.markDirty();
|
||||||
|
if (world instanceof ServerWorld serverWorld) {
|
||||||
|
serverWorld.getChunkManager().markForUpdate(pos);
|
||||||
|
}
|
||||||
|
|
||||||
|
world.playSound(null, pos.getX(), pos.getY(), pos.getZ(), USounds.BLOCK_WEATHER_VANE_ROTATE, SoundCategory.BLOCKS, 1, 0.5F + (float)world.random.nextGaussian());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void clientTick(World world, BlockPos pos, BlockState state, WeatherVane entity) {
|
||||||
|
entity.prevAngle = entity.clientAngle;
|
||||||
|
|
||||||
|
float angle = entity.angle + (float)Math.sin(world.getTime() / 70F) * (world.isThundering() ? 30 : 1);
|
||||||
|
|
||||||
|
float step = (Math.abs(entity.clientAngle) - Math.abs(angle)) / 7F;
|
||||||
|
|
||||||
|
if (entity.clientAngle < angle) {
|
||||||
|
entity.clientAngle += step;
|
||||||
|
} else if (entity.clientAngle > angle) {
|
||||||
|
entity.clientAngle -= step;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,13 +1,19 @@
|
||||||
package com.minelittlepony.unicopia.block.data;
|
package com.minelittlepony.unicopia.block.data;
|
||||||
|
|
||||||
|
import com.minelittlepony.unicopia.Unicopia;
|
||||||
|
import com.minelittlepony.unicopia.util.Tickable;
|
||||||
|
|
||||||
import net.minecraft.block.BlockState;
|
import net.minecraft.block.BlockState;
|
||||||
import net.minecraft.block.Blocks;
|
import net.minecraft.block.Blocks;
|
||||||
|
import net.minecraft.nbt.NbtCompound;
|
||||||
import net.minecraft.tag.BlockTags;
|
import net.minecraft.tag.BlockTags;
|
||||||
|
import net.minecraft.util.Identifier;
|
||||||
import net.minecraft.util.math.*;
|
import net.minecraft.util.math.*;
|
||||||
import net.minecraft.world.Heightmap.Type;
|
import net.minecraft.world.Heightmap.Type;
|
||||||
|
import net.minecraft.world.PersistentState;
|
||||||
import net.minecraft.world.World;
|
import net.minecraft.world.World;
|
||||||
|
|
||||||
public class WeatherConditions {
|
public class WeatherConditions extends PersistentState implements Tickable {
|
||||||
public static final TwoDimensionalField HEIGHT_MAP_FIELD = (world, pos) -> {
|
public static final TwoDimensionalField HEIGHT_MAP_FIELD = (world, pos) -> {
|
||||||
return world.getTopY(Type.WORLD_SURFACE_WG, pos.getX(), pos.getZ());
|
return world.getTopY(Type.WORLD_SURFACE_WG, pos.getX(), pos.getZ());
|
||||||
};
|
};
|
||||||
|
@ -29,16 +35,87 @@ public class WeatherConditions {
|
||||||
|
|
||||||
public static final float MAX_UPDRAFT_HEIGHT = 20;
|
public static final float MAX_UPDRAFT_HEIGHT = 20;
|
||||||
public static final float MAX_TERRAIN_HEIGHT = 50;
|
public static final float MAX_TERRAIN_HEIGHT = 50;
|
||||||
|
public static final float MAX_WIND_HEIGHT = 70;
|
||||||
|
|
||||||
|
private static final Identifier ID = Unicopia.id("weather_conditions");
|
||||||
|
|
||||||
|
public static WeatherConditions get(World world) {
|
||||||
|
return WorldOverlay.getPersistableStorage(world, ID, WeatherConditions::new, WeatherConditions::new);
|
||||||
|
}
|
||||||
|
|
||||||
|
private final World world;
|
||||||
|
|
||||||
|
private float windYaw;
|
||||||
|
private float prevWindYaw;
|
||||||
|
private int interpolation;
|
||||||
|
private int maxInterpolation = 100;
|
||||||
|
|
||||||
|
private boolean prevDayState;
|
||||||
|
|
||||||
|
private WeatherConditions(World world, NbtCompound compound) {
|
||||||
|
this(world);
|
||||||
|
windYaw = compound.getFloat("windYaw");
|
||||||
|
prevWindYaw = compound.getFloat("prevWindYaw");
|
||||||
|
prevDayState = compound.getBoolean("prevDayState");
|
||||||
|
interpolation = compound.getInt("interpolation");
|
||||||
|
maxInterpolation = compound.getInt("maxInterpolation");
|
||||||
|
}
|
||||||
|
|
||||||
|
private WeatherConditions(World world) {
|
||||||
|
this.world = world;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void tick() {
|
||||||
|
if (interpolation < maxInterpolation) {
|
||||||
|
interpolation++;
|
||||||
|
markDirty();
|
||||||
|
}
|
||||||
|
|
||||||
|
boolean isDay = world.isDay();
|
||||||
|
if (isDay != prevDayState
|
||||||
|
|| world.random.nextInt(1200) == 0
|
||||||
|
|| (world.isRaining() && world.random.nextInt(120) == 0)
|
||||||
|
|| (world.isThundering() && world.random.nextInt(90) == 0)) {
|
||||||
|
prevDayState = isDay;
|
||||||
|
prevWindYaw = getWindYaw();
|
||||||
|
windYaw = world.random.nextFloat() * 360;
|
||||||
|
interpolation = 0;
|
||||||
|
maxInterpolation = world.isRaining() || world.isThundering() ? 50 : 100;
|
||||||
|
markDirty();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public float getWindYaw() {
|
||||||
|
return MathHelper.lerp(interpolation / (float)maxInterpolation, prevWindYaw, windYaw);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Vec3d getWindDirection() {
|
||||||
|
return Vec3d.fromPolar(0, windYaw).normalize();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public NbtCompound writeNbt(NbtCompound compound) {
|
||||||
|
compound.putFloat("windYaw", windYaw);
|
||||||
|
compound.putFloat("prevWindYaw", prevWindYaw);
|
||||||
|
compound.putBoolean("prevDayState", prevDayState);
|
||||||
|
compound.putInt("interpolation", interpolation);
|
||||||
|
compound.putInt("maxInterpolation", maxInterpolation);
|
||||||
|
return compound;
|
||||||
|
}
|
||||||
|
|
||||||
public static Vec3d getAirflow(BlockPos pos, World world) {
|
public static Vec3d getAirflow(BlockPos pos, World world) {
|
||||||
BlockPos.Mutable probedPosition = new BlockPos.Mutable();
|
BlockPos.Mutable probedPosition = new BlockPos.Mutable();
|
||||||
|
|
||||||
final float terrainFactor = Math.min(MAX_TERRAIN_HEIGHT, LOCAL_ALTITUDE_FIELD.getValue(world, probedPosition.set(pos))) / MAX_TERRAIN_HEIGHT;
|
final float localAltitude = LOCAL_ALTITUDE_FIELD.getValue(world, probedPosition.set(pos));
|
||||||
|
final float terrainFactor = Math.min(MAX_TERRAIN_HEIGHT, localAltitude) / MAX_TERRAIN_HEIGHT;
|
||||||
|
final float windFactor = Math.min(MAX_WIND_HEIGHT, localAltitude) / MAX_WIND_HEIGHT;
|
||||||
|
|
||||||
Vec3d terrainGradient = LOCAL_ALTITUDE_FIELD.computeAverage(world, pos, probedPosition).multiply(1 - terrainFactor);
|
Vec3d terrainGradient = LOCAL_ALTITUDE_FIELD.computeAverage(world, pos, probedPosition).multiply(1 - terrainFactor);
|
||||||
Vec3d thermalGradient = THERMAL_FIELD.computeAverage(world, pos, probedPosition).multiply(terrainFactor);
|
Vec3d thermalGradient = THERMAL_FIELD.computeAverage(world, pos, probedPosition).multiply(terrainFactor);
|
||||||
|
Vec3d wind = get(world).getWindDirection().multiply(1 - windFactor);
|
||||||
|
|
||||||
return terrainGradient.add(thermalGradient).normalize().add(0, getUpdraft(probedPosition.set(pos), world), 0);
|
return terrainGradient.add(thermalGradient).add(wind).normalize().add(0, getUpdraft(probedPosition.set(pos), world), 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static double getUpdraft(BlockPos.Mutable pos, World world) {
|
public static double getUpdraft(BlockPos.Mutable pos, World world) {
|
||||||
|
|
|
@ -24,9 +24,7 @@ import com.minelittlepony.unicopia.particle.UParticles;
|
||||||
import net.fabricmc.fabric.api.blockrenderlayer.v1.BlockRenderLayerMap;
|
import net.fabricmc.fabric.api.blockrenderlayer.v1.BlockRenderLayerMap;
|
||||||
import net.fabricmc.fabric.api.client.particle.v1.ParticleFactoryRegistry;
|
import net.fabricmc.fabric.api.client.particle.v1.ParticleFactoryRegistry;
|
||||||
import net.fabricmc.fabric.api.client.particle.v1.ParticleFactoryRegistry.PendingParticleFactory;
|
import net.fabricmc.fabric.api.client.particle.v1.ParticleFactoryRegistry.PendingParticleFactory;
|
||||||
import net.fabricmc.fabric.api.client.rendering.v1.EntityRendererRegistry;
|
import net.fabricmc.fabric.api.client.rendering.v1.*;
|
||||||
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.block.Block;
|
||||||
import net.minecraft.client.MinecraftClient;
|
import net.minecraft.client.MinecraftClient;
|
||||||
import net.minecraft.client.color.block.BlockColorProvider;
|
import net.minecraft.client.color.block.BlockColorProvider;
|
||||||
|
@ -77,6 +75,8 @@ public interface URenderers {
|
||||||
EntityRendererRegistry.register(UEntities.SPELLBOOK, SpellbookEntityRenderer::new);
|
EntityRendererRegistry.register(UEntities.SPELLBOOK, SpellbookEntityRenderer::new);
|
||||||
EntityRendererRegistry.register(UEntities.AIR_BALLOON, AirBalloonEntityRenderer::new);
|
EntityRendererRegistry.register(UEntities.AIR_BALLOON, AirBalloonEntityRenderer::new);
|
||||||
|
|
||||||
|
BlockEntityRendererRegistry.register(UBlockEntities.WEATHER_VANE, WeatherVaneBlockEntityRenderer::new);
|
||||||
|
|
||||||
ColorProviderRegistry.ITEM.register((stack, i) -> i > 0 ? -1 : ((DyeableItem)stack.getItem()).getColor(stack), UItems.FRIENDSHIP_BRACELET);
|
ColorProviderRegistry.ITEM.register((stack, i) -> i > 0 ? -1 : ((DyeableItem)stack.getItem()).getColor(stack), UItems.FRIENDSHIP_BRACELET);
|
||||||
BuiltinItemRendererRegistry.INSTANCE.register(UItems.FILLED_JAR, (stack, mode, matrices, vertexConsumers, light, overlay) -> {
|
BuiltinItemRendererRegistry.INSTANCE.register(UItems.FILLED_JAR, (stack, mode, matrices, vertexConsumers, light, overlay) -> {
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,58 @@
|
||||||
|
package com.minelittlepony.unicopia.client.render.entity;
|
||||||
|
|
||||||
|
import com.minelittlepony.unicopia.Unicopia;
|
||||||
|
import com.minelittlepony.unicopia.block.WeatherVaneBlock;
|
||||||
|
import com.minelittlepony.unicopia.block.WeatherVaneBlock.WeatherVane;
|
||||||
|
import com.minelittlepony.unicopia.client.render.RenderLayers;
|
||||||
|
|
||||||
|
import net.minecraft.client.model.*;
|
||||||
|
import net.minecraft.client.render.VertexConsumerProvider;
|
||||||
|
import net.minecraft.client.render.block.entity.BlockEntityRenderer;
|
||||||
|
import net.minecraft.client.render.block.entity.BlockEntityRendererFactory;
|
||||||
|
import net.minecraft.client.util.math.MatrixStack;
|
||||||
|
import net.minecraft.util.Identifier;
|
||||||
|
|
||||||
|
public class WeatherVaneBlockEntityRenderer implements BlockEntityRenderer<WeatherVaneBlock.WeatherVane> {
|
||||||
|
private static final Identifier TEXTURE = Unicopia.id("textures/entity/weather_vane.png");
|
||||||
|
|
||||||
|
private final ModelPart root;
|
||||||
|
private final ModelPart pole;
|
||||||
|
|
||||||
|
public WeatherVaneBlockEntityRenderer(BlockEntityRendererFactory.Context ctx) {
|
||||||
|
root = getTexturedModelData().createModel();
|
||||||
|
pole = root.getChild("pole");
|
||||||
|
}
|
||||||
|
|
||||||
|
private static TexturedModelData getTexturedModelData() {
|
||||||
|
ModelData modelData = new ModelData();
|
||||||
|
ModelPartData root = modelData.getRoot();
|
||||||
|
|
||||||
|
root.addChild("base", ModelPartBuilder.create()
|
||||||
|
.uv(30, 14).mirrored().cuboid(-9, -1, 7, 2, 1, 2, Dilation.NONE), ModelTransform.pivot(8, 0, -8));
|
||||||
|
|
||||||
|
ModelPartData pole = root.addChild("pole", ModelPartBuilder.create(), ModelTransform.NONE);
|
||||||
|
|
||||||
|
pole.addChild("ew_arrow", ModelPartBuilder.create()
|
||||||
|
.uv(0, -16).cuboid(0, -12, -8, 0, 5, 16, Dilation.NONE), ModelTransform.rotation(0, 0.7854F, 0));
|
||||||
|
pole.addChild("apple", ModelPartBuilder.create()
|
||||||
|
.uv(0, 2).cuboid(0, -27, -7, 0, 15, 15, Dilation.NONE)
|
||||||
|
.uv(0, -11).cuboid(0, -9, -8, 0, 5, 16, Dilation.NONE)
|
||||||
|
.uv(32, 0).cuboid(-0.5F, -14, -0.5F, 1, 14, 1, Dilation.NONE), ModelTransform.NONE);
|
||||||
|
|
||||||
|
|
||||||
|
return TexturedModelData.of(modelData, 64, 32);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void render(WeatherVane entity, float tickDelta, MatrixStack matrices, VertexConsumerProvider vertices, int light, int overlay) {
|
||||||
|
matrices.push();
|
||||||
|
matrices.scale(1, -1, -1);
|
||||||
|
matrices.translate(0.5F, 0, -0.5F);
|
||||||
|
|
||||||
|
pole.yaw = entity.getAngle(tickDelta);
|
||||||
|
root.render(matrices, vertices.getBuffer(RenderLayers.getEntityCutoutNoCull(TEXTURE, true)), light, overlay);
|
||||||
|
|
||||||
|
matrices.pop();
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,5 @@
|
||||||
|
{
|
||||||
|
"variants": {
|
||||||
|
"": { "model": "unicopia:block/weather_vane" }
|
||||||
|
}
|
||||||
|
}
|
|
@ -119,6 +119,7 @@
|
||||||
"block.unicopia.zap_apple": "Zap Apple",
|
"block.unicopia.zap_apple": "Zap Apple",
|
||||||
"block.unicopia.zap_bulb": "Unripened Zap Apple",
|
"block.unicopia.zap_bulb": "Unripened Zap Apple",
|
||||||
"block.unicopia.apple_pie": "Apple Pie",
|
"block.unicopia.apple_pie": "Apple Pie",
|
||||||
|
"block.unicopia.weather_vane": "Weather Vane",
|
||||||
|
|
||||||
"block.unicopia.green_apple_leaves": "Granny Smith Leaves",
|
"block.unicopia.green_apple_leaves": "Granny Smith Leaves",
|
||||||
"block.unicopia.green_apple_sapling": "Granny Smith Sapling",
|
"block.unicopia.green_apple_sapling": "Granny Smith Sapling",
|
||||||
|
|
|
@ -0,0 +1,6 @@
|
||||||
|
{
|
||||||
|
"parent": "minecraft:block/cube_all",
|
||||||
|
"textures": {
|
||||||
|
"particle": "unicopia:item/weather_vane"
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,6 @@
|
||||||
|
{
|
||||||
|
"parent": "item/generated",
|
||||||
|
"textures": {
|
||||||
|
"layer0": "unicopia:item/weather_vane"
|
||||||
|
}
|
||||||
|
}
|
Binary file not shown.
After Width: | Height: | Size: 314 B |
Binary file not shown.
After Width: | Height: | Size: 1.4 KiB |
|
@ -0,0 +1,30 @@
|
||||||
|
{
|
||||||
|
"parent": "minecraft:recipes/root",
|
||||||
|
"rewards": {
|
||||||
|
"recipes": [
|
||||||
|
"unicopia:weather_vane"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"criteria": {
|
||||||
|
"has_iron": {
|
||||||
|
"trigger": "minecraft:inventory_changed",
|
||||||
|
"conditions": {
|
||||||
|
"items": [
|
||||||
|
{ "items": [ "minecraft:iron_nugget", "minecraft:iron_ingot" ] }
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"has_the_recipe": {
|
||||||
|
"trigger": "minecraft:recipe_unlocked",
|
||||||
|
"conditions": {
|
||||||
|
"recipe": "unicopia:weather_vane"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"requirements": [
|
||||||
|
[
|
||||||
|
"has_iron",
|
||||||
|
"has_the_recipe"
|
||||||
|
]
|
||||||
|
]
|
||||||
|
}
|
16
src/main/resources/data/unicopia/recipes/weather_vane.json
Normal file
16
src/main/resources/data/unicopia/recipes/weather_vane.json
Normal file
|
@ -0,0 +1,16 @@
|
||||||
|
{
|
||||||
|
"type": "minecraft:crafting_shaped",
|
||||||
|
"pattern": [
|
||||||
|
" **",
|
||||||
|
"** ",
|
||||||
|
" * "
|
||||||
|
],
|
||||||
|
"key": {
|
||||||
|
"*": {
|
||||||
|
"item": "minecraft:iron_nugget"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"result": {
|
||||||
|
"item": "unicopia:weather_vane"
|
||||||
|
}
|
||||||
|
}
|
1
weather_vane.bbmodel
Normal file
1
weather_vane.bbmodel
Normal file
|
@ -0,0 +1 @@
|
||||||
|
{"meta":{"format_version":"4.0","model_format":"modded_entity","box_uv":true},"name":"weather_vane","model_identifier":"weather_vane","modded_entity_version":"Fabric 1.17+","modded_entity_flip_y":true,"visible_box":[1,1,0],"variable_placeholders":"","variable_placeholder_buttons":[],"resolution":{"width":64,"height":32},"elements":[{"name":"apple","rescale":false,"locked":false,"from":[0,12,-7],"to":[0,27,8],"autouv":0,"color":7,"rotation":[0,8.110414437731967e-14,0],"origin":[0,0,0],"uv_offset":[0,2],"faces":{"north":{"uv":[15,17,15,32],"texture":0},"east":{"uv":[0,17,15,32],"texture":0},"south":{"uv":[30,17,30,32],"texture":0},"west":{"uv":[15,17,30,32],"texture":0},"up":{"uv":[15,17,15,2],"texture":0},"down":{"uv":[15,2,15,17],"texture":0}},"type":"cube","uuid":"cf1d6a48-071c-9144-ba90-50a7556f60e6"},{"name":"ns_arrow","rescale":false,"locked":false,"from":[0,4,-8],"to":[0,9,8],"autouv":0,"color":5,"rotation":[0,8.110414437731967e-14,0],"origin":[0,0,0],"uv_offset":[0,-11],"faces":{"north":{"uv":[16,5,16,10],"texture":0},"east":{"uv":[0,5,16,10],"texture":0},"south":{"uv":[32,5,32,10],"texture":0},"west":{"uv":[16,5,32,10],"texture":0},"up":{"uv":[16,5,16,-11],"texture":0},"down":{"uv":[16,-11,16,5],"texture":0}},"type":"cube","uuid":"9d8bbb1a-615f-7e29-0c45-d0ab4e454c68"},{"name":"pole","rescale":false,"locked":false,"from":[-0.5,0,-0.5],"to":[0.5,14,0.5],"autouv":0,"color":3,"rotation":[0,8.110414437731967e-14,0],"origin":[0,0,0],"uv_offset":[32,0],"faces":{"north":{"uv":[33,1,34,15],"texture":0},"east":{"uv":[32,1,33,15],"texture":0},"south":{"uv":[35,1,36,15],"texture":0},"west":{"uv":[34,1,35,15],"texture":0},"up":{"uv":[34,1,33,0],"texture":0},"down":{"uv":[35,0,34,1],"texture":0}},"type":"cube","uuid":"609b452e-a0c3-4214-c7ea-c46aee0927c2"},{"name":"base","rescale":false,"locked":false,"from":[-1,0,-1],"to":[1,1,1],"autouv":0,"color":5,"shade":false,"rotation":[0,8.110414437731967e-14,0],"origin":[-8,0,-8],"uv_offset":[30,14],"faces":{"north":{"uv":[34,16,32,17],"texture":0},"east":{"uv":[36,16,34,17],"texture":0},"south":{"uv":[38,16,36,17],"texture":0},"west":{"uv":[32,16,30,17],"texture":0},"up":{"uv":[32,16,34,14],"texture":0},"down":{"uv":[34,14,36,16],"texture":0}},"type":"cube","uuid":"8a648ab7-7658-12e0-233e-a97a4787e8b8"},{"name":"ew_arrow","rescale":false,"locked":false,"from":[0,7,-8],"to":[0,12,8],"autouv":0,"color":6,"rotation":[0,-44.99999999999998,0],"origin":[0,0,0],"uv_offset":[0,-16],"faces":{"north":{"uv":[16,0,16,5],"texture":0},"east":{"uv":[0,0,16,5],"texture":0},"south":{"uv":[32,0,32,5],"texture":0},"west":{"uv":[16,0,32,5],"texture":0},"up":{"uv":[16,0,16,-16],"texture":0},"down":{"uv":[16,-16,16,0],"texture":0}},"type":"cube","uuid":"ed31b929-d052-7393-a621-100c6adcbbfc"}],"outliner":[{"name":"root","origin":[0,0,0],"color":0,"uuid":"959db0ac-606f-c388-103d-475b7ea65a55","export":true,"isOpen":true,"locked":false,"visibility":true,"autouv":0,"children":["8a648ab7-7658-12e0-233e-a97a4787e8b8",{"name":"pole","origin":[0,0,0],"color":0,"uuid":"122cf60f-4817-d325-a071-47e7a5de8643","export":true,"isOpen":true,"locked":false,"visibility":true,"autouv":0,"children":["609b452e-a0c3-4214-c7ea-c46aee0927c2","9d8bbb1a-615f-7e29-0c45-d0ab4e454c68","ed31b929-d052-7393-a621-100c6adcbbfc","cf1d6a48-071c-9144-ba90-50a7556f60e6"]}]}],"textures":[{"path":"C:\\Users\\Chris Albers\\Documents\\GitRepos\\minecraft_mods\\Unicopia\\src\\main\\resources\\assets\\unicopia\\textures\\block\\weather_vane_arrows.png","name":"weather_vane_arrows.png","folder":"block","namespace":"unicopia","id":"arrows","particle":false,"render_mode":"default","visible":true,"mode":"bitmap","saved":true,"uuid":"62f348a9-1fd6-3c07-309c-0196f613de31","relative_path":"../../Documents/GitRepos/minecraft_mods/Unicopia/src/main/resources/assets/unicopia/textures/block/weather_vane_arrows.png","source":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEAAAAAgCAYAAACinX6EAAAAAXNSR0IArs4c6QAAAUpJREFUaENjZCAD8FjO/v/leCojGVqxaflPwBxq2YPVGkaQZ0AypHiIHD14PDmwAQB1GCFHYHU/j+VskgIORyCg203TGEd3w2BMAfQNAHLyMY3LgMEfADEcHP+X/PhBLYcObBYAeQaUCkjxEDl6SCgEqRWwRCVumGVkFYIxHBwkBdygLATJiU1y9Az2FEBUcoEpGlZlAEk+p43igS0EaeMnkkwdDQC04BqQWoCkKKOy4tEUMJoCUENgxGQBQo0vugQEXSyhcplBVeNGA4CqwTkEDSM6BWycEA/Os/4FC4nWMxTCA6dnQB6GeXa4eh4UQUQHwHCLeVjqxJuch3PM4w2Ay6ys8Dr6XncUg1LpMrB63d+/h1X+x5oFkD2PrRAbboGAEaOjAYCU/EdkCgB5GlcqGG7JH2c1OOIDAFsqGI6xj7chNBSasdRwIwBGcoAhA5g2PwAAAABJRU5ErkJggg=="}],"fabricOptions":{"header":"package com.example.mod;","entity":"Entity","render":"","members":""}}
|
Loading…
Reference in a new issue