Some fixes and utils

This commit is contained in:
Aleksey 2020-11-22 00:42:12 +03:00
parent 3b31532fea
commit 70d5a6d209
5 changed files with 216 additions and 6 deletions

View file

@ -35,7 +35,10 @@ public class InfusionPedestal extends BlockPedestal {
if (blockEntity instanceof InfusionPedestalEntity) { if (blockEntity instanceof InfusionPedestalEntity) {
pedestal = (InfusionPedestalEntity) blockEntity; pedestal = (InfusionPedestalEntity) blockEntity;
if (!pedestal.isEmpty() && pedestal.hasRitual()) { if (!pedestal.isEmpty() && pedestal.hasRitual()) {
if (pedestal.getRitual().checkRecipe()) { if (pedestal.getRitual().hasRecipe()) {
pedestal.getRitual().stop();
return ActionResult.SUCCESS;
} else if (pedestal.getRitual().checkRecipe()) {
return ActionResult.SUCCESS; return ActionResult.SUCCESS;
} }
} }

View file

@ -72,7 +72,7 @@ public class PedestalBlockEntity extends BlockEntity implements Inventory, Ticka
public void removeStack(World world, BlockState state) { public void removeStack(World world, BlockState state) {
world.setBlockState(pos, state.with(BlockPedestal.HAS_ITEM, false) world.setBlockState(pos, state.with(BlockPedestal.HAS_ITEM, false)
.with(BlockPedestal.HAS_LIGHT, false)); .with(BlockPedestal.HAS_LIGHT, false));
this.removeStack(0); this.removeStack(0);
} }
@ -83,12 +83,11 @@ public class PedestalBlockEntity extends BlockEntity implements Inventory, Ticka
} }
public void setStack(World world, BlockState state, ItemStack stack) { public void setStack(World world, BlockState state, ItemStack stack) {
world.setBlockState(pos, state.with(BlockPedestal.HAS_ITEM, true)); state = state.with(BlockPedestal.HAS_ITEM, true);
if (stack.getItem() == EndItems.ETERNAL_CRYSTAL) { if (stack.getItem() == EndItems.ETERNAL_CRYSTAL) {
world.setBlockState(pos, state.with(BlockPedestal.HAS_LIGHT, true)); state = state.with(BlockPedestal.HAS_LIGHT, true);
} else {
world.setBlockState(pos, state.with(BlockPedestal.HAS_LIGHT, false));
} }
world.setBlockState(pos, state);
this.setStack(0, stack); this.setStack(0, stack);
} }

View file

@ -0,0 +1,151 @@
package ru.betterend.util;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.Random;
public class ColorExtractor {
private List<Center> centers = new ArrayList<>();
private List<Integer> colors;
private Integer result;
public ColorExtractor(List<Integer> colors) {
this.colors = colors;
Random rnd = new Random();
int size = colors.size();
for (int i = 0; i < 4; i++) {
int color = colors.get(rnd.nextInt(size));
this.centers.add(new Center(color));
}
}
public int analize() {
boolean moved = true;
while (moved) {
this.remap();
moved = false;
for (Center center : centers) {
if (center.move()) {
moved = true;
}
}
}
List<Center> toClear = new ArrayList<>();
this.centers.forEach(center -> {
if (center.colors.isEmpty()) {
toClear.add(center);
}
});
if (toClear.size() > 0) {
toClear.forEach(clear ->
centers.remove(clear));
}
this.centers.sort(Center.COMPARATOR);
return this.getResult();
}
public int getResult() {
if (result == null) {
double weights = 0;
double alpha = 0;
double red = 0;
double green = 0;
double blue = 0;
for (Center center : centers) {
double weight = (double) center.colors.size() / colors.size();
weights += weight;
alpha += center.a * weight;
red += center.r * weight;
green += center.g * weight;
blue += center.b * weight;
};
int a = (int) Math.round(alpha / weights);
int r = (int) Math.round(red / weights);
int g = (int) Math.round(green / weights);
int b = (int) Math.round(blue / weights);
this.result = a << 24 | r << 16 | g << 8 | b;
}
return this.result;
}
private void remap() {
this.centers.forEach(entry -> entry.colors.clear());
this.colors.forEach(color -> {
int id = 0;
int base = centers.get(0).getColor();
int dst = ColorUtil.colorDistance(color, base);
for (Center center : centers) {
base = center.getColor();
int dst1 = ColorUtil.colorDistance(color, base);
if (dst1 < dst) {
dst = dst1;
id = centers.indexOf(center);
}
}
this.centers.get(id).colors.add(color);
});
}
private static class Center {
static final Comparator<Center> COMPARATOR = new Comparator<Center>() {
@Override
public int compare(Center c1, Center c2) {
return Integer.compare(c1.getColor(), c2.getColor());
}
};
List<Integer> colors = new ArrayList<>();
double a, r, g, b;
Center(int color) {
this.a = (color >> 24) & 255;
this.r = (color >> 16) & 255;
this.g = (color >> 8) & 255;
this.b = color & 255;
}
private void update(double a, double r, double g, double b) {
this.a = a;
this.r = r;
this.g = g;
this.b = b;
}
public int getColor() {
int a = (int) Math.round(this.a);
int r = (int) Math.round(this.r);
int g = (int) Math.round(this.g);
int b = (int) Math.round(this.b);
return a << 24 | r << 16 | g << 8 | b;
}
public boolean move() {
double or = r;
double og = g;
double ob = b;
double a = 0, r = 0, g = 0, b = 0;
int size = this.colors.size();
for (int col : colors) {
a += (col >> 24) & 255;
r += (col >> 16) & 255;
g += (col >> 8) & 255;
b += col & 255;
}
a /= size;
r /= size;
g /= size;
b /= size;
this.update(a, r, g, b);
return Math.abs(r - or) > 0.1 ||
Math.abs(g - og) > 0.1 ||
Math.abs(b - ob) > 0.1;
}
}
}

View file

@ -1,8 +1,18 @@
package ru.betterend.util; package ru.betterend.util;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import net.fabricmc.api.EnvType; import net.fabricmc.api.EnvType;
import net.fabricmc.api.Environment; import net.fabricmc.api.Environment;
import net.fabricmc.fabric.impl.client.indigo.renderer.helper.ColorHelper; import net.fabricmc.fabric.impl.client.indigo.renderer.helper.ColorHelper;
import net.minecraft.client.MinecraftClient;
import net.minecraft.client.texture.NativeImage;
import net.minecraft.resource.Resource;
import net.minecraft.resource.ResourceManager;
import net.minecraft.util.Identifier;
import net.minecraft.util.math.MathHelper; import net.minecraft.util.math.MathHelper;
import ru.betterend.BetterEnd; import ru.betterend.BetterEnd;
@ -165,4 +175,47 @@ public class ColorUtil {
public static int applyTint(int color, int tint) { public static int applyTint(int color, int tint) {
return colorBrigtness(ColorHelper.multiplyColor(color, tint), 1.5F); return colorBrigtness(ColorHelper.multiplyColor(color, tint), 1.5F);
} }
public static int colorDistance(int color1, int color2) {
int r1 = (color1 >> 16) & 255;
int g1 = (color1 >> 8) & 255;
int b1 = color1 & 255;
int r2 = (color2 >> 16) & 255;
int g2 = (color2 >> 8) & 255;
int b2 = color2 & 255;
return MHelper.pow2(r1 - r2) + MHelper.pow2(g1 - g2) + MHelper.pow2(b1 - b2);
}
public static int extractColor(Identifier texture) {
NativeImage image = loadImage(texture, 16, 16);
List<Integer> colors = new ArrayList<>();
for (int i = 0; i < image.getWidth(); i++) {
for (int j = 0; j < 16; j++) {
int col = image.getPixelColor(i, j);
if (((col >> 24) & 255) > 0) {
colors.add(ABGRtoARGB(col));
}
}
}
image.close();
if (colors.size() == 0) return -1;
ColorExtractor extractor = new ColorExtractor(colors);
return extractor.analize();
}
public static NativeImage loadImage(Identifier image, int w, int h) {
MinecraftClient minecraft = MinecraftClient.getInstance();
ResourceManager resourceManager = minecraft.getResourceManager();
if (resourceManager.containsResource(image)) {
try (Resource resource = resourceManager.getResource(image)) {
return NativeImage.read(resource.getInputStream());
} catch (IOException e) {
BetterEnd.LOGGER.warning("Can't load texture image: {}. Will be created empty image.", image);
BetterEnd.LOGGER.warning("Cause: {}.", e.getMessage());
}
}
return new NativeImage(w, h, false);
}
} }

View file

@ -133,4 +133,8 @@ public class MHelper {
array[i2] = element; array[i2] = element;
} }
} }
public static int pow2(int i) {
return i * i;
}
} }