Port to 1.16.5
Kottle -> KotlinForForge
This commit is contained in:
@@ -1,26 +1,28 @@
|
|||||||
plugins {
|
plugins {
|
||||||
kotlin("jvm").version("1.3.61")
|
kotlin("jvm").version("1.4.20")
|
||||||
id("net.minecraftforge.gradle").version("3.0.194")
|
id("net.minecraftforge.gradle").version("4.1.12")
|
||||||
id("org.spongepowered.mixin").version("0.7-SNAPSHOT")
|
id("org.spongepowered.mixin").version("0.7-SNAPSHOT")
|
||||||
}
|
}
|
||||||
apply(plugin = "org.spongepowered.mixin")
|
//apply(plugin = "org.spongepowered.mixin")
|
||||||
|
|
||||||
repositories {
|
repositories {
|
||||||
maven("http://files.minecraftforge.net/maven")
|
maven("https://files.minecraftforge.net/maven")
|
||||||
maven("https://repo.spongepowered.org/maven")
|
maven("https://repo.spongepowered.org/maven")
|
||||||
maven("https://minecraft.curseforge.com/api/maven")
|
maven("https://minecraft.curseforge.com/api/maven")
|
||||||
maven("https://maven.shedaniel.me/")
|
maven("https://maven.shedaniel.me/")
|
||||||
maven("https://www.cursemaven.com")
|
maven("https://www.cursemaven.com")
|
||||||
|
maven("https://thedarkcolour.github.io/KotlinForForge/")
|
||||||
}
|
}
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
"minecraft"("net.minecraftforge:forge:${properties["mcVersion"]}-${properties["forgeVersion"]}")
|
"minecraft"("net.minecraftforge:forge:${properties["mcVersion"]}-${properties["forgeVersion"]}")
|
||||||
|
|
||||||
"api"(fg.deobf("curse.maven:clothconfig-348521:2938583"))
|
// "api"(fg.deobf("curse.maven:clothconfig-348521:2938583"))
|
||||||
|
|
||||||
"implementation"(fg.deobf("curse.maven:biomesoplenty-220318:2988999"))
|
// "implementation"(fg.deobf("curse.maven:biomesoplenty-220318:2988999"))
|
||||||
"implementation"("kottle:Kottle:${properties["kottleVersion"]}")
|
"implementation"("thedarkcolour:kotlinforforge:1.7.0")
|
||||||
// "implementation"("org.spongepowered:mixin:0.8-SNAPSHOT")
|
|
||||||
|
"implementation"("org.spongepowered:mixin:0.8-SNAPSHOT")
|
||||||
}
|
}
|
||||||
|
|
||||||
configurations["annotationProcessor"].extendsFrom(configurations["implementation"])
|
configurations["annotationProcessor"].extendsFrom(configurations["implementation"])
|
||||||
|
|||||||
@@ -6,9 +6,9 @@ jarName = BetterFoliage-Forge
|
|||||||
|
|
||||||
version = 2.6.1
|
version = 2.6.1
|
||||||
|
|
||||||
mcVersion = 1.15.2
|
mcVersion = 1.16.5
|
||||||
forgeVersion = 31.2.44
|
forgeVersion = 36.1.17
|
||||||
mappingsChannel = snapshot
|
mappingsChannel = official
|
||||||
mappingsVersion = 20200514-1.15.1
|
mappingsVersion = 1.16.5
|
||||||
|
|
||||||
kottleVersion = 1.4.0
|
#kottleVersion = 1.4.0
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
pluginManagement {
|
pluginManagement {
|
||||||
repositories {
|
repositories {
|
||||||
maven("http://files.minecraftforge.net/maven")
|
maven("https://files.minecraftforge.net/maven")
|
||||||
maven("https://repo.spongepowered.org/maven")
|
maven("https://repo.spongepowered.org/maven")
|
||||||
gradlePluginPortal()
|
gradlePluginPortal()
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -21,7 +21,7 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
|
|||||||
*/
|
*/
|
||||||
@Mixin(Block.class)
|
@Mixin(Block.class)
|
||||||
public class MixinBlock {
|
public class MixinBlock {
|
||||||
private static final String shouldSideBeRendered = "Lnet/minecraft/block/Block;shouldSideBeRendered(Lnet/minecraft/block/BlockState;Lnet/minecraft/world/IBlockReader;Lnet/minecraft/util/math/BlockPos;Lnet/minecraft/util/Direction;)Z";
|
private static final String shouldSideBeRendered = "Lnet/minecraft/block/Block;shouldRenderFace(Lnet/minecraft/block/BlockState;Lnet/minecraft/world/IBlockReader;Lnet/minecraft/util/math/BlockPos;Lnet/minecraft/util/Direction;)Z";
|
||||||
private static final String getVoxelShape = "Lnet/minecraft/block/BlockState;func_215702_a(Lnet/minecraft/world/IBlockReader;Lnet/minecraft/util/math/BlockPos;Lnet/minecraft/util/Direction;)Lnet/minecraft/util/math/shapes/VoxelShape;";
|
private static final String getVoxelShape = "Lnet/minecraft/block/BlockState;func_215702_a(Lnet/minecraft/world/IBlockReader;Lnet/minecraft/util/math/BlockPos;Lnet/minecraft/util/Direction;)Lnet/minecraft/util/math/shapes/VoxelShape;";
|
||||||
private static final String getFaceOcclusionShape = "Lnet/minecraft/block/BlockState;getFaceOcclusionShape(Lnet/minecraft/world/IBlockReader;Lnet/minecraft/util/math/BlockPos;Lnet/minecraft/util/Direction;)Lnet/minecraft/util/math/shapes/VoxelShape;";
|
private static final String getFaceOcclusionShape = "Lnet/minecraft/block/BlockState;getFaceOcclusionShape(Lnet/minecraft/world/IBlockReader;Lnet/minecraft/util/math/BlockPos;Lnet/minecraft/util/Direction;)Lnet/minecraft/util/math/shapes/VoxelShape;";
|
||||||
private static final String isOpaqueCube = "Lnet/minecraft/block/Block;isOpaqueCube(Lnet/minecraft/block/BlockState;Lnet/minecraft/world/IBlockReader;Lnet/minecraft/util/math/BlockPos;)Z";
|
private static final String isOpaqueCube = "Lnet/minecraft/block/Block;isOpaqueCube(Lnet/minecraft/block/BlockState;Lnet/minecraft/world/IBlockReader;Lnet/minecraft/util/math/BlockPos;)Z";
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ import net.minecraft.block.BlockState;
|
|||||||
import net.minecraft.client.renderer.BlockModelRenderer;
|
import net.minecraft.client.renderer.BlockModelRenderer;
|
||||||
import net.minecraft.client.renderer.model.IBakedModel;
|
import net.minecraft.client.renderer.model.IBakedModel;
|
||||||
import net.minecraft.util.math.BlockPos;
|
import net.minecraft.util.math.BlockPos;
|
||||||
import net.minecraft.world.ILightReader;
|
import net.minecraft.world.IBlockDisplayReader;
|
||||||
import net.minecraftforge.client.model.data.IModelData;
|
import net.minecraftforge.client.model.data.IModelData;
|
||||||
import org.spongepowered.asm.mixin.Mixin;
|
import org.spongepowered.asm.mixin.Mixin;
|
||||||
import org.spongepowered.asm.mixin.injection.At;
|
import org.spongepowered.asm.mixin.injection.At;
|
||||||
@@ -19,12 +19,12 @@ import java.util.Random;
|
|||||||
@Mixin(BlockModelRenderer.class)
|
@Mixin(BlockModelRenderer.class)
|
||||||
public class MixinBlockModelRenderer {
|
public class MixinBlockModelRenderer {
|
||||||
|
|
||||||
private static final String renderModel = "Lnet/minecraft/client/renderer/BlockModelRenderer;renderModel(Lnet/minecraft/world/ILightReader;Lnet/minecraft/client/renderer/model/IBakedModel;Lnet/minecraft/block/BlockState;Lnet/minecraft/util/math/BlockPos;Lcom/mojang/blaze3d/matrix/MatrixStack;Lcom/mojang/blaze3d/vertex/IVertexBuilder;ZLjava/util/Random;JILnet/minecraftforge/client/model/data/IModelData;)Z";
|
private static final String renderModel = "Lnet/minecraft/client/renderer/BlockModelRenderer;renderModel(Lnet/minecraft/world/IBlockDisplayReader;Lnet/minecraft/client/renderer/model/IBakedModel;Lnet/minecraft/block/BlockState;Lnet/minecraft/util/math/BlockPos;Lcom/mojang/blaze3d/matrix/MatrixStack;Lcom/mojang/blaze3d/vertex/IVertexBuilder;ZLjava/util/Random;JILnet/minecraftforge/client/model/data/IModelData;)Z";
|
||||||
private static final String renderModelFlat = "Lnet/minecraft/client/renderer/BlockModelRenderer;renderModelFlat(Lnet/minecraft/world/ILightReader;Lnet/minecraft/client/renderer/model/IBakedModel;Lnet/minecraft/block/BlockState;Lnet/minecraft/util/math/BlockPos;Lcom/mojang/blaze3d/matrix/MatrixStack;Lcom/mojang/blaze3d/vertex/IVertexBuilder;ZLjava/util/Random;JILnet/minecraftforge/client/model/data/IModelData;)Z";
|
private static final String renderModelFlat = "Lnet/minecraft/client/renderer/BlockModelRenderer;renderModelFlat(Lnet/minecraft/world/IBlockDisplayReader;Lnet/minecraft/client/renderer/model/IBakedModel;Lnet/minecraft/block/BlockState;Lnet/minecraft/util/math/BlockPos;Lcom/mojang/blaze3d/matrix/MatrixStack;Lcom/mojang/blaze3d/vertex/IVertexBuilder;ZLjava/util/Random;JILnet/minecraftforge/client/model/data/IModelData;)Z";
|
||||||
private static final String renderModelSmooth = "Lnet/minecraft/client/renderer/BlockModelRenderer;renderModelSmooth(Lnet/minecraft/world/ILightReader;Lnet/minecraft/client/renderer/model/IBakedModel;Lnet/minecraft/block/BlockState;Lnet/minecraft/util/math/BlockPos;Lcom/mojang/blaze3d/matrix/MatrixStack;Lcom/mojang/blaze3d/vertex/IVertexBuilder;ZLjava/util/Random;JILnet/minecraftforge/client/model/data/IModelData;)Z";
|
private static final String renderModelSmooth = "Lnet/minecraft/client/renderer/BlockModelRenderer;renderModelSmooth(Lnet/minecraft/world/IBlockDisplayReader;Lnet/minecraft/client/renderer/model/IBakedModel;Lnet/minecraft/block/BlockState;Lnet/minecraft/util/math/BlockPos;Lcom/mojang/blaze3d/matrix/MatrixStack;Lcom/mojang/blaze3d/vertex/IVertexBuilder;ZLjava/util/Random;JILnet/minecraftforge/client/model/data/IModelData;)Z";
|
||||||
|
|
||||||
@Redirect(method = renderModel, at = @At(value = "INVOKE", target = renderModelSmooth), remap = false)
|
@Redirect(method = renderModel, at = @At(value = "INVOKE", target = renderModelSmooth), remap = false)
|
||||||
public boolean onRenderModelSmooth(BlockModelRenderer renderer, ILightReader world, IBakedModel model, BlockState state, BlockPos pos, MatrixStack matrixStack, IVertexBuilder buffer, boolean checkSides, Random random, long rand, int combinedOverlay, IModelData modelData) {
|
public boolean onRenderModelSmooth(BlockModelRenderer renderer, IBlockDisplayReader world, IBakedModel model, BlockState state, BlockPos pos, MatrixStack matrixStack, IVertexBuilder buffer, boolean checkSides, Random random, long rand, int combinedOverlay, IModelData modelData) {
|
||||||
if (model instanceof SpecialRenderModel)
|
if (model instanceof SpecialRenderModel)
|
||||||
return RenderCtxVanilla.render(renderer, world, (SpecialRenderModel) model, state, pos, matrixStack, buffer, checkSides, random, rand, combinedOverlay, modelData, true);
|
return RenderCtxVanilla.render(renderer, world, (SpecialRenderModel) model, state, pos, matrixStack, buffer, checkSides, random, rand, combinedOverlay, modelData, true);
|
||||||
else
|
else
|
||||||
@@ -32,7 +32,7 @@ public class MixinBlockModelRenderer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Redirect(method = renderModel, at = @At(value = "INVOKE", target = renderModelFlat), remap = false)
|
@Redirect(method = renderModel, at = @At(value = "INVOKE", target = renderModelFlat), remap = false)
|
||||||
public boolean onRenderModelFlat(BlockModelRenderer renderer, ILightReader world, IBakedModel model, BlockState state, BlockPos pos, MatrixStack matrixStack, IVertexBuilder buffer, boolean checkSides, Random random, long rand, int combinedOverlay, IModelData modelData) {
|
public boolean onRenderModelFlat(BlockModelRenderer renderer, IBlockDisplayReader world, IBakedModel model, BlockState state, BlockPos pos, MatrixStack matrixStack, IVertexBuilder buffer, boolean checkSides, Random random, long rand, int combinedOverlay, IModelData modelData) {
|
||||||
if (model instanceof SpecialRenderModel)
|
if (model instanceof SpecialRenderModel)
|
||||||
return RenderCtxVanilla.render(renderer, world, (SpecialRenderModel) model, state, pos, matrixStack, buffer, checkSides, random, rand, combinedOverlay, modelData, false);
|
return RenderCtxVanilla.render(renderer, world, (SpecialRenderModel) model, state, pos, matrixStack, buffer, checkSides, random, rand, combinedOverlay, modelData, false);
|
||||||
else
|
else
|
||||||
|
|||||||
@@ -1,12 +1,15 @@
|
|||||||
package mods.betterfoliage.mixin;
|
package mods.betterfoliage.mixin;
|
||||||
|
|
||||||
import mods.betterfoliage.Hooks;
|
import mods.betterfoliage.Hooks;
|
||||||
|
import net.minecraft.block.AbstractBlock;
|
||||||
import net.minecraft.block.Block;
|
import net.minecraft.block.Block;
|
||||||
import net.minecraft.block.BlockState;
|
import net.minecraft.block.BlockState;
|
||||||
import net.minecraft.util.math.BlockPos;
|
import net.minecraft.util.math.BlockPos;
|
||||||
import net.minecraft.world.IBlockReader;
|
import net.minecraft.world.IBlockReader;
|
||||||
|
import org.spongepowered.asm.mixin.Debug;
|
||||||
import org.spongepowered.asm.mixin.Mixin;
|
import org.spongepowered.asm.mixin.Mixin;
|
||||||
import org.spongepowered.asm.mixin.injection.At;
|
import org.spongepowered.asm.mixin.injection.At;
|
||||||
|
import org.spongepowered.asm.mixin.injection.Coerce;
|
||||||
import org.spongepowered.asm.mixin.injection.Redirect;
|
import org.spongepowered.asm.mixin.injection.Redirect;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -14,14 +17,15 @@ import org.spongepowered.asm.mixin.injection.Redirect;
|
|||||||
*
|
*
|
||||||
* Needed to avoid excessive darkening of Round Logs at the corners, now that they are not full blocks.
|
* Needed to avoid excessive darkening of Round Logs at the corners, now that they are not full blocks.
|
||||||
*/
|
*/
|
||||||
@Mixin(BlockState.class)
|
@Mixin(AbstractBlock.AbstractBlockState.class)
|
||||||
@SuppressWarnings({"deprecation"})
|
@SuppressWarnings({"deprecation"})
|
||||||
public class MixinBlockState {
|
public class MixinBlockState {
|
||||||
private static final String callFrom = "Lnet/minecraft/block/BlockState;getAmbientOcclusionLightValue(Lnet/minecraft/world/IBlockReader;Lnet/minecraft/util/math/BlockPos;)F";
|
private static final String callFrom = "Lnet/minecraft/block/AbstractBlock$AbstractBlockState;getShadeBrightness(Lnet/minecraft/world/IBlockReader;Lnet/minecraft/util/math/BlockPos;)F";
|
||||||
private static final String callTo = "Lnet/minecraft/block/Block;getAmbientOcclusionLightValue(Lnet/minecraft/block/BlockState;Lnet/minecraft/world/IBlockReader;Lnet/minecraft/util/math/BlockPos;)F";
|
// why is the INVOKEVIRTUAL target class Block in the bytecode, not AbstractBlock?
|
||||||
|
private static final String callTo = "Lnet/minecraft/block/Block;getShadeBrightness(Lnet/minecraft/block/BlockState;Lnet/minecraft/world/IBlockReader;Lnet/minecraft/util/math/BlockPos;)F";
|
||||||
|
|
||||||
@Redirect(method = callFrom, at = @At(value = "INVOKE", target = callTo))
|
@Redirect(method = callFrom, at = @At(value = "INVOKE", target = callTo))
|
||||||
float getAmbientOcclusionValue(Block block, BlockState state, IBlockReader reader, BlockPos pos) {
|
float getAmbientOcclusionValue(Block block, BlockState state, IBlockReader reader, BlockPos pos) {
|
||||||
return Hooks.getAmbientOcclusionLightValueOverride(block.getAmbientOcclusionLightValue(state, reader, pos), state);
|
return Hooks.getAmbientOcclusionLightValueOverride(block.getShadeBrightness(state, reader, pos), state);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,18 +17,18 @@ import java.util.Random;
|
|||||||
@Mixin(ClientWorld.class)
|
@Mixin(ClientWorld.class)
|
||||||
public class MixinClientWorld {
|
public class MixinClientWorld {
|
||||||
|
|
||||||
private static final String worldAnimateTick = "Lnet/minecraft/client/world/ClientWorld;animateTick(IIIILjava/util/Random;ZLnet/minecraft/util/math/BlockPos$Mutable;)V";
|
private static final String worldAnimateTick = "Lnet/minecraft/client/world/ClientWorld;doAnimateTick(IIIILjava/util/Random;ZLnet/minecraft/util/math/BlockPos$Mutable;)V";
|
||||||
private static final String blockAnimateTick = "Lnet/minecraft/block/Block;animateTick(Lnet/minecraft/block/BlockState;Lnet/minecraft/world/World;Lnet/minecraft/util/math/BlockPos;Ljava/util/Random;)V";
|
private static final String blockAnimateTick = "Lnet/minecraft/block/Block;animateTick(Lnet/minecraft/block/BlockState;Lnet/minecraft/world/World;Lnet/minecraft/util/math/BlockPos;Ljava/util/Random;)V";
|
||||||
|
|
||||||
private static final String worldNotify = "Lnet/minecraft/client/world/ClientWorld;notifyBlockUpdate(Lnet/minecraft/util/math/BlockPos;Lnet/minecraft/block/BlockState;Lnet/minecraft/block/BlockState;I)V";
|
private static final String worldNotify = "Lnet/minecraft/client/world/ClientWorld;sendBlockUpdated(Lnet/minecraft/util/math/BlockPos;Lnet/minecraft/block/BlockState;Lnet/minecraft/block/BlockState;I)V";
|
||||||
private static final String rendererNotify = "Lnet/minecraft/client/renderer/WorldRenderer;notifyBlockUpdate(Lnet/minecraft/world/IBlockReader;Lnet/minecraft/util/math/BlockPos;Lnet/minecraft/block/BlockState;Lnet/minecraft/block/BlockState;I)V";
|
private static final String rendererNotify = "Lnet/minecraft/client/renderer/WorldRenderer;blockChanged(Lnet/minecraft/world/IBlockReader;Lnet/minecraft/util/math/BlockPos;Lnet/minecraft/block/BlockState;Lnet/minecraft/block/BlockState;I)V";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Inject a callback to call for every random display tick. Used for adding custom particle effects to blocks.
|
* Inject a callback to call for every random display tick. Used for adding custom particle effects to blocks.
|
||||||
*/
|
*/
|
||||||
@Redirect(method = worldAnimateTick, at = @At(value = "INVOKE", target = blockAnimateTick))
|
@Redirect(method = worldAnimateTick, at = @At(value = "INVOKE", target = blockAnimateTick))
|
||||||
void onAnimateTick(Block block, BlockState state, World world, BlockPos pos, Random random) {
|
void onAnimateTick(Block block, BlockState state, World world, BlockPos pos, Random random) {
|
||||||
Hooks.onRandomDisplayTick(block, state, world, pos, random);
|
Hooks.onRandomDisplayTick(block, state, (ClientWorld) world, pos, random);
|
||||||
block.animateTick(state, world, pos, random);
|
block.animateTick(state, world, pos, random);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -39,6 +39,6 @@ public class MixinClientWorld {
|
|||||||
@Redirect(method = worldNotify, at = @At(value = "INVOKE", target = rendererNotify))
|
@Redirect(method = worldNotify, at = @At(value = "INVOKE", target = rendererNotify))
|
||||||
void onClientBlockChanged(WorldRenderer renderer, IBlockReader world, BlockPos pos, BlockState oldState, BlockState newState, int flags) {
|
void onClientBlockChanged(WorldRenderer renderer, IBlockReader world, BlockPos pos, BlockState oldState, BlockState newState, int flags) {
|
||||||
Hooks.onClientBlockChanged((ClientWorld) world, pos, oldState, newState, flags);
|
Hooks.onClientBlockChanged((ClientWorld) world, pos, oldState, newState, flags);
|
||||||
renderer.notifyBlockUpdate(world, pos, oldState, newState, flags);
|
renderer.blockChanged(world, pos, oldState, newState, flags);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,12 +1,12 @@
|
|||||||
package mods.betterfoliage.mixin;
|
package mods.betterfoliage.mixin;
|
||||||
|
|
||||||
import com.mojang.blaze3d.matrix.MatrixStack;
|
import com.mojang.blaze3d.matrix.MatrixStack;
|
||||||
import mods.betterfoliage.render.pipeline.RenderCtxForge;
|
|
||||||
import mods.betterfoliage.model.SpecialRenderModel;
|
import mods.betterfoliage.model.SpecialRenderModel;
|
||||||
|
import mods.betterfoliage.render.pipeline.RenderCtxForge;
|
||||||
import net.minecraft.block.BlockState;
|
import net.minecraft.block.BlockState;
|
||||||
import net.minecraft.client.renderer.model.IBakedModel;
|
import net.minecraft.client.renderer.model.IBakedModel;
|
||||||
import net.minecraft.util.math.BlockPos;
|
import net.minecraft.util.math.BlockPos;
|
||||||
import net.minecraft.world.ILightReader;
|
import net.minecraft.world.IBlockDisplayReader;
|
||||||
import net.minecraftforge.client.model.data.IModelData;
|
import net.minecraftforge.client.model.data.IModelData;
|
||||||
import net.minecraftforge.client.model.pipeline.ForgeBlockModelRenderer;
|
import net.minecraftforge.client.model.pipeline.ForgeBlockModelRenderer;
|
||||||
import net.minecraftforge.client.model.pipeline.VertexLighterFlat;
|
import net.minecraftforge.client.model.pipeline.VertexLighterFlat;
|
||||||
@@ -19,14 +19,14 @@ import java.util.Random;
|
|||||||
@Mixin(ForgeBlockModelRenderer.class)
|
@Mixin(ForgeBlockModelRenderer.class)
|
||||||
public class MixinForgeBlockModelRenderer {
|
public class MixinForgeBlockModelRenderer {
|
||||||
|
|
||||||
private static final String renderModelFlat = "renderModelFlat(Lnet/minecraft/world/ILightReader;Lnet/minecraft/client/renderer/model/IBakedModel;Lnet/minecraft/block/BlockState;Lnet/minecraft/util/math/BlockPos;Lcom/mojang/blaze3d/matrix/MatrixStack;Lcom/mojang/blaze3d/vertex/IVertexBuilder;ZLjava/util/Random;JILnet/minecraftforge/client/model/data/IModelData;)Z";
|
private static final String renderModelFlat = "Lnet/minecraftforge/client/model/pipeline/ForgeBlockModelRenderer;renderModelFlat(Lnet/minecraft/world/IBlockDisplayReader;Lnet/minecraft/client/renderer/model/IBakedModel;Lnet/minecraft/block/BlockState;Lnet/minecraft/util/math/BlockPos;Lcom/mojang/blaze3d/matrix/MatrixStack;Lcom/mojang/blaze3d/vertex/IVertexBuilder;ZLjava/util/Random;JILnet/minecraftforge/client/model/data/IModelData;)Z";
|
||||||
private static final String renderModelSmooth = "renderModelSmooth(Lnet/minecraft/world/ILightReader;Lnet/minecraft/client/renderer/model/IBakedModel;Lnet/minecraft/block/BlockState;Lnet/minecraft/util/math/BlockPos;Lcom/mojang/blaze3d/matrix/MatrixStack;Lcom/mojang/blaze3d/vertex/IVertexBuilder;ZLjava/util/Random;JILnet/minecraftforge/client/model/data/IModelData;)Z";
|
private static final String renderModelSmooth = "Lnet/minecraftforge/client/model/pipeline/ForgeBlockModelRenderer;renderModelSmooth(Lnet/minecraft/world/IBlockDisplayReader;Lnet/minecraft/client/renderer/model/IBakedModel;Lnet/minecraft/block/BlockState;Lnet/minecraft/util/math/BlockPos;Lcom/mojang/blaze3d/matrix/MatrixStack;Lcom/mojang/blaze3d/vertex/IVertexBuilder;ZLjava/util/Random;JILnet/minecraftforge/client/model/data/IModelData;)Z";
|
||||||
private static final String render = "Lnet/minecraftforge/client/model/pipeline/ForgeBlockModelRenderer;render(Lnet/minecraftforge/client/model/pipeline/VertexLighterFlat;Lnet/minecraft/world/ILightReader;Lnet/minecraft/client/renderer/model/IBakedModel;Lnet/minecraft/block/BlockState;Lnet/minecraft/util/math/BlockPos;Lcom/mojang/blaze3d/matrix/MatrixStack;ZLjava/util/Random;JLnet/minecraftforge/client/model/data/IModelData;)Z";
|
private static final String render = "Lnet/minecraftforge/client/model/pipeline/ForgeBlockModelRenderer;render(Lnet/minecraftforge/client/model/pipeline/VertexLighterFlat;Lnet/minecraft/world/IBlockDisplayReader;Lnet/minecraft/client/renderer/model/IBakedModel;Lnet/minecraft/block/BlockState;Lnet/minecraft/util/math/BlockPos;Lcom/mojang/blaze3d/matrix/MatrixStack;ZLjava/util/Random;JLnet/minecraftforge/client/model/data/IModelData;)Z";
|
||||||
|
|
||||||
@Redirect(method = {renderModelFlat, renderModelSmooth}, at = @At(value = "INVOKE", target = render), remap = false)
|
@Redirect(method = {renderModelFlat, renderModelSmooth}, at = @At(value = "INVOKE", target = render), remap = false)
|
||||||
public boolean render(
|
public boolean render(
|
||||||
VertexLighterFlat lighter,
|
VertexLighterFlat lighter,
|
||||||
ILightReader world,
|
IBlockDisplayReader world,
|
||||||
IBakedModel model,
|
IBakedModel model,
|
||||||
BlockState state,
|
BlockState state,
|
||||||
BlockPos pos,
|
BlockPos pos,
|
||||||
|
|||||||
@@ -20,13 +20,13 @@ abstract public class MixinModelBakery {
|
|||||||
|
|
||||||
private static final String processLoading = "Lnet/minecraft/client/renderer/model/ModelBakery;processLoading(Lnet/minecraft/profiler/IProfiler;I)V";
|
private static final String processLoading = "Lnet/minecraft/client/renderer/model/ModelBakery;processLoading(Lnet/minecraft/profiler/IProfiler;I)V";
|
||||||
private static final String stitch = "Lnet/minecraft/client/renderer/texture/AtlasTexture;stitch(Lnet/minecraft/resources/IResourceManager;Ljava/util/stream/Stream;Lnet/minecraft/profiler/IProfiler;I)Lnet/minecraft/client/renderer/texture/AtlasTexture$SheetData;";
|
private static final String stitch = "Lnet/minecraft/client/renderer/texture/AtlasTexture;stitch(Lnet/minecraft/resources/IResourceManager;Ljava/util/stream/Stream;Lnet/minecraft/profiler/IProfiler;I)Lnet/minecraft/client/renderer/texture/AtlasTexture$SheetData;";
|
||||||
private static final String profilerSection = "Lnet/minecraft/profiler/IProfiler;endStartSection(Ljava/lang/String;)V";
|
private static final String profilerSection = "Lnet/minecraft/profiler/IProfiler;popPush(Ljava/lang/String;)V";
|
||||||
private static final String getBakedModel = "Lnet/minecraft/client/renderer/model/ModelBakery;getBakedModel(Lnet/minecraft/util/ResourceLocation;Lnet/minecraft/client/renderer/model/IModelTransform;Ljava/util/function/Function;)Lnet/minecraft/client/renderer/model/IBakedModel;";
|
private static final String getBakedModel = "Lnet/minecraft/client/renderer/model/ModelBakery;getBakedModel(Lnet/minecraft/util/ResourceLocation;Lnet/minecraft/client/renderer/model/IModelTransform;Ljava/util/function/Function;)Lnet/minecraft/client/renderer/model/IBakedModel;";
|
||||||
private static final String bakeModel = "Lnet/minecraft/client/renderer/model/IUnbakedModel;bakeModel(Lnet/minecraft/client/renderer/model/ModelBakery;Ljava/util/function/Function;Lnet/minecraft/client/renderer/model/IModelTransform;Lnet/minecraft/util/ResourceLocation;)Lnet/minecraft/client/renderer/model/IBakedModel;";
|
private static final String bakeModel = "Lnet/minecraft/client/renderer/model/IUnbakedModel;bake(Lnet/minecraft/client/renderer/model/ModelBakery;Ljava/util/function/Function;Lnet/minecraft/client/renderer/model/IModelTransform;Lnet/minecraft/util/ResourceLocation;)Lnet/minecraft/client/renderer/model/IBakedModel;";
|
||||||
|
|
||||||
@Inject(method = processLoading, at = @At(value = "INVOKE", target = profilerSection, ordinal = 4))
|
@Inject(method = processLoading, at = @At(value = "INVOKE", target = profilerSection, ordinal = 4))
|
||||||
void onBeforeTextures(IProfiler profiler, int maxMipmapLevel, CallbackInfo ci) {
|
void onBeforeTextures(IProfiler profiler, int maxMipmapLevel, CallbackInfo ci) {
|
||||||
profiler.endStartSection("betterfoliage");
|
profiler.popPush("betterfoliage");
|
||||||
BetterFoliageMod.INSTANCE.getBus().post(new ModelDefinitionsLoadedEvent(ModelBakery.class.cast(this)));
|
BetterFoliageMod.INSTANCE.getBus().post(new ModelDefinitionsLoadedEvent(ModelBakery.class.cast(this)));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -34,7 +34,7 @@ abstract public class MixinModelBakery {
|
|||||||
IBakedModel onBakeModel(
|
IBakedModel onBakeModel(
|
||||||
IUnbakedModel unbaked,
|
IUnbakedModel unbaked,
|
||||||
ModelBakery bakery,
|
ModelBakery bakery,
|
||||||
Function<Material, TextureAtlasSprite> spriteGetter,
|
Function<RenderMaterial, TextureAtlasSprite> spriteGetter,
|
||||||
IModelTransform transform,
|
IModelTransform transform,
|
||||||
ResourceLocation locationIn
|
ResourceLocation locationIn
|
||||||
) {
|
) {
|
||||||
|
|||||||
@@ -31,6 +31,7 @@ import mods.betterfoliage.resource.discovery.ModelDefinitionsLoadedEvent
|
|||||||
import mods.betterfoliage.resource.generated.GeneratedTexturePack
|
import mods.betterfoliage.resource.generated.GeneratedTexturePack
|
||||||
import mods.betterfoliage.render.particle.LeafParticleRegistry
|
import mods.betterfoliage.render.particle.LeafParticleRegistry
|
||||||
import mods.betterfoliage.render.particle.RisingSoulParticle
|
import mods.betterfoliage.render.particle.RisingSoulParticle
|
||||||
|
import mods.betterfoliage.util.resourceManager
|
||||||
import net.minecraft.block.BlockState
|
import net.minecraft.block.BlockState
|
||||||
import net.minecraft.client.Minecraft
|
import net.minecraft.client.Minecraft
|
||||||
import net.minecraft.resources.IReloadableResourceManager
|
import net.minecraft.resources.IReloadableResourceManager
|
||||||
@@ -51,7 +52,7 @@ object BetterFoliage {
|
|||||||
// discoverers
|
// discoverers
|
||||||
BetterFoliageMod.bus.register(BakeWrapperManager)
|
BetterFoliageMod.bus.register(BakeWrapperManager)
|
||||||
BetterFoliageMod.bus.register(LeafParticleRegistry)
|
BetterFoliageMod.bus.register(LeafParticleRegistry)
|
||||||
(Minecraft.getInstance().resourceManager as IReloadableResourceManager).addReloadListener(LeafParticleRegistry)
|
resourceManager.registerReloadListener(LeafParticleRegistry)
|
||||||
|
|
||||||
ChunkOverlayManager.layers.add(RoundLogOverlayLayer)
|
ChunkOverlayManager.layers.add(RoundLogOverlayLayer)
|
||||||
|
|
||||||
|
|||||||
@@ -2,7 +2,6 @@ package mods.betterfoliage
|
|||||||
|
|
||||||
import mods.betterfoliage.config.BlockConfig
|
import mods.betterfoliage.config.BlockConfig
|
||||||
import mods.betterfoliage.config.Config
|
import mods.betterfoliage.config.Config
|
||||||
import net.alexwells.kottle.FMLKotlinModLoadingContext
|
|
||||||
import net.minecraft.client.Minecraft
|
import net.minecraft.client.Minecraft
|
||||||
import net.minecraftforge.fml.ModLoadingContext
|
import net.minecraftforge.fml.ModLoadingContext
|
||||||
import net.minecraftforge.fml.common.Mod
|
import net.minecraftforge.fml.common.Mod
|
||||||
@@ -11,6 +10,7 @@ import org.apache.logging.log4j.Level
|
|||||||
import org.apache.logging.log4j.LogManager
|
import org.apache.logging.log4j.LogManager
|
||||||
import org.apache.logging.log4j.simple.SimpleLogger
|
import org.apache.logging.log4j.simple.SimpleLogger
|
||||||
import org.apache.logging.log4j.util.PropertiesUtil
|
import org.apache.logging.log4j.util.PropertiesUtil
|
||||||
|
import thedarkcolour.kotlinforforge.forge.MOD_BUS
|
||||||
import java.io.File
|
import java.io.File
|
||||||
import java.io.PrintStream
|
import java.io.PrintStream
|
||||||
import java.util.Properties
|
import java.util.Properties
|
||||||
@@ -19,7 +19,7 @@ import java.util.Properties
|
|||||||
object BetterFoliageMod {
|
object BetterFoliageMod {
|
||||||
const val MOD_ID = "betterfoliage"
|
const val MOD_ID = "betterfoliage"
|
||||||
|
|
||||||
val bus = FMLKotlinModLoadingContext.get().modEventBus
|
val bus = MOD_BUS
|
||||||
|
|
||||||
val detailLogStream = PrintStream(File("logs/betterfoliage.log").apply {
|
val detailLogStream = PrintStream(File("logs/betterfoliage.log").apply {
|
||||||
parentFile.mkdirs()
|
parentFile.mkdirs()
|
||||||
@@ -33,7 +33,7 @@ object BetterFoliageMod {
|
|||||||
|
|
||||||
init {
|
init {
|
||||||
ModLoadingContext.get().registerConfig(ModConfig.Type.CLIENT, Config.build())
|
ModLoadingContext.get().registerConfig(ModConfig.Type.CLIENT, Config.build())
|
||||||
Minecraft.getInstance().resourcePackList.addPackFinder(BetterFoliage.generatedPack.finder)
|
Minecraft.getInstance().resourcePackRepository.addPackFinder(BetterFoliage.generatedPack.finder)
|
||||||
bus.register(BlockConfig)
|
bus.register(BlockConfig)
|
||||||
BetterFoliage.init()
|
BetterFoliage.init()
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,11 +17,11 @@ import net.minecraft.client.renderer.model.ModelBakery
|
|||||||
import net.minecraft.client.renderer.texture.TextureAtlasSprite
|
import net.minecraft.client.renderer.texture.TextureAtlasSprite
|
||||||
import net.minecraft.util.ResourceLocation
|
import net.minecraft.util.ResourceLocation
|
||||||
import net.minecraft.util.math.BlockPos
|
import net.minecraft.util.math.BlockPos
|
||||||
|
import net.minecraft.world.IBlockDisplayReader
|
||||||
import net.minecraft.world.IBlockReader
|
import net.minecraft.world.IBlockReader
|
||||||
import net.minecraft.world.ILightReader
|
|
||||||
import net.minecraftforge.client.model.pipeline.BlockInfo
|
import net.minecraftforge.client.model.pipeline.BlockInfo
|
||||||
import net.minecraftforge.client.model.pipeline.VertexLighterFlat
|
import net.minecraftforge.client.model.pipeline.VertexLighterFlat
|
||||||
import java.util.*
|
import java.util.Random
|
||||||
|
|
||||||
// Java
|
// Java
|
||||||
val String = ClassRef<String>("java.lang.String")
|
val String = ClassRef<String>("java.lang.String")
|
||||||
@@ -32,7 +32,7 @@ fun <K, V> mapRefMutable() = ClassRef<MutableMap<K, V>>("java.util.Map")
|
|||||||
|
|
||||||
// Minecraft
|
// Minecraft
|
||||||
val IBlockReader = ClassRef<IBlockReader>("net.minecraft.world.IBlockReader")
|
val IBlockReader = ClassRef<IBlockReader>("net.minecraft.world.IBlockReader")
|
||||||
val ILightReader = ClassRef<ILightReader>("net.minecraft.world.ILightReader")
|
val ILightReader = ClassRef<IBlockDisplayReader>("net.minecraft.world.IBlockDisplayReader")
|
||||||
val BlockState = ClassRef<BlockState>("net.minecraft.block.BlockState")
|
val BlockState = ClassRef<BlockState>("net.minecraft.block.BlockState")
|
||||||
val BlockPos = ClassRef<BlockPos>("net.minecraft.util.math.BlockPos")
|
val BlockPos = ClassRef<BlockPos>("net.minecraft.util.math.BlockPos")
|
||||||
val Block = ClassRef<Block>("net.minecraft.block.Block")
|
val Block = ClassRef<Block>("net.minecraft.block.Block")
|
||||||
|
|||||||
@@ -20,8 +20,8 @@ import net.minecraft.util.Direction.UP
|
|||||||
import net.minecraft.util.math.BlockPos
|
import net.minecraft.util.math.BlockPos
|
||||||
import net.minecraft.util.math.shapes.VoxelShape
|
import net.minecraft.util.math.shapes.VoxelShape
|
||||||
import net.minecraft.util.math.shapes.VoxelShapes
|
import net.minecraft.util.math.shapes.VoxelShapes
|
||||||
|
import net.minecraft.world.IBlockDisplayReader
|
||||||
import net.minecraft.world.IBlockReader
|
import net.minecraft.world.IBlockReader
|
||||||
import net.minecraft.world.ILightReader
|
|
||||||
import net.minecraft.world.World
|
import net.minecraft.world.World
|
||||||
import java.util.Random
|
import java.util.Random
|
||||||
|
|
||||||
@@ -35,11 +35,11 @@ fun onClientBlockChanged(worldClient: ClientWorld, pos: BlockPos, oldState: Bloc
|
|||||||
ChunkOverlayManager.onBlockChange(worldClient, pos)
|
ChunkOverlayManager.onBlockChange(worldClient, pos)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun onRandomDisplayTick(block: Block, state: BlockState, world: World, pos: BlockPos, random: Random) {
|
fun onRandomDisplayTick(block: Block, state: BlockState, world: ClientWorld, pos: BlockPos, random: Random) {
|
||||||
if (Config.enabled &&
|
if (Config.enabled &&
|
||||||
Config.risingSoul.enabled &&
|
Config.risingSoul.enabled &&
|
||||||
state.block == Blocks.SOUL_SAND &&
|
state.block == Blocks.SOUL_SAND &&
|
||||||
world.isAirBlock(pos.offset(UP)) &&
|
world.getBlockState(pos.relative(UP)).isAir &&
|
||||||
Math.random() < Config.risingSoul.chance) {
|
Math.random() < Config.risingSoul.chance) {
|
||||||
RisingSoulParticle(world, pos).addIfValid()
|
RisingSoulParticle(world, pos).addIfValid()
|
||||||
}
|
}
|
||||||
@@ -47,7 +47,7 @@ fun onRandomDisplayTick(block: Block, state: BlockState, world: World, pos: Bloc
|
|||||||
if (Config.enabled &&
|
if (Config.enabled &&
|
||||||
Config.fallingLeaves.enabled &&
|
Config.fallingLeaves.enabled &&
|
||||||
random.nextDouble() < Config.fallingLeaves.chance &&
|
random.nextDouble() < Config.fallingLeaves.chance &&
|
||||||
world.isAirBlock(pos.offset(DOWN))
|
world.getBlockState(pos.relative(DOWN)).isAir
|
||||||
) {
|
) {
|
||||||
(getActualRenderModel(world, pos, state, random) as? LeafBlockModel)?.let { leafModel ->
|
(getActualRenderModel(world, pos, state, random) as? LeafBlockModel)?.let { leafModel ->
|
||||||
val blockColor = Minecraft.getInstance().blockColors.getColor(state, world, pos, 0)
|
val blockColor = Minecraft.getInstance().blockColors.getColor(state, world, pos, 0)
|
||||||
@@ -63,13 +63,13 @@ fun getVoxelShapeOverride(state: BlockState, reader: IBlockReader, pos: BlockPos
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun shouldForceSideRenderOF(state: BlockState, world: IBlockReader, pos: BlockPos, face: Direction) =
|
fun shouldForceSideRenderOF(state: BlockState, world: IBlockReader, pos: BlockPos, face: Direction) =
|
||||||
world.getBlockState(pos.offset(face)).let { neighbor -> BetterFoliage.blockTypes.hasTyped<RoundLogKey>(neighbor) }
|
world.getBlockState(pos.relative(face)).let { neighbor -> BetterFoliage.blockTypes.hasTyped<RoundLogKey>(neighbor) }
|
||||||
|
|
||||||
fun getActualRenderModel(world: ILightReader, pos: BlockPos, state: BlockState, random: Random): SpecialRenderModel? {
|
fun getActualRenderModel(world: IBlockDisplayReader, pos: BlockPos, state: BlockState, random: Random): SpecialRenderModel? {
|
||||||
val model = Minecraft.getInstance().blockRendererDispatcher.blockModelShapes.getModel(state) as? SpecialRenderModel
|
val model = Minecraft.getInstance().blockRenderer.blockModelShaper.getBlockModel(state) as? SpecialRenderModel
|
||||||
?: return null
|
?: return null
|
||||||
if (model is WeightedModelWrapper) {
|
if (model is WeightedModelWrapper) {
|
||||||
random.setSeed(state.getPositionRandom(pos))
|
random.setSeed(state.getSeed(pos))
|
||||||
return model.getModel(random).model
|
return model.getModel(random).model
|
||||||
}
|
}
|
||||||
return model
|
return model
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
package mods.betterfoliage.chunk
|
package mods.betterfoliage.chunk
|
||||||
|
|
||||||
import mods.betterfoliage.util.Int3
|
import mods.betterfoliage.util.Int3
|
||||||
import mods.betterfoliage.util.allDirections
|
|
||||||
import mods.betterfoliage.util.offset
|
import mods.betterfoliage.util.offset
|
||||||
import mods.betterfoliage.util.plus
|
import mods.betterfoliage.util.plus
|
||||||
import mods.betterfoliage.util.semiRandom
|
import mods.betterfoliage.util.semiRandom
|
||||||
@@ -10,7 +9,7 @@ import net.minecraft.block.BlockState
|
|||||||
import net.minecraft.client.renderer.chunk.ChunkRenderCache
|
import net.minecraft.client.renderer.chunk.ChunkRenderCache
|
||||||
import net.minecraft.util.Direction
|
import net.minecraft.util.Direction
|
||||||
import net.minecraft.util.math.BlockPos
|
import net.minecraft.util.math.BlockPos
|
||||||
import net.minecraft.world.ILightReader
|
import net.minecraft.world.IBlockDisplayReader
|
||||||
import net.minecraft.world.IWorldReader
|
import net.minecraft.world.IWorldReader
|
||||||
import net.minecraft.world.biome.Biome
|
import net.minecraft.world.biome.Biome
|
||||||
import net.minecraft.world.level.ColorResolver
|
import net.minecraft.world.level.ColorResolver
|
||||||
@@ -20,7 +19,7 @@ import net.minecraft.world.level.ColorResolver
|
|||||||
* block-relative coordinates.
|
* block-relative coordinates.
|
||||||
*/
|
*/
|
||||||
interface BlockCtx {
|
interface BlockCtx {
|
||||||
val world: ILightReader
|
val world: IBlockDisplayReader
|
||||||
val pos: BlockPos
|
val pos: BlockPos
|
||||||
|
|
||||||
fun offset(dir: Direction) = offset(dir.offset)
|
fun offset(dir: Direction) = offset(dir.offset)
|
||||||
@@ -35,13 +34,13 @@ interface BlockCtx {
|
|||||||
|
|
||||||
val biome: Biome? get() =
|
val biome: Biome? get() =
|
||||||
(world as? IWorldReader)?.getBiome(pos) ?:
|
(world as? IWorldReader)?.getBiome(pos) ?:
|
||||||
(world as? ChunkRenderCache)?.world?.getBiome(pos)
|
(world as? ChunkRenderCache)?.level?.getBiome(pos)
|
||||||
|
|
||||||
val isNormalCube: Boolean get() = state.isNormalCube(world, pos)
|
val isFullBlock: Boolean get() = state.isCollisionShapeFullBlock(world, pos)
|
||||||
|
|
||||||
fun isNeighborSolid(dir: Direction) = offset(dir).let { it.state.isSolidSide(it.world, it.pos, dir.opposite) }
|
fun isNeighborSturdy(dir: Direction) = offset(dir).let { it.state.isFaceSturdy(it.world, it.pos, dir.opposite) }
|
||||||
|
|
||||||
fun shouldSideBeRendered(side: Direction) = Block.shouldSideBeRendered(state, world, pos, side)
|
fun shouldSideBeRendered(side: Direction) = Block.shouldRenderFace(state, world, pos, side)
|
||||||
|
|
||||||
/** Get a semi-random value based on the block coordinate and the given seed. */
|
/** Get a semi-random value based on the block coordinate and the given seed. */
|
||||||
fun semiRandom(seed: Int) = pos.semiRandom(seed)
|
fun semiRandom(seed: Int) = pos.semiRandom(seed)
|
||||||
@@ -49,11 +48,11 @@ interface BlockCtx {
|
|||||||
/** Get an array of semi-random values based on the block coordinate. */
|
/** Get an array of semi-random values based on the block coordinate. */
|
||||||
fun semiRandomArray(num: Int): Array<Int> = Array(num) { semiRandom(it) }
|
fun semiRandomArray(num: Int): Array<Int> = Array(num) { semiRandom(it) }
|
||||||
|
|
||||||
fun color(resolver: ColorResolver) = world.getBlockColor(pos, resolver)
|
fun color(resolver: ColorResolver) = world.getBlockTint(pos, resolver)
|
||||||
}
|
}
|
||||||
|
|
||||||
class BasicBlockCtx(
|
class BasicBlockCtx(
|
||||||
override val world: ILightReader,
|
override val world: IBlockDisplayReader,
|
||||||
override val pos: BlockPos
|
override val pos: BlockPos
|
||||||
) : BlockCtx {
|
) : BlockCtx {
|
||||||
override val state: BlockState = world.getBlockState(pos)
|
override val state: BlockState = world.getBlockState(pos)
|
||||||
|
|||||||
@@ -1,32 +1,26 @@
|
|||||||
package mods.betterfoliage.chunk
|
package mods.betterfoliage.chunk
|
||||||
|
|
||||||
import mods.octarinecore.ChunkCacheOF
|
|
||||||
import mods.betterfoliage.util.get
|
import mods.betterfoliage.util.get
|
||||||
import mods.betterfoliage.util.isInstance
|
import mods.betterfoliage.util.isInstance
|
||||||
|
import mods.octarinecore.ChunkCacheOF
|
||||||
import net.minecraft.client.renderer.chunk.ChunkRenderCache
|
import net.minecraft.client.renderer.chunk.ChunkRenderCache
|
||||||
import net.minecraft.client.world.ClientWorld
|
import net.minecraft.client.world.ClientWorld
|
||||||
import net.minecraft.util.math.BlockPos
|
import net.minecraft.util.math.BlockPos
|
||||||
import net.minecraft.util.math.ChunkPos
|
import net.minecraft.util.math.ChunkPos
|
||||||
import net.minecraft.world.ILightReader
|
import net.minecraft.world.DimensionType
|
||||||
|
import net.minecraft.world.IBlockDisplayReader
|
||||||
import net.minecraft.world.IWorldReader
|
import net.minecraft.world.IWorldReader
|
||||||
import net.minecraft.world.dimension.DimensionType
|
|
||||||
import net.minecraftforge.common.MinecraftForge
|
import net.minecraftforge.common.MinecraftForge
|
||||||
import net.minecraftforge.event.world.ChunkEvent
|
import net.minecraftforge.event.world.ChunkEvent
|
||||||
import net.minecraftforge.event.world.WorldEvent
|
import net.minecraftforge.event.world.WorldEvent
|
||||||
import net.minecraftforge.eventbus.api.SubscribeEvent
|
import net.minecraftforge.eventbus.api.SubscribeEvent
|
||||||
import java.util.*
|
import java.util.*
|
||||||
import kotlin.collections.List
|
|
||||||
import kotlin.collections.MutableMap
|
|
||||||
import kotlin.collections.associateWith
|
|
||||||
import kotlin.collections.forEach
|
|
||||||
import kotlin.collections.mutableListOf
|
|
||||||
import kotlin.collections.mutableMapOf
|
|
||||||
import kotlin.collections.set
|
import kotlin.collections.set
|
||||||
|
|
||||||
val ILightReader.dimType: DimensionType get() = when {
|
val IBlockDisplayReader.dimType: DimensionType get() = when {
|
||||||
this is IWorldReader -> dimension.type
|
this is IWorldReader -> dimensionType()
|
||||||
this is ChunkRenderCache -> world.dimension.type
|
this is ChunkRenderCache -> level.dimensionType()
|
||||||
this.isInstance(ChunkCacheOF) -> this[ChunkCacheOF.chunkCache].world.dimension.type
|
this.isInstance(ChunkCacheOF) -> this[ChunkCacheOF.chunkCache].level.dimensionType()
|
||||||
else -> throw IllegalArgumentException("DimensionType of world with class ${this::class.qualifiedName} cannot be determined!")
|
else -> throw IllegalArgumentException("DimensionType of world with class ${this::class.qualifiedName} cannot be determined!")
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -35,7 +29,7 @@ val ILightReader.dimType: DimensionType get() = when {
|
|||||||
*/
|
*/
|
||||||
interface ChunkOverlayLayer<T> {
|
interface ChunkOverlayLayer<T> {
|
||||||
fun calculate(ctx: BlockCtx): T
|
fun calculate(ctx: BlockCtx): T
|
||||||
fun onBlockUpdate(world: ILightReader, pos: BlockPos)
|
fun onBlockUpdate(world: IBlockDisplayReader, pos: BlockPos)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -55,6 +55,7 @@ object Config : DelegatingConfig(BetterFoliageMod.MOD_ID, BetterFoliageMod.MOD_I
|
|||||||
|
|
||||||
object roundLogs : ConfigCategory(){
|
object roundLogs : ConfigCategory(){
|
||||||
val enabled by featureEnable()
|
val enabled by featureEnable()
|
||||||
|
val plantsOnly by boolean(true)
|
||||||
val radiusSmall by double(max=0.5, default=0.25)
|
val radiusSmall by double(max=0.5, default=0.25)
|
||||||
val radiusLarge by double(max=0.5, default=0.44)
|
val radiusLarge by double(max=0.5, default=0.44)
|
||||||
val dimming by double(default = 0.7)
|
val dimming by double(default = 0.7)
|
||||||
|
|||||||
@@ -14,5 +14,7 @@ val MYCELIUM_BLOCKS = listOf(Blocks.MYCELIUM)
|
|||||||
|
|
||||||
val SALTWATER_BIOMES = listOf(Biome.Category.BEACH, Biome.Category.OCEAN)
|
val SALTWATER_BIOMES = listOf(Biome.Category.BEACH, Biome.Category.OCEAN)
|
||||||
|
|
||||||
val SNOW_MATERIALS = listOf(Material.SNOW_BLOCK, Material.SNOW)
|
val SNOW_MATERIALS = listOf(Material.TOP_SNOW, Material.SNOW)
|
||||||
val BlockState.isSnow: Boolean get() = material in SNOW_MATERIALS
|
val BlockState.isSnow: Boolean get() = material in SNOW_MATERIALS
|
||||||
|
|
||||||
|
val ACCEPTED_ROUND_LOG_MATERIALS = listOf(Material.WOOD, Material.GRASS)
|
||||||
|
|||||||
@@ -34,7 +34,7 @@ object OptifineCustomColors {
|
|||||||
val fakeQuad = BakedQuad(IntArray(0), 1, UP, null, true)
|
val fakeQuad = BakedQuad(IntArray(0), 1, UP, null, true)
|
||||||
|
|
||||||
fun getBlockColor(ctx: BlockCtx, resolver: ColorResolver): Int {
|
fun getBlockColor(ctx: BlockCtx, resolver: ColorResolver): Int {
|
||||||
val ofColor = if (isColorAvailable && Minecraft.getInstance().gameSettings.reflectField<Boolean>("ofCustomColors") == true) {
|
val ofColor = if (isColorAvailable && Minecraft.getInstance().options.reflectField<Boolean>("ofCustomColors") == true) {
|
||||||
renderEnv.reset(ctx.state, ctx.pos)
|
renderEnv.reset(ctx.state, ctx.pos)
|
||||||
CustomColors.getColorMultiplier.invokeStatic(fakeQuad, ctx.state, ctx.world, ctx.pos, renderEnv.wrapped) as? Int
|
CustomColors.getColorMultiplier.invokeStatic(fakeQuad, ctx.state, ctx.world, ctx.pos, renderEnv.wrapped) as? Int
|
||||||
} else null
|
} else null
|
||||||
|
|||||||
@@ -1,8 +1,6 @@
|
|||||||
package mods.betterfoliage.integration
|
package mods.betterfoliage.integration
|
||||||
|
|
||||||
import mods.betterfoliage.config.BlockConfig
|
|
||||||
import mods.betterfoliage.render.pipeline.RenderCtxBase
|
import mods.betterfoliage.render.pipeline.RenderCtxBase
|
||||||
import mods.betterfoliage.render.pipeline.RenderCtxForge
|
|
||||||
import mods.betterfoliage.render.pipeline.RenderCtxVanilla
|
import mods.betterfoliage.render.pipeline.RenderCtxVanilla
|
||||||
import mods.betterfoliage.util.HasLogger
|
import mods.betterfoliage.util.HasLogger
|
||||||
import mods.betterfoliage.util.allAvailable
|
import mods.betterfoliage.util.allAvailable
|
||||||
@@ -14,7 +12,7 @@ import net.minecraft.block.BlockState
|
|||||||
import net.minecraft.block.Blocks
|
import net.minecraft.block.Blocks
|
||||||
import net.minecraft.client.renderer.BufferBuilder
|
import net.minecraft.client.renderer.BufferBuilder
|
||||||
import net.minecraft.util.math.BlockPos
|
import net.minecraft.util.math.BlockPos
|
||||||
import net.minecraft.world.ILightReader
|
import net.minecraft.world.IBlockDisplayReader
|
||||||
import org.apache.logging.log4j.Level.INFO
|
import org.apache.logging.log4j.Level.INFO
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -23,14 +21,14 @@ import org.apache.logging.log4j.Level.INFO
|
|||||||
object ShadersModIntegration : HasLogger() {
|
object ShadersModIntegration : HasLogger() {
|
||||||
@JvmStatic val isAvailable = allAvailable(SVertexBuilder, SVertexBuilder.pushState, SVertexBuilder.popState, BlockAliases.getAliasBlockId)
|
@JvmStatic val isAvailable = allAvailable(SVertexBuilder, SVertexBuilder.pushState, SVertexBuilder.popState, BlockAliases.getAliasBlockId)
|
||||||
|
|
||||||
val defaultLeaves = Blocks.OAK_LEAVES.defaultState
|
val defaultLeaves = Blocks.OAK_LEAVES.defaultBlockState()
|
||||||
val defaultGrass = Blocks.GRASS.defaultState
|
val defaultGrass = Blocks.GRASS.defaultBlockState()
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Called from transformed ShadersMod code.
|
* Called from transformed ShadersMod code.
|
||||||
* @see mods.betterfoliage.loader.BetterFoliageTransformer
|
* @see mods.betterfoliage.loader.BetterFoliageTransformer
|
||||||
*/
|
*/
|
||||||
@JvmStatic fun getBlockStateOverride(state: BlockState, world: ILightReader, pos: BlockPos): BlockState {
|
@JvmStatic fun getBlockStateOverride(state: BlockState, world: IBlockDisplayReader, pos: BlockPos): BlockState {
|
||||||
// if (LeafRegistry[state, world, pos] != null) return defaultLeaves
|
// if (LeafRegistry[state, world, pos] != null) return defaultLeaves
|
||||||
// if (BlockConfig.crops.matchesClass(state.block)) return defaultGrass
|
// if (BlockConfig.crops.matchesClass(state.block)) return defaultGrass
|
||||||
return state
|
return state
|
||||||
|
|||||||
@@ -68,8 +68,8 @@ fun List<Quad>.bake(applyDiffuseLighting: Boolean) = map { quad ->
|
|||||||
)
|
)
|
||||||
// don't fill lightmap UV coords
|
// don't fill lightmap UV coords
|
||||||
element.usage == VertexFormatElement.Usage.UV && element.type == VertexFormatElement.Type.FLOAT -> builder.put(idx,
|
element.usage == VertexFormatElement.Usage.UV && element.type == VertexFormatElement.Type.FLOAT -> builder.put(idx,
|
||||||
quad.sprite.minU + (quad.sprite.maxU - quad.sprite.minU) * (vertex.uv.u + 0.5).toFloat(),
|
quad.sprite.u0 + (quad.sprite.u1 - quad.sprite.u0) * (vertex.uv.u + 0.5).toFloat(),
|
||||||
quad.sprite.minV + (quad.sprite.maxV - quad.sprite.minV) * (vertex.uv.v + 0.5).toFloat(),
|
quad.sprite.v0 + (quad.sprite.v1 - quad.sprite.v0) * (vertex.uv.v + 0.5).toFloat(),
|
||||||
0.0f, 1.0f
|
0.0f, 1.0f
|
||||||
)
|
)
|
||||||
element.usage == VertexFormatElement.Usage.COLOR -> builder.put(idx,
|
element.usage == VertexFormatElement.Usage.COLOR -> builder.put(idx,
|
||||||
@@ -96,18 +96,18 @@ fun Array<List<Quad>>.bake(applyDiffuseLighting: Boolean) = mapArray { it.bake(a
|
|||||||
fun BakedQuad.unbake(): HalfBakedQuad {
|
fun BakedQuad.unbake(): HalfBakedQuad {
|
||||||
val size = DefaultVertexFormats.BLOCK.integerSize
|
val size = DefaultVertexFormats.BLOCK.integerSize
|
||||||
val verts = Array(4) { vIdx ->
|
val verts = Array(4) { vIdx ->
|
||||||
val x = java.lang.Float.intBitsToFloat(vertexData[vIdx * size + 0])
|
val x = java.lang.Float.intBitsToFloat(vertices[vIdx * size + 0])
|
||||||
val y = java.lang.Float.intBitsToFloat(vertexData[vIdx * size + 1])
|
val y = java.lang.Float.intBitsToFloat(vertices[vIdx * size + 1])
|
||||||
val z = java.lang.Float.intBitsToFloat(vertexData[vIdx * size + 2])
|
val z = java.lang.Float.intBitsToFloat(vertices[vIdx * size + 2])
|
||||||
val color = vertexData[vIdx * size + 3]
|
val color = vertices[vIdx * size + 3]
|
||||||
val u = java.lang.Float.intBitsToFloat(vertexData[vIdx * size + 4])
|
val u = java.lang.Float.intBitsToFloat(vertices[vIdx * size + 4])
|
||||||
val v = java.lang.Float.intBitsToFloat(vertexData[vIdx * size + 5])
|
val v = java.lang.Float.intBitsToFloat(vertices[vIdx * size + 5])
|
||||||
Vertex(Double3(x, y, z), UV(u.toDouble(), v.toDouble()), Color(color))
|
Vertex(Double3(x, y, z), UV(u.toDouble(), v.toDouble()), Color(color))
|
||||||
}
|
}
|
||||||
val unbaked = Quad(
|
val unbaked = Quad(
|
||||||
verts[0], verts[1], verts[2], verts[3],
|
verts[0], verts[1], verts[2], verts[3],
|
||||||
colorIndex = if (hasTintIndex()) tintIndex else -1,
|
colorIndex = if (isTinted) tintIndex else -1,
|
||||||
face = face
|
face = direction
|
||||||
)
|
)
|
||||||
return HalfBakedQuad(unbaked, this)
|
return HalfBakedQuad(unbaked, this)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,17 +1,9 @@
|
|||||||
package mods.betterfoliage.model
|
package mods.betterfoliage.model
|
||||||
|
|
||||||
import mods.betterfoliage.render.pipeline.RenderCtxBase
|
import mods.betterfoliage.render.pipeline.RenderCtxBase
|
||||||
import mods.betterfoliage.util.HasLogger
|
|
||||||
import net.minecraft.client.renderer.model.IBakedModel
|
import net.minecraft.client.renderer.model.IBakedModel
|
||||||
import net.minecraft.client.renderer.model.Material
|
|
||||||
import net.minecraft.client.renderer.model.ModelBakery
|
|
||||||
import net.minecraft.client.renderer.model.VariantList
|
|
||||||
import net.minecraft.client.renderer.texture.TextureAtlasSprite
|
|
||||||
import net.minecraft.util.ResourceLocation
|
|
||||||
import net.minecraft.util.WeightedRandom
|
import net.minecraft.util.WeightedRandom
|
||||||
import org.apache.logging.log4j.Level.WARN
|
|
||||||
import java.util.Random
|
import java.util.Random
|
||||||
import java.util.function.Function
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Model that makes use of advanced rendering features.
|
* Model that makes use of advanced rendering features.
|
||||||
@@ -24,9 +16,9 @@ class WeightedModelWrapper(
|
|||||||
val models: List<WeightedModel>, baseModel: SpecialRenderModel
|
val models: List<WeightedModel>, baseModel: SpecialRenderModel
|
||||||
): IBakedModel by baseModel, SpecialRenderModel {
|
): IBakedModel by baseModel, SpecialRenderModel {
|
||||||
class WeightedModel(val model: SpecialRenderModel, weight: Int) : WeightedRandom.Item(weight)
|
class WeightedModel(val model: SpecialRenderModel, weight: Int) : WeightedRandom.Item(weight)
|
||||||
val totalWeight = models.sumBy { it.itemWeight }
|
val totalWeight = models.sumBy { it.weight }
|
||||||
|
|
||||||
fun getModel(random: Random) = WeightedRandom.getRandomItem(models, random.nextInt(totalWeight))
|
fun getModel(random: Random) = WeightedRandom.getWeightedItem(models, random.nextInt(totalWeight))
|
||||||
|
|
||||||
override fun render(ctx: RenderCtxBase, noDecorations: Boolean) {
|
override fun render(ctx: RenderCtxBase, noDecorations: Boolean) {
|
||||||
getModel(ctx.random).model.render(ctx, noDecorations)
|
getModel(ctx.random).model.render(ctx, noDecorations)
|
||||||
|
|||||||
@@ -59,7 +59,7 @@ class SpriteSetDelegate(
|
|||||||
|
|
||||||
@SubscribeEvent
|
@SubscribeEvent
|
||||||
fun handlePreStitch(event: TextureStitchEvent.Pre) {
|
fun handlePreStitch(event: TextureStitchEvent.Pre) {
|
||||||
if (event.map.textureLocation != Atlas.BLOCKS.resourceId) return
|
if (event.map.location() != Atlas.BLOCKS.resourceId) return
|
||||||
spriteSet = null
|
spriteSet = null
|
||||||
idList = (0 until 16)
|
idList = (0 until 16)
|
||||||
.map(idFunc)
|
.map(idFunc)
|
||||||
|
|||||||
@@ -1,10 +1,11 @@
|
|||||||
package mods.betterfoliage.render.block.vanilla
|
package mods.betterfoliage.render.block.vanilla
|
||||||
|
|
||||||
import mods.betterfoliage.BetterFoliageMod
|
|
||||||
import mods.betterfoliage.BetterFoliage
|
import mods.betterfoliage.BetterFoliage
|
||||||
|
import mods.betterfoliage.BetterFoliageMod
|
||||||
import mods.betterfoliage.config.Config
|
import mods.betterfoliage.config.Config
|
||||||
import mods.betterfoliage.config.DIRT_BLOCKS
|
import mods.betterfoliage.config.DIRT_BLOCKS
|
||||||
import mods.betterfoliage.config.SALTWATER_BIOMES
|
import mods.betterfoliage.config.SALTWATER_BIOMES
|
||||||
|
import mods.betterfoliage.config.isSnow
|
||||||
import mods.betterfoliage.integration.ShadersModIntegration
|
import mods.betterfoliage.integration.ShadersModIntegration
|
||||||
import mods.betterfoliage.model.HalfBakedSpecialWrapper
|
import mods.betterfoliage.model.HalfBakedSpecialWrapper
|
||||||
import mods.betterfoliage.model.HalfBakedWrapperKey
|
import mods.betterfoliage.model.HalfBakedWrapperKey
|
||||||
@@ -15,7 +16,6 @@ import mods.betterfoliage.model.tuftModelSet
|
|||||||
import mods.betterfoliage.model.tuftShapeSet
|
import mods.betterfoliage.model.tuftShapeSet
|
||||||
import mods.betterfoliage.render.lighting.LightingPreferredFace
|
import mods.betterfoliage.render.lighting.LightingPreferredFace
|
||||||
import mods.betterfoliage.render.pipeline.RenderCtxBase
|
import mods.betterfoliage.render.pipeline.RenderCtxBase
|
||||||
import mods.betterfoliage.render.pipeline.RenderCtxVanilla
|
|
||||||
import mods.betterfoliage.resource.discovery.AbstractModelDiscovery
|
import mods.betterfoliage.resource.discovery.AbstractModelDiscovery
|
||||||
import mods.betterfoliage.resource.discovery.BakeWrapperManager
|
import mods.betterfoliage.resource.discovery.BakeWrapperManager
|
||||||
import mods.betterfoliage.resource.discovery.ModelBakingContext
|
import mods.betterfoliage.resource.discovery.ModelBakingContext
|
||||||
@@ -27,20 +27,18 @@ import mods.betterfoliage.util.LazyInvalidatable
|
|||||||
import mods.betterfoliage.util.get
|
import mods.betterfoliage.util.get
|
||||||
import mods.betterfoliage.util.offset
|
import mods.betterfoliage.util.offset
|
||||||
import mods.betterfoliage.util.randomI
|
import mods.betterfoliage.util.randomI
|
||||||
import net.minecraft.block.Blocks
|
|
||||||
import net.minecraft.block.material.Material
|
import net.minecraft.block.material.Material
|
||||||
import net.minecraft.client.renderer.RenderType
|
import net.minecraft.client.renderer.RenderType
|
||||||
import net.minecraft.client.renderer.RenderTypeLookup
|
import net.minecraft.client.renderer.RenderTypeLookup
|
||||||
import net.minecraft.client.renderer.model.BlockModel
|
import net.minecraft.client.renderer.model.BlockModel
|
||||||
import net.minecraft.util.Direction.UP
|
import net.minecraft.util.Direction.UP
|
||||||
import net.minecraft.util.ResourceLocation
|
import net.minecraft.util.ResourceLocation
|
||||||
import net.minecraft.world.biome.Biome
|
|
||||||
|
|
||||||
object StandardDirtDiscovery : AbstractModelDiscovery() {
|
object StandardDirtDiscovery : AbstractModelDiscovery() {
|
||||||
fun canRenderInLayer(layer: RenderType) = when {
|
fun canRenderInLayer(layer: RenderType) = when {
|
||||||
!Config.enabled -> layer == RenderType.getSolid()
|
!Config.enabled -> layer == RenderType.solid()
|
||||||
!Config.connectedGrass.enabled && !Config.algae.enabled && !Config.reed.enabled -> layer == RenderType.getSolid()
|
!Config.connectedGrass.enabled && !Config.algae.enabled && !Config.reed.enabled -> layer == RenderType.solid()
|
||||||
else -> layer == RenderType.getCutoutMipped()
|
else -> layer == RenderType.cutoutMipped()
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun processModel(ctx: ModelDiscoveryContext) {
|
override fun processModel(ctx: ModelDiscoveryContext) {
|
||||||
@@ -67,9 +65,12 @@ class StandardDirtModel(
|
|||||||
|
|
||||||
val stateUp = ctx.state(UP)
|
val stateUp = ctx.state(UP)
|
||||||
val state2Up = ctx.state(Int3(0, 2, 0))
|
val state2Up = ctx.state(Int3(0, 2, 0))
|
||||||
val isConnectedGrass = Config.connectedGrass.enabled && stateUp in BetterFoliage.blockTypes.grass
|
val isConnectedGrass = Config.connectedGrass.enabled &&
|
||||||
|
stateUp in BetterFoliage.blockTypes.grass &&
|
||||||
|
(Config.connectedGrass.snowEnabled || !state2Up.isSnow)
|
||||||
|
|
||||||
if (isConnectedGrass) {
|
if (isConnectedGrass) {
|
||||||
(ctx.blockModelShapes.getModel(stateUp) as? SpecialRenderModel)?.let { grassModel ->
|
(ctx.blockModelShapes.getBlockModel(stateUp) as? SpecialRenderModel)?.let { grassModel ->
|
||||||
ctx.renderMasquerade(UP.offset) {
|
ctx.renderMasquerade(UP.offset) {
|
||||||
grassModel.render(ctx, true)
|
grassModel.render(ctx, true)
|
||||||
}
|
}
|
||||||
@@ -81,9 +82,9 @@ class StandardDirtModel(
|
|||||||
super.render(ctx, false)
|
super.render(ctx, false)
|
||||||
|
|
||||||
val isWater = stateUp.material == Material.WATER
|
val isWater = stateUp.material == Material.WATER
|
||||||
val isDeepWater = isWater && ctx.offset(Int3(2 to UP)).state.material == Material.WATER
|
val isDeepWater = isWater && state2Up.material == Material.WATER
|
||||||
val isShallowWater = isWater && ctx.offset(Int3(2 to UP)).state.isAir
|
val isShallowWater = isWater && state2Up.isAir
|
||||||
val isSaltWater = isWater && ctx.biome?.category in SALTWATER_BIOMES
|
val isSaltWater = isWater && ctx.biome?.biomeCategory in SALTWATER_BIOMES
|
||||||
|
|
||||||
if (Config.algae.enabled(ctx.random) && isDeepWater) {
|
if (Config.algae.enabled(ctx.random) && isDeepWater) {
|
||||||
ctx.vertexLighter = vanillaTuftLighting
|
ctx.vertexLighter = vanillaTuftLighting
|
||||||
|
|||||||
@@ -31,7 +31,7 @@ object StandardMyceliumDiscovery : AbstractModelDiscovery() {
|
|||||||
override fun processModel(ctx: ModelDiscoveryContext) {
|
override fun processModel(ctx: ModelDiscoveryContext) {
|
||||||
if (ctx.getUnbaked() is BlockModel && ctx.blockState.block in MYCELIUM_BLOCKS) {
|
if (ctx.getUnbaked() is BlockModel && ctx.blockState.block in MYCELIUM_BLOCKS) {
|
||||||
ctx.addReplacement(StandardMyceliumKey)
|
ctx.addReplacement(StandardMyceliumKey)
|
||||||
RenderTypeLookup.setRenderLayer(ctx.blockState.block, RenderType.getCutout())
|
RenderTypeLookup.setRenderLayer(ctx.blockState.block, RenderType.cutout())
|
||||||
}
|
}
|
||||||
super.processModel(ctx)
|
super.processModel(ctx)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -32,9 +32,9 @@ import net.minecraft.util.ResourceLocation
|
|||||||
|
|
||||||
object StandardNetherrackDiscovery : AbstractModelDiscovery() {
|
object StandardNetherrackDiscovery : AbstractModelDiscovery() {
|
||||||
fun canRenderInLayer(layer: RenderType) = when {
|
fun canRenderInLayer(layer: RenderType) = when {
|
||||||
!Config.enabled -> layer == RenderType.getSolid()
|
!Config.enabled -> layer == RenderType.solid()
|
||||||
!Config.netherrack.enabled -> layer == RenderType.getSolid()
|
!Config.netherrack.enabled -> layer == RenderType.solid()
|
||||||
else -> layer == RenderType.getCutoutMipped()
|
else -> layer == RenderType.cutoutMipped()
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun processModel(ctx: ModelDiscoveryContext) {
|
override fun processModel(ctx: ModelDiscoveryContext) {
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
package mods.betterfoliage.render.block.vanilla
|
package mods.betterfoliage.render.block.vanilla
|
||||||
|
|
||||||
import mods.betterfoliage.BetterFoliage
|
import mods.betterfoliage.BetterFoliage
|
||||||
|
import mods.betterfoliage.config.ACCEPTED_ROUND_LOG_MATERIALS
|
||||||
import mods.betterfoliage.config.BlockConfig
|
import mods.betterfoliage.config.BlockConfig
|
||||||
import mods.betterfoliage.config.Config
|
import mods.betterfoliage.config.Config
|
||||||
import mods.betterfoliage.resource.discovery.ModelTextureList
|
|
||||||
import mods.betterfoliage.model.HalfBakedWrapperKey
|
import mods.betterfoliage.model.HalfBakedWrapperKey
|
||||||
import mods.betterfoliage.model.SpecialRenderModel
|
import mods.betterfoliage.model.SpecialRenderModel
|
||||||
import mods.betterfoliage.render.column.ColumnBlockKey
|
import mods.betterfoliage.render.column.ColumnBlockKey
|
||||||
@@ -16,11 +16,12 @@ import mods.betterfoliage.resource.discovery.ConfigurableModelDiscovery
|
|||||||
import mods.betterfoliage.resource.discovery.ModelBakingContext
|
import mods.betterfoliage.resource.discovery.ModelBakingContext
|
||||||
import mods.betterfoliage.resource.discovery.ModelBakingKey
|
import mods.betterfoliage.resource.discovery.ModelBakingKey
|
||||||
import mods.betterfoliage.resource.discovery.ModelDiscoveryContext
|
import mods.betterfoliage.resource.discovery.ModelDiscoveryContext
|
||||||
|
import mods.betterfoliage.resource.discovery.ModelTextureList
|
||||||
import mods.betterfoliage.util.Atlas
|
import mods.betterfoliage.util.Atlas
|
||||||
import mods.betterfoliage.util.LazyMapInvalidatable
|
import mods.betterfoliage.util.LazyMapInvalidatable
|
||||||
import mods.betterfoliage.util.tryDefault
|
import mods.betterfoliage.util.tryDefault
|
||||||
import net.minecraft.block.BlockState
|
import net.minecraft.block.BlockState
|
||||||
import net.minecraft.block.LogBlock
|
import net.minecraft.block.RotatedPillarBlock
|
||||||
import net.minecraft.util.Direction.Axis
|
import net.minecraft.util.Direction.Axis
|
||||||
import net.minecraft.util.ResourceLocation
|
import net.minecraft.util.ResourceLocation
|
||||||
import org.apache.logging.log4j.Level.INFO
|
import org.apache.logging.log4j.Level.INFO
|
||||||
@@ -43,13 +44,15 @@ object StandardRoundLogDiscovery : ConfigurableModelDiscovery() {
|
|||||||
|
|
||||||
override fun processModel(ctx: ModelDiscoveryContext, textureMatch: List<ResourceLocation>) {
|
override fun processModel(ctx: ModelDiscoveryContext, textureMatch: List<ResourceLocation>) {
|
||||||
val axis = getAxis(ctx.blockState)
|
val axis = getAxis(ctx.blockState)
|
||||||
detailLogger.log(INFO, " axis $axis")
|
|
||||||
ctx.addReplacement(StandardRoundLogKey(axis, textureMatch[0], textureMatch[1]))
|
detailLogger.log(INFO, " axis $axis, material ${ctx.blockState.material}")
|
||||||
|
if (!Config.roundLogs.plantsOnly || ctx.blockState.material in ACCEPTED_ROUND_LOG_MATERIALS)
|
||||||
|
ctx.addReplacement(StandardRoundLogKey(axis, textureMatch[0], textureMatch[1]))
|
||||||
}
|
}
|
||||||
|
|
||||||
fun getAxis(state: BlockState): Axis? {
|
fun getAxis(state: BlockState): Axis? {
|
||||||
val axis = tryDefault(null) { state.get(LogBlock.AXIS).toString() } ?:
|
val axis = tryDefault(null) { state.getValue(RotatedPillarBlock.AXIS).toString() } ?:
|
||||||
state.values.entries.find { it.key.getName().toLowerCase() == "axis" }?.value?.toString()
|
state.values.entries.find { it.key.name.toLowerCase() == "axis" }?.value?.toString()
|
||||||
return when (axis) {
|
return when (axis) {
|
||||||
"x" -> Axis.X
|
"x" -> Axis.X
|
||||||
"y" -> Axis.Y
|
"y" -> Axis.Y
|
||||||
|
|||||||
@@ -43,7 +43,7 @@ object StandardSandDiscovery : AbstractModelDiscovery() {
|
|||||||
if (ctx.getUnbaked() is BlockModel && ctx.blockState.block in SAND_BLOCKS) {
|
if (ctx.getUnbaked() is BlockModel && ctx.blockState.block in SAND_BLOCKS) {
|
||||||
BetterFoliage.blockTypes.dirt.add(ctx.blockState)
|
BetterFoliage.blockTypes.dirt.add(ctx.blockState)
|
||||||
ctx.addReplacement(StandardSandKey)
|
ctx.addReplacement(StandardSandKey)
|
||||||
RenderTypeLookup.setRenderLayer(ctx.blockState.block, RenderType.getCutoutMipped())
|
RenderTypeLookup.setRenderLayer(ctx.blockState.block, RenderType.cutoutMipped())
|
||||||
}
|
}
|
||||||
super.processModel(ctx)
|
super.processModel(ctx)
|
||||||
}
|
}
|
||||||
@@ -61,7 +61,7 @@ class StandardSandModel(
|
|||||||
override fun render(ctx: RenderCtxBase, noDecorations: Boolean) {
|
override fun render(ctx: RenderCtxBase, noDecorations: Boolean) {
|
||||||
super.render(ctx, noDecorations)
|
super.render(ctx, noDecorations)
|
||||||
if (noDecorations || !Config.enabled || !Config.coral.enabled(ctx.random)) return
|
if (noDecorations || !Config.enabled || !Config.coral.enabled(ctx.random)) return
|
||||||
if (ctx.biome?.category !in SALTWATER_BIOMES) return
|
if (ctx.biome?.biomeCategory !in SALTWATER_BIOMES) return
|
||||||
|
|
||||||
allDirections.filter { ctx.random.nextInt(64) < Config.coral.chance }.forEach { face ->
|
allDirections.filter { ctx.random.nextInt(64) < Config.coral.chance }.forEach { face ->
|
||||||
val isWater = ctx.state(face).material == Material.WATER
|
val isWater = ctx.state(face).material == Material.WATER
|
||||||
|
|||||||
@@ -23,7 +23,7 @@ import net.minecraft.block.BlockState
|
|||||||
import net.minecraft.util.Direction
|
import net.minecraft.util.Direction
|
||||||
import net.minecraft.util.Direction.Axis
|
import net.minecraft.util.Direction.Axis
|
||||||
import net.minecraft.util.math.BlockPos
|
import net.minecraft.util.math.BlockPos
|
||||||
import net.minecraft.world.ILightReader
|
import net.minecraft.world.IBlockDisplayReader
|
||||||
|
|
||||||
/** Index of SOUTH-EAST quadrant. */
|
/** Index of SOUTH-EAST quadrant. */
|
||||||
const val SE = 0
|
const val SE = 0
|
||||||
@@ -83,13 +83,13 @@ abstract class ColumnRenderLayer : ChunkOverlayLayer<ColumnLayerData> {
|
|||||||
|
|
||||||
val allNeighborOffsets = (-1..1).flatMap { offsetX -> (-1..1).flatMap { offsetY -> (-1..1).map { offsetZ -> Int3(offsetX, offsetY, offsetZ) }}}
|
val allNeighborOffsets = (-1..1).flatMap { offsetX -> (-1..1).flatMap { offsetY -> (-1..1).map { offsetZ -> Int3(offsetX, offsetY, offsetZ) }}}
|
||||||
|
|
||||||
override fun onBlockUpdate(world: ILightReader, pos: BlockPos) {
|
override fun onBlockUpdate(world: IBlockDisplayReader, pos: BlockPos) {
|
||||||
allNeighborOffsets.forEach { offset -> ChunkOverlayManager.clear(world.dimType, this, pos + offset) }
|
allNeighborOffsets.forEach { offset -> ChunkOverlayManager.clear(world.dimType, this, pos + offset) }
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun calculate(ctx: BlockCtx): ColumnLayerData {
|
override fun calculate(ctx: BlockCtx): ColumnLayerData {
|
||||||
// TODO detect round logs
|
// TODO detect round logs
|
||||||
if (allDirections.all { dir -> ctx.offset(dir).let { it.isNormalCube } }) return ColumnLayerData.SkipRender
|
if (allDirections.all { dir -> ctx.offset(dir).let { it.isFullBlock } }) return ColumnLayerData.SkipRender
|
||||||
val columnTextures = getColumnKey(ctx.state) ?: return ColumnLayerData.ResolveError
|
val columnTextures = getColumnKey(ctx.state) ?: return ColumnLayerData.ResolveError
|
||||||
|
|
||||||
// if log axis is not defined and "Default to vertical" config option is not set, render normally
|
// if log axis is not defined and "Default to vertical" config option is not set, render normally
|
||||||
@@ -185,7 +185,7 @@ abstract class ColumnRenderLayer : ChunkOverlayLayer<ColumnLayerData> {
|
|||||||
val offsetRot = offset.rotate(rotation)
|
val offsetRot = offset.rotate(rotation)
|
||||||
val key = getColumnKey(state(offsetRot))
|
val key = getColumnKey(state(offsetRot))
|
||||||
return if (key == null) {
|
return if (key == null) {
|
||||||
if (offset(offsetRot).isNormalCube) SOLID else NONSOLID
|
if (offset(offsetRot).isFullBlock) SOLID else NONSOLID
|
||||||
} else {
|
} else {
|
||||||
(key.axis ?: if (Config.roundLogs.defaultY) Axis.Y else null)?.let {
|
(key.axis ?: if (Config.roundLogs.defaultY) Axis.Y else null)?.let {
|
||||||
if (it == axis) PARALLEL else PERPENDICULAR
|
if (it == axis) PARALLEL else PERPENDICULAR
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ import net.minecraft.block.BlockState
|
|||||||
import net.minecraft.client.renderer.BlockModelRenderer
|
import net.minecraft.client.renderer.BlockModelRenderer
|
||||||
import net.minecraft.util.Direction
|
import net.minecraft.util.Direction
|
||||||
import net.minecraft.util.math.BlockPos
|
import net.minecraft.util.math.BlockPos
|
||||||
import net.minecraft.world.ILightReader
|
import net.minecraft.world.IBlockDisplayReader
|
||||||
|
|
||||||
data class LightingData(
|
data class LightingData(
|
||||||
@JvmField var packedLight: Int = 0,
|
@JvmField var packedLight: Int = 0,
|
||||||
@@ -29,7 +29,7 @@ data class LightingData(
|
|||||||
* Not thread-safe, always use a [ThreadLocal] instance
|
* Not thread-safe, always use a [ThreadLocal] instance
|
||||||
*/
|
*/
|
||||||
class VanillaAoCalculator {
|
class VanillaAoCalculator {
|
||||||
lateinit var world: ILightReader
|
lateinit var world: IBlockDisplayReader
|
||||||
|
|
||||||
/** [blockPos] is used to get block-related information (i.e. tint, opacity, etc.)
|
/** [blockPos] is used to get block-related information (i.e. tint, opacity, etc.)
|
||||||
* [lightPos] is used to get light-related information
|
* [lightPos] is used to get light-related information
|
||||||
@@ -37,7 +37,7 @@ class VanillaAoCalculator {
|
|||||||
lateinit var blockPos: BlockPos
|
lateinit var blockPos: BlockPos
|
||||||
lateinit var lightPos: BlockPos
|
lateinit var lightPos: BlockPos
|
||||||
|
|
||||||
private val probe = LightProbe(BlockModelRenderer.CACHE_COMBINED_LIGHT.get())
|
private val probe = LightProbe(BlockModelRenderer.CACHE.get())
|
||||||
|
|
||||||
val isValid = BooleanArray(6)
|
val isValid = BooleanArray(6)
|
||||||
val aoData = Array(24) { LightingData() }
|
val aoData = Array(24) { LightingData() }
|
||||||
@@ -70,13 +70,13 @@ class VanillaAoCalculator {
|
|||||||
|
|
||||||
// Bit 0 of the bitset in vanilla calculations
|
// Bit 0 of the bitset in vanilla calculations
|
||||||
// true if the block model is planar with the block boundary
|
// true if the block model is planar with the block boundary
|
||||||
val isFullBlock = forceFull ?: world.getBlockState(blockPos).isCollisionShapeOpaque(world, blockPos)
|
val isFullBlock = forceFull ?: world.getBlockState(blockPos).isCollisionShapeFullBlock(world, blockPos)
|
||||||
|
|
||||||
val lightOrigin = if (isFullBlock) lightPos.offset(lightFace) else lightPos
|
val lightOrigin = if (isFullBlock) lightPos.relative(lightFace) else lightPos
|
||||||
|
|
||||||
// AO calculation for the face center
|
// AO calculation for the face center
|
||||||
probe.position { setPos(lightOrigin) }.writeTo(centerAo)
|
probe.position { set(lightOrigin) }.writeTo(centerAo)
|
||||||
if (!isFullBlock && !probe.position { move(lightFace) }.state.isOpaqueCube(world, probe.pos)) {
|
if (!isFullBlock && !probe.position { move(lightFace) }.state.isSolidRender(world, probe.pos)) {
|
||||||
// if the neighboring block in the lightface direction is
|
// if the neighboring block in the lightface direction is
|
||||||
// transparent (non-opaque), use its packed light instead of our own
|
// transparent (non-opaque), use its packed light instead of our own
|
||||||
// (if our block is a full block, we are already using this value)
|
// (if our block is a full block, we are already using this value)
|
||||||
@@ -86,7 +86,7 @@ class VanillaAoCalculator {
|
|||||||
// AO calculation for the 4 sides
|
// AO calculation for the 4 sides
|
||||||
sideHelper.sides.forEachIndexed { sideIdx, sideDir ->
|
sideHelper.sides.forEachIndexed { sideIdx, sideDir ->
|
||||||
// record light data in the block 1 step to the side
|
// record light data in the block 1 step to the side
|
||||||
probe.position { setPos(lightOrigin).move(sideDir) }.writeTo(sideAo[sideIdx])
|
probe.position { set(lightOrigin).move(sideDir) }.writeTo(sideAo[sideIdx])
|
||||||
// side is considered occluded if the block 1 step to that side and
|
// side is considered occluded if the block 1 step to that side and
|
||||||
// 1 step forward (in the lightface direction) is not fully transparent
|
// 1 step forward (in the lightface direction) is not fully transparent
|
||||||
isOccluded[sideIdx] = probe.position { move(lightFace) }.isNonTransparent
|
isOccluded[sideIdx] = probe.position { move(lightFace) }.isNonTransparent
|
||||||
@@ -103,7 +103,7 @@ class VanillaAoCalculator {
|
|||||||
else {
|
else {
|
||||||
// lookup actual packed light from the cornering block in the world
|
// lookup actual packed light from the cornering block in the world
|
||||||
probe.position {
|
probe.position {
|
||||||
setPos(lightOrigin)
|
set(lightOrigin)
|
||||||
.move(sideHelper.sides[sideIndices.first])
|
.move(sideHelper.sides[sideIndices.first])
|
||||||
.move(sideHelper.sides[sideIndices.second])
|
.move(sideHelper.sides[sideIndices.second])
|
||||||
}.writeTo(cornerAo[cornerIdx])
|
}.writeTo(cornerAo[cornerIdx])
|
||||||
@@ -129,9 +129,9 @@ class VanillaAoCalculator {
|
|||||||
lateinit var state: BlockState
|
lateinit var state: BlockState
|
||||||
val pos = BlockPos.Mutable()
|
val pos = BlockPos.Mutable()
|
||||||
|
|
||||||
val packedLight: Int get() = cache.getPackedLight(state, world, pos)
|
val packedLight: Int get() = cache.getLightColor(state, world, pos)
|
||||||
val colorMultiplier: Float get() = cache.getBrightness(state, world, pos)
|
val colorMultiplier: Float get() = cache.getShadeBrightness(state, world, pos)
|
||||||
val isNonTransparent: Boolean get() = state.getOpacity(world, pos) > 0
|
val isNonTransparent: Boolean get() = state.getLightBlock(world, pos) > 0
|
||||||
|
|
||||||
fun writeTo(data: LightingData) {
|
fun writeTo(data: LightingData) {
|
||||||
data.packedLight = packedLight
|
data.packedLight = packedLight
|
||||||
|
|||||||
@@ -69,7 +69,7 @@ object VanillaFullBlockLighting : VanillaVertexLighter() {
|
|||||||
lighting.calc.fillLightData(face, true)
|
lighting.calc.fillLightData(face, true)
|
||||||
lighting.updateWithCornerAo(quad) { nearestCornerOnFace(it, face) }
|
lighting.updateWithCornerAo(quad) { nearestCornerOnFace(it, face) }
|
||||||
lighting.updateBlockTint(quad.baked.tintIndex)
|
lighting.updateBlockTint(quad.baked.tintIndex)
|
||||||
if (quad.baked.shouldApplyDiffuseLighting()) lighting.applyDiffuseLighting(face)
|
if (quad.baked.isShade) lighting.applyDiffuseLighting(face)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -5,12 +5,12 @@ import mods.betterfoliage.util.Double3
|
|||||||
import net.minecraft.client.Minecraft
|
import net.minecraft.client.Minecraft
|
||||||
import net.minecraft.client.particle.SpriteTexturedParticle
|
import net.minecraft.client.particle.SpriteTexturedParticle
|
||||||
import net.minecraft.client.renderer.ActiveRenderInfo
|
import net.minecraft.client.renderer.ActiveRenderInfo
|
||||||
import net.minecraft.client.renderer.Vector3f
|
|
||||||
import net.minecraft.client.renderer.texture.TextureAtlasSprite
|
import net.minecraft.client.renderer.texture.TextureAtlasSprite
|
||||||
|
import net.minecraft.client.world.ClientWorld
|
||||||
import net.minecraft.util.math.MathHelper
|
import net.minecraft.util.math.MathHelper
|
||||||
import net.minecraft.world.World
|
import net.minecraft.util.math.vector.Vector3f
|
||||||
|
|
||||||
abstract class AbstractParticle(world: World, x: Double, y: Double, z: Double) : SpriteTexturedParticle(world, x, y, z) {
|
abstract class AbstractParticle(world: ClientWorld, x: Double, y: Double, z: Double) : SpriteTexturedParticle(world, x, y, z) {
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
// @JvmStatic val sin = Array(64) { idx -> Math.sin(PI2 / 64.0 * idx) }
|
// @JvmStatic val sin = Array(64) { idx -> Math.sin(PI2 / 64.0 * idx) }
|
||||||
@@ -24,12 +24,12 @@ abstract class AbstractParticle(world: World, x: Double, y: Double, z: Double) :
|
|||||||
|
|
||||||
override fun tick() {
|
override fun tick() {
|
||||||
super.tick()
|
super.tick()
|
||||||
currentPos.setTo(posX, posY, posZ)
|
currentPos.setTo(x, y, z)
|
||||||
prevPos.setTo(prevPosX, prevPosY, prevPosZ)
|
prevPos.setTo(xo, yo, zo)
|
||||||
velocity.setTo(motionX, motionY, motionZ)
|
velocity.setTo(xd, yd, zd)
|
||||||
update()
|
update()
|
||||||
posX = currentPos.x; posY = currentPos.y; posZ = currentPos.z;
|
x = currentPos.x; y = currentPos.y; z = currentPos.z;
|
||||||
motionX = velocity.x; motionY = velocity.y; motionZ = velocity.z;
|
xd = velocity.x; yd = velocity.y; zd = velocity.z;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Update particle on world tick. */
|
/** Update particle on world tick. */
|
||||||
@@ -39,10 +39,10 @@ abstract class AbstractParticle(world: World, x: Double, y: Double, z: Double) :
|
|||||||
abstract val isValid: Boolean
|
abstract val isValid: Boolean
|
||||||
|
|
||||||
/** Add the particle to the effect renderer if it is valid. */
|
/** Add the particle to the effect renderer if it is valid. */
|
||||||
fun addIfValid() { if (isValid) Minecraft.getInstance().particles.addEffect(this) }
|
fun addIfValid() { if (isValid) Minecraft.getInstance().particleEngine.add(this) }
|
||||||
|
|
||||||
override fun renderParticle(vertexBuilder: IVertexBuilder, camera: ActiveRenderInfo, tickDelta: Float) {
|
override fun render(vertexBuilder: IVertexBuilder, camera: ActiveRenderInfo, tickDelta: Float) {
|
||||||
super.renderParticle(vertexBuilder, camera, tickDelta)
|
super.render(vertexBuilder, camera, tickDelta)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -63,39 +63,39 @@ abstract class AbstractParticle(world: World, x: Double, y: Double, z: Double) :
|
|||||||
tickDelta: Float,
|
tickDelta: Float,
|
||||||
currentPos: Double3 = this.currentPos,
|
currentPos: Double3 = this.currentPos,
|
||||||
prevPos: Double3 = this.prevPos,
|
prevPos: Double3 = this.prevPos,
|
||||||
size: Double = particleScale.toDouble(),
|
size: Double = quadSize.toDouble(),
|
||||||
currentAngle: Float = this.particleAngle,
|
currentAngle: Float = this.roll,
|
||||||
prevAngle: Float = this.prevParticleAngle,
|
prevAngle: Float = this.oRoll,
|
||||||
sprite: TextureAtlasSprite = this.sprite,
|
sprite: TextureAtlasSprite = this.sprite,
|
||||||
alpha: Float = this.particleAlpha) {
|
alpha: Float = this.alpha) {
|
||||||
|
|
||||||
val center = Double3.lerp(tickDelta.toDouble(), prevPos, currentPos)
|
val center = Double3.lerp(tickDelta.toDouble(), prevPos, currentPos)
|
||||||
val angle = MathHelper.lerp(tickDelta, prevAngle, currentAngle)
|
val angle = MathHelper.lerp(tickDelta, prevAngle, currentAngle)
|
||||||
val rotation = camera.rotation.copy().apply { multiply(Vector3f.ZP.rotation(angle)) }
|
val rotation = camera.rotation().copy().apply { mul(Vector3f.ZP.rotation(angle)) }
|
||||||
val lightmapCoord = getBrightnessForRender(tickDelta)
|
val lightmapCoord = getLightColor(tickDelta)
|
||||||
|
|
||||||
val coords = arrayOf(
|
val coords = arrayOf(
|
||||||
Double3(-1.0, -1.0, 0.0),
|
Double3(-1.0, -1.0, 0.0),
|
||||||
Double3(-1.0, 1.0, 0.0),
|
Double3(-1.0, 1.0, 0.0),
|
||||||
Double3(1.0, 1.0, 0.0),
|
Double3(1.0, 1.0, 0.0),
|
||||||
Double3(1.0, -1.0, 0.0)
|
Double3(1.0, -1.0, 0.0)
|
||||||
).map { it.rotate(rotation).mul(size).add(center).sub(camera.projectedView.x, camera.projectedView.y, camera.projectedView.z) }
|
).map { it.rotate(rotation).mul(size).add(center).sub(camera.position.x, camera.position.y, camera.position.z) }
|
||||||
|
|
||||||
fun renderVertex(vertex: Double3, u: Float, v: Float) = vertexConsumer
|
fun renderVertex(vertex: Double3, u: Float, v: Float) = vertexConsumer
|
||||||
.pos(vertex.x, vertex.y, vertex.z).tex(u, v)
|
.vertex(vertex.x, vertex.y, vertex.z).uv(u, v)
|
||||||
.color(particleRed, particleGreen, particleBlue, alpha).lightmap(lightmapCoord)
|
.color(rCol, gCol, bCol, alpha).uv2(lightmapCoord)
|
||||||
.endVertex()
|
.endVertex()
|
||||||
|
|
||||||
renderVertex(coords[0], sprite.maxU, sprite.maxV)
|
renderVertex(coords[0], sprite.u1, sprite.v1)
|
||||||
renderVertex(coords[1], sprite.maxU, sprite.minV)
|
renderVertex(coords[1], sprite.u1, sprite.v0)
|
||||||
renderVertex(coords[2], sprite.minU, sprite.minV)
|
renderVertex(coords[2], sprite.u0, sprite.v0)
|
||||||
renderVertex(coords[3], sprite.minU, sprite.maxV)
|
renderVertex(coords[3], sprite.u0, sprite.v1)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun setColor(color: Int) {
|
fun setColor(color: Int) {
|
||||||
particleBlue = (color and 255) / 256.0f
|
bCol = (color and 255) / 256.0f
|
||||||
particleGreen = ((color shr 8) and 255) / 256.0f
|
gCol = ((color shr 8) and 255) / 256.0f
|
||||||
particleRed = ((color shr 16) and 255) / 256.0f
|
rCol = ((color shr 16) and 255) / 256.0f
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -8,22 +8,22 @@ import mods.betterfoliage.util.randomB
|
|||||||
import mods.betterfoliage.util.randomD
|
import mods.betterfoliage.util.randomD
|
||||||
import mods.betterfoliage.util.randomF
|
import mods.betterfoliage.util.randomF
|
||||||
import mods.betterfoliage.util.randomI
|
import mods.betterfoliage.util.randomI
|
||||||
import net.minecraft.client.Minecraft
|
|
||||||
import net.minecraft.client.particle.IParticleRenderType
|
import net.minecraft.client.particle.IParticleRenderType
|
||||||
|
import net.minecraft.client.world.ClientWorld
|
||||||
import net.minecraft.util.math.BlockPos
|
import net.minecraft.util.math.BlockPos
|
||||||
import net.minecraft.util.math.MathHelper
|
import net.minecraft.util.math.MathHelper
|
||||||
import net.minecraft.world.World
|
import net.minecraft.world.World
|
||||||
import net.minecraftforge.common.MinecraftForge
|
import net.minecraftforge.common.MinecraftForge
|
||||||
import net.minecraftforge.event.TickEvent
|
import net.minecraftforge.event.TickEvent
|
||||||
import net.minecraftforge.event.world.WorldEvent
|
|
||||||
import net.minecraftforge.eventbus.api.SubscribeEvent
|
import net.minecraftforge.eventbus.api.SubscribeEvent
|
||||||
|
import net.minecraftforge.fml.LogicalSide
|
||||||
import java.util.Random
|
import java.util.Random
|
||||||
import kotlin.math.abs
|
import kotlin.math.abs
|
||||||
import kotlin.math.cos
|
import kotlin.math.cos
|
||||||
import kotlin.math.sin
|
import kotlin.math.sin
|
||||||
|
|
||||||
class FallingLeafParticle(
|
class FallingLeafParticle(
|
||||||
world: World, pos: BlockPos, leaf: LeafParticleKey, blockColor: Int, random: Random
|
world: ClientWorld, pos: BlockPos, leaf: LeafParticleKey, blockColor: Int, random: Random
|
||||||
) : AbstractParticle(
|
) : AbstractParticle(
|
||||||
world, pos.x.toDouble() + 0.5, pos.y.toDouble(), pos.z.toDouble() + 0.5
|
world, pos.x.toDouble() + 0.5, pos.y.toDouble(), pos.z.toDouble() + 0.5
|
||||||
) {
|
) {
|
||||||
@@ -37,13 +37,13 @@ class FallingLeafParticle(
|
|||||||
var wasCollided = false
|
var wasCollided = false
|
||||||
|
|
||||||
init {
|
init {
|
||||||
particleAngle = random.randomF(max = PI2)
|
roll = random.randomF(max = PI2)
|
||||||
prevParticleAngle = particleAngle - rotationSpeed
|
oRoll = roll - rotationSpeed
|
||||||
|
|
||||||
maxAge = MathHelper.floor(randomD(0.6, 1.0) * Config.fallingLeaves.lifetime * 20.0)
|
lifetime = MathHelper.floor(randomD(0.6, 1.0) * Config.fallingLeaves.lifetime * 20.0)
|
||||||
motionY = -Config.fallingLeaves.speed
|
yd = -Config.fallingLeaves.speed
|
||||||
|
|
||||||
particleScale = Config.fallingLeaves.size.toFloat() * 0.1f
|
quadSize = Config.fallingLeaves.size.toFloat() * 0.1f
|
||||||
setColor(leaf.overrideColor?.asInt ?: blockColor)
|
setColor(leaf.overrideColor?.asInt ?: blockColor)
|
||||||
sprite = LeafParticleRegistry[leaf.leafType][randomI(max = 1024)]
|
sprite = LeafParticleRegistry[leaf.leafType][randomI(max = 1024)]
|
||||||
}
|
}
|
||||||
@@ -52,21 +52,21 @@ class FallingLeafParticle(
|
|||||||
|
|
||||||
|
|
||||||
override fun update() {
|
override fun update() {
|
||||||
if (rand.nextFloat() > 0.95f) rotationSpeed *= -1.0f
|
if (random.nextFloat() > 0.95f) rotationSpeed *= -1.0f
|
||||||
if (age > maxAge - 20) particleAlpha = 0.05f * (maxAge - age)
|
if (age > lifetime - 20) alpha = 0.05f * (lifetime - age)
|
||||||
|
|
||||||
if (onGround || wasCollided) {
|
if (onGround || wasCollided) {
|
||||||
velocity.setTo(0.0, 0.0, 0.0)
|
velocity.setTo(0.0, 0.0, 0.0)
|
||||||
if (!wasCollided) {
|
if (!wasCollided) {
|
||||||
age = age.coerceAtLeast(maxAge - 20)
|
age = age.coerceAtLeast(lifetime - 20)
|
||||||
wasCollided = true
|
wasCollided = true
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
val cosRotation = cos(particleAngle).toDouble(); val sinRotation = sin(particleAngle).toDouble()
|
val cosRotation = cos(roll).toDouble(); val sinRotation = sin(roll).toDouble()
|
||||||
velocity.setTo(cosRotation, 0.0, sinRotation).mul(Config.fallingLeaves.perturb)
|
velocity.setTo(cosRotation, 0.0, sinRotation).mul(Config.fallingLeaves.perturb)
|
||||||
.add(LeafWindTracker.current).add(0.0, -1.0, 0.0).mul(Config.fallingLeaves.speed)
|
.add(LeafWindTracker.current).add(0.0, -1.0, 0.0).mul(Config.fallingLeaves.speed)
|
||||||
prevParticleAngle = particleAngle
|
oRoll = roll
|
||||||
particleAngle += rotationSpeed
|
roll += rotationSpeed
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -84,7 +84,7 @@ object LeafWindTracker {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun changeWind(world: World) {
|
fun changeWind(world: World) {
|
||||||
nextChange = world.worldInfo.gameTime + 120 + random.nextInt(80)
|
nextChange = world.gameTime + 120 + random.nextInt(80)
|
||||||
val direction = PI2 * random.nextDouble()
|
val direction = PI2 * random.nextDouble()
|
||||||
val speed = abs(random.nextGaussian()) * Config.fallingLeaves.windStrength +
|
val speed = abs(random.nextGaussian()) * Config.fallingLeaves.windStrength +
|
||||||
(if (!world.isRaining) 0.0 else abs(random.nextGaussian()) * Config.fallingLeaves.stormStrength)
|
(if (!world.isRaining) 0.0 else abs(random.nextGaussian()) * Config.fallingLeaves.stormStrength)
|
||||||
@@ -92,10 +92,10 @@ object LeafWindTracker {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@SubscribeEvent
|
@SubscribeEvent
|
||||||
fun handleWorldTick(event: TickEvent.ClientTickEvent) {
|
fun handleWorldTick(event: TickEvent.WorldTickEvent) {
|
||||||
if (event.phase == TickEvent.Phase.START) Minecraft.getInstance().world?.let { world ->
|
if (event.phase == TickEvent.Phase.START && event.side == LogicalSide.CLIENT) event.world.let { world ->
|
||||||
// change target wind speed
|
// change target wind speed
|
||||||
if (world.worldInfo.dayTime >= nextChange) changeWind(world)
|
if (world.dayTime >= nextChange) changeWind(world)
|
||||||
|
|
||||||
// change current wind speed
|
// change current wind speed
|
||||||
val changeRate = if (world.isRaining) 0.015 else 0.005
|
val changeRate = if (world.isRaining) 0.015 else 0.005
|
||||||
@@ -107,6 +107,6 @@ object LeafWindTracker {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@SubscribeEvent
|
// @SubscribeEvent
|
||||||
fun handleWorldLoad(event: WorldEvent.Load) { if (event.world.isRemote) changeWind(event.world.world) }
|
// fun handleWorldLoad(event: WorldEvent.Load) { if (event.world.isClientSide) changeWind(event.world) }
|
||||||
}
|
}
|
||||||
@@ -41,7 +41,7 @@ object LeafParticleRegistry : HasLogger(), VeryEarlyReloadListener {
|
|||||||
|
|
||||||
@SubscribeEvent
|
@SubscribeEvent
|
||||||
fun handlePreStitch(event: TextureStitchEvent.Pre) {
|
fun handlePreStitch(event: TextureStitchEvent.Pre) {
|
||||||
if (event.map.textureLocation == Atlas.PARTICLES.resourceId) {
|
if (event.map.location() == Atlas.PARTICLES.resourceId) {
|
||||||
allTypes.forEach { leafType ->
|
allTypes.forEach { leafType ->
|
||||||
val locations = (0 until 16).map { idx ->
|
val locations = (0 until 16).map { idx ->
|
||||||
ResourceLocation(BetterFoliageMod.MOD_ID, "particle/falling_leaf_${leafType}_$idx")
|
ResourceLocation(BetterFoliageMod.MOD_ID, "particle/falling_leaf_${leafType}_$idx")
|
||||||
@@ -55,7 +55,7 @@ object LeafParticleRegistry : HasLogger(), VeryEarlyReloadListener {
|
|||||||
|
|
||||||
@SubscribeEvent
|
@SubscribeEvent
|
||||||
fun handlePostStitch(event: TextureStitchEvent.Post) {
|
fun handlePostStitch(event: TextureStitchEvent.Post) {
|
||||||
if (event.map.textureLocation == Atlas.PARTICLES.resourceId) {
|
if (event.map.location() == Atlas.PARTICLES.resourceId) {
|
||||||
(typeMappings.mappings.map { it.type } + "default").distinct().forEach { leafType ->
|
(typeMappings.mappings.map { it.type } + "default").distinct().forEach { leafType ->
|
||||||
val sprites = (0 until 16).map { idx ->
|
val sprites = (0 until 16).map { idx ->
|
||||||
ResourceLocation(BetterFoliageMod.MOD_ID, "particle/falling_leaf_${leafType}_$idx")
|
ResourceLocation(BetterFoliageMod.MOD_ID, "particle/falling_leaf_${leafType}_$idx")
|
||||||
|
|||||||
@@ -13,6 +13,7 @@ import mods.betterfoliage.util.randomD
|
|||||||
import mods.betterfoliage.util.randomI
|
import mods.betterfoliage.util.randomI
|
||||||
import net.minecraft.client.particle.IParticleRenderType
|
import net.minecraft.client.particle.IParticleRenderType
|
||||||
import net.minecraft.client.renderer.ActiveRenderInfo
|
import net.minecraft.client.renderer.ActiveRenderInfo
|
||||||
|
import net.minecraft.client.world.ClientWorld
|
||||||
import net.minecraft.util.ResourceLocation
|
import net.minecraft.util.ResourceLocation
|
||||||
import net.minecraft.util.math.BlockPos
|
import net.minecraft.util.math.BlockPos
|
||||||
import net.minecraft.util.math.MathHelper
|
import net.minecraft.util.math.MathHelper
|
||||||
@@ -23,7 +24,7 @@ import kotlin.math.cos
|
|||||||
import kotlin.math.sin
|
import kotlin.math.sin
|
||||||
|
|
||||||
class RisingSoulParticle(
|
class RisingSoulParticle(
|
||||||
world: World, pos: BlockPos
|
world: ClientWorld, pos: BlockPos
|
||||||
) : AbstractParticle(
|
) : AbstractParticle(
|
||||||
world, pos.x.toDouble() + 0.5, pos.y.toDouble() + 1.0, pos.z.toDouble() + 0.5
|
world, pos.x.toDouble() + 0.5, pos.y.toDouble() + 1.0, pos.z.toDouble() + 0.5
|
||||||
) {
|
) {
|
||||||
@@ -32,10 +33,10 @@ class RisingSoulParticle(
|
|||||||
val initialPhase = randomD(max = PI2)
|
val initialPhase = randomD(max = PI2)
|
||||||
|
|
||||||
init {
|
init {
|
||||||
motionY = 0.1
|
yd = 0.1
|
||||||
particleGravity = 0.0f
|
gravity = 0.0f
|
||||||
sprite = headIcons[randomI(max = 1024)]
|
sprite = headIcons[randomI(max = 1024)]
|
||||||
maxAge = MathHelper.floor((0.6 + 0.4 * randomD()) * Config.risingSoul.lifetime * 20.0)
|
lifetime = MathHelper.floor((0.6 + 0.4 * randomD()) * Config.risingSoul.lifetime * 20.0)
|
||||||
}
|
}
|
||||||
|
|
||||||
override val isValid: Boolean get() = true
|
override val isValid: Boolean get() = true
|
||||||
@@ -49,12 +50,12 @@ class RisingSoulParticle(
|
|||||||
particleTrail.addFirst(currentPos.copy())
|
particleTrail.addFirst(currentPos.copy())
|
||||||
while (particleTrail.size > Config.risingSoul.trailLength) particleTrail.removeLast()
|
while (particleTrail.size > Config.risingSoul.trailLength) particleTrail.removeLast()
|
||||||
|
|
||||||
if (!Config.enabled) setExpired()
|
if (!Config.enabled) remove()
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun renderParticle(vertexBuilder: IVertexBuilder, camera: ActiveRenderInfo, tickDelta: Float) {
|
override fun render(vertexBuilder: IVertexBuilder, camera: ActiveRenderInfo, tickDelta: Float) {
|
||||||
var alpha = Config.risingSoul.opacity.toFloat()
|
var alpha = Config.risingSoul.opacity.toFloat()
|
||||||
if (age > maxAge - 40) alpha *= (maxAge - age) / 40.0f
|
if (age > lifetime - 40) alpha *= (lifetime - age) / 40.0f
|
||||||
|
|
||||||
renderParticleQuad(
|
renderParticleQuad(
|
||||||
vertexBuilder, camera, tickDelta,
|
vertexBuilder, camera, tickDelta,
|
||||||
|
|||||||
@@ -3,18 +3,18 @@ package mods.betterfoliage.render.pipeline
|
|||||||
import com.mojang.blaze3d.matrix.MatrixStack
|
import com.mojang.blaze3d.matrix.MatrixStack
|
||||||
import mods.betterfoliage.chunk.BasicBlockCtx
|
import mods.betterfoliage.chunk.BasicBlockCtx
|
||||||
import mods.betterfoliage.chunk.BlockCtx
|
import mods.betterfoliage.chunk.BlockCtx
|
||||||
|
import mods.betterfoliage.model.HalfBakedQuad
|
||||||
import mods.betterfoliage.model.SpecialRenderModel
|
import mods.betterfoliage.model.SpecialRenderModel
|
||||||
import mods.betterfoliage.render.lighting.VanillaFullBlockLighting
|
import mods.betterfoliage.render.lighting.VanillaFullBlockLighting
|
||||||
import mods.betterfoliage.render.lighting.VanillaQuadLighting
|
import mods.betterfoliage.render.lighting.VanillaQuadLighting
|
||||||
import mods.betterfoliage.render.lighting.VanillaVertexLighter
|
import mods.betterfoliage.render.lighting.VanillaVertexLighter
|
||||||
import mods.betterfoliage.model.HalfBakedQuad
|
|
||||||
import mods.betterfoliage.util.Int3
|
import mods.betterfoliage.util.Int3
|
||||||
import mods.betterfoliage.util.plus
|
import mods.betterfoliage.util.plus
|
||||||
import net.minecraft.block.Block
|
import net.minecraft.block.Block
|
||||||
import net.minecraft.client.Minecraft
|
import net.minecraft.client.Minecraft
|
||||||
import net.minecraft.util.Direction
|
import net.minecraft.util.Direction
|
||||||
import net.minecraft.util.math.BlockPos
|
import net.minecraft.util.math.BlockPos
|
||||||
import net.minecraft.world.ILightReader
|
import net.minecraft.world.IBlockDisplayReader
|
||||||
import net.minecraftforge.client.model.data.IModelData
|
import net.minecraftforge.client.model.data.IModelData
|
||||||
import java.util.Random
|
import java.util.Random
|
||||||
|
|
||||||
@@ -25,7 +25,7 @@ import java.util.Random
|
|||||||
* push-based partial rendering pipeline for [SpecialRenderModel] instances.
|
* push-based partial rendering pipeline for [SpecialRenderModel] instances.
|
||||||
*/
|
*/
|
||||||
abstract class RenderCtxBase(
|
abstract class RenderCtxBase(
|
||||||
world: ILightReader,
|
world: IBlockDisplayReader,
|
||||||
pos: BlockPos,
|
pos: BlockPos,
|
||||||
val matrixStack: MatrixStack,
|
val matrixStack: MatrixStack,
|
||||||
var checkSides: Boolean,
|
var checkSides: Boolean,
|
||||||
@@ -36,14 +36,14 @@ abstract class RenderCtxBase(
|
|||||||
abstract fun renderQuad(quad: HalfBakedQuad)
|
abstract fun renderQuad(quad: HalfBakedQuad)
|
||||||
|
|
||||||
var hasRendered = false
|
var hasRendered = false
|
||||||
val blockModelShapes = Minecraft.getInstance().blockRendererDispatcher.blockModelShapes
|
val blockModelShapes = Minecraft.getInstance().blockRenderer.blockModelShaper
|
||||||
var vertexLighter: VanillaVertexLighter = VanillaFullBlockLighting
|
var vertexLighter: VanillaVertexLighter = VanillaFullBlockLighting
|
||||||
protected val lightingData = RenderCtxBase.lightingData.get().apply {
|
protected val lightingData = RenderCtxBase.lightingData.get().apply {
|
||||||
calc.reset(this@RenderCtxBase)
|
calc.reset(this@RenderCtxBase)
|
||||||
blockColors = Minecraft.getInstance().blockColors
|
blockColors = Minecraft.getInstance().blockColors
|
||||||
}
|
}
|
||||||
|
|
||||||
inline fun Direction?.shouldRender() = this == null || !checkSides || Block.shouldSideBeRendered(state, world, pos, this)
|
inline fun Direction?.shouldRender() = this == null || !checkSides || Block.shouldRenderFace(state, world, pos, this)
|
||||||
|
|
||||||
fun renderQuads(quads: Iterable<HalfBakedQuad>) {
|
fun renderQuads(quads: Iterable<HalfBakedQuad>) {
|
||||||
quads.forEach { quad ->
|
quads.forEach { quad ->
|
||||||
|
|||||||
@@ -1,20 +1,20 @@
|
|||||||
package mods.betterfoliage.render.pipeline
|
package mods.betterfoliage.render.pipeline
|
||||||
|
|
||||||
import com.mojang.blaze3d.matrix.MatrixStack
|
import com.mojang.blaze3d.matrix.MatrixStack
|
||||||
|
import mods.betterfoliage.model.HalfBakedQuad
|
||||||
import mods.betterfoliage.model.SpecialRenderModel
|
import mods.betterfoliage.model.SpecialRenderModel
|
||||||
import mods.betterfoliage.render.lighting.ForgeVertexLighter
|
import mods.betterfoliage.render.lighting.ForgeVertexLighter
|
||||||
import mods.betterfoliage.render.lighting.ForgeVertexLighterAccess
|
import mods.betterfoliage.render.lighting.ForgeVertexLighterAccess
|
||||||
import mods.betterfoliage.model.HalfBakedQuad
|
|
||||||
import net.minecraft.block.BlockState
|
import net.minecraft.block.BlockState
|
||||||
import net.minecraft.client.renderer.LightTexture
|
import net.minecraft.client.renderer.LightTexture
|
||||||
import net.minecraft.util.math.BlockPos
|
import net.minecraft.util.math.BlockPos
|
||||||
import net.minecraft.world.ILightReader
|
import net.minecraft.world.IBlockDisplayReader
|
||||||
import net.minecraftforge.client.model.data.IModelData
|
import net.minecraftforge.client.model.data.IModelData
|
||||||
import net.minecraftforge.client.model.pipeline.VertexLighterFlat
|
import net.minecraftforge.client.model.pipeline.VertexLighterFlat
|
||||||
import java.util.Random
|
import java.util.Random
|
||||||
|
|
||||||
class RenderCtxForge(
|
class RenderCtxForge(
|
||||||
world: ILightReader,
|
world: IBlockDisplayReader,
|
||||||
pos: BlockPos,
|
pos: BlockPos,
|
||||||
val lighter: VertexLighterFlat,
|
val lighter: VertexLighterFlat,
|
||||||
matrixStack: MatrixStack,
|
matrixStack: MatrixStack,
|
||||||
@@ -33,8 +33,8 @@ class RenderCtxForge(
|
|||||||
var vIdx = 0
|
var vIdx = 0
|
||||||
override fun updateVertexLightmap(normal: FloatArray, lightmap: FloatArray, x: Float, y: Float, z: Float) {
|
override fun updateVertexLightmap(normal: FloatArray, lightmap: FloatArray, x: Float, y: Float, z: Float) {
|
||||||
lightingData.packedLight[vIdx].let { packedLight ->
|
lightingData.packedLight[vIdx].let { packedLight ->
|
||||||
lightmap[0] = LightTexture.getLightBlock(packedLight) / 0xF.toFloat()
|
lightmap[0] = LightTexture.block(packedLight) / 0xF.toFloat()
|
||||||
lightmap[1] = LightTexture.getLightSky(packedLight) / 0xF.toFloat()
|
lightmap[1] = LightTexture.sky(packedLight) / 0xF.toFloat()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -49,7 +49,7 @@ class RenderCtxForge(
|
|||||||
@JvmStatic
|
@JvmStatic
|
||||||
fun render(
|
fun render(
|
||||||
lighter: VertexLighterFlat,
|
lighter: VertexLighterFlat,
|
||||||
world: ILightReader,
|
world: IBlockDisplayReader,
|
||||||
model: SpecialRenderModel,
|
model: SpecialRenderModel,
|
||||||
state: BlockState,
|
state: BlockState,
|
||||||
pos: BlockPos,
|
pos: BlockPos,
|
||||||
|
|||||||
@@ -2,18 +2,18 @@ package mods.betterfoliage.render.pipeline
|
|||||||
|
|
||||||
import com.mojang.blaze3d.matrix.MatrixStack
|
import com.mojang.blaze3d.matrix.MatrixStack
|
||||||
import com.mojang.blaze3d.vertex.IVertexBuilder
|
import com.mojang.blaze3d.vertex.IVertexBuilder
|
||||||
import mods.betterfoliage.model.SpecialRenderModel
|
|
||||||
import mods.betterfoliage.model.HalfBakedQuad
|
import mods.betterfoliage.model.HalfBakedQuad
|
||||||
|
import mods.betterfoliage.model.SpecialRenderModel
|
||||||
import net.minecraft.block.BlockState
|
import net.minecraft.block.BlockState
|
||||||
import net.minecraft.client.renderer.BlockModelRenderer
|
import net.minecraft.client.renderer.BlockModelRenderer
|
||||||
import net.minecraft.util.math.BlockPos
|
import net.minecraft.util.math.BlockPos
|
||||||
import net.minecraft.world.ILightReader
|
import net.minecraft.world.IBlockDisplayReader
|
||||||
import net.minecraftforge.client.model.data.IModelData
|
import net.minecraftforge.client.model.data.IModelData
|
||||||
import java.util.Random
|
import java.util.Random
|
||||||
|
|
||||||
class RenderCtxVanilla(
|
class RenderCtxVanilla(
|
||||||
val renderer: BlockModelRenderer,
|
val renderer: BlockModelRenderer,
|
||||||
world: ILightReader,
|
world: IBlockDisplayReader,
|
||||||
pos: BlockPos,
|
pos: BlockPos,
|
||||||
val buffer: IVertexBuilder,
|
val buffer: IVertexBuilder,
|
||||||
val combinedOverlay: Int,
|
val combinedOverlay: Int,
|
||||||
@@ -27,8 +27,8 @@ class RenderCtxVanilla(
|
|||||||
|
|
||||||
override fun renderQuad(quad: HalfBakedQuad) {
|
override fun renderQuad(quad: HalfBakedQuad) {
|
||||||
vertexLighter.updateLightmapAndColor(quad, lightingData)
|
vertexLighter.updateLightmapAndColor(quad, lightingData)
|
||||||
buffer.addQuad(
|
buffer.putBulkData(
|
||||||
matrixStack.last, quad.baked,
|
matrixStack.last(), quad.baked,
|
||||||
lightingData.colorMultiplier,
|
lightingData.colorMultiplier,
|
||||||
lightingData.tint[0], lightingData.tint[1], lightingData.tint[2],
|
lightingData.tint[0], lightingData.tint[1], lightingData.tint[2],
|
||||||
lightingData.packedLight, combinedOverlay, true
|
lightingData.packedLight, combinedOverlay, true
|
||||||
@@ -39,7 +39,7 @@ class RenderCtxVanilla(
|
|||||||
@JvmStatic
|
@JvmStatic
|
||||||
fun render(
|
fun render(
|
||||||
renderer: BlockModelRenderer,
|
renderer: BlockModelRenderer,
|
||||||
world: ILightReader,
|
world: IBlockDisplayReader,
|
||||||
model: SpecialRenderModel,
|
model: SpecialRenderModel,
|
||||||
state: BlockState,
|
state: BlockState,
|
||||||
pos: BlockPos,
|
pos: BlockPos,
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ interface VeryEarlyReloadListener : IFutureReloadListener {
|
|||||||
gameExecutor: Executor
|
gameExecutor: Executor
|
||||||
): CompletableFuture<Void> {
|
): CompletableFuture<Void> {
|
||||||
onReloadStarted()
|
onReloadStarted()
|
||||||
return stage.markCompleteAwaitingOthers(null)
|
return stage.wait(null)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun onReloadStarted() {}
|
fun onReloadStarted() {}
|
||||||
|
|||||||
@@ -8,8 +8,8 @@ import net.minecraft.block.BlockState
|
|||||||
import net.minecraft.client.renderer.model.IBakedModel
|
import net.minecraft.client.renderer.model.IBakedModel
|
||||||
import net.minecraft.client.renderer.model.IModelTransform
|
import net.minecraft.client.renderer.model.IModelTransform
|
||||||
import net.minecraft.client.renderer.model.IUnbakedModel
|
import net.minecraft.client.renderer.model.IUnbakedModel
|
||||||
import net.minecraft.client.renderer.model.Material
|
|
||||||
import net.minecraft.client.renderer.model.ModelBakery
|
import net.minecraft.client.renderer.model.ModelBakery
|
||||||
|
import net.minecraft.client.renderer.model.RenderMaterial
|
||||||
import net.minecraft.client.renderer.texture.TextureAtlasSprite
|
import net.minecraft.client.renderer.texture.TextureAtlasSprite
|
||||||
import net.minecraft.util.ResourceLocation
|
import net.minecraft.util.ResourceLocation
|
||||||
import net.minecraftforge.client.event.ModelBakeEvent
|
import net.minecraftforge.client.event.ModelBakeEvent
|
||||||
@@ -30,7 +30,7 @@ data class ModelDefinitionsLoadedEvent(
|
|||||||
|
|
||||||
interface ModelBakingKey {
|
interface ModelBakingKey {
|
||||||
fun bake(ctx: ModelBakingContext): IBakedModel? =
|
fun bake(ctx: ModelBakingContext): IBakedModel? =
|
||||||
ctx.getUnbaked().bakeModel(ctx.bakery, ctx.spriteGetter, ctx.transform, ctx.location)
|
ctx.getUnbaked().bake(ctx.bakery, ctx.spriteGetter, ctx.transform, ctx.location)
|
||||||
}
|
}
|
||||||
|
|
||||||
interface ModelDiscovery {
|
interface ModelDiscovery {
|
||||||
@@ -49,7 +49,7 @@ data class ModelDiscoveryContext(
|
|||||||
val replacements: MutableMap<ResourceLocation, ModelBakingKey>,
|
val replacements: MutableMap<ResourceLocation, ModelBakingKey>,
|
||||||
val logger: Logger
|
val logger: Logger
|
||||||
) {
|
) {
|
||||||
fun getUnbaked(location: ResourceLocation = modelLocation) = bakery.getUnbakedModel(location)
|
fun getUnbaked(location: ResourceLocation = modelLocation) = bakery.getModel(location)
|
||||||
fun addReplacement(key: ModelBakingKey, addToStateKeys: Boolean = true) {
|
fun addReplacement(key: ModelBakingKey, addToStateKeys: Boolean = true) {
|
||||||
replacements[modelLocation] = key
|
replacements[modelLocation] = key
|
||||||
if (addToStateKeys) BetterFoliage.blockTypes.stateKeys[blockState] = key
|
if (addToStateKeys) BetterFoliage.blockTypes.stateKeys[blockState] = key
|
||||||
@@ -59,12 +59,12 @@ data class ModelDiscoveryContext(
|
|||||||
|
|
||||||
data class ModelBakingContext(
|
data class ModelBakingContext(
|
||||||
val bakery: ModelBakery,
|
val bakery: ModelBakery,
|
||||||
val spriteGetter: Function<Material, TextureAtlasSprite>,
|
val spriteGetter: Function<RenderMaterial, TextureAtlasSprite>,
|
||||||
val location: ResourceLocation,
|
val location: ResourceLocation,
|
||||||
val transform: IModelTransform,
|
val transform: IModelTransform,
|
||||||
val logger: Logger
|
val logger: Logger
|
||||||
) {
|
) {
|
||||||
fun getUnbaked() = bakery.getUnbakedModel(location)
|
fun getUnbaked() = bakery.getModel(location)
|
||||||
fun getBaked() = bakery.getBakedModel(location, transform, spriteGetter)
|
fun getBaked() = bakery.getBakedModel(location, transform, spriteGetter)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -94,7 +94,7 @@ object BakeWrapperManager : Invalidator, HasLogger() {
|
|||||||
|
|
||||||
@SubscribeEvent
|
@SubscribeEvent
|
||||||
fun handleStitch(event: TextureStitchEvent.Pre) {
|
fun handleStitch(event: TextureStitchEvent.Pre) {
|
||||||
if (event.map.textureLocation == Atlas.BLOCKS.resourceId) {
|
if (event.map.location() == Atlas.BLOCKS.resourceId) {
|
||||||
logger.log(INFO, "Adding ${sprites.size} sprites to block atlas")
|
logger.log(INFO, "Adding ${sprites.size} sprites to block atlas")
|
||||||
sprites.forEach { event.addSprite(it) }
|
sprites.forEach { event.addSprite(it) }
|
||||||
sprites.clear()
|
sprites.clear()
|
||||||
@@ -109,7 +109,7 @@ object BakeWrapperManager : Invalidator, HasLogger() {
|
|||||||
fun onBake(
|
fun onBake(
|
||||||
unbaked: IUnbakedModel,
|
unbaked: IUnbakedModel,
|
||||||
bakery: ModelBakery,
|
bakery: ModelBakery,
|
||||||
spriteGetter: Function<Material, TextureAtlasSprite>,
|
spriteGetter: Function<RenderMaterial, TextureAtlasSprite>,
|
||||||
transform: IModelTransform,
|
transform: IModelTransform,
|
||||||
location: ResourceLocation
|
location: ResourceLocation
|
||||||
): IBakedModel? {
|
): IBakedModel? {
|
||||||
@@ -124,6 +124,6 @@ object BakeWrapperManager : Invalidator, HasLogger() {
|
|||||||
logger.log(WARN, "Error while baking $replacement", e)
|
logger.log(WARN, "Error while baking $replacement", e)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return unbaked.bakeModel(bakery, spriteGetter, transform, location)
|
return unbaked.bake(bakery, spriteGetter, transform, location)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
package mods.betterfoliage.resource.discovery
|
package mods.betterfoliage.resource.discovery
|
||||||
|
|
||||||
import mods.betterfoliage.BetterFoliageMod
|
|
||||||
import mods.betterfoliage.util.HasLogger
|
import mods.betterfoliage.util.HasLogger
|
||||||
import mods.betterfoliage.util.getJavaClass
|
import mods.betterfoliage.util.getJavaClass
|
||||||
import mods.betterfoliage.util.getLines
|
import mods.betterfoliage.util.getLines
|
||||||
@@ -45,8 +44,8 @@ class ConfigurableBlockMatcher(val location: ResourceLocation) : HasLogger(), IB
|
|||||||
fun readDefaults() {
|
fun readDefaults() {
|
||||||
blackList.clear()
|
blackList.clear()
|
||||||
whiteList.clear()
|
whiteList.clear()
|
||||||
resourceManager.getAllResources(location).forEach { resource ->
|
resourceManager.getResources(location).forEach { resource ->
|
||||||
detailLogger.log(INFO, "Reading block class configuration $location from pack ${resource.packName}")
|
detailLogger.log(INFO, "Reading block class configuration $location from pack ${resource.sourceName}")
|
||||||
resource.getLines().map{ it.trim() }.filter { !it.startsWith("//") && it.isNotEmpty() }.forEach { line ->
|
resource.getLines().map{ it.trim() }.filter { !it.startsWith("//") && it.isNotEmpty() }.forEach { line ->
|
||||||
if (line.startsWith("-")) getJavaClass(line.substring(1))?.let { blackList.add(it) }
|
if (line.startsWith("-")) getJavaClass(line.substring(1))?.let { blackList.add(it) }
|
||||||
else getJavaClass(line)?.let { whiteList.add(it) }
|
else getJavaClass(line)?.let { whiteList.add(it) }
|
||||||
@@ -63,8 +62,8 @@ data class ModelTextureList(val modelLocation: ResourceLocation, val textureName
|
|||||||
class ModelTextureListConfiguration(val location: ResourceLocation) : HasLogger() {
|
class ModelTextureListConfiguration(val location: ResourceLocation) : HasLogger() {
|
||||||
val modelList = mutableListOf<ModelTextureList>()
|
val modelList = mutableListOf<ModelTextureList>()
|
||||||
fun readDefaults() {
|
fun readDefaults() {
|
||||||
resourceManager.getAllResources(location).forEach { resource ->
|
resourceManager.getResources(location).forEach { resource ->
|
||||||
detailLogger.log(INFO, "Reading model/texture configuration $location from pack ${resource.packName}")
|
detailLogger.log(INFO, "Reading model/texture configuration $location from pack ${resource.sourceName}")
|
||||||
resource.getLines().map{ it.trim() }.filter { !it.startsWith("//") && it.isNotEmpty() }.forEach { line ->
|
resource.getLines().map{ it.trim() }.filter { !it.startsWith("//") && it.isNotEmpty() }.forEach { line ->
|
||||||
val elements = line.split(",")
|
val elements = line.split(",")
|
||||||
modelList.add(ModelTextureList(ResourceLocation(elements.first()), elements.drop(1)))
|
modelList.add(ModelTextureList(ResourceLocation(elements.first()), elements.drop(1)))
|
||||||
|
|||||||
@@ -18,9 +18,9 @@ abstract class AbstractModelDiscovery : HasLogger(), ModelDiscovery {
|
|||||||
replacements: MutableMap<ResourceLocation, ModelBakingKey>
|
replacements: MutableMap<ResourceLocation, ModelBakingKey>
|
||||||
) {
|
) {
|
||||||
ForgeRegistries.BLOCKS
|
ForgeRegistries.BLOCKS
|
||||||
.flatMap { block -> block.stateContainer.validStates }
|
.flatMap { block -> block.stateDefinition.possibleStates }
|
||||||
.forEach { state ->
|
.forEach { state ->
|
||||||
val location = BlockModelShapes.getModelLocation(state)
|
val location = BlockModelShapes.stateToModelLocation(state)
|
||||||
val ctx = ModelDiscoveryContext(bakery, state, location, sprites, replacements, detailLogger)
|
val ctx = ModelDiscoveryContext(bakery, state, location, sprites, replacements, detailLogger)
|
||||||
try {
|
try {
|
||||||
processModel(ctx)
|
processModel(ctx)
|
||||||
@@ -38,7 +38,7 @@ abstract class AbstractModelDiscovery : HasLogger(), ModelDiscovery {
|
|||||||
// per-location replacements need to be scoped to the variant list, as replacement models
|
// per-location replacements need to be scoped to the variant list, as replacement models
|
||||||
// may need information from the BlockState which is not available at baking time
|
// may need information from the BlockState which is not available at baking time
|
||||||
val scopedReplacements = mutableMapOf<ResourceLocation, ModelBakingKey>()
|
val scopedReplacements = mutableMapOf<ResourceLocation, ModelBakingKey>()
|
||||||
model.variantList.forEach { variant ->
|
model.variants.forEach { variant ->
|
||||||
processModel(ctx.copy(modelLocation = variant.modelLocation, replacements = scopedReplacements))
|
processModel(ctx.copy(modelLocation = variant.modelLocation, replacements = scopedReplacements))
|
||||||
}
|
}
|
||||||
if (scopedReplacements.isNotEmpty()) {
|
if (scopedReplacements.isNotEmpty()) {
|
||||||
@@ -73,15 +73,18 @@ abstract class ConfigurableModelDiscovery : AbstractModelDiscovery() {
|
|||||||
matches.forEach { match ->
|
matches.forEach { match ->
|
||||||
detailLogger.log(Level.INFO, " model $model matches ${match.modelLocation}")
|
detailLogger.log(Level.INFO, " model $model matches ${match.modelLocation}")
|
||||||
|
|
||||||
val materials = match.textureNames.map { it to model.resolveTextureName(it) }
|
val materials = match.textureNames.map { it to model.getMaterial(it) }
|
||||||
val texMapString = Joiner.on(", ").join(materials.map { "${it.first}=${it.second.textureLocation}" })
|
val texMapString = Joiner.on(", ").join(materials.map { "${it.first}=${it.second.texture()}" })
|
||||||
detailLogger.log(Level.INFO, " sprites [$texMapString]")
|
detailLogger.log(Level.INFO, " sprites [$texMapString]")
|
||||||
|
|
||||||
if (materials.all { it.second.textureLocation != MissingTextureSprite.getLocation() }) {
|
if (materials.all { it.second.texture() != MissingTextureSprite.getLocation() }) {
|
||||||
// found a valid model (all required textures exist)
|
// found a valid model (all required textures exist)
|
||||||
processModel(ctx, materials.map { it.second.textureLocation })
|
processModel(ctx, materials.map { it.second.texture() })
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
if (matches.isEmpty()) {
|
||||||
|
detailLogger.log(Level.INFO, " no matches for model ${ctx.modelLocation}, inheritance chain ${ancestry.joinToString(" -> ")}")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return super.processModel(ctx)
|
return super.processModel(ctx)
|
||||||
}
|
}
|
||||||
@@ -90,12 +93,12 @@ abstract class ConfigurableModelDiscovery : AbstractModelDiscovery() {
|
|||||||
fun ModelBakery.modelDerivesFrom(model: BlockModel, location: ResourceLocation, target: ResourceLocation): Boolean =
|
fun ModelBakery.modelDerivesFrom(model: BlockModel, location: ResourceLocation, target: ResourceLocation): Boolean =
|
||||||
if (location == target) true
|
if (location == target) true
|
||||||
else model.parentLocation
|
else model.parentLocation
|
||||||
?.let { getUnbakedModel(it) as? BlockModel }
|
?.let { getModel(it) as? BlockModel }
|
||||||
?.let { parent -> modelDerivesFrom(parent, model.parentLocation!!, target) }
|
?.let { parent -> modelDerivesFrom(parent, model.parentLocation!!, target) }
|
||||||
?: false
|
?: false
|
||||||
|
|
||||||
fun ModelBakery.getAncestry(location: ResourceLocation): List<ResourceLocation> {
|
fun ModelBakery.getAncestry(location: ResourceLocation): List<ResourceLocation> {
|
||||||
val model = getUnbakedModel(location) as? BlockModel ?: return listOf(location)
|
val model = getModel(location) as? BlockModel ?: return listOf(location)
|
||||||
val parentAncestry = model.parentLocation?.let { getAncestry(it) } ?: emptyList()
|
val parentAncestry = model.parentLocation?.let { getAncestry(it) } ?: emptyList()
|
||||||
return listOf(location) + parentAncestry
|
return listOf(location) + parentAncestry
|
||||||
}
|
}
|
||||||
@@ -20,7 +20,7 @@ class WeightedUnbakedKey(
|
|||||||
if (unbaked !is VariantList) return super.bake(ctx)
|
if (unbaked !is VariantList) return super.bake(ctx)
|
||||||
|
|
||||||
// bake all variants, replace as needed
|
// bake all variants, replace as needed
|
||||||
val bakedModels = unbaked.variantList.mapNotNull {
|
val bakedModels = unbaked.variants.mapNotNull {
|
||||||
val variantCtx = ctx.copy(location = it.modelLocation, transform = it)
|
val variantCtx = ctx.copy(location = it.modelLocation, transform = it)
|
||||||
val replacement = replacements[it.modelLocation]
|
val replacement = replacements[it.modelLocation]
|
||||||
val baked = replacement?.let { replacement ->
|
val baked = replacement?.let { replacement ->
|
||||||
@@ -40,10 +40,10 @@ class WeightedUnbakedKey(
|
|||||||
// let it through unchanged
|
// let it through unchanged
|
||||||
if (bakedModels.isEmpty()) return super.bake(ctx)
|
if (bakedModels.isEmpty()) return super.bake(ctx)
|
||||||
|
|
||||||
if (bakedModels.size < unbaked.variantList.size) {
|
if (bakedModels.size < unbaked.variants.size) {
|
||||||
detailLogger.log(
|
detailLogger.log(
|
||||||
WARN,
|
WARN,
|
||||||
"Dropped ${unbaked.variantList.size - bakedModels.size} variants from model ${ctx.location}"
|
"Dropped ${unbaked.variants.size - bakedModels.size} variants from model ${ctx.location}"
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
val weightedSpecials = bakedModels.map { (variant, model) ->
|
val weightedSpecials = bakedModels.map { (variant, model) ->
|
||||||
|
|||||||
@@ -1,10 +1,8 @@
|
|||||||
package mods.betterfoliage.resource.generated
|
package mods.betterfoliage.resource.generated
|
||||||
|
|
||||||
import mods.betterfoliage.BetterFoliageMod
|
|
||||||
import mods.betterfoliage.util.Atlas
|
import mods.betterfoliage.util.Atlas
|
||||||
import mods.betterfoliage.util.HasLogger
|
import mods.betterfoliage.util.HasLogger
|
||||||
import net.minecraft.client.Minecraft
|
import net.minecraft.client.Minecraft
|
||||||
import net.minecraft.client.resources.ClientResourcePackInfo
|
|
||||||
import net.minecraft.resources.*
|
import net.minecraft.resources.*
|
||||||
import net.minecraft.resources.ResourcePackType.CLIENT_RESOURCES
|
import net.minecraft.resources.ResourcePackType.CLIENT_RESOURCES
|
||||||
import net.minecraft.resources.data.IMetadataSectionSerializer
|
import net.minecraft.resources.data.IMetadataSectionSerializer
|
||||||
@@ -12,6 +10,7 @@ import net.minecraft.util.ResourceLocation
|
|||||||
import net.minecraft.util.text.StringTextComponent
|
import net.minecraft.util.text.StringTextComponent
|
||||||
import org.apache.logging.log4j.Level.INFO
|
import org.apache.logging.log4j.Level.INFO
|
||||||
import java.util.*
|
import java.util.*
|
||||||
|
import java.util.function.Consumer
|
||||||
import java.util.function.Predicate
|
import java.util.function.Predicate
|
||||||
import java.util.function.Supplier
|
import java.util.function.Supplier
|
||||||
|
|
||||||
@@ -25,10 +24,10 @@ class GeneratedTexturePack(
|
|||||||
val nameSpace: String, val packName: String
|
val nameSpace: String, val packName: String
|
||||||
) : HasLogger(), IResourcePack {
|
) : HasLogger(), IResourcePack {
|
||||||
override fun getName() = packName
|
override fun getName() = packName
|
||||||
override fun getResourceNamespaces(type: ResourcePackType) = setOf(nameSpace)
|
override fun getNamespaces(type: ResourcePackType) = setOf(nameSpace)
|
||||||
override fun <T : Any?> getMetadata(deserializer: IMetadataSectionSerializer<T>) = null
|
override fun <T : Any?> getMetadataSection(deserializer: IMetadataSectionSerializer<T>) = null
|
||||||
override fun getRootResourceStream(id: String) = null
|
override fun getRootResource(id: String) = null
|
||||||
override fun getAllResourceLocations(type: ResourcePackType, namespace:String, path: String, maxDepth: Int, filter: Predicate<String>) = emptyList<ResourceLocation>()
|
override fun getResources(type: ResourcePackType, namespace:String, path: String, maxDepth: Int, filter: Predicate<String>) = emptyList<ResourceLocation>()
|
||||||
|
|
||||||
override fun close() {}
|
override fun close() {}
|
||||||
|
|
||||||
@@ -49,21 +48,22 @@ class GeneratedTexturePack(
|
|||||||
return id
|
return id
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getResourceStream(type: ResourcePackType, id: ResourceLocation) =
|
override fun getResource(type: ResourcePackType, id: ResourceLocation) =
|
||||||
if (type != CLIENT_RESOURCES) null else resources[id]?.inputStream()
|
if (type != CLIENT_RESOURCES) null else resources[id]?.inputStream()
|
||||||
|
|
||||||
override fun resourceExists(type: ResourcePackType, id: ResourceLocation) =
|
override fun hasResource(type: ResourcePackType, id: ResourceLocation) =
|
||||||
type == CLIENT_RESOURCES && resources.containsKey(id)
|
type == CLIENT_RESOURCES && resources.containsKey(id)
|
||||||
|
|
||||||
val finder = object : IPackFinder {
|
val finder = object : IPackFinder {
|
||||||
val packInfo = ClientResourcePackInfo(
|
val packInfo = ResourcePackInfo(
|
||||||
packName, true, Supplier { this@GeneratedTexturePack },
|
packName, true, Supplier { this@GeneratedTexturePack },
|
||||||
StringTextComponent(packName),
|
StringTextComponent(packName),
|
||||||
StringTextComponent("Generated block textures resource pack"),
|
StringTextComponent("Generated block textures resource pack"),
|
||||||
PackCompatibility.COMPATIBLE, ResourcePackInfo.Priority.TOP, true, null, true
|
PackCompatibility.COMPATIBLE, ResourcePackInfo.Priority.TOP, true, null, true
|
||||||
)
|
)
|
||||||
override fun <T : ResourcePackInfo> addPackInfosToMap(nameToPackMap: MutableMap<String, T>, packInfoFactory: ResourcePackInfo.IFactory<T>) {
|
|
||||||
(nameToPackMap as MutableMap<String, ResourcePackInfo>).put(packName, packInfo)
|
override fun loadPacks(p0: Consumer<ResourcePackInfo>, p1: ResourcePackInfo.IFactory) {
|
||||||
|
p0.accept(packInfo)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,9 +0,0 @@
|
|||||||
package mods.betterfoliage.util
|
|
||||||
|
|
||||||
import net.minecraft.block.BlockState
|
|
||||||
import net.minecraft.block.Blocks
|
|
||||||
import net.minecraft.block.material.Material
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
val DIRT_BLOCKS = listOf(Blocks.DIRT, Blocks.COARSE_DIRT)
|
|
||||||
@@ -1,12 +1,12 @@
|
|||||||
package mods.betterfoliage.util
|
package mods.betterfoliage.util
|
||||||
|
|
||||||
import net.minecraft.client.renderer.Quaternion
|
|
||||||
import net.minecraft.util.Direction
|
import net.minecraft.util.Direction
|
||||||
import net.minecraft.util.Direction.*
|
import net.minecraft.util.Direction.*
|
||||||
import net.minecraft.util.Direction.Axis.*
|
import net.minecraft.util.Direction.Axis.*
|
||||||
import net.minecraft.util.Direction.AxisDirection.NEGATIVE
|
import net.minecraft.util.Direction.AxisDirection.NEGATIVE
|
||||||
import net.minecraft.util.Direction.AxisDirection.POSITIVE
|
import net.minecraft.util.Direction.AxisDirection.POSITIVE
|
||||||
import net.minecraft.util.math.BlockPos
|
import net.minecraft.util.math.BlockPos
|
||||||
|
import net.minecraft.util.math.vector.Quaternion
|
||||||
|
|
||||||
val EPSILON_ZERO = 0.05
|
val EPSILON_ZERO = 0.05
|
||||||
val EPSILON_ONE = 0.95
|
val EPSILON_ONE = 0.95
|
||||||
@@ -55,15 +55,15 @@ val ROTATION_MATRIX: Array<IntArray> get() = arrayOf(
|
|||||||
// Vectors
|
// Vectors
|
||||||
// ================================
|
// ================================
|
||||||
operator fun Direction.times(scale: Double) =
|
operator fun Direction.times(scale: Double) =
|
||||||
Double3(directionVec.x.toDouble() * scale, directionVec.y.toDouble() * scale, directionVec.z.toDouble() * scale)
|
Double3(normal.x.toDouble() * scale, normal.y.toDouble() * scale, normal.z.toDouble() * scale)
|
||||||
val Direction.vec: Double3 get() = Double3(directionVec.x.toDouble(), directionVec.y.toDouble(), directionVec.z.toDouble())
|
val Direction.vec: Double3 get() = Double3(normal.x.toDouble(), normal.y.toDouble(), normal.z.toDouble())
|
||||||
|
|
||||||
operator fun BlockPos.plus(other: Int3) = BlockPos(x + other.x, y + other.y, z + other.z)
|
operator fun BlockPos.plus(other: Int3) = BlockPos(x + other.x, y + other.y, z + other.z)
|
||||||
|
|
||||||
/** 3D vector of [Double]s. Offers both mutable operations, and immutable operations in operator notation. */
|
/** 3D vector of [Double]s. Offers both mutable operations, and immutable operations in operator notation. */
|
||||||
data class Double3(var x: Double, var y: Double, var z: Double) {
|
data class Double3(var x: Double, var y: Double, var z: Double) {
|
||||||
constructor(x: Float, y: Float, z: Float) : this(x.toDouble(), y.toDouble(), z.toDouble())
|
constructor(x: Float, y: Float, z: Float) : this(x.toDouble(), y.toDouble(), z.toDouble())
|
||||||
constructor(dir: Direction) : this(dir.directionVec.x.toDouble(), dir.directionVec.y.toDouble(), dir.directionVec.z.toDouble())
|
constructor(dir: Direction) : this(dir.normal.x.toDouble(), dir.normal.y.toDouble(), dir.normal.z.toDouble())
|
||||||
companion object {
|
companion object {
|
||||||
val zero: Double3 get() = Double3(0.0, 0.0, 0.0)
|
val zero: Double3 get() = Double3(0.0, 0.0, 0.0)
|
||||||
fun weight(v1: Double3, weight1: Double, v2: Double3, weight2: Double) =
|
fun weight(v1: Double3, weight1: Double, v2: Double3, weight2: Double) =
|
||||||
@@ -88,9 +88,9 @@ data class Double3(var x: Double, var y: Double, var z: Double) {
|
|||||||
/** Rotate vector by the given [Quaternion] */
|
/** Rotate vector by the given [Quaternion] */
|
||||||
fun rotate(quat: Quaternion) =
|
fun rotate(quat: Quaternion) =
|
||||||
quat.copy()
|
quat.copy()
|
||||||
.apply { multiply(Quaternion(x, y, z, 0.0F)) }
|
.apply { mul(Quaternion(x.toFloat(), y.toFloat(), z.toFloat(), 0.0F)) }
|
||||||
.apply { multiply(quat.copy().apply(Quaternion::conjugate)) }
|
.apply { mul(quat.copy().apply(Quaternion::conj)) }
|
||||||
.let { Double3(it.x, it.y, it.z) }
|
.let { Double3(it.i().toDouble(), it.j().toDouble(), it.k().toDouble()) }
|
||||||
|
|
||||||
// mutable operations
|
// mutable operations
|
||||||
fun setTo(other: Double3): Double3 { x = other.x; y = other.y; z = other.z; return this }
|
fun setTo(other: Double3): Double3 { x = other.x; y = other.y; z = other.z; return this }
|
||||||
@@ -120,11 +120,11 @@ data class Double3(var x: Double, var y: Double, var z: Double) {
|
|||||||
|
|
||||||
/** 3D vector of [Int]s. Offers both mutable operations, and immutable operations in operator notation. */
|
/** 3D vector of [Int]s. Offers both mutable operations, and immutable operations in operator notation. */
|
||||||
data class Int3(var x: Int, var y: Int, var z: Int) {
|
data class Int3(var x: Int, var y: Int, var z: Int) {
|
||||||
constructor(dir: Direction) : this(dir.directionVec.x, dir.directionVec.y, dir.directionVec.z)
|
constructor(dir: Direction) : this(dir.normal.x, dir.normal.y, dir.normal.z)
|
||||||
constructor(offset: Pair<Int, Direction>) : this(
|
constructor(offset: Pair<Int, Direction>) : this(
|
||||||
offset.first * offset.second.directionVec.x,
|
offset.first * offset.second.normal.x,
|
||||||
offset.first * offset.second.directionVec.y,
|
offset.first * offset.second.normal.y,
|
||||||
offset.first * offset.second.directionVec.z
|
offset.first * offset.second.normal.z
|
||||||
)
|
)
|
||||||
companion object {
|
companion object {
|
||||||
val zero = Int3(0, 0, 0)
|
val zero = Int3(0, 0, 0)
|
||||||
@@ -133,9 +133,9 @@ data class Int3(var x: Int, var y: Int, var z: Int) {
|
|||||||
// immutable operations
|
// immutable operations
|
||||||
operator fun plus(other: Int3) = Int3(x + other.x, y + other.y, z + other.z)
|
operator fun plus(other: Int3) = Int3(x + other.x, y + other.y, z + other.z)
|
||||||
operator fun plus(other: Pair<Int, Direction>) = Int3(
|
operator fun plus(other: Pair<Int, Direction>) = Int3(
|
||||||
x + other.first * other.second.directionVec.x,
|
x + other.first * other.second.normal.x,
|
||||||
y + other.first * other.second.directionVec.y,
|
y + other.first * other.second.normal.y,
|
||||||
z + other.first * other.second.directionVec.z
|
z + other.first * other.second.normal.z
|
||||||
)
|
)
|
||||||
operator fun unaryMinus() = Int3(-x, -y, -z)
|
operator fun unaryMinus() = Int3(-x, -y, -z)
|
||||||
operator fun minus(other: Int3) = Int3(x - other.x, y - other.y, z - other.z)
|
operator fun minus(other: Int3) = Int3(x - other.x, y - other.y, z - other.z)
|
||||||
|
|||||||
@@ -7,16 +7,16 @@ import net.minecraft.util.text.TextFormatting
|
|||||||
import net.minecraft.util.text.TextFormatting.AQUA
|
import net.minecraft.util.text.TextFormatting.AQUA
|
||||||
import net.minecraft.util.text.TextFormatting.GRAY
|
import net.minecraft.util.text.TextFormatting.GRAY
|
||||||
|
|
||||||
fun stripTooltipDefaultText(tooltip: MutableList<String>) {
|
//fun stripTooltipDefaultText(tooltip: MutableList<String>) {
|
||||||
var defaultRows = false
|
// var defaultRows = false
|
||||||
val iter = tooltip.iterator()
|
// val iter = tooltip.iterator()
|
||||||
while (iter.hasNext()) {
|
// while (iter.hasNext()) {
|
||||||
if (iter.next().startsWith(AQUA.toString())) defaultRows = true
|
// if (iter.next().startsWith(AQUA.toString())) defaultRows = true
|
||||||
if (defaultRows) iter.remove()
|
// if (defaultRows) iter.remove()
|
||||||
}
|
// }
|
||||||
}
|
//}
|
||||||
|
//
|
||||||
fun textComponent(msg: String, color: TextFormatting = GRAY): StringTextComponent {
|
//fun textComponent(msg: String, color: TextFormatting = GRAY): StringTextComponent {
|
||||||
val style = Style().apply { this.color = color }
|
// val style = Style().apply { this.color = color }
|
||||||
return StringTextComponent(msg).apply { this.style = style }
|
// return StringTextComponent(msg).apply { this.style = style }
|
||||||
}
|
//}
|
||||||
@@ -1,8 +1,6 @@
|
|||||||
package mods.betterfoliage.util
|
package mods.betterfoliage.util
|
||||||
|
|
||||||
import net.minecraft.client.Minecraft
|
import net.minecraft.client.Minecraft
|
||||||
import net.minecraft.client.renderer.model.Material
|
|
||||||
import net.minecraft.client.renderer.texture.AtlasTexture
|
|
||||||
import net.minecraft.resources.IReloadableResourceManager
|
import net.minecraft.resources.IReloadableResourceManager
|
||||||
import net.minecraft.resources.IResource
|
import net.minecraft.resources.IResource
|
||||||
import net.minecraft.resources.IResourceManager
|
import net.minecraft.resources.IResourceManager
|
||||||
@@ -19,11 +17,6 @@ operator fun ResourceLocation.plus(str: String) = ResourceLocation(namespace, pa
|
|||||||
fun ResourceLocation.prependLocation(basePath: String) =
|
fun ResourceLocation.prependLocation(basePath: String) =
|
||||||
ResourceLocation(namespace, basePath.stripEnd("/").let { "$it/$path" })
|
ResourceLocation(namespace, basePath.stripEnd("/").let { "$it/$path" })
|
||||||
|
|
||||||
val ResourceLocation.asBlockMaterial: Material get() = Material(
|
|
||||||
AtlasTexture.LOCATION_BLOCKS_TEXTURE,
|
|
||||||
this
|
|
||||||
)
|
|
||||||
|
|
||||||
/** Index operator to get a resource. */
|
/** Index operator to get a resource. */
|
||||||
operator fun IResourceManager.get(domain: String, path: String): IResource? = get(ResourceLocation(domain, path))
|
operator fun IResourceManager.get(domain: String, path: String): IResource? = get(ResourceLocation(domain, path))
|
||||||
/** Index operator to get a resource. */
|
/** Index operator to get a resource. */
|
||||||
|
|||||||
@@ -3,7 +3,6 @@ package mods.betterfoliage.util
|
|||||||
import mods.betterfoliage.model.Color
|
import mods.betterfoliage.model.Color
|
||||||
import mods.betterfoliage.model.HSB
|
import mods.betterfoliage.model.HSB
|
||||||
import net.minecraft.client.Minecraft
|
import net.minecraft.client.Minecraft
|
||||||
import net.minecraft.client.renderer.model.Material
|
|
||||||
import net.minecraft.client.renderer.texture.AtlasTexture
|
import net.minecraft.client.renderer.texture.AtlasTexture
|
||||||
import net.minecraft.client.renderer.texture.TextureAtlasSprite
|
import net.minecraft.client.renderer.texture.TextureAtlasSprite
|
||||||
import net.minecraft.resources.IResource
|
import net.minecraft.resources.IResource
|
||||||
@@ -20,8 +19,8 @@ import kotlin.math.cos
|
|||||||
import kotlin.math.sin
|
import kotlin.math.sin
|
||||||
|
|
||||||
enum class Atlas(val resourceId: ResourceLocation) {
|
enum class Atlas(val resourceId: ResourceLocation) {
|
||||||
BLOCKS(AtlasTexture.LOCATION_BLOCKS_TEXTURE),
|
BLOCKS(AtlasTexture.LOCATION_BLOCKS),
|
||||||
PARTICLES(AtlasTexture.LOCATION_PARTICLES_TEXTURE);
|
PARTICLES(AtlasTexture.LOCATION_PARTICLES);
|
||||||
|
|
||||||
/** Get the fully-qualified resource name for sprites belonging to this atlas */
|
/** Get the fully-qualified resource name for sprites belonging to this atlas */
|
||||||
fun file(resource: ResourceLocation) = ResourceLocation(resource.namespace, "textures/${resource.path}.png")
|
fun file(resource: ResourceLocation) = ResourceLocation(resource.namespace, "textures/${resource.path}.png")
|
||||||
@@ -33,7 +32,7 @@ enum class Atlas(val resourceId: ResourceLocation) {
|
|||||||
operator fun get(location: ResourceLocation) = atlas.getSprite(location)
|
operator fun get(location: ResourceLocation) = atlas.getSprite(location)
|
||||||
}
|
}
|
||||||
|
|
||||||
val Material.atlas: Atlas get() = Atlas.values().find { it.resourceId == atlasLocation } ?: Atlas.BLOCKS
|
//val Spr.atlas: Atlas get() = Atlas.values().find { it.resourceId == atlasLocation } ?: Atlas.BLOCKS
|
||||||
|
|
||||||
inline operator fun AtlasTexture.get(res: ResourceLocation): TextureAtlasSprite? = this.getSprite(res)
|
inline operator fun AtlasTexture.get(res: ResourceLocation): TextureAtlasSprite? = this.getSprite(res)
|
||||||
inline operator fun AtlasTexture.get(name: String): TextureAtlasSprite? = get(ResourceLocation(name))
|
inline operator fun AtlasTexture.get(name: String): TextureAtlasSprite? = get(ResourceLocation(name))
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
modLoader="kotlinfml"
|
modLoader="kotlinforforge"
|
||||||
loaderVersion="[1.4,)"
|
loaderVersion="[1,)"
|
||||||
issueTrackerURL="https://github.com/octarine-noise/BetterFoliage/issues"
|
issueTrackerURL="https://github.com/octarine-noise/BetterFoliage/issues"
|
||||||
|
license="MIT"
|
||||||
[[mods]]
|
[[mods]]
|
||||||
modId="betterfoliage"
|
modId="betterfoliage"
|
||||||
version="${version}"
|
version="${version}"
|
||||||
|
|||||||
@@ -230,6 +230,8 @@ betterfoliage.connectedGrass.enabled.tooltip=If there is a grass block on top of
|
|||||||
|
|
||||||
betterfoliage.roundLogs=Round Logs
|
betterfoliage.roundLogs=Round Logs
|
||||||
betterfoliage.roundLogs.tooltip=Connect round blocks to solid full blocks?
|
betterfoliage.roundLogs.tooltip=Connect round blocks to solid full blocks?
|
||||||
|
betterfoliage.roundLogs.plantsOnly=Plant materials only
|
||||||
|
betterfoliage.roundLogs.plantsOnly.tooltip=Only apply to wood and hay, not all column blocks?
|
||||||
betterfoliage.roundLogs.connectSolids=Connect to solid
|
betterfoliage.roundLogs.connectSolids=Connect to solid
|
||||||
betterfoliage.roundLogs.connectSolids.tooltip=Connect round blocks to solid full blocks?
|
betterfoliage.roundLogs.connectSolids.tooltip=Connect round blocks to solid full blocks?
|
||||||
betterfoliage.roundLogs.connectPerpendicular=Connect to perpendicular logs
|
betterfoliage.roundLogs.connectPerpendicular=Connect to perpendicular logs
|
||||||
|
|||||||
@@ -1,2 +1,2 @@
|
|||||||
// Vanilla
|
// Vanilla
|
||||||
net.minecraft.block.LogBlock
|
net.minecraft.block.RotatedPillarBlock
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
// Vanilla
|
// Vanilla
|
||||||
block/column_side,side,end
|
|
||||||
block/cube_column,side,end
|
block/cube_column,side,end
|
||||||
|
block/cube_column_horizontal,side,end
|
||||||
block/cube_all,all,all
|
block/cube_all,all,all
|
||||||
|
|||||||
Reference in New Issue
Block a user