Eternal Crystal item & model
This commit is contained in:
parent
7192df49d1
commit
3b31532fea
10 changed files with 225 additions and 19 deletions
|
@ -8,6 +8,7 @@ public class BlockProperties {
|
|||
public static final EnumProperty<TripleShape> TRIPLE_SHAPE = EnumProperty.of("shape", TripleShape.class);
|
||||
public final static EnumProperty<PedestalState> PEDESTAL_STATE = EnumProperty.of("state", PedestalState.class);
|
||||
public static final BooleanProperty HAS_ITEM = BooleanProperty.of("has_item");
|
||||
public static final BooleanProperty HAS_LIGHT = BooleanProperty.of("has_light");
|
||||
public static final BooleanProperty ACTIVATED = BooleanProperty.of("active");
|
||||
|
||||
public static enum TripleShape implements StringIdentifiable {
|
||||
|
|
|
@ -46,6 +46,7 @@ import ru.betterend.util.BlocksHelper;
|
|||
public class BlockPedestal extends BlockBaseNotFull implements BlockEntityProvider {
|
||||
public final static EnumProperty<PedestalState> STATE = BlockProperties.PEDESTAL_STATE;
|
||||
public static final BooleanProperty HAS_ITEM = BlockProperties.HAS_ITEM;
|
||||
public static final BooleanProperty HAS_LIGHT = BlockProperties.HAS_LIGHT;
|
||||
|
||||
private static final VoxelShape SHAPE_DEFAULT;
|
||||
private static final VoxelShape SHAPE_COLUMN;
|
||||
|
@ -82,8 +83,10 @@ public class BlockPedestal extends BlockBaseNotFull implements BlockEntityProvid
|
|||
protected float height = 1.0F;
|
||||
|
||||
public BlockPedestal(Block parent) {
|
||||
super(FabricBlockSettings.copyOf(parent));
|
||||
this.setDefaultState(stateManager.getDefaultState().with(STATE, PedestalState.DEFAULT).with(HAS_ITEM, false));
|
||||
super(FabricBlockSettings.copyOf(parent).luminance(state -> {
|
||||
return state.get(HAS_LIGHT) ? 12 : 0;
|
||||
}));
|
||||
this.setDefaultState(stateManager.getDefaultState().with(STATE, PedestalState.DEFAULT).with(HAS_ITEM, false).with(HAS_LIGHT, false));
|
||||
this.parent = parent;
|
||||
}
|
||||
|
||||
|
@ -294,7 +297,7 @@ public class BlockPedestal extends BlockBaseNotFull implements BlockEntityProvid
|
|||
|
||||
@Override
|
||||
protected void appendProperties(StateManager.Builder<Block, BlockState> stateManager) {
|
||||
stateManager.add(STATE, HAS_ITEM);
|
||||
stateManager.add(STATE, HAS_ITEM, HAS_LIGHT);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -12,6 +12,7 @@ import net.minecraft.util.Tickable;
|
|||
import net.minecraft.world.World;
|
||||
import ru.betterend.blocks.basis.BlockPedestal;
|
||||
import ru.betterend.registry.EndBlockEntities;
|
||||
import ru.betterend.registry.EndItems;
|
||||
|
||||
public class PedestalBlockEntity extends BlockEntity implements Inventory, Tickable {
|
||||
private ItemStack activeItem = ItemStack.EMPTY;
|
||||
|
@ -70,7 +71,8 @@ public class PedestalBlockEntity extends BlockEntity implements Inventory, Ticka
|
|||
}
|
||||
|
||||
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));
|
||||
this.removeStack(0);
|
||||
}
|
||||
|
||||
|
@ -82,6 +84,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));
|
||||
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));
|
||||
}
|
||||
this.setStack(0, stack);
|
||||
}
|
||||
|
||||
|
|
|
@ -19,6 +19,7 @@ import net.minecraft.item.Items;
|
|||
import net.minecraft.util.DyeColor;
|
||||
import net.minecraft.util.Identifier;
|
||||
import net.minecraft.util.math.MathHelper;
|
||||
|
||||
import ru.betterend.blocks.EternalPedestal;
|
||||
import ru.betterend.blocks.basis.BlockPedestal;
|
||||
import ru.betterend.blocks.entities.PedestalBlockEntity;
|
||||
|
|
|
@ -9,31 +9,56 @@ import net.minecraft.client.util.math.MatrixStack;
|
|||
import net.minecraft.client.util.math.Vector3f;
|
||||
import net.minecraft.util.Identifier;
|
||||
import net.minecraft.util.math.MathHelper;
|
||||
import net.minecraft.util.math.Vec3i;
|
||||
|
||||
import ru.betterend.BetterEnd;
|
||||
import ru.betterend.blocks.AuroraCrystalBlock;
|
||||
import ru.betterend.util.ColorUtil;
|
||||
import ru.betterend.util.MHelper;
|
||||
|
||||
public class EternalCrystalRenderer {
|
||||
private static final Identifier CRYSTAL_TEXTURE = BetterEnd.makeID("textures/entity/eternal_crystal.png");
|
||||
private static final RenderLayer RENDER_LAYER;
|
||||
private static final ModelPart SHARDS;
|
||||
private static final ModelPart CORE;
|
||||
|
||||
public static void render(int age, float tickDelta, MatrixStack matrices, VertexConsumerProvider vertexConsumerProvider, int light) {
|
||||
VertexConsumer vertexConsumer = vertexConsumerProvider.getBuffer(RENDER_LAYER);
|
||||
float[] colors = colors(age);
|
||||
float rotation = (age + tickDelta) / 25.0F + 6.0F;
|
||||
float altitude = MathHelper.sin((age + tickDelta) / 10.0F) * 0.1F + 0.1F;
|
||||
matrices.push();
|
||||
matrices.scale(0.6F, 0.6F, 0.6F);
|
||||
matrices.translate(0.0D, altitude / 2.0D, 0.0D);
|
||||
matrices.multiply(Vector3f.POSITIVE_Y.getRadialQuaternion(rotation));
|
||||
matrices.push();
|
||||
matrices.translate(-0.125D, -0.1D, -0.125D);
|
||||
CORE.render(matrices, vertexConsumer, light, OverlayTexture.DEFAULT_UV);
|
||||
matrices.pop();
|
||||
CORE.render(matrices, vertexConsumer, light, OverlayTexture.DEFAULT_UV, colors[0], colors[1], colors[2], colors[3]);
|
||||
SHARDS.render(matrices, vertexConsumer, light, OverlayTexture.DEFAULT_UV, colors[0], colors[1], colors[2], colors[3]);
|
||||
matrices.pop();
|
||||
}
|
||||
|
||||
private static float[] colors(int age) {
|
||||
double delta = age * 0.01;
|
||||
int index = MHelper.floor(delta);
|
||||
int index2 = (index + 1) & 3;
|
||||
delta -= index;
|
||||
index &= 3;
|
||||
|
||||
Vec3i color1 = AuroraCrystalBlock.COLORS[index];
|
||||
Vec3i color2 = AuroraCrystalBlock.COLORS[index2];
|
||||
|
||||
int r = MHelper.floor(MathHelper.lerp(delta, color1.getX(), color2.getX()));
|
||||
int g = MHelper.floor(MathHelper.lerp(delta, color1.getY(), color2.getY()));
|
||||
int b = MHelper.floor(MathHelper.lerp(delta, color1.getZ(), color2.getZ()));
|
||||
|
||||
return ColorUtil.toFloatArray(MHelper.color(r, g, b));
|
||||
}
|
||||
|
||||
static {
|
||||
RENDER_LAYER = RenderLayer.getEntityTranslucent(CRYSTAL_TEXTURE);
|
||||
RENDER_LAYER = RenderLayer.getBeaconBeam(CRYSTAL_TEXTURE, true);
|
||||
SHARDS = new ModelPart(16, 16, 2, 4);
|
||||
SHARDS.addCuboid(-5.0F, 1.0F, -3.0F, 2.0F, 8.0F, 2.0F);
|
||||
SHARDS.addCuboid(3.0F, -1.0F, -1.0F, 2.0F, 8.0F, 2.0F);
|
||||
SHARDS.addCuboid(-1.0F, 0.0F, -5.0F, 2.0F, 4.0F, 2.0F);
|
||||
SHARDS.addCuboid(0.0F, 3.0F, 4.0F, 2.0F, 6.0F, 2.0F);
|
||||
CORE = new ModelPart(16, 16, 0, 0);
|
||||
CORE.addCuboid(0.0F, 0.0F, 0.0F, 4.0F, 12.0F, 4.0F);
|
||||
CORE.addCuboid(-2.0F, -2.0F, -2.0F, 4.0F, 12.0F, 4.0F);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,11 +1,18 @@
|
|||
package ru.betterend.item;
|
||||
|
||||
import net.minecraft.item.Item;
|
||||
import ru.betterend.patterns.Patterned;
|
||||
import ru.betterend.patterns.Patterns;
|
||||
import ru.betterend.registry.EndItems;
|
||||
|
||||
public class EternalCrystal extends Item {
|
||||
public class EternalCrystal extends Item implements Patterned {
|
||||
|
||||
public EternalCrystal() {
|
||||
super(EndItems.makeSettings());
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getModelPattern(String name) {
|
||||
return Patterns.createJson(Patterns.ITEM_GENERATED, name);
|
||||
}
|
||||
}
|
168
src/main/java/ru/betterend/util/ColorUtil.java
Normal file
168
src/main/java/ru/betterend/util/ColorUtil.java
Normal file
|
@ -0,0 +1,168 @@
|
|||
package ru.betterend.util;
|
||||
|
||||
import net.fabricmc.api.EnvType;
|
||||
import net.fabricmc.api.Environment;
|
||||
import net.fabricmc.fabric.impl.client.indigo.renderer.helper.ColorHelper;
|
||||
import net.minecraft.util.math.MathHelper;
|
||||
|
||||
import ru.betterend.BetterEnd;
|
||||
|
||||
@Environment(EnvType.CLIENT)
|
||||
public class ColorUtil {
|
||||
|
||||
private static float[] floatBuffer = new float[4];
|
||||
|
||||
public static int[] toIntArray(int color) {
|
||||
return new int[] {
|
||||
(color >> 24) & 255,
|
||||
(color >> 16) & 255,
|
||||
(color >> 8) & 255,
|
||||
color & 255
|
||||
};
|
||||
}
|
||||
|
||||
public static float[] toFloatArray(int color) {
|
||||
floatBuffer[0] = ((color >> 16 & 255) / 255.0F);
|
||||
floatBuffer[1] = ((color >> 8 & 255) / 255.0F);
|
||||
floatBuffer[2] = ((color & 255) / 255.0F);
|
||||
floatBuffer[3] = ((color >> 24 & 255) / 255.0F);
|
||||
|
||||
return floatBuffer;
|
||||
}
|
||||
|
||||
public static float[] RGBtoHSB(int r, int g, int b, float[] hsbvals) {
|
||||
float hue, saturation, brightness;
|
||||
if (hsbvals == null) {
|
||||
hsbvals = floatBuffer;
|
||||
}
|
||||
int cmax = (r > g) ? r : g;
|
||||
if (b > cmax) cmax = b;
|
||||
int cmin = (r < g) ? r : g;
|
||||
if (b < cmin) cmin = b;
|
||||
|
||||
brightness = ((float) cmax) / 255.0F;
|
||||
if (cmax != 0)
|
||||
saturation = ((float) (cmax - cmin)) / ((float) cmax);
|
||||
else
|
||||
saturation = 0;
|
||||
if (saturation == 0)
|
||||
hue = 0;
|
||||
else {
|
||||
float redc = ((float) (cmax - r)) / ((float) (cmax - cmin));
|
||||
float greenc = ((float) (cmax - g)) / ((float) (cmax - cmin));
|
||||
float bluec = ((float) (cmax - b)) / ((float) (cmax - cmin));
|
||||
if (r == cmax)
|
||||
hue = bluec - greenc;
|
||||
else if (g == cmax)
|
||||
hue = 2.0F + redc - bluec;
|
||||
else
|
||||
hue = 4.0F + greenc - redc;
|
||||
hue = hue / 6.0F;
|
||||
if (hue < 0)
|
||||
hue = hue + 1.0F;
|
||||
}
|
||||
hsbvals[0] = hue;
|
||||
hsbvals[1] = saturation;
|
||||
hsbvals[2] = brightness;
|
||||
return hsbvals;
|
||||
}
|
||||
|
||||
public static int HSBtoRGB(float hue, float saturation, float brightness) {
|
||||
int r = 0, g = 0, b = 0;
|
||||
if (saturation == 0) {
|
||||
r = g = b = (int) (brightness * 255.0F + 0.5F);
|
||||
} else {
|
||||
float h = (hue - (float)Math.floor(hue)) * 6.0F;
|
||||
float f = h - (float)java.lang.Math.floor(h);
|
||||
float p = brightness * (1.0F - saturation);
|
||||
float q = brightness * (1.0F - saturation * f);
|
||||
float t = brightness * (1.0F - (saturation * (1.0F - f)));
|
||||
switch ((int) h) {
|
||||
case 0:
|
||||
r = (int) (brightness * 255.0F + 0.5F);
|
||||
g = (int) (t * 255.0F + 0.5F);
|
||||
b = (int) (p * 255.0F + 0.5F);
|
||||
break;
|
||||
case 1:
|
||||
r = (int) (q * 255.0F + 0.5F);
|
||||
g = (int) (brightness * 255.0F + 0.5F);
|
||||
b = (int) (p * 255.0F + 0.5F);
|
||||
break;
|
||||
case 2:
|
||||
r = (int) (p * 255.0F + 0.5F);
|
||||
g = (int) (brightness * 255.0F + 0.5F);
|
||||
b = (int) (t * 255.0F + 0.5F);
|
||||
break;
|
||||
case 3:
|
||||
r = (int) (p * 255.0F + 0.5F);
|
||||
g = (int) (q * 255.0F + 0.5F);
|
||||
b = (int) (brightness * 255.0F + 0.5F);
|
||||
break;
|
||||
case 4:
|
||||
r = (int) (t * 255.0F + 0.5F);
|
||||
g = (int) (p * 255.0F + 0.5F);
|
||||
b = (int) (brightness * 255.0F + 0.5F);
|
||||
break;
|
||||
case 5:
|
||||
r = (int) (brightness * 255.0F + 0.5F);
|
||||
g = (int) (p * 255.0F + 0.5F);
|
||||
b = (int) (q * 255.0F + 0.5F);
|
||||
break;
|
||||
}
|
||||
}
|
||||
return 0xFF000000 | (r << 16) | (g << 8) | (b << 0);
|
||||
}
|
||||
|
||||
public static int parseHex(String hexColor) {
|
||||
int len = hexColor.length();
|
||||
if (len < 6 || len > 8 || len % 2 > 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
int color, shift;
|
||||
if(len == 6) {
|
||||
color = 0xFF000000; shift = 16;
|
||||
} else {
|
||||
color = 0; shift = 24;
|
||||
}
|
||||
|
||||
try {
|
||||
String[] splited = hexColor.split("(?<=\\G.{2})");
|
||||
for (String digit : splited) {
|
||||
color |= Integer.valueOf(digit, 16) << shift;
|
||||
shift -= 8;
|
||||
}
|
||||
} catch(NumberFormatException ex) {
|
||||
BetterEnd.LOGGER.catching(ex);
|
||||
return -1;
|
||||
}
|
||||
|
||||
return color;
|
||||
}
|
||||
|
||||
public static int toABGR(int color) {
|
||||
int r = (color >> 16) & 255;
|
||||
int g = (color >> 8) & 255;
|
||||
int b = color & 255;
|
||||
return 0xFF000000 | b << 16 | g << 8 | r;
|
||||
}
|
||||
|
||||
public static int ABGRtoARGB(int color) {
|
||||
int a = (color >> 24) & 255;
|
||||
int b = (color >> 16) & 255;
|
||||
int g = (color >> 8) & 255;
|
||||
int r = color & 255;
|
||||
return a << 24 | r << 16 | g << 8 | b;
|
||||
}
|
||||
|
||||
public static int colorBrigtness(int color, float val) {
|
||||
RGBtoHSB((color >> 16) & 255, (color >> 8) & 255, color & 255, floatBuffer);
|
||||
floatBuffer[2] += val / 10.0F;
|
||||
floatBuffer[2] = MathHelper.clamp(floatBuffer[2], 0.0F, 1.0F);
|
||||
return HSBtoRGB(floatBuffer[0], floatBuffer[1], floatBuffer[2]);
|
||||
}
|
||||
|
||||
public static int applyTint(int color, int tint) {
|
||||
return colorBrigtness(ColorHelper.multiplyColor(color, tint), 1.5F);
|
||||
}
|
||||
}
|
|
@ -1,6 +0,0 @@
|
|||
{
|
||||
"parent": "item/generated",
|
||||
"textures": {
|
||||
"layer0": "betterend:item/crystal_shards"
|
||||
}
|
||||
}
|
Binary file not shown.
Before Width: | Height: | Size: 338 B After Width: | Height: | Size: 415 B |
Binary file not shown.
After Width: | Height: | Size: 528 B |
Loading…
Add table
Add a link
Reference in a new issue