implement sentinels!
This commit is contained in:
parent
65acd401f9
commit
aea94953a7
3 changed files with 90 additions and 25 deletions
|
@ -2,62 +2,127 @@ package at.petrak.hexcasting.client;
|
||||||
|
|
||||||
import at.petrak.hexcasting.common.casting.operators.spells.sentinel.CapSentinel;
|
import at.petrak.hexcasting.common.casting.operators.spells.sentinel.CapSentinel;
|
||||||
import at.petrak.hexcasting.common.lib.LibCapabilities;
|
import at.petrak.hexcasting.common.lib.LibCapabilities;
|
||||||
import at.petrak.hexcasting.common.lib.RegisterHelper;
|
|
||||||
import com.mojang.blaze3d.systems.RenderSystem;
|
import com.mojang.blaze3d.systems.RenderSystem;
|
||||||
import com.mojang.blaze3d.vertex.DefaultVertexFormat;
|
import com.mojang.blaze3d.vertex.DefaultVertexFormat;
|
||||||
import com.mojang.blaze3d.vertex.PoseStack;
|
import com.mojang.blaze3d.vertex.PoseStack;
|
||||||
import com.mojang.blaze3d.vertex.Tesselator;
|
import com.mojang.blaze3d.vertex.Tesselator;
|
||||||
import com.mojang.blaze3d.vertex.VertexFormat;
|
import com.mojang.blaze3d.vertex.VertexFormat;
|
||||||
|
import com.mojang.math.Quaternion;
|
||||||
|
import com.mojang.math.Vector3f;
|
||||||
import net.minecraft.client.Minecraft;
|
import net.minecraft.client.Minecraft;
|
||||||
import net.minecraft.client.player.LocalPlayer;
|
import net.minecraft.client.player.LocalPlayer;
|
||||||
import net.minecraft.client.renderer.GameRenderer;
|
import net.minecraft.client.renderer.GameRenderer;
|
||||||
import net.minecraftforge.client.event.RenderGameOverlayEvent;
|
import net.minecraft.util.Mth;
|
||||||
|
import net.minecraftforge.client.event.RenderLevelLastEvent;
|
||||||
import net.minecraftforge.eventbus.api.SubscribeEvent;
|
import net.minecraftforge.eventbus.api.SubscribeEvent;
|
||||||
|
|
||||||
|
import java.util.function.Consumer;
|
||||||
|
|
||||||
public class HexRenderOverlays {
|
public class HexRenderOverlays {
|
||||||
@SubscribeEvent
|
@SubscribeEvent
|
||||||
public static void overlay(RenderGameOverlayEvent evt) {
|
public static void overlay(RenderLevelLastEvent evt) {
|
||||||
var player = Minecraft.getInstance().player;
|
var player = Minecraft.getInstance().player;
|
||||||
var maybeSentinelCap = player.getCapability(LibCapabilities.SENTINEL).resolve();
|
var maybeSentinelCap = player.getCapability(LibCapabilities.SENTINEL).resolve();
|
||||||
if (maybeSentinelCap.isPresent()) {
|
if (maybeSentinelCap.isPresent()) {
|
||||||
var cap = maybeSentinelCap.get();
|
var cap = maybeSentinelCap.get();
|
||||||
renderSentinel(cap, player, evt.getMatrixStack());
|
if (cap.hasSentinel) {
|
||||||
|
renderSentinel(cap, player, evt.getPoseStack(), evt.getPartialTick());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void renderSentinel(CapSentinel sentinel, LocalPlayer owner,
|
private static void renderSentinel(CapSentinel sentinel, LocalPlayer owner,
|
||||||
PoseStack ps) {
|
PoseStack ps, float partialTicks) {
|
||||||
ps.pushPose();
|
ps.pushPose();
|
||||||
|
|
||||||
// i am just reading VCC code i have no idea
|
// zero vector is the player
|
||||||
var mc = Minecraft.getInstance();
|
var mc = Minecraft.getInstance();
|
||||||
ps.translate(sentinel.position.x, sentinel.position.y, sentinel.position.z);
|
var playerPos = mc.gameRenderer.getMainCamera().getPosition();
|
||||||
var campos = mc.gameRenderer.getMainCamera().getLookVector();
|
ps.translate(
|
||||||
ps.translate(-campos.x(), -campos.y(), -campos.z());
|
sentinel.position.x - playerPos.x + 0.5,
|
||||||
|
sentinel.position.y - playerPos.y + 0.5,
|
||||||
|
sentinel.position.z - playerPos.z + 0.5);
|
||||||
|
|
||||||
ps.mulPose(mc.gameRenderer.getMainCamera().rotation());
|
var time = mc.level.getLevelData().getGameTime() + partialTicks;
|
||||||
float scale = 0.0166666f * 1.6f;
|
var bobSpeed = 1f / 20;
|
||||||
ps.scale(-scale, -scale, scale);
|
var magnitude = 0.1f;
|
||||||
|
ps.translate(0, Mth.sin(bobSpeed * time) * magnitude, 0);
|
||||||
|
var spinSpeed = 1f / 30;
|
||||||
|
ps.mulPose(Quaternion.fromXYZ(new Vector3f(0, spinSpeed * time, 0)));
|
||||||
|
|
||||||
|
float scale = 0.5f;
|
||||||
|
ps.scale(scale, scale, scale);
|
||||||
|
|
||||||
RenderSystem.setShader(GameRenderer::getPositionColorTexShader);
|
|
||||||
RenderSystem.setShaderTexture(0, RegisterHelper.prefix("entity/sentinel.png"));
|
|
||||||
|
|
||||||
var tess = Tesselator.getInstance();
|
var tess = Tesselator.getInstance();
|
||||||
var buf = tess.getBuilder();
|
var buf = tess.getBuilder();
|
||||||
|
|
||||||
var neo = ps.last().pose();
|
var neo = ps.last().pose();
|
||||||
|
RenderSystem.enableBlend();
|
||||||
|
RenderSystem.setShader(GameRenderer::getRendertypeLinesShader);
|
||||||
RenderSystem.disableDepthTest();
|
RenderSystem.disableDepthTest();
|
||||||
buf.begin(VertexFormat.Mode.TRIANGLE_STRIP, DefaultVertexFormat.POSITION_COLOR_TEX);
|
RenderSystem.disableCull();
|
||||||
buf.vertex(neo, 0f, 0f, 0f).color(sentinel.color).uv(0f, 0f).endVertex();
|
RenderSystem.lineWidth(5f);
|
||||||
buf.vertex(neo, 0f, 1f, 0f).color(sentinel.color).uv(0f, 1f).endVertex();
|
|
||||||
buf.vertex(neo, 1f, 0f, 0f).color(sentinel.color).uv(1f, 0f).endVertex();
|
// we have to put *something* in the normal lest flickering
|
||||||
buf.vertex(neo, 1f, 1f, 0f).color(sentinel.color).uv(1f, 1f).endVertex();
|
Consumer<float[]> v = (point) -> buf.vertex(neo, point[0], point[1], point[2])
|
||||||
|
.color(sentinel.color)
|
||||||
|
.normal(point[0], point[1], point[2])
|
||||||
|
.endVertex();
|
||||||
|
|
||||||
|
// Icosahedron inscribed inside the unit sphere
|
||||||
|
for (int side = 0; side <= 1; side++) {
|
||||||
|
var ring = (side == 0) ? Icos.BOTTOM_RING : Icos.TOP_RING;
|
||||||
|
var apex = (side == 0) ? Icos.BOTTOM : Icos.TOP;
|
||||||
|
|
||||||
|
// top & bottom spider
|
||||||
|
buf.begin(VertexFormat.Mode.LINES, DefaultVertexFormat.POSITION_COLOR_NORMAL);
|
||||||
|
for (int i = 0; i < 5; i++) {
|
||||||
|
var end = ring[i];
|
||||||
|
v.accept(apex);
|
||||||
|
v.accept(end);
|
||||||
|
}
|
||||||
|
tess.end();
|
||||||
|
|
||||||
|
// ring around
|
||||||
|
buf.begin(VertexFormat.Mode.LINE_STRIP, DefaultVertexFormat.POSITION_COLOR_NORMAL);
|
||||||
|
for (int i = 0; i <= 5; i++) {
|
||||||
|
var point = ring[i % 5];
|
||||||
|
v.accept(point);
|
||||||
|
}
|
||||||
|
tess.end();
|
||||||
|
}
|
||||||
|
// center band
|
||||||
|
buf.begin(VertexFormat.Mode.LINE_STRIP, DefaultVertexFormat.POSITION_COLOR_NORMAL);
|
||||||
|
for (int i = 0; i < 5; i++) {
|
||||||
|
var bottom = Icos.BOTTOM_RING[i];
|
||||||
|
var top = Icos.TOP_RING[(i + 3) % 5];
|
||||||
|
v.accept(bottom);
|
||||||
|
v.accept(top);
|
||||||
|
}
|
||||||
|
v.accept(Icos.BOTTOM_RING[0]);
|
||||||
tess.end();
|
tess.end();
|
||||||
|
|
||||||
RenderSystem.enableDepthTest();
|
RenderSystem.enableDepthTest();
|
||||||
|
RenderSystem.enableCull();
|
||||||
ps.popPose();
|
ps.popPose();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static class Icos {
|
||||||
|
public static float[] TOP = {0, 1, 0};
|
||||||
|
public static float[] BOTTOM = {0, -1, 0};
|
||||||
|
public static float[][] TOP_RING = new float[5][];
|
||||||
|
public static float[][] BOTTOM_RING = new float[5][];
|
||||||
|
|
||||||
|
static {
|
||||||
|
var theta = (float) Mth.atan2(0.5, 1);
|
||||||
|
for (int i = 0; i < 5; i++) {
|
||||||
|
var phi = (float) i / 5f * Mth.TWO_PI;
|
||||||
|
var x = Mth.cos(theta) * Mth.cos(phi);
|
||||||
|
var y = Mth.sin(theta);
|
||||||
|
var z = Mth.cos(theta) * Mth.sin(phi);
|
||||||
|
TOP_RING[i] = new float[]{x, y, z};
|
||||||
|
BOTTOM_RING[i] = new float[]{-x, -y, -z};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -31,7 +31,7 @@ object OpColorizeSentinel : SpellOperator {
|
||||||
val color = DyeColor.getColor(otherHandItem)
|
val color = DyeColor.getColor(otherHandItem)
|
||||||
if (color != null) {
|
if (color != null) {
|
||||||
otherHandItem.shrink(1)
|
otherHandItem.shrink(1)
|
||||||
cap.color = color.textColor
|
cap.color = color.textColor or 0xff_000000u.toInt()
|
||||||
|
|
||||||
HexMessages.getNetwork()
|
HexMessages.getNetwork()
|
||||||
.send(PacketDistributor.PLAYER.with { ctx.caster }, MsgSentinelStatusUpdateAck(cap))
|
.send(PacketDistributor.PLAYER.with { ctx.caster }, MsgSentinelStatusUpdateAck(cap))
|
||||||
|
|
Loading…
Reference in a new issue