Skip to content

Commit

Permalink
Complete rewrite for better support
Browse files Browse the repository at this point in the history
  • Loading branch information
ishikyoo committed Oct 5, 2024
1 parent 5fd5629 commit 4cff84a
Show file tree
Hide file tree
Showing 16 changed files with 462 additions and 467 deletions.
144 changes: 144 additions & 0 deletions src/main/java/com/ishikyoo/leavesly/ColorProvider.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,144 @@
package com.ishikyoo.leavesly;

import com.ishikyoo.leavesly.property.Properties;
import com.ishikyoo.leavesly.support.Support;
import net.fabricmc.fabric.api.client.rendering.v1.ColorProviderRegistry;
import net.minecraft.block.Block;
import net.minecraft.block.BlockState;
import net.minecraft.client.color.world.BiomeColors;
import net.minecraft.state.property.IntProperty;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.BlockRenderView;
import net.minecraft.world.biome.FoliageColors;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

public class ColorProvider {
private static final IntProperty SNOW_LAYER = Properties.SNOW_LAYER;

private static final Block[] BlockArray = Support.getBlocks();

private static final List<Block> blockStaticColorsList = new ArrayList<>();
private static final HashMap<Block, Integer> blockStaticColorsHashMap = new HashMap<>();

private static final List<Block> blockFoliageColorsList = new ArrayList<>();
private static final List<Block> blockGrassColorsList = new ArrayList<>();
private static final HashMap<Block, Double> blockColorMasksHashMap = new HashMap<>();

public static void initialize() {
initializeColorMasks();
initializeColorProvides();
}

private static void initializeColorMasks() {
for (Block block : BlockArray) {
String blockId = Support.getBlockId(block);
if (blockId.equals("azalea_leaves"))
addBlockStaticColor(block,0xC4FF4F, 0.5725490196);
else if (blockId.equals("birch_leaves"))
addBlockStaticColor(block, FoliageColors.getBirchColor(), 0.72549019607);
else if (blockId.equals("cherry_leaves"))
addBlockStaticColor(block,0xDEFF4C, 0.6);
else if (blockId.equals("dark_oak_leaves"))
addBlockFoliageColor(block, 0.72549019607);
else if (blockId.equals("flowering_azalea_leaves"))
addBlockStaticColor(block, 0xC4FF4F, 0.5725490196);
else if (blockId.equals("jungle_leaves"))
addBlockFoliageColor(block, 0.72549019607);
else if (blockId.equals("mangrove_leaves"))
addBlockStaticColor(block, FoliageColors.getBirchColor(), 0.70980392156);
else if (blockId.equals("oak_leaves"))
addBlockFoliageColor(block, 0.73725490196);
else if (blockId.equals("spruce_leaves"))
addBlockStaticColor(block, FoliageColors.getSpruceColor(), 0.60392156862);
else if (blockId.equals("vine"))
addBlockFoliageColor(block, 0.66666666666);
else if (blockId.equals("short_grass"))
addBlockGrassColor(block, 0.72156862745);
else if (blockId.equals("tall_grass"))
addBlockGrassColor(block, 0.67450980392);
else if (blockId.equals("fern"))
addBlockGrassColor(block, 0.64705882352);
else if (blockId.equals("large_fern"))
addBlockGrassColor(block, 0.67450980392);
}
}

private static void initializeColorProvides() {
Block[] staticColorBlocks = new Block[blockStaticColorsList.size()];
blockStaticColorsList.toArray(staticColorBlocks);

Block[] foliageColorBlocks = new Block[blockFoliageColorsList.size()];
blockFoliageColorsList.toArray(foliageColorBlocks);

Block[] grassColorBlocks = new Block[blockGrassColorsList.size()];
blockGrassColorsList.toArray(grassColorBlocks);

ColorProviderRegistry.BLOCK.register(ColorProvider::getBlockSnowLayeredStaticColor,
staticColorBlocks
);
ColorProviderRegistry.BLOCK.register(ColorProvider::getBlockSnowLayeredFoliageColor,
foliageColorBlocks
);
ColorProviderRegistry.BLOCK.register(ColorProvider::getBlockSnowLayeredGrassColor,
grassColorBlocks
);
}

private static int getBlockSnowLayeredStaticColor(BlockState state, BlockRenderView world, BlockPos position, int index) {
Block block = state.getBlock();
int color = blockStaticColorsHashMap.get(block);
int snowLayer = state.get(SNOW_LAYER);
double leavesSnowLayerMask = (double) snowLayer / SNOW_LAYER.getValues().size();
return getSnowLayeredColor(color, leavesSnowLayerMask);
}

private static int getBlockSnowLayeredFoliageColor(BlockState state, BlockRenderView world, BlockPos position, int index) {
Block block = state.getBlock();
int color = getMaskedColor(BiomeColors.getFoliageColor(world, position), blockColorMasksHashMap.get(block));
int snowLayer = state.get(SNOW_LAYER);
double leavesSnowLayerMask = (double) snowLayer / SNOW_LAYER.getValues().size();
return getSnowLayeredColor(color, leavesSnowLayerMask);
}

private static int getBlockSnowLayeredGrassColor(BlockState state, BlockRenderView world, BlockPos position, int index) {
Block block = state.getBlock();
int color = getMaskedColor(BiomeColors.getGrassColor(world, position), blockColorMasksHashMap.get(block));
int snowLayer = state.get(SNOW_LAYER);
double leavesSnowLayerMask = (double) snowLayer / SNOW_LAYER.getValues().size();
return getSnowLayeredColor(color, leavesSnowLayerMask);
}

private static void addBlockStaticColor(Block block, int color, double mask) {
blockStaticColorsList.add(block);
blockStaticColorsHashMap.put(block, getMaskedColor(color, mask));
}

private static void addBlockFoliageColor(Block block, double mask) {
blockFoliageColorsList.add(block);
blockColorMasksHashMap.put(block, mask);
}

private static void addBlockGrassColor(Block block, double mask) {
blockGrassColorsList.add(block);
blockColorMasksHashMap.put(block, mask);
}

private static int getMaskedColor(int color, double mask) {
int r = (int) Math.round((color >> 16 & 0xff) * mask);
int g = (int) Math.round((color >> 8 & 0xff) * mask);
int b = (int) Math.round((color & 0xff) * mask);
return r << 16 | g << 8 | b;
}
private static int getSnowLayeredColor(int color, double mask) {
int r = (color >> 16 & 0xff);
int g = (color >> 8 & 0xff);
int b = (color & 0xff);
r += (int) Math.round((0xff - r) * mask);
g += (int) Math.round((0xff - g) * mask);
b += (int) Math.round((0xff - b) * mask);
return r << 16 | g << 8 | b;
}
}
121 changes: 4 additions & 117 deletions src/main/java/com/ishikyoo/leavesly/Leavesly.java
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
package com.ishikyoo.leavesly;

import com.ishikyoo.leavesly.support.Support;
import net.fabricmc.api.ModInitializer;

import net.minecraft.block.Block;
import net.minecraft.block.BlockState;
import net.minecraft.block.Blocks;
import net.minecraft.server.world.ServerWorld;
import net.minecraft.state.property.Properties;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.random.Random;
import net.minecraft.world.LightType;
Expand All @@ -15,129 +17,14 @@

import net.minecraft.state.property.IntProperty;

import java.net.Inet4Address;

public class Leavesly implements ModInitializer {
public static final String MOD_ID = "leavesly";
public static final Logger LOGGER = LoggerFactory.getLogger(MOD_ID);

private static Leavesly instance;

static final int SKYLIGHT_MAX = 15;
static final int SKYLIGHT_CUTOFF = 9;
static final int SKYLIGHT_RANGE = SKYLIGHT_MAX - SKYLIGHT_CUTOFF;
static final int SNOW_MAX_VALUE = 8 * SKYLIGHT_RANGE - 1;
static final int SNOW_VALUE_TO_CHANGE = (SNOW_MAX_VALUE + 1) / 2;
static final double NEIGHBOURS_INFLUENCE = 0.875;
static final double MAIN_INFLUENCE = Math.abs(NEIGHBOURS_INFLUENCE - 1);
static final int NEIGHBOURS_INFLUENCE_RANGE = 1;
public static final IntProperty SNOW = IntProperty.of("snow", 0, SNOW_MAX_VALUE);

public static Leavesly getInstance() { return instance; }

boolean isLeavesBlock(Block block) {
if (block == Blocks.ACACIA_LEAVES)
return true;
else if (block == Blocks.AZALEA_LEAVES)
return true;
else if (block == Blocks.BIRCH_LEAVES)
return true;
else if (block == Blocks.CHERRY_LEAVES)
return true;
else if (block == Blocks.DARK_OAK_LEAVES)
return true;
else if (block == Blocks.FLOWERING_AZALEA_LEAVES)
return true;
else if (block == Blocks.JUNGLE_LEAVES)
return true;
else if (block == Blocks.MANGROVE_LEAVES)
return true;
else if (block == Blocks.OAK_LEAVES)
return true;
else if (block == Blocks.SPRUCE_LEAVES)
return true;
return false;
}
boolean isVineBlock(Block block) {
return block == Blocks.VINE;
}
boolean isPlantBlock(Block block) {
if (block == Blocks.SHORT_GRASS)
return true;
else if (block == Blocks.FERN)
return true;
else if (block == Blocks.TALL_GRASS)
return true;
else if (block == Blocks.LARGE_FERN)
return true;
return false;
}
boolean isValidBlock(Block block) {
return isLeavesBlock(block) | isVineBlock(block) | isPlantBlock(block);
}

double getNeighboursInfluence(ServerWorld world, BlockPos pos, int range) {
int value = 0;
int blockCount = 0;
for (int x = pos.getX() - range; x <= pos.getX() + range; x++) {
for (int y = pos.getY() - range; y <= pos.getY() + range; y++) {
for (int z = pos.getZ() - range; z <= pos.getZ() + range; z++) {
BlockPos rangePos = new BlockPos(x, y, z);
if (!rangePos.equals(pos)) {
BlockState rangeState = world.getBlockState(rangePos);
Block rangeBlock = rangeState.getBlock();
if (isValidBlock(rangeBlock)) {
value += rangeState.get(SNOW);
blockCount++;
}
}
}
}
}
return ((double) value / blockCount) / SNOW_MAX_VALUE;
}

@Override
public void onInitialize() {
instance = this;
}

public void tick(BlockState state, ServerWorld world, BlockPos pos, Random random) {
if (isValidBlock(state.getBlock())) {
if (world.getBiome(pos).value().getPrecipitation(pos) == Biome.Precipitation.SNOW) {
int skyLight = world.getLightLevel(LightType.SKY, pos);

if (skyLight > SKYLIGHT_CUTOFF) {
int blockSnow = state.get(SNOW);
double skyLightN = (double) (skyLight - SKYLIGHT_CUTOFF) / (SKYLIGHT_MAX - SKYLIGHT_CUTOFF);
double neighboursInfluenceN = getNeighboursInfluence(world, pos, NEIGHBOURS_INFLUENCE_RANGE);
double maxSnowPerSkyLight = skyLightN * SNOW_MAX_VALUE;
double mainInfluenceN = skyLightN * MAIN_INFLUENCE;
double mainInfluenceValue = mainInfluenceN * SNOW_VALUE_TO_CHANGE;

if (world.isRaining()) {
double neighboursInfluenceAddN = (neighboursInfluenceN * skyLightN) * NEIGHBOURS_INFLUENCE;
double neighboursInfluenceValueAdd = neighboursInfluenceAddN * SNOW_VALUE_TO_CHANGE;

int valueToAdd = (int) Math.floor(mainInfluenceValue + neighboursInfluenceValueAdd);
if (valueToAdd == 0) valueToAdd = 1;

if (blockSnow < maxSnowPerSkyLight && blockSnow <= SNOW_MAX_VALUE - valueToAdd)
world.setBlockState(pos, state.with(Leavesly.SNOW, blockSnow + valueToAdd));
else
world.setBlockState(pos, state.with(Leavesly.SNOW, (int) maxSnowPerSkyLight));
} else {
double neighboursInfluenceSubN = (Math.abs(neighboursInfluenceN - 1) * skyLightN) * NEIGHBOURS_INFLUENCE;
double neighboursInfluenceValueSub = neighboursInfluenceSubN * SNOW_VALUE_TO_CHANGE;

int valueToSub = (int) Math.floor(mainInfluenceValue + neighboursInfluenceValueSub);
if (valueToSub == 0) valueToSub = 1;

if (blockSnow > 0 && blockSnow >= valueToSub) {
world.setBlockState(pos, state.with(Leavesly.SNOW, blockSnow - valueToSub));
} else
world.setBlockState(pos, state.with(Leavesly.SNOW, 0));
}
}
}
}
}
}
Loading

0 comments on commit 4cff84a

Please sign in to comment.