diff --git a/src/main/java/ru/betterend/blocks/InfusionPedestal.java b/src/main/java/ru/betterend/blocks/InfusionPedestal.java index 6b16e515..ff59fbbb 100644 --- a/src/main/java/ru/betterend/blocks/InfusionPedestal.java +++ b/src/main/java/ru/betterend/blocks/InfusionPedestal.java @@ -35,7 +35,10 @@ public class InfusionPedestal extends BlockPedestal { if (blockEntity instanceof InfusionPedestalEntity) { pedestal = (InfusionPedestalEntity) blockEntity; 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; } } diff --git a/src/main/java/ru/betterend/blocks/entities/PedestalBlockEntity.java b/src/main/java/ru/betterend/blocks/entities/PedestalBlockEntity.java index 86fd7126..5165470e 100644 --- a/src/main/java/ru/betterend/blocks/entities/PedestalBlockEntity.java +++ b/src/main/java/ru/betterend/blocks/entities/PedestalBlockEntity.java @@ -72,7 +72,7 @@ public class PedestalBlockEntity extends BlockEntity implements Inventory, Ticka public void removeStack(World world, BlockState state) { world.setBlockState(pos, state.with(BlockPedestal.HAS_ITEM, false) - .with(BlockPedestal.HAS_LIGHT, false)); + .with(BlockPedestal.HAS_LIGHT, false)); this.removeStack(0); } @@ -83,12 +83,11 @@ public class PedestalBlockEntity extends BlockEntity implements Inventory, Ticka } 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) { - world.setBlockState(pos, state.with(BlockPedestal.HAS_LIGHT, true)); - } else { - world.setBlockState(pos, state.with(BlockPedestal.HAS_LIGHT, false)); + state = state.with(BlockPedestal.HAS_LIGHT, true); } + world.setBlockState(pos, state); this.setStack(0, stack); } diff --git a/src/main/java/ru/betterend/util/ColorExtractor.java b/src/main/java/ru/betterend/util/ColorExtractor.java new file mode 100644 index 00000000..a1827a61 --- /dev/null +++ b/src/main/java/ru/betterend/util/ColorExtractor.java @@ -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
centers = new ArrayList<>(); + private List colors; + private Integer result; + + public ColorExtractor(List 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
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
COMPARATOR = new Comparator
() { + @Override + public int compare(Center c1, Center c2) { + return Integer.compare(c1.getColor(), c2.getColor()); + } + }; + + List 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; + } + } +} diff --git a/src/main/java/ru/betterend/util/ColorUtil.java b/src/main/java/ru/betterend/util/ColorUtil.java index 2cb6e80a..771c94a6 100644 --- a/src/main/java/ru/betterend/util/ColorUtil.java +++ b/src/main/java/ru/betterend/util/ColorUtil.java @@ -1,8 +1,18 @@ 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.Environment; 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 ru.betterend.BetterEnd; @@ -165,4 +175,47 @@ public class ColorUtil { public static int applyTint(int color, int tint) { 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 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); + } } \ No newline at end of file diff --git a/src/main/java/ru/betterend/util/MHelper.java b/src/main/java/ru/betterend/util/MHelper.java index 8402d39e..bf08ac41 100644 --- a/src/main/java/ru/betterend/util/MHelper.java +++ b/src/main/java/ru/betterend/util/MHelper.java @@ -133,4 +133,8 @@ public class MHelper { array[i2] = element; } } + + public static int pow2(int i) { + return i * i; + } }