Eternal Crystal item & model

This commit is contained in:
Aleksey 2020-11-21 23:29:45 +03:00
parent 7192df49d1
commit 3b31532fea
10 changed files with 225 additions and 19 deletions

View file

@ -8,6 +8,7 @@ public class BlockProperties {
public static final EnumProperty<TripleShape> TRIPLE_SHAPE = EnumProperty.of("shape", TripleShape.class); 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 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_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 final BooleanProperty ACTIVATED = BooleanProperty.of("active");
public static enum TripleShape implements StringIdentifiable { public static enum TripleShape implements StringIdentifiable {

View file

@ -46,6 +46,7 @@ import ru.betterend.util.BlocksHelper;
public class BlockPedestal extends BlockBaseNotFull implements BlockEntityProvider { public class BlockPedestal extends BlockBaseNotFull implements BlockEntityProvider {
public final static EnumProperty<PedestalState> STATE = BlockProperties.PEDESTAL_STATE; public final static EnumProperty<PedestalState> STATE = BlockProperties.PEDESTAL_STATE;
public static final BooleanProperty HAS_ITEM = BlockProperties.HAS_ITEM; 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_DEFAULT;
private static final VoxelShape SHAPE_COLUMN; private static final VoxelShape SHAPE_COLUMN;
@ -82,8 +83,10 @@ public class BlockPedestal extends BlockBaseNotFull implements BlockEntityProvid
protected float height = 1.0F; protected float height = 1.0F;
public BlockPedestal(Block parent) { public BlockPedestal(Block parent) {
super(FabricBlockSettings.copyOf(parent)); super(FabricBlockSettings.copyOf(parent).luminance(state -> {
this.setDefaultState(stateManager.getDefaultState().with(STATE, PedestalState.DEFAULT).with(HAS_ITEM, false)); 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; this.parent = parent;
} }
@ -294,7 +297,7 @@ public class BlockPedestal extends BlockBaseNotFull implements BlockEntityProvid
@Override @Override
protected void appendProperties(StateManager.Builder<Block, BlockState> stateManager) { protected void appendProperties(StateManager.Builder<Block, BlockState> stateManager) {
stateManager.add(STATE, HAS_ITEM); stateManager.add(STATE, HAS_ITEM, HAS_LIGHT);
} }
@Override @Override

View file

@ -12,6 +12,7 @@ import net.minecraft.util.Tickable;
import net.minecraft.world.World; import net.minecraft.world.World;
import ru.betterend.blocks.basis.BlockPedestal; import ru.betterend.blocks.basis.BlockPedestal;
import ru.betterend.registry.EndBlockEntities; import ru.betterend.registry.EndBlockEntities;
import ru.betterend.registry.EndItems;
public class PedestalBlockEntity extends BlockEntity implements Inventory, Tickable { public class PedestalBlockEntity extends BlockEntity implements Inventory, Tickable {
private ItemStack activeItem = ItemStack.EMPTY; private ItemStack activeItem = ItemStack.EMPTY;
@ -70,7 +71,8 @@ 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));
this.removeStack(0); this.removeStack(0);
} }
@ -82,6 +84,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)); 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); this.setStack(0, stack);
} }

View file

@ -19,6 +19,7 @@ import net.minecraft.item.Items;
import net.minecraft.util.DyeColor; import net.minecraft.util.DyeColor;
import net.minecraft.util.Identifier; import net.minecraft.util.Identifier;
import net.minecraft.util.math.MathHelper; import net.minecraft.util.math.MathHelper;
import ru.betterend.blocks.EternalPedestal; import ru.betterend.blocks.EternalPedestal;
import ru.betterend.blocks.basis.BlockPedestal; import ru.betterend.blocks.basis.BlockPedestal;
import ru.betterend.blocks.entities.PedestalBlockEntity; import ru.betterend.blocks.entities.PedestalBlockEntity;

View file

@ -9,31 +9,56 @@ import net.minecraft.client.util.math.MatrixStack;
import net.minecraft.client.util.math.Vector3f; import net.minecraft.client.util.math.Vector3f;
import net.minecraft.util.Identifier; import net.minecraft.util.Identifier;
import net.minecraft.util.math.MathHelper; import net.minecraft.util.math.MathHelper;
import net.minecraft.util.math.Vec3i;
import ru.betterend.BetterEnd; import ru.betterend.BetterEnd;
import ru.betterend.blocks.AuroraCrystalBlock;
import ru.betterend.util.ColorUtil;
import ru.betterend.util.MHelper;
public class EternalCrystalRenderer { public class EternalCrystalRenderer {
private static final Identifier CRYSTAL_TEXTURE = BetterEnd.makeID("textures/entity/eternal_crystal.png"); private static final Identifier CRYSTAL_TEXTURE = BetterEnd.makeID("textures/entity/eternal_crystal.png");
private static final RenderLayer RENDER_LAYER; private static final RenderLayer RENDER_LAYER;
private static final ModelPart SHARDS;
private static final ModelPart CORE; private static final ModelPart CORE;
public static void render(int age, float tickDelta, MatrixStack matrices, VertexConsumerProvider vertexConsumerProvider, int light) { public static void render(int age, float tickDelta, MatrixStack matrices, VertexConsumerProvider vertexConsumerProvider, int light) {
VertexConsumer vertexConsumer = vertexConsumerProvider.getBuffer(RENDER_LAYER); VertexConsumer vertexConsumer = vertexConsumerProvider.getBuffer(RENDER_LAYER);
float[] colors = colors(age);
float rotation = (age + tickDelta) / 25.0F + 6.0F; float rotation = (age + tickDelta) / 25.0F + 6.0F;
float altitude = MathHelper.sin((age + tickDelta) / 10.0F) * 0.1F + 0.1F;
matrices.push(); matrices.push();
matrices.scale(0.6F, 0.6F, 0.6F); 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.multiply(Vector3f.POSITIVE_Y.getRadialQuaternion(rotation));
matrices.push(); CORE.render(matrices, vertexConsumer, light, OverlayTexture.DEFAULT_UV, colors[0], colors[1], colors[2], colors[3]);
matrices.translate(-0.125D, -0.1D, -0.125D); SHARDS.render(matrices, vertexConsumer, light, OverlayTexture.DEFAULT_UV, colors[0], colors[1], colors[2], colors[3]);
CORE.render(matrices, vertexConsumer, light, OverlayTexture.DEFAULT_UV);
matrices.pop();
matrices.pop(); 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 { 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 = 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);
} }
} }

View file

@ -1,11 +1,18 @@
package ru.betterend.item; package ru.betterend.item;
import net.minecraft.item.Item; import net.minecraft.item.Item;
import ru.betterend.patterns.Patterned;
import ru.betterend.patterns.Patterns;
import ru.betterend.registry.EndItems; import ru.betterend.registry.EndItems;
public class EternalCrystal extends Item { public class EternalCrystal extends Item implements Patterned {
public EternalCrystal() { public EternalCrystal() {
super(EndItems.makeSettings()); super(EndItems.makeSettings());
} }
@Override
public String getModelPattern(String name) {
return Patterns.createJson(Patterns.ITEM_GENERATED, name);
}
} }

View 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);
}
}

View file

@ -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

Before After
Before After

Binary file not shown.

After

Width:  |  Height:  |  Size: 528 B