diff --git a/build.gradle b/build.gradle index 2b1990d3..071cab8b 100644 --- a/build.gradle +++ b/build.gradle @@ -188,6 +188,8 @@ dependencies { minecraft "net.minecraftforge:forge:${minecraft_version}-${forge_version}" implementation fg.deobf('com.corosus.coroutil:coroutil:1.20.1-1.3.0') + implementation fg.deobf('com.corosus.enderio:EnderIO:1.20.1-6.0.21-alpha') + implementation fg.deobf('com.corosus.pipez:pipez:1.20.1-1.1.5') annotationProcessor 'org.spongepowered:mixin:0.8.5-SNAPSHOT:processor' //implementation fg.deobf('com.lovetropics.ltweather:ltweather:1.20.1-1.0') //implementation fg.deobf('com.lovetropics.minigames:LTMinigames:0.1.0-alpha+custom') diff --git a/libs/EnderIO-1.20.1-6.0.21-alpha.jar b/libs/EnderIO-1.20.1-6.0.21-alpha.jar new file mode 100644 index 00000000..907d1672 Binary files /dev/null and b/libs/EnderIO-1.20.1-6.0.21-alpha.jar differ diff --git a/libs/LTMinigames-0.1.0-alpha+custom.jar b/libs/LTMinigames-0.1.0-alpha+custom.jar deleted file mode 100644 index 6fe4aaf1..00000000 Binary files a/libs/LTMinigames-0.1.0-alpha+custom.jar and /dev/null differ diff --git a/libs/ltweather-1.20.1-1.0.jar b/libs/ltweather-1.20.1-1.0.jar deleted file mode 100644 index 10fcd0a2..00000000 Binary files a/libs/ltweather-1.20.1-1.0.jar and /dev/null differ diff --git a/libs/pipez-1.20.1-1.1.5.jar b/libs/pipez-1.20.1-1.1.5.jar new file mode 100644 index 00000000..4ad298a2 Binary files /dev/null and b/libs/pipez-1.20.1-1.1.5.jar differ diff --git a/src/generated/resources/assets/minecraft/atlases/blocks.json b/src/generated/resources/assets/minecraft/atlases/blocks.json index 67d00de5..9866a24a 100644 --- a/src/generated/resources/assets/minecraft/atlases/blocks.json +++ b/src/generated/resources/assets/minecraft/atlases/blocks.json @@ -36,6 +36,10 @@ "type": "minecraft:single", "resource": "weather2:blocks/wind_vane" }, + { + "type": "minecraft:single", + "resource": "weather2:blocks/wind_turbine" + }, { "type": "minecraft:single", "resource": "weather2:items/weather_item" diff --git a/src/main/java/weather2/BlockAndItemProvider.java b/src/main/java/weather2/BlockAndItemProvider.java index 9e5c514b..5bf6db6b 100644 --- a/src/main/java/weather2/BlockAndItemProvider.java +++ b/src/main/java/weather2/BlockAndItemProvider.java @@ -27,6 +27,7 @@ protected void addSources() addSpriteBlock("weather_machine"); addSpriteBlock("anemometer"); addSpriteBlock("wind_vane"); + addSpriteBlock("wind_turbine"); addSpriteItem("weather_item"); addSpriteItem("sand_layer"); addSpriteItem("sand_layer_placeable"); diff --git a/src/main/java/weather2/ClientRegistry.java b/src/main/java/weather2/ClientRegistry.java index 98983d02..33afafb0 100644 --- a/src/main/java/weather2/ClientRegistry.java +++ b/src/main/java/weather2/ClientRegistry.java @@ -7,9 +7,11 @@ import net.minecraftforge.eventbus.api.SubscribeEvent; import net.minecraftforge.fml.common.Mod; import net.minecraftforge.fml.event.lifecycle.FMLClientSetupEvent; -import weather2.client.AnemometerEntityRenderer; -import weather2.client.WindVaneEntityRenderer; +import weather2.client.tile.AnemometerEntityRenderer; +import weather2.client.tile.WindTurbineEntityRenderer; +import weather2.client.tile.WindVaneEntityRenderer; import weather2.client.entity.model.AnemometerModel; +import weather2.client.entity.model.WindTurbineModel; import weather2.client.entity.model.WindVaneModel; import weather2.client.entity.render.LightningBoltWeatherNewRenderer; @@ -27,6 +29,7 @@ public static void clientSetup(FMLClientSetupEvent event) { public static void registerRenderers(EntityRenderersEvent.RegisterRenderers e) { e.registerBlockEntityRenderer(WeatherBlocks.BLOCK_ENTITY_ANEMOMETER.get(), AnemometerEntityRenderer::new); e.registerBlockEntityRenderer(WeatherBlocks.BLOCK_ENTITY_WIND_VANE.get(), WindVaneEntityRenderer::new); + e.registerBlockEntityRenderer(WeatherBlocks.BLOCK_ENTITY_WIND_TURBINE.get(), WindTurbineEntityRenderer::new); } @OnlyIn(Dist.CLIENT) @@ -34,6 +37,7 @@ public static void registerRenderers(EntityRenderersEvent.RegisterRenderers e) { public static void registerLayerDefinitions(EntityRenderersEvent.RegisterLayerDefinitions event) { event.registerLayerDefinition(WindVaneModel.LAYER_LOCATION, WindVaneModel::createBodyLayer); event.registerLayerDefinition(AnemometerModel.LAYER_LOCATION, AnemometerModel::createBodyLayer); + event.registerLayerDefinition(WindTurbineModel.LAYER_LOCATION, WindTurbineModel::createBodyLayer); } } diff --git a/src/main/java/weather2/EventHandlerForge.java b/src/main/java/weather2/EventHandlerForge.java index e2dfde94..24aa0523 100644 --- a/src/main/java/weather2/EventHandlerForge.java +++ b/src/main/java/weather2/EventHandlerForge.java @@ -17,6 +17,7 @@ import net.minecraftforge.event.TickEvent; import net.minecraftforge.event.entity.living.LivingEvent; import net.minecraftforge.event.entity.player.PlayerEvent; +import net.minecraftforge.eventbus.api.EventPriority; import net.minecraftforge.eventbus.api.SubscribeEvent; import net.minecraftforge.fml.common.Mod; import weather2.client.SceneEnhancer; @@ -39,14 +40,14 @@ public void worldRender(RenderLevelStageEvent event) } } - @SubscribeEvent + @SubscribeEvent(priority = EventPriority.LOWEST) @OnlyIn(Dist.CLIENT) public void onFogColors(ViewportEvent.ComputeFogColor event) { SceneEnhancer.getFogAdjuster().onFogColors(event); } - @SubscribeEvent + @SubscribeEvent(priority = EventPriority.LOWEST) @OnlyIn(Dist.CLIENT) public void onFogRender(ViewportEvent.RenderFog event) { SceneEnhancer.getFogAdjuster().onFogRender(event); diff --git a/src/main/java/weather2/Weather.java b/src/main/java/weather2/Weather.java index 4cba05c1..6cf136cc 100644 --- a/src/main/java/weather2/Weather.java +++ b/src/main/java/weather2/Weather.java @@ -78,6 +78,7 @@ public class Weather output.accept(WeatherItems.BLOCK_SAND_LAYER_ITEM.get()); output.accept(WeatherItems.BLOCK_ANEMOMETER_ITEM.get()); output.accept(WeatherItems.BLOCK_WIND_VANE_ITEM.get()); + output.accept(WeatherItems.BLOCK_WIND_TURBINE_ITEM.get()); }).build()); public Weather() { diff --git a/src/main/java/weather2/WeatherBlocks.java b/src/main/java/weather2/WeatherBlocks.java index 198ced5a..cecb202c 100644 --- a/src/main/java/weather2/WeatherBlocks.java +++ b/src/main/java/weather2/WeatherBlocks.java @@ -35,6 +35,7 @@ public class WeatherBlocks { public static final String SAND_LAYER_PLACEABLE = "sand_layer_placeable"; public static final String WEATHER_ITEM = "weather_item"; public static final String POCKET_SAND = "pocket_sand"; + public static final String WIND_TURBINE = "wind_turbine"; private static final DeferredRegister BLOCKS = DeferredRegister.create(ForgeRegistries.BLOCKS, Weather.MODID); private static final DeferredRegister> BLOCK_ENTITIES = DeferredRegister.create(ForgeRegistries.BLOCK_ENTITY_TYPES, Weather.MODID); @@ -46,6 +47,7 @@ public class WeatherBlocks { public static final RegistryObject BLOCK_ANEMOMETER = BLOCKS.register(ANEMOMETER, () -> new AnemometerBlock(BlockBehaviour.Properties.of().mapColor(MapColor.STONE).randomTicks().strength(1.5F, 6F).requiresCorrectToolForDrops().sound(SoundType.STONE))); public static final RegistryObject BLOCK_WIND_VANE = BLOCKS.register(WIND_VANE, () -> new WindVaneBlock(BlockBehaviour.Properties.of().mapColor(MapColor.STONE).randomTicks().strength(1.5F, 6F).requiresCorrectToolForDrops().sound(SoundType.STONE))); public static final RegistryObject BLOCK_TORNADO_SIREN = BLOCKS.register(TORNADO_SIREN, () -> new SirenBlock(BlockBehaviour.Properties.of().mapColor(MapColor.STONE).randomTicks().strength(1.5F, 6F).requiresCorrectToolForDrops().sound(SoundType.STONE))); + public static final RegistryObject BLOCK_WIND_TURBINE = BLOCKS.register(WIND_TURBINE, () -> new WindTurbineBlock(BlockBehaviour.Properties.of().mapColor(MapColor.STONE).randomTicks().strength(1.5F, 6F).requiresCorrectToolForDrops().sound(SoundType.STONE))); //public static final RegistryObject BLOCK_WEATHER_MACHINE = BLOCKS.register(WEATHER_MACHINE, () -> new WeatherMachineBlock(BlockBehaviour.Properties.of(Material.STONE).randomTicks().strength(1.5F, 6F).requiresCorrectToolForDrops().sound(SoundType.STONE))); @SuppressWarnings("ConstantConditions") @@ -65,6 +67,9 @@ public class WeatherBlocks { public static final RegistryObject> BLOCK_ENTITY_WIND_VANE = BLOCK_ENTITIES.register(WIND_VANE, () -> BlockEntityType.Builder.of(WindVaneBlockEntity::new, BLOCK_WIND_VANE.get()).build(null)); + public static final RegistryObject> BLOCK_ENTITY_WIND_TURBINE = BLOCK_ENTITIES.register(WIND_TURBINE, () -> + BlockEntityType.Builder.of(WindTurbineBlockEntity::new, BLOCK_WIND_TURBINE.get()).build(null)); + /*public static final RegistryObject> BLOCK_ENTITY_WEATHER_MACHINE = BLOCK_ENTITIES.register(WEATHER_MACHINE, () -> BlockEntityType.Builder.of(WeatherMachineBlockEntity::new, BLOCK_WEATHER_MACHINE.get()).build(null));*/ diff --git a/src/main/java/weather2/WeatherItems.java b/src/main/java/weather2/WeatherItems.java index 4a385624..73f2fa06 100644 --- a/src/main/java/weather2/WeatherItems.java +++ b/src/main/java/weather2/WeatherItems.java @@ -20,6 +20,7 @@ public class WeatherItems { public static final RegistryObject BLOCK_FORECAST_ITEM = ITEMS.register(WeatherBlocks.WEATHER_FORECAST, () -> new BlockItem(WeatherBlocks.BLOCK_FORECAST.get(), new Item.Properties())); public static final RegistryObject BLOCK_ANEMOMETER_ITEM = ITEMS.register(WeatherBlocks.ANEMOMETER, () -> new BlockItem(WeatherBlocks.BLOCK_ANEMOMETER.get(), new Item.Properties())); public static final RegistryObject BLOCK_WIND_VANE_ITEM = ITEMS.register(WeatherBlocks.WIND_VANE, () -> new BlockItem(WeatherBlocks.BLOCK_WIND_VANE.get(), new Item.Properties())); + public static final RegistryObject BLOCK_WIND_TURBINE_ITEM = ITEMS.register(WeatherBlocks.WIND_TURBINE, () -> new BlockItem(WeatherBlocks.BLOCK_WIND_TURBINE.get(), new Item.Properties())); public static void registerHandlers(IEventBus modBus) { ITEMS.register(modBus); diff --git a/src/main/java/weather2/block/WindTurbineBlock.java b/src/main/java/weather2/block/WindTurbineBlock.java new file mode 100644 index 00000000..4d8e5d94 --- /dev/null +++ b/src/main/java/weather2/block/WindTurbineBlock.java @@ -0,0 +1,78 @@ +package weather2.block; + +import net.minecraft.core.BlockPos; +import net.minecraft.network.chat.Component; +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.item.TooltipFlag; +import net.minecraft.world.level.BlockGetter; +import net.minecraft.world.level.Level; +import net.minecraft.world.level.block.BaseEntityBlock; +import net.minecraft.world.level.block.Block; +import net.minecraft.world.level.block.RenderShape; +import net.minecraft.world.level.block.entity.BlockEntity; +import net.minecraft.world.level.block.entity.BlockEntityTicker; +import net.minecraft.world.level.block.entity.BlockEntityType; +import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.world.level.block.state.StateDefinition; +import net.minecraft.world.phys.shapes.CollisionContext; +import net.minecraft.world.phys.shapes.VoxelShape; +import net.minecraftforge.api.distmarker.Dist; +import net.minecraftforge.api.distmarker.OnlyIn; +import org.jetbrains.annotations.Nullable; +import weather2.WeatherBlocks; +import weather2.blockentity.WindTurbineBlockEntity; +import weather2.blockentity.WindVaneBlockEntity; + +import java.util.List; + +public class WindTurbineBlock extends BaseEntityBlock { + + public static final VoxelShape SHAPE = box(2.0, 0.0, 2.0, 14.0, 32.0, 14.0); + + public static final void register() {} + + public WindTurbineBlock(Properties properties) { + super(properties); + } + + @Override + protected void createBlockStateDefinition(StateDefinition.Builder pBuilder) { + + } + + @Override + public VoxelShape getShape(BlockState state, BlockGetter world, BlockPos pos, CollisionContext context) { + return SHAPE; + } + + @Override + public RenderShape getRenderShape(BlockState p_49232_) { + return RenderShape.INVISIBLE; + } + + @Override + @OnlyIn(Dist.CLIENT) + public void appendHoverText(ItemStack stack, BlockGetter worldIn, List tooltip, TooltipFlag flagIn) { + super.appendHoverText(stack, worldIn, tooltip, flagIn); + //tooltip.add(Component.translatable(this.getDescriptionId() + ".desc").withStyle(ChatFormatting.GRAY)); + } + + @Nullable + @Override + public BlockEntity newBlockEntity(BlockPos p_153215_, BlockState p_153216_) { + return new WindTurbineBlockEntity(p_153215_, p_153216_); + } + + @Nullable + @Override + public BlockEntityTicker getTicker(Level p_153212_, BlockState p_153213_, BlockEntityType p_153214_) { + return createTickerHelper(p_153214_, WeatherBlocks.BLOCK_ENTITY_WIND_TURBINE.get(), WindTurbineBlockEntity::tick); + } + + @Nullable + @SuppressWarnings("unchecked") + private static BlockEntityTicker createTicker(final BlockEntityType type, final BlockEntityType tickerType, final BlockEntityTicker ticker) { + return tickerType == type ? (BlockEntityTicker) ticker : null; + } + +} diff --git a/src/main/java/weather2/blockentity/WindTurbineBlockEntity.java b/src/main/java/weather2/blockentity/WindTurbineBlockEntity.java new file mode 100644 index 00000000..0e56dcf3 --- /dev/null +++ b/src/main/java/weather2/blockentity/WindTurbineBlockEntity.java @@ -0,0 +1,137 @@ +package weather2.blockentity; + +import net.minecraft.core.BlockPos; +import net.minecraft.core.Direction; +import net.minecraft.nbt.CompoundTag; +import net.minecraft.util.Mth; +import net.minecraft.world.level.Level; +import net.minecraft.world.level.block.entity.BlockEntity; +import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.world.phys.Vec3; +import net.minecraftforge.common.capabilities.Capability; +import net.minecraftforge.common.capabilities.ForgeCapabilities; +import net.minecraftforge.common.util.LazyOptional; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; +import weather2.Weather; +import weather2.WeatherBlocks; +import weather2.WeatherItems; +import weather2.energy.EnergyManager; +import weather2.util.WeatherUtilEntity; +import weather2.util.WindReader; + +public class WindTurbineBlockEntity extends BlockEntity { + + public float smoothAngle = 0; + public float smoothAnglePrev = 0; + + public float smoothAngleRotationalVel = 0; + + public boolean isOutsideCached = false; + + //private final EnergyManager energyManager; + private LazyOptional energy; + private EnergyManager energyManager; + + //amount generated at windspeed of 1, theoretical max windspeed is 2 when tornado right on top of it + private int maxNormalGenerated = 10; + private int capacity = maxNormalGenerated * 2; + private int maxTransfer = capacity; + + private float lastWindSpeed = 0; + + public WindTurbineBlockEntity(BlockPos p_155229_, BlockState p_155230_) { + super(WeatherBlocks.BLOCK_ENTITY_WIND_TURBINE.get(), p_155229_, p_155230_); + + this.energyManager = new EnergyManager(maxTransfer, capacity); + this.energy = LazyOptional.of(() -> this.energyManager); + } + + @Override + public void setLevel(final Level level) { + super.setLevel(level); + } + + public static void tick(Level level, BlockPos pos, BlockState state, WindTurbineBlockEntity entity) { + entity.tick(level, pos, state); + } + + public void tick(Level level, BlockPos pos, BlockState state) { + if (!level.isClientSide) { + if (level.getGameTime() % 100 == 0) { + lastWindSpeed = WindReader.getWindSpeed(level, getBlockPos()); + } + this.energyManager.addEnergy((int) (maxNormalGenerated * lastWindSpeed)); + outputEnergy(); + } else { + if (level.getGameTime() % 40 == 0) { + isOutsideCached = WeatherUtilEntity.isPosOutside(level, new Vec3(getBlockPos().getX()+0.5F, getBlockPos().getY()+0.5F, getBlockPos().getZ()+0.5F)); + } + + if (isOutsideCached) { + float windSpeed = WindReader.getWindSpeed(level); + float rotMax = 100F; + float maxSpeed = (windSpeed / 2F) * rotMax; + if (smoothAngleRotationalVel < maxSpeed) { + smoothAngleRotationalVel += windSpeed * 0.3F; + } + if (smoothAngleRotationalVel > rotMax) smoothAngleRotationalVel = rotMax; + if (smoothAngle >= 180) smoothAngle -= 360; + } + + smoothAnglePrev = smoothAngle; + smoothAngle += smoothAngleRotationalVel; + smoothAngleRotationalVel -= 0.01F; + + smoothAngleRotationalVel *= 0.99F; + + if (smoothAngleRotationalVel <= 0) smoothAngleRotationalVel = 0; + } + } + + public void outputEnergy() { + //System.out.println(this.energyManager.getEnergyStored()); + if (this.energyManager.getEnergyStored() >= this.energyManager.getMaxExtract() && this.energyManager.canExtract()) { + for (final var direction : Direction.values()) { + final BlockEntity be = this.level.getBlockEntity(this.worldPosition.relative(direction)); + if (be == null) { + continue; + } + + be.getCapability(ForgeCapabilities.ENERGY, direction.getOpposite()).ifPresent(storage -> { + if (be != this && storage.getEnergyStored() < storage.getMaxEnergyStored()) { + this.energyManager.drainEnergy(this.energyManager.getMaxExtract()); + //Weather.LOGGER.info("Send: {}", this.energyManager.getMaxExtract()); + final int received = storage.receiveEnergy(this.energyManager.getMaxExtract(), false); + //Weather.LOGGER.info("Final Received: {}", received); + } + }); + } + } + } + + @Override + public void load(final CompoundTag tag) { + super.load(tag); + } + + @Override + protected void saveAdditional(final CompoundTag tag) { + super.saveAdditional(tag); + } + + @Override + public @NotNull LazyOptional getCapability(@NotNull Capability cap, @Nullable Direction side) { + LazyOptional energyCapability = energyManager.getCapability(cap); + if (energyCapability.isPresent()) { + return energyCapability; + } + return super.getCapability(cap, side); + } + + @Override + public void invalidateCaps() { + super.invalidateCaps(); + this.energy.invalidate(); + } +} diff --git a/src/main/java/weather2/client/entity/model/WindTurbineModel.java b/src/main/java/weather2/client/entity/model/WindTurbineModel.java new file mode 100644 index 00000000..885dca79 --- /dev/null +++ b/src/main/java/weather2/client/entity/model/WindTurbineModel.java @@ -0,0 +1,67 @@ +package weather2.client.entity.model;// Made with Blockbench 4.8.3 +// Exported for Minecraft version 1.17 or later with Mojang mappings +// Paste this class into your mod and generate all required imports + + +import com.mojang.blaze3d.vertex.PoseStack; +import com.mojang.blaze3d.vertex.VertexConsumer; +import net.minecraft.client.model.HierarchicalModel; +import net.minecraft.client.model.geom.ModelLayerLocation; +import net.minecraft.client.model.geom.ModelPart; +import net.minecraft.client.model.geom.PartPose; +import net.minecraft.client.model.geom.builders.*; +import net.minecraft.resources.ResourceLocation; +import net.minecraft.world.entity.Entity; +import weather2.Weather; + +public class WindTurbineModel extends HierarchicalModel { + // This layer location should be baked with EntityRendererProvider.Context in the entity renderer and passed into this model's constructor + public static final ModelLayerLocation LAYER_LOCATION = new ModelLayerLocation(new ResourceLocation(Weather.MODID, "wind_turbine"), "main"); + private final ModelPart root; + + public WindTurbineModel(ModelPart root) { + this.root = root; + } + + @Override + public ModelPart root() { + return this.root; + } + + public static LayerDefinition createBodyLayer() { + MeshDefinition meshdefinition = new MeshDefinition(); + PartDefinition partdefinition = meshdefinition.getRoot(); + + PartDefinition root = partdefinition.addOrReplaceChild("root", CubeListBuilder.create().texOffs(0, 0).addBox(-6.0F, -2.0F, -6.0F, 12.0F, 2.0F, 12.0F, new CubeDeformation(0.0F)) + .texOffs(36, 2).addBox(-3.0F, -4.0F, -3.0F, 6.0F, 2.0F, 6.0F, new CubeDeformation(0.0F)), PartPose.offset(0.0F, 24.0F, 0.0F)); + + PartDefinition shaft = root.addOrReplaceChild("shaft", CubeListBuilder.create().texOffs(0, 35).addBox(-1.0F, -31.0F, -1.0F, 2.0F, 29.0F, 2.0F, new CubeDeformation(0.0F)) + .texOffs(0, 20).addBox(-2.0F, -30.0F, -2.0F, 4.0F, 2.0F, 4.0F, new CubeDeformation(0.0F)) + .texOffs(0, 33).addBox(-9.0F, -29.5F, -0.5F, 18.0F, 1.0F, 1.0F, new CubeDeformation(0.0F)) + .texOffs(0, 14).addBox(-0.5F, -29.5F, -9.0F, 1.0F, 1.0F, 18.0F, new CubeDeformation(0.0F)) + .texOffs(2, 16).addBox(-0.5F, -13.5F, -8.0F, 1.0F, 1.0F, 16.0F, new CubeDeformation(0.0F)) + .texOffs(36, 0).addBox(-8.0F, -13.5F, -0.5F, 16.0F, 1.0F, 1.0F, new CubeDeformation(0.0F)) + .texOffs(2, 16).addBox(-0.5F, -13.5F, -8.0F, 1.0F, 1.0F, 16.0F, new CubeDeformation(0.0F)) + .texOffs(0, 14).addBox(-2.0F, -14.0F, -2.0F, 4.0F, 2.0F, 4.0F, new CubeDeformation(0.0F)), PartPose.offset(0.0F, 0.0F, 0.0F)); + + PartDefinition fin_r1 = shaft.addOrReplaceChild("fin_r1", CubeListBuilder.create().texOffs(8, 35).addBox(-2.0F, -21.0F, -1.0F, 4.0F, 22.0F, 2.0F, new CubeDeformation(0.0F)), PartPose.offsetAndRotation(0.0F, -13.0F, -8.0F, -0.4162F, 0.1863F, 0.3969F)); + + PartDefinition fin_r2 = shaft.addOrReplaceChild("fin_r2", CubeListBuilder.create().texOffs(8, 35).addBox(-2.0F, -21.0F, -1.0F, 4.0F, 22.0F, 2.0F, new CubeDeformation(0.0F)), PartPose.offsetAndRotation(0.0F, -13.0F, 8.0F, 0.4164F, 0.2075F, -0.436F)); + + PartDefinition fin_r3 = shaft.addOrReplaceChild("fin_r3", CubeListBuilder.create().texOffs(34, 31).addBox(-1.0F, -21.0F, -2.0F, 2.0F, 22.0F, 4.0F, new CubeDeformation(0.0F)), PartPose.offsetAndRotation(-8.0F, -13.0F, 0.0F, 0.4363F, 0.0F, 0.4712F)); + + PartDefinition fin_r4 = shaft.addOrReplaceChild("fin_r4", CubeListBuilder.create().texOffs(34, 31).addBox(-1.0F, -21.0F, -2.0F, 2.0F, 22.0F, 4.0F, new CubeDeformation(0.0F)), PartPose.offsetAndRotation(8.0F, -13.0F, 0.0F, -0.4363F, 0.0F, -0.4712F)); + + return LayerDefinition.create(meshdefinition, 128, 128); + } + + @Override + public void setupAnim(T entity, float limbSwing, float limbSwingAmount, float ageInTicks, float netHeadYaw, float headPitch) { + + } + + @Override + public void renderToBuffer(PoseStack poseStack, VertexConsumer vertexConsumer, int packedLight, int packedOverlay, float red, float green, float blue, float alpha) { + root.render(poseStack, vertexConsumer, packedLight, packedOverlay, red, green, blue, alpha); + } +} \ No newline at end of file diff --git a/src/main/java/weather2/client/AnemometerEntityRenderer.java b/src/main/java/weather2/client/tile/AnemometerEntityRenderer.java similarity index 97% rename from src/main/java/weather2/client/AnemometerEntityRenderer.java rename to src/main/java/weather2/client/tile/AnemometerEntityRenderer.java index 08ac8341..bf8943b6 100644 --- a/src/main/java/weather2/client/AnemometerEntityRenderer.java +++ b/src/main/java/weather2/client/tile/AnemometerEntityRenderer.java @@ -1,4 +1,4 @@ -package weather2.client; +package weather2.client.tile; import com.google.common.collect.Maps; import com.mojang.blaze3d.vertex.PoseStack; @@ -72,7 +72,6 @@ public void render(T te, float partialTicks, PoseStack stack, MultiBufferSource //fixes for block ModelPart root = this.model.root(); - float scale = 0.2F; root.x += 8; root.y += 8; root.z += 8; @@ -98,7 +97,6 @@ public void render(T te, float partialTicks, PoseStack stack, MultiBufferSource top.zRot = (float) ((rand.nextFloat() - rand.nextFloat()) * Math.toRadians(7)); } } - root.offsetScale(new Vector3f(scale, scale, scale)); renderModel(getTEMaterial("anemometer"), model, stack, buffer, combinedLightIn, combinedOverlayIn); } diff --git a/src/main/java/weather2/client/tile/WindTurbineEntityRenderer.java b/src/main/java/weather2/client/tile/WindTurbineEntityRenderer.java new file mode 100644 index 00000000..accac08e --- /dev/null +++ b/src/main/java/weather2/client/tile/WindTurbineEntityRenderer.java @@ -0,0 +1,94 @@ +package weather2.client.tile; + +import com.google.common.collect.Maps; +import com.mojang.blaze3d.vertex.PoseStack; +import net.minecraft.client.Minecraft; +import net.minecraft.client.model.Model; +import net.minecraft.client.model.geom.ModelPart; +import net.minecraft.client.renderer.MultiBufferSource; +import net.minecraft.client.renderer.blockentity.BlockEntityRenderer; +import net.minecraft.client.renderer.blockentity.BlockEntityRendererProvider; +import net.minecraft.client.renderer.texture.TextureAtlas; +import net.minecraft.client.resources.model.Material; +import net.minecraft.resources.ResourceLocation; +import net.minecraft.util.Mth; +import net.minecraft.world.level.block.Block; +import net.minecraft.world.level.block.entity.BlockEntity; +import org.joml.Vector3f; +import weather2.ClientTickHandler; +import weather2.Weather; +import weather2.WeatherBlocks; +import weather2.blockentity.WindTurbineBlockEntity; +import weather2.blockentity.WindVaneBlockEntity; +import weather2.client.entity.model.WindTurbineModel; +import weather2.client.entity.model.WindVaneModel; +import weather2.weathersystem.WeatherManagerClient; +import weather2.weathersystem.wind.WindManager; + +import java.util.Map; +import java.util.Random; + +public class WindTurbineEntityRenderer implements BlockEntityRenderer { + + private static Map resLocMap = Maps.newHashMap(); + private static Map materialMap = Maps.newHashMap(); + + public static Material getTEMaterial(final String path) { + return materialMap.computeIfAbsent(path, m -> createTEMaterial(path)); + } + + private static Material createTEMaterial(final String path) { + return new Material(TextureAtlas.LOCATION_BLOCKS, getTextureTE(path)); + } + + public static ResourceLocation getTextureTE(String path) { + return getTexture(String.format("textures/blocks/te/%s.png", path)); + } + + public static ResourceLocation getTexture(String path) { + return resLocMap.computeIfAbsent(path, k -> getResLoc(path)); + } + + private static ResourceLocation getResLoc(String path) { + return new ResourceLocation(Weather.MODID, path); + } + + public static void renderModel(final Material material, final Model model, PoseStack stack, MultiBufferSource buffer, int combinedLightIn, int combinedOverlayIn) { + model.renderToBuffer(stack, buffer.getBuffer(model.renderType(material.texture())), combinedLightIn, combinedOverlayIn, 1, 1, 1, 1); + } + + private final Block block; + protected final WindTurbineModel model; + + public WindTurbineEntityRenderer(final BlockEntityRendererProvider.Context context) { + super(); + this.block = WeatherBlocks.BLOCK_WIND_TURBINE.get(); + this.model = new WindTurbineModel<>(Minecraft.getInstance().getEntityModels().bakeLayer(WindTurbineModel.LAYER_LOCATION)); + } + + @Override + public void render(T te, float partialTicks, PoseStack stack, MultiBufferSource buffer, int combinedLightIn, int combinedOverlayIn) { + this.model.root().getAllParts().forEach(ModelPart::resetPose); + + //fixes for block + ModelPart root = this.model.root(); + root.x += 8; + root.y += 8; + root.z += 8; + root.xRot += Math.toRadians(180); + root.yRot += Math.toRadians(180); + //te.getLevel().getBrightness(LightLayer.BLOCK, te.getBlockPos().above()) + + root.y += 16; + + ModelPart top = this.model.root().getChild("root").getChild("shaft"); + if (top != null) { + float lerpAngle = (float) Mth.lerp((double)partialTicks, ((WindTurbineBlockEntity) te).smoothAnglePrev, ((WindTurbineBlockEntity) te).smoothAngle); + float renderAngle = lerpAngle; + + top.yRot = (float) Math.toRadians(renderAngle); + } + + renderModel(getTEMaterial("wind_turbine"), model, stack, buffer, combinedLightIn, combinedOverlayIn); + } +} diff --git a/src/main/java/weather2/client/WindVaneEntityRenderer.java b/src/main/java/weather2/client/tile/WindVaneEntityRenderer.java similarity index 95% rename from src/main/java/weather2/client/WindVaneEntityRenderer.java rename to src/main/java/weather2/client/tile/WindVaneEntityRenderer.java index d79dd72d..9acb16cc 100644 --- a/src/main/java/weather2/client/WindVaneEntityRenderer.java +++ b/src/main/java/weather2/client/tile/WindVaneEntityRenderer.java @@ -1,4 +1,4 @@ -package weather2.client; +package weather2.client.tile; import com.google.common.collect.Maps; import com.mojang.blaze3d.vertex.PoseStack; @@ -71,15 +71,13 @@ public void render(T te, float partialTicks, PoseStack stack, MultiBufferSource //fixes for block ModelPart root = this.model.root(); - float scale = 1.0F; root.x += 8; root.y += 8; root.z += 8; root.xRot += Math.toRadians(180); root.yRot += Math.toRadians(180); - //te.getLevel().getBrightness(LightLayer.BLOCK, te.getBlockPos().above()) - root.y += 40; + root.y += 16; ModelPart top = this.model.root().getChild("root").getChild("base").getChild("middle").getChild("top"); if (top != null) { @@ -100,7 +98,6 @@ public void render(T te, float partialTicks, PoseStack stack, MultiBufferSource top.zRot = (float) ((rand.nextFloat() - rand.nextFloat()) * Math.toRadians(1)); } } - root.offsetScale(new Vector3f(scale, scale, scale)); renderModel(getTEMaterial("wind_vane"), model, stack, buffer, combinedLightIn, combinedOverlayIn); } diff --git a/src/main/java/weather2/config/ConfigTornado.java b/src/main/java/weather2/config/ConfigTornado.java index 4f6321df..448d50a0 100644 --- a/src/main/java/weather2/config/ConfigTornado.java +++ b/src/main/java/weather2/config/ConfigTornado.java @@ -59,6 +59,8 @@ public class ConfigTornado implements IConfigCategory { @ConfigComment("Extra bit of grab angle for the tornado, tweak for different grab shapes, higher = tigher grab, lower = wider grab, might toss them away") public static int Storm_Tornado_extraGrabAngle = 20; + public static boolean Storm_Tornado_fallDamage = true; + //@ConfigComment("Experimental idea, places the WIP repairing block where a tornado does damage instead of removing the block, causes tornado damage to self repair, recommend setting Storm_Tornado_rarityOfBreakOnFall to 0 to avoid duplicated blocks") //public static boolean Storm_Tornado_grabbedBlocksRepairOverTime = false; diff --git a/src/main/java/weather2/energy/EnergyManager.java b/src/main/java/weather2/energy/EnergyManager.java new file mode 100644 index 00000000..5a835770 --- /dev/null +++ b/src/main/java/weather2/energy/EnergyManager.java @@ -0,0 +1,72 @@ +package weather2.energy; + +import net.minecraft.nbt.CompoundTag; +import net.minecraftforge.common.capabilities.Capability; +import net.minecraftforge.common.capabilities.ForgeCapabilities; +import net.minecraftforge.common.util.LazyOptional; +import net.minecraftforge.energy.EnergyStorage; +import net.minecraftforge.energy.IEnergyStorage; + +public class EnergyManager extends EnergyStorage { + private boolean canExtract = true; + + public EnergyManager(int maxTransfer, int capacity) { + super(capacity, maxTransfer, maxTransfer); + } + + public int getMaxExtract() { + return maxExtract; + } + + public void setReceiveOnly() { + canExtract = false; + }/* + + @Override + public void read(CompoundTag nbt) { + setEnergyStored(nbt.getInt("Energy")); + } + + @Override + public CompoundTag write(CompoundTag nbt) { + nbt.putInt("Energy", energy); + return nbt; + }*/ + + public int getMaxEnergyReceived() { + return this.maxReceive; + } + + /** + * Drains an amount of energy, due to decay from lack of work or other factors + */ + public void drainEnergy(int amount) { + setEnergyStored(energy - amount); + } + + public void addEnergy(int amount) { + setEnergyStored(energy + amount); + } + + public int getEnergy() { + return energy; + } + + public void setEnergyStored(int energyStored) { + this.energy = energyStored; + if (this.energy > capacity) { + this.energy = capacity; + } else if (this.energy < 0) { + this.energy = 0; + } + } + + public LazyOptional getCapability(Capability capability) { + if (capability == ForgeCapabilities.ENERGY) { + //IEnergyStorage energyStorage = new EnergyStorageWrapper(this, canExtract); + return LazyOptional.of(() -> this).cast(); + } + + return LazyOptional.empty(); + } +} diff --git a/src/main/java/weather2/util/WindReader.java b/src/main/java/weather2/util/WindReader.java index 88ebfafa..9652363e 100644 --- a/src/main/java/weather2/util/WindReader.java +++ b/src/main/java/weather2/util/WindReader.java @@ -1,5 +1,6 @@ package weather2.util; +import net.minecraft.core.BlockPos; import net.minecraft.world.level.Level; import net.minecraft.world.phys.Vec3; import net.minecraftforge.api.distmarker.Dist; @@ -17,12 +18,17 @@ public static float getWindAngle(Level world, Vec3 pos) { WeatherManager weather = getWeatherManagerFor(world); return weather != null ? weather.getWindManager().getWindAngle(pos) : 0; } - + public static float getWindSpeed(Level world) { WeatherManager weather = getWeatherManagerFor(world); return weather != null ? weather.getWindManager().getWindSpeed() : 0; } + public static float getWindSpeed(Level world, BlockPos pos) { + WeatherManager weather = getWeatherManagerFor(world); + return weather != null ? weather.getWindManager().getWindSpeed(pos) : 0; + } + private static WeatherManager getWeatherManagerFor(Level world) { if (world.isClientSide) { return getWeatherManagerClient(); diff --git a/src/main/java/weather2/weathersystem/storm/StormObject.java b/src/main/java/weather2/weathersystem/storm/StormObject.java index 6a5e3ec6..28680c51 100644 --- a/src/main/java/weather2/weathersystem/storm/StormObject.java +++ b/src/main/java/weather2/weathersystem/storm/StormObject.java @@ -2452,7 +2452,10 @@ public void spinEntityv2(Entity entity) { entity.setDeltaMovement(spinObject(entity.position(), entity.getDeltaMovement(), entity instanceof Player, dampenXZ, dampenY, false, grabAdj)); - entity.fallDistance = 0; + if (!ConfigTornado.Storm_Tornado_fallDamage || CoroUtilEntOrParticle.getMotionY(entity) > -0.8) + { + entity.fallDistance = 0F; + } if (isFirenado) { Vec3 posEnt = entity.position(); diff --git a/src/main/java/weather2/weathersystem/wind/WindInfoCache.java b/src/main/java/weather2/weathersystem/wind/WindInfoCache.java new file mode 100644 index 00000000..7d1afb00 --- /dev/null +++ b/src/main/java/weather2/weathersystem/wind/WindInfoCache.java @@ -0,0 +1,8 @@ +package weather2.weathersystem.wind; + +public class WindInfoCache { + + public long cacheTime; + public float windSpeed; + +} diff --git a/src/main/java/weather2/weathersystem/wind/WindManager.java b/src/main/java/weather2/weathersystem/wind/WindManager.java index cf30794b..90104178 100644 --- a/src/main/java/weather2/weathersystem/wind/WindManager.java +++ b/src/main/java/weather2/weathersystem/wind/WindManager.java @@ -2,17 +2,16 @@ import com.corosus.coroutil.util.CoroUtilBlock; import com.corosus.coroutil.util.CoroUtilEntOrParticle; +import com.corosus.coroutil.util.CoroUtilMisc; import net.minecraft.client.Minecraft; import net.minecraft.core.BlockPos; import net.minecraft.nbt.CompoundTag; import net.minecraft.world.entity.player.Player; -import net.minecraft.world.level.levelgen.LegacyRandomSource; import net.minecraft.world.level.levelgen.synth.PerlinNoise; import net.minecraft.world.phys.Vec3; import net.minecraft.server.level.ServerLevel; import net.minecraftforge.api.distmarker.Dist; import net.minecraftforge.api.distmarker.OnlyIn; -import weather2.ClientTickHandler; import weather2.PerlinNoiseHelper; import weather2.ServerWeatherProxy; import weather2.Weather; @@ -23,6 +22,7 @@ import weather2.weathersystem.WeatherManagerServer; import weather2.weathersystem.storm.StormObject; +import java.util.HashMap; import java.util.Random; public class WindManager { @@ -43,7 +43,9 @@ public class WindManager { public float windAngleEvent = 0; public BlockPos windOriginEvent = BlockPos.ZERO; public float windSpeedEvent = 0; - public int windTimeEvent = 0; //its assumed this will get set by whatever initializes an event, and this class counts it down from a couple seconds, helps wind system know what takes priority + //client side only + //its assumed this will get set by whatever initializes an event, and this class counts it down from a couple seconds, helps wind system know what takes priority + public int windTimeEvent = 0; //gusts public float windAngleGust = 0; @@ -61,6 +63,9 @@ public class WindManager { public int highWindTimer = 0; public static boolean FORCE_ON_DEBUG_TESTING = false; + + public HashMap lookupChunkToWindInfo = new HashMap<>(); + public int cachedWindInfoUpdateFrequency = 100; public WindManager(WeatherManager parManager) { manager = parManager; @@ -74,8 +79,12 @@ public float getWindSpeed() { return getWindSpeed(null); } - public float getWindSpeed(Vec3 pos) { - if (windTimeEvent > 0 && (windTimeEvent > windTimeGust && windTimeEvent > windSpeedGlobal)) { + public float getWindSpeed(BlockPos pos) { + if (pos != null) { + float speed = getWindSpeedEventForChunkPos(pos); + return Math.max(speed, Math.max(windSpeedGlobal, windSpeedGust)); + } + if (windTimeEvent > 0 && (windSpeedEvent > windSpeedGust && windSpeedEvent > windSpeedGlobal)) { return windSpeedEvent; } else if (windTimeGust > 0) { return windSpeedGust; @@ -171,16 +180,9 @@ public void setWindTimeEvent(int parVal) { public void tick() { - Random rand = new Random(); + Random rand = CoroUtilMisc.random(); - //debug - //Weather.dbg("wind angle: " + windAngleGlobal); - //windAngleGlobal = 90; - //indSpeedGlobal = 0.71F; - //windAngleGlobal = 180; - //lowWindOddsTo1 = 20*200; - //lowWindTimer = 0; - //windSpeedGlobalChangeRate = 0.05F; + //windSpeedGust = 0; if (!ConfigWind.Misc_windOn) { windSpeedGlobal = 0; @@ -260,6 +262,7 @@ public void tick() { windTimeGust--; if (windTimeGust == 0) { + windSpeedGust = 0; syncData(); } } @@ -357,12 +360,15 @@ public void tickClient() { if (windTimeEvent > 0) { windTimeEvent--; + if (windTimeEvent == 0) { + windTimeGust = 0; + } } //event data if (entP != null) { if (manager.getWorld().getGameTime() % 10 == 0) { - float maxDist = 256; + float maxDist = 512; StormObject so = manager.getClosestStorm(new Vec3(entP.getX(), StormObject.layers.get(0), entP.getZ()), maxDist, StormObject.STATE_HIGHWIND); if (so != null) { @@ -382,7 +388,7 @@ public void tickClient() { double dist = entP.position().distanceTo(so.posGround); - windSpeedEvent = (float) (1F - (dist / maxDist)) * 2F; //make dynamic? + windSpeedEvent = (float) (1F - (dist / maxDist)) * 2F; //System.out.println(windSpeedEvent); //Weather.dbg("!!!!!!!!!!!!!!!!!!!storm event near, wind speed: " + windSpeedEvent); @@ -391,74 +397,35 @@ public void tickClient() { } } - /*public void tick(Level world) { - Random rand = new Random(); - - FORCE_ON_DEBUG_TESTING = true; - - // TODO: better merge this logic - if (world.isClientSide) { - windSpeedGlobal = ClientWeather.get().getWindSpeed(); - if (windSpeedGlobal == 0) { - chanceOfWindGustEvent = 0; - } else { - chanceOfWindGustEvent = 0.5F; - } - } else { - WeatherController weatherController = WeatherControllerManager.forWorld((ServerLevel) world); - windSpeedGlobal = weatherController.getWindSpeed(); - if (windSpeedGlobal == 0) { - chanceOfWindGustEvent = 0; - } else { - chanceOfWindGustEvent = 0.5F; - } - } - - if (windTimeGust > 0) { - windTimeGust--; - } - - float randGustWindFactor = 1F; + public float getWindSpeedEventForChunkPos(BlockPos blockPos) { + BlockPos chunkPos = new BlockPos(blockPos.getX() >> 4, 0, blockPos.getZ() >> 4); - //gust data - if (this.windTimeGust == 0) - { - if (chanceOfWindGustEvent > 0F) - { - if (rand.nextInt((int)((100 - chanceOfWindGustEvent) * randGustWindFactor)) == 0) - { - windSpeedGust = windSpeedGlobal + rand.nextFloat() * 0.6F; - windAngleGust = windAngleGlobal + rand.nextInt(120) - 60; - - setWindTimeGust(rand.nextInt(windGustEventTimeRand)); - } + long hash = chunkPos.asLong(); + if (lookupChunkToWindInfo.containsKey(hash)) { + WindInfoCache cache = lookupChunkToWindInfo.get(hash); + if (cache.cacheTime + cachedWindInfoUpdateFrequency > manager.getWorld().getGameTime()) { + return cache.windSpeed; } } + WindInfoCache cache = lookupChunkToWindInfo.get(hash); + if (cache == null) cache = new WindInfoCache(); + cache.cacheTime = manager.getWorld().getGameTime(); + cache.windSpeed = getWindSpeedEventForPosImpl(blockPos); + lookupChunkToWindInfo.put(hash, cache); + //System.out.println("wind: " + cache.windSpeed); + return cache.windSpeed; + } - windAngleGlobal += rand.nextFloat() - rand.nextFloat(); - - if (FORCE_ON_DEBUG_TESTING) { - //windAngleGlobal += 1; - windAngleGlobal = 0; - windSpeedGlobal = 0.8F; - chanceOfWindGustEvent = 0; - chanceOfWindGustEvent = 0.5F; - } - - //MORE TEST - if (!world.isClientSide) { - //windAngleGlobal += 0.25F; - //chanceOfWindGustEvent = 0; - } - - if (windAngleGlobal < -180) { - windAngleGlobal += 360; - } - - if (windAngleGlobal > 180) { - windAngleGlobal -= 360; + public float getWindSpeedEventForPosImpl(BlockPos pos) { + float maxDist = 512; + Vec3 posVec = new Vec3(pos.getX(), pos.getY(), pos.getZ()); + StormObject so = manager.getClosestStorm(posVec, maxDist, StormObject.STATE_HIGHWIND); + if (so != null) { + double dist = posVec.distanceTo(so.posGround); + return (float) (1F - (dist / maxDist)) * 2F; } - }*/ + return 0; + } /** * @@ -600,7 +567,6 @@ public void read(CompoundTag data) { lowWindTimer = data.getInt("lowWindTimer"); highWindTimer = data.getInt("highWindTimer"); - } public CompoundTag write(CompoundTag data) { @@ -618,9 +584,6 @@ public CompoundTag write(CompoundTag data) { data.putInt("lowWindTimer", lowWindTimer); data.putInt("highWindTimer", highWindTimer); - - - return data; } diff --git a/src/main/resources/assets/weather2/textures/blocks/anemometer_custom.png b/src/main/resources/assets/weather2/textures/blocks/anemometer_custom.png deleted file mode 100644 index dc52d7b9..00000000 Binary files a/src/main/resources/assets/weather2/textures/blocks/anemometer_custom.png and /dev/null differ diff --git a/src/main/resources/assets/weather2/textures/blocks/anemometerbak.png b/src/main/resources/assets/weather2/textures/blocks/anemometerbak.png deleted file mode 100644 index e7b187f8..00000000 Binary files a/src/main/resources/assets/weather2/textures/blocks/anemometerbak.png and /dev/null differ diff --git a/src/main/resources/assets/weather2/textures/blocks/te/wind_turbine.png b/src/main/resources/assets/weather2/textures/blocks/te/wind_turbine.png new file mode 100644 index 00000000..7e2fd809 Binary files /dev/null and b/src/main/resources/assets/weather2/textures/blocks/te/wind_turbine.png differ diff --git a/src/main/resources/assets/weather2/textures/blocks/te/wind_vane_bak.png b/src/main/resources/assets/weather2/textures/blocks/te/wind_vane_bak.png deleted file mode 100644 index f304f7d8..00000000 Binary files a/src/main/resources/assets/weather2/textures/blocks/te/wind_vane_bak.png and /dev/null differ diff --git a/src/main/resources/assets/weather2/textures/blocks/wind_vane2.png b/src/main/resources/assets/weather2/textures/blocks/wind_vane2.png deleted file mode 100644 index e2170bbb..00000000 Binary files a/src/main/resources/assets/weather2/textures/blocks/wind_vane2.png and /dev/null differ diff --git a/src/main/resources/assets/weather2/textures/blocks/windvane_custom.png b/src/main/resources/assets/weather2/textures/blocks/windvane_custom.png deleted file mode 100644 index cacffc1e..00000000 Binary files a/src/main/resources/assets/weather2/textures/blocks/windvane_custom.png and /dev/null differ