2.1.0
This commit is contained in:
1 parent
06bada5191
commit
3316df7195
43 files changed
+614
-98672
No files matched your search
@@ -231,7 +231,7 @@ public final class AntarchySettings {
|
||||
private static double royalAssailantLeggingsDoubleDamageChance = 0.07D;
|
||||
private static double royalAssailantBootsDoubleDamageChance = 0.05D;
|
||||
private static double royalGuardianSwordAttackDamage = 111.0D;
|
||||
private static double giantFryingPanAttackDamage = 80.0D;
|
||||
private static double giantFryingPanAttackDamage = 50.0D;
|
||||
private static double royalGuardianSwordAttackSpeed = -2.5D;
|
||||
private static int royalGuardianSwordElementalCooldownTicks = 120;
|
||||
private static double royalGuardianSwordFirePrimaryDamage = 22.0D;
|
||||
|
||||
+1
-1
@@ -41,7 +41,7 @@ public final class GiantFryingPanRenderer extends GeoItemRenderer<GiantFryingPan
|
||||
int row = slot / 3;
|
||||
int column = slot % 3;
|
||||
poseStack.pushPose();
|
||||
poseStack.translate((column - 1) * 0.42D, 1.72D, (row - 1) * 0.42D);
|
||||
poseStack.translate((column - 1) * 0.55D, 2.5D - (row - 1) * 0.55D, 0.03125D);
|
||||
poseStack.scale(0.24F, 0.24F, 0.24F);
|
||||
Minecraft.getInstance().getItemRenderer().renderStatic(stack, ItemDisplayContext.FIXED, packedLight, packedOverlay, poseStack, bufferSource, Minecraft.getInstance().level, 0);
|
||||
poseStack.popPose();
|
||||
|
||||
+124
-76
@@ -13,6 +13,8 @@ import com.mojang.blaze3d.vertex.Tesselator;
|
||||
import com.mojang.blaze3d.vertex.VertexBuffer;
|
||||
import com.mojang.blaze3d.vertex.VertexFormat;
|
||||
import com.mojang.blaze3d.vertex.VertexSorting;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Random;
|
||||
import net.minecraft.client.Camera;
|
||||
import net.minecraft.client.Minecraft;
|
||||
@@ -25,6 +27,7 @@ import net.minecraft.util.Mth;
|
||||
import net.minecraft.world.level.Level;
|
||||
import org.joml.Matrix4f;
|
||||
import org.joml.Matrix4fStack;
|
||||
import org.joml.Vector3f;
|
||||
|
||||
public final class ThoraxisUndersideSkyRenderer {
|
||||
public static final ResourceKey<Level> THORAXIS = ResourceKey.create(
|
||||
@@ -32,7 +35,6 @@ public final class ThoraxisUndersideSkyRenderer {
|
||||
ResourceLocation.fromNamespaceAndPath(Antarchy.MODID, "thoraxis")
|
||||
);
|
||||
private static final ResourceLocation SUN_TEXTURE = ResourceLocation.fromNamespaceAndPath(Antarchy.MODID, "textures/environment/eye_moon.png");
|
||||
private static final ResourceLocation MOON_TEXTURE = ResourceLocation.withDefaultNamespace("textures/environment/moon_phases.png");
|
||||
private static final ResourceLocation[] EYE_STAR_TEXTURES = {
|
||||
ResourceLocation.fromNamespaceAndPath(Antarchy.MODID, "textures/environment/eye_star1.png"),
|
||||
ResourceLocation.fromNamespaceAndPath(Antarchy.MODID, "textures/environment/eye_star2.png"),
|
||||
@@ -41,8 +43,27 @@ public final class ThoraxisUndersideSkyRenderer {
|
||||
ResourceLocation.fromNamespaceAndPath(Antarchy.MODID, "textures/environment/eye_star5.png")
|
||||
};
|
||||
private static final float[] EYE_STAR_SCALES = {1.0F, 0.86F, 0.72F, 0.58F, 0.46F};
|
||||
private static final double STAR_FOOTPRINT = Math.sqrt(2.0D);
|
||||
private static final double STAR_GAP = 1.0D;
|
||||
private static final float SKY_RADIUS = 100.0F;
|
||||
private static final float BODY_SIZE = 32.0F;
|
||||
private static final float SUN_RADIUS = 27.0F;
|
||||
private static final float SUN_GLOW_RED = 1.0F;
|
||||
private static final float SUN_GLOW_GREEN = 0x1F / 255.0F;
|
||||
private static final float SUN_GLOW_BLUE = 0x18 / 255.0F;
|
||||
private static final float SUN_GLOW_CENTER_ALPHA = 0.04F;
|
||||
private static final float SUN_GLOW_PEAK_RADIUS = 15.5F;
|
||||
private static final float SUN_GLOW_PEAK_ALPHA = 0.12F;
|
||||
private static final float SUN_GLOW_KNEE_RADIUS = 19.0F;
|
||||
private static final float SUN_GLOW_KNEE_ALPHA = 0.03F;
|
||||
private static final float SUN_GLOW_RADIUS = 25.0F;
|
||||
private static final float[][] EYE_SUNS = {
|
||||
{259.2F, -10.0F, 245.5F},
|
||||
{200.0F, 20.0F, 30.0F},
|
||||
{150.0F, -35.0F, 200.0F},
|
||||
{120.0F, 40.0F, 300.0F},
|
||||
{215.0F, -60.0F, 120.0F}
|
||||
};
|
||||
private static final float SKY_RED = 0.015F;
|
||||
private static final float SKY_GREEN = 0.0F;
|
||||
private static final float SKY_BLUE = 0.035F;
|
||||
@@ -79,9 +100,8 @@ public final class ThoraxisUndersideSkyRenderer {
|
||||
VertexBuffer.unbind();
|
||||
RenderSystem.setShaderColor(1.0F, 1.0F, 1.0F, 1.0F);
|
||||
|
||||
float timeOfDay = 0.72F + partialTick * 0.0F;
|
||||
renderCelestialBodies(poseStack.last().pose(), projectionMatrix, timeOfDay);
|
||||
renderEyeStars(poseStack.last().pose(), projectionMatrix);
|
||||
renderEyeSuns(poseStack.last().pose(), projectionMatrix);
|
||||
|
||||
RenderSystem.depthMask(true);
|
||||
}
|
||||
@@ -92,14 +112,9 @@ public final class ThoraxisUndersideSkyRenderer {
|
||||
}
|
||||
|
||||
RenderSystem.enableBlend();
|
||||
RenderSystem.blendFuncSeparate(
|
||||
GlStateManager.SourceFactor.ONE,
|
||||
GlStateManager.DestFactor.ONE,
|
||||
GlStateManager.SourceFactor.ONE,
|
||||
GlStateManager.DestFactor.ZERO
|
||||
);
|
||||
RenderSystem.defaultBlendFunc();
|
||||
RenderSystem.setShader(GameRenderer::getPositionTexShader);
|
||||
RenderSystem.setShaderColor(1.0F, 0.015F, 0.02F, 1.0F);
|
||||
RenderSystem.setShaderColor(1.0F, 1.0F, 1.0F, 1.0F);
|
||||
RenderSystem.backupProjectionMatrix();
|
||||
RenderSystem.setProjectionMatrix(projectionMatrix, VertexSorting.DISTANCE_TO_ORIGIN);
|
||||
|
||||
@@ -116,26 +131,48 @@ public final class ThoraxisUndersideSkyRenderer {
|
||||
}
|
||||
|
||||
private static VertexBuffer[] buildEyeStarBuffers() {
|
||||
Vector3f[] sunDirections = new Vector3f[EYE_SUNS.length];
|
||||
for (int sun = 0; sun < EYE_SUNS.length; sun++) {
|
||||
sunDirections[sun] = bodyDirection(EYE_SUNS[sun][0], EYE_SUNS[sun][1]);
|
||||
}
|
||||
double sunLimit = Math.cos(bodyAngularRadius(SUN_RADIUS));
|
||||
List<double[]> stars = new ArrayList<>();
|
||||
Random random = new Random(552031L);
|
||||
for (int i = 0; i < 1800; i++) {
|
||||
double x = random.nextFloat() * 2.0F - 1.0F;
|
||||
double y = random.nextFloat() * 2.0F - 1.0F;
|
||||
double z = random.nextFloat() * 2.0F - 1.0F;
|
||||
int textureIndex = i % EYE_STAR_TEXTURES.length;
|
||||
double size = (0.52F + random.nextFloat() * 1.24F) * EYE_STAR_SCALES[textureIndex];
|
||||
double rot = random.nextDouble() * Math.PI * 2.0D;
|
||||
double lenSq = x * x + y * y + z * z;
|
||||
if (lenSq >= 1.0D || lenSq <= 0.01D) {
|
||||
continue;
|
||||
}
|
||||
|
||||
double len = 1.0D / Math.sqrt(lenSq);
|
||||
x *= len;
|
||||
y *= len;
|
||||
z *= len;
|
||||
if (behindEyeSun(sunDirections, sunLimit, x, y, z) || crowdsExistingStar(stars, x, y, z, size)) {
|
||||
continue;
|
||||
}
|
||||
stars.add(new double[]{x, y, z, size, rot, textureIndex});
|
||||
}
|
||||
|
||||
VertexBuffer[] buffers = new VertexBuffer[EYE_STAR_TEXTURES.length];
|
||||
for (int textureIndex = 0; textureIndex < EYE_STAR_TEXTURES.length; textureIndex++) {
|
||||
Random random = new Random(552031L);
|
||||
BufferBuilder builder = Tesselator.getInstance().begin(VertexFormat.Mode.QUADS, DefaultVertexFormat.POSITION_TEX);
|
||||
|
||||
for (int i = 0; i < 1800; i++) {
|
||||
double x = random.nextFloat() * 2.0F - 1.0F;
|
||||
double y = random.nextFloat() * 2.0F - 1.0F;
|
||||
double z = random.nextFloat() * 2.0F - 1.0F;
|
||||
double size = (0.52F + random.nextFloat() * 0.36F) * EYE_STAR_SCALES[textureIndex];
|
||||
double rot = random.nextDouble() * Math.PI * 2.0D;
|
||||
double lenSq = x * x + y * y + z * z;
|
||||
if (i % EYE_STAR_TEXTURES.length != textureIndex || lenSq >= 1.0D || lenSq <= 0.01D) {
|
||||
for (double[] star : stars) {
|
||||
if ((int) star[5] != textureIndex) {
|
||||
continue;
|
||||
}
|
||||
|
||||
double len = 1.0D / Math.sqrt(lenSq);
|
||||
x *= len;
|
||||
y *= len;
|
||||
z *= len;
|
||||
double x = star[0];
|
||||
double y = star[1];
|
||||
double z = star[2];
|
||||
double size = star[3];
|
||||
double rot = star[4];
|
||||
double sx = x * 100.0D;
|
||||
double sy = y * 100.0D;
|
||||
double sz = z * 100.0D;
|
||||
@@ -173,17 +210,48 @@ public final class ThoraxisUndersideSkyRenderer {
|
||||
return buffers;
|
||||
}
|
||||
|
||||
private static void renderCelestialBodies(Matrix4f modelViewMatrix, Matrix4f projectionMatrix, float timeOfDay) {
|
||||
float t = timeOfDay * 360.0F;
|
||||
renderBodyGlow(modelViewMatrix, projectionMatrix, t, -10.0F, 0xFF1F18, 86.0F);
|
||||
renderTexturedBody(modelViewMatrix, projectionMatrix, t, -10.0F, 42.0F, 0xFF1F18, SUN_TEXTURE, false, 0, t * 0.6F + 90.0F);
|
||||
|
||||
float moonOrbit = t + 180.0F;
|
||||
renderBodyGlow(modelViewMatrix, projectionMatrix, moonOrbit, 24.0F, 0x8F30FF, 76.0F);
|
||||
renderTexturedBody(modelViewMatrix, projectionMatrix, moonOrbit, 24.0F, 26.0F, 0x8F30FF, MOON_TEXTURE, true, 0, -t * 0.35F);
|
||||
private static boolean behindEyeSun(Vector3f[] sunDirections, double limit, double x, double y, double z) {
|
||||
for (Vector3f direction : sunDirections) {
|
||||
if (x * direction.x + y * direction.y + z * direction.z > limit) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private static void renderBodyGlow(Matrix4f modelViewMatrix, Matrix4f projectionMatrix, float orbitDegrees, float yawDegrees, int rgb, float glowRadius) {
|
||||
private static boolean crowdsExistingStar(List<double[]> stars, double x, double y, double z, double size) {
|
||||
for (double[] other : stars) {
|
||||
double dx = (x - other[0]) * SKY_RADIUS;
|
||||
double dy = (y - other[1]) * SKY_RADIUS;
|
||||
double dz = (z - other[2]) * SKY_RADIUS;
|
||||
double minDistance = (size + other[3]) * STAR_FOOTPRINT + STAR_GAP;
|
||||
if (dx * dx + dy * dy + dz * dz < minDistance * minDistance) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private static Vector3f bodyDirection(float orbitDegrees, float yawDegrees) {
|
||||
return new Matrix4f()
|
||||
.rotateX((float) Math.toRadians(orbitDegrees))
|
||||
.rotateZ((float) Math.toRadians(yawDegrees))
|
||||
.transformDirection(new Vector3f(0.0F, 1.0F, 0.0F))
|
||||
.normalize();
|
||||
}
|
||||
|
||||
private static double bodyAngularRadius(float radius) {
|
||||
return Math.atan(BODY_SIZE * 0.5F * (radius / 22.0F) / SKY_RADIUS) + 0.02D;
|
||||
}
|
||||
|
||||
private static void renderEyeSuns(Matrix4f modelViewMatrix, Matrix4f projectionMatrix) {
|
||||
for (float[] sun : EYE_SUNS) {
|
||||
renderSunGlow(modelViewMatrix, projectionMatrix, sun[0], sun[1]);
|
||||
renderSunBody(modelViewMatrix, projectionMatrix, sun[0], sun[1], sun[2]);
|
||||
}
|
||||
}
|
||||
|
||||
private static void renderSunGlow(Matrix4f modelViewMatrix, Matrix4f projectionMatrix, float orbitDegrees, float yawDegrees) {
|
||||
RenderSystem.enableBlend();
|
||||
RenderSystem.defaultBlendFunc();
|
||||
RenderSystem.disableCull();
|
||||
@@ -198,16 +266,9 @@ public final class ThoraxisUndersideSkyRenderer {
|
||||
modelViewStack.rotateZ((float) Math.toRadians(yawDegrees));
|
||||
RenderSystem.applyModelViewMatrix();
|
||||
|
||||
float red = ((rgb >> 16) & 0xFF) / 255.0F;
|
||||
float green = ((rgb >> 8) & 0xFF) / 255.0F;
|
||||
float blue = (rgb & 0xFF) / 255.0F;
|
||||
BufferBuilder buffer = Tesselator.getInstance().begin(VertexFormat.Mode.TRIANGLE_FAN, DefaultVertexFormat.POSITION_COLOR);
|
||||
buffer.addVertex(0.0F, SKY_RADIUS, 0.0F).setColor(red, green, blue, 0.55F);
|
||||
for (int i = 0; i <= 24; i++) {
|
||||
float angle = i * Mth.TWO_PI / 24.0F;
|
||||
buffer.addVertex(Mth.sin(angle) * glowRadius, SKY_RADIUS, Mth.cos(angle) * glowRadius).setColor(red, green, blue, 0.0F);
|
||||
}
|
||||
BufferUploader.drawWithShader(buffer.buildOrThrow());
|
||||
drawGlowBand(0.0F, SUN_GLOW_CENTER_ALPHA, SUN_GLOW_PEAK_RADIUS, SUN_GLOW_PEAK_ALPHA);
|
||||
drawGlowBand(SUN_GLOW_PEAK_RADIUS, SUN_GLOW_PEAK_ALPHA, SUN_GLOW_KNEE_RADIUS, SUN_GLOW_KNEE_ALPHA);
|
||||
drawGlowBand(SUN_GLOW_KNEE_RADIUS, SUN_GLOW_KNEE_ALPHA, SUN_GLOW_RADIUS, 0.0F);
|
||||
|
||||
modelViewStack.popMatrix();
|
||||
RenderSystem.applyModelViewMatrix();
|
||||
@@ -216,18 +277,19 @@ public final class ThoraxisUndersideSkyRenderer {
|
||||
RenderSystem.disableBlend();
|
||||
}
|
||||
|
||||
private static void renderTexturedBody(
|
||||
Matrix4f modelViewMatrix,
|
||||
Matrix4f projectionMatrix,
|
||||
float orbitDegrees,
|
||||
float yawDegrees,
|
||||
float radius,
|
||||
int rgb,
|
||||
ResourceLocation texture,
|
||||
boolean usePhaseSheet,
|
||||
int phaseIndex,
|
||||
float selfRotationDegrees
|
||||
) {
|
||||
private static void drawGlowBand(float fromRadius, float fromAlpha, float toRadius, float toAlpha) {
|
||||
BufferBuilder buffer = Tesselator.getInstance().begin(VertexFormat.Mode.TRIANGLE_STRIP, DefaultVertexFormat.POSITION_COLOR);
|
||||
for (int i = 0; i <= 32; i++) {
|
||||
float angle = i * Mth.TWO_PI / 32.0F;
|
||||
float sin = Mth.sin(angle);
|
||||
float cos = Mth.cos(angle);
|
||||
buffer.addVertex(sin * fromRadius, SKY_RADIUS, cos * fromRadius).setColor(SUN_GLOW_RED, SUN_GLOW_GREEN, SUN_GLOW_BLUE, fromAlpha);
|
||||
buffer.addVertex(sin * toRadius, SKY_RADIUS, cos * toRadius).setColor(SUN_GLOW_RED, SUN_GLOW_GREEN, SUN_GLOW_BLUE, toAlpha);
|
||||
}
|
||||
BufferUploader.drawWithShader(buffer.buildOrThrow());
|
||||
}
|
||||
|
||||
private static void renderSunBody(Matrix4f modelViewMatrix, Matrix4f projectionMatrix, float orbitDegrees, float yawDegrees, float selfRotationDegrees) {
|
||||
RenderSystem.enableBlend();
|
||||
RenderSystem.blendFuncSeparate(
|
||||
GlStateManager.SourceFactor.ONE,
|
||||
@@ -236,9 +298,9 @@ public final class ThoraxisUndersideSkyRenderer {
|
||||
GlStateManager.DestFactor.ZERO
|
||||
);
|
||||
RenderSystem.disableCull();
|
||||
RenderSystem.setShaderColor(((rgb >> 16) & 0xFF) / 255.0F, ((rgb >> 8) & 0xFF) / 255.0F, (rgb & 0xFF) / 255.0F, 1.0F);
|
||||
RenderSystem.setShaderColor(1.0F, 1.0F, 1.0F, 1.0F);
|
||||
RenderSystem.setShader(GameRenderer::getPositionTexShader);
|
||||
RenderSystem.setShaderTexture(0, texture);
|
||||
RenderSystem.setShaderTexture(0, SUN_TEXTURE);
|
||||
RenderSystem.backupProjectionMatrix();
|
||||
RenderSystem.setProjectionMatrix(projectionMatrix, VertexSorting.DISTANCE_TO_ORIGIN);
|
||||
|
||||
@@ -250,31 +312,17 @@ public final class ThoraxisUndersideSkyRenderer {
|
||||
modelViewStack.rotateY((float) Math.toRadians(selfRotationDegrees));
|
||||
RenderSystem.applyModelViewMatrix();
|
||||
|
||||
float halfSize = BODY_SIZE * 0.5F * (radius / 22.0F);
|
||||
float minU = 0.0F;
|
||||
float maxU = 1.0F;
|
||||
float minV = 0.0F;
|
||||
float maxV = 1.0F;
|
||||
if (usePhaseSheet) {
|
||||
int phaseX = phaseIndex % 4;
|
||||
int phaseY = phaseIndex / 4;
|
||||
minU = phaseX / 4.0F;
|
||||
maxU = (phaseX + 1) / 4.0F;
|
||||
minV = phaseY / 2.0F;
|
||||
maxV = (phaseY + 1) / 2.0F;
|
||||
}
|
||||
|
||||
float halfSize = BODY_SIZE * 0.5F * (SUN_RADIUS / 22.0F);
|
||||
BufferBuilder buffer = Tesselator.getInstance().begin(VertexFormat.Mode.QUADS, DefaultVertexFormat.POSITION_TEX);
|
||||
buffer.addVertex(-halfSize, SKY_RADIUS, -halfSize).setUv(minU, minV);
|
||||
buffer.addVertex(-halfSize, SKY_RADIUS, halfSize).setUv(minU, maxV);
|
||||
buffer.addVertex(halfSize, SKY_RADIUS, halfSize).setUv(maxU, maxV);
|
||||
buffer.addVertex(halfSize, SKY_RADIUS, -halfSize).setUv(maxU, minV);
|
||||
buffer.addVertex(-halfSize, SKY_RADIUS, -halfSize).setUv(0.0F, 0.0F);
|
||||
buffer.addVertex(-halfSize, SKY_RADIUS, halfSize).setUv(0.0F, 1.0F);
|
||||
buffer.addVertex(halfSize, SKY_RADIUS, halfSize).setUv(1.0F, 1.0F);
|
||||
buffer.addVertex(halfSize, SKY_RADIUS, -halfSize).setUv(1.0F, 0.0F);
|
||||
BufferUploader.drawWithShader(buffer.buildOrThrow());
|
||||
|
||||
modelViewStack.popMatrix();
|
||||
RenderSystem.applyModelViewMatrix();
|
||||
RenderSystem.restoreProjectionMatrix();
|
||||
RenderSystem.setShaderColor(1.0F, 1.0F, 1.0F, 1.0F);
|
||||
RenderSystem.defaultBlendFunc();
|
||||
RenderSystem.enableCull();
|
||||
RenderSystem.disableBlend();
|
||||
|
||||
+24
-5
@@ -1,5 +1,6 @@
|
||||
package com.craisinlord.antarchy.content.client.screen;
|
||||
|
||||
import com.craisinlord.antarchy.content.item.GiantFryingPanStorage;
|
||||
import com.craisinlord.antarchy.content.menu.GiantFryingPanMenu;
|
||||
import net.minecraft.client.gui.GuiGraphics;
|
||||
import net.minecraft.client.gui.screens.inventory.AbstractContainerScreen;
|
||||
@@ -8,17 +9,35 @@ import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.world.entity.player.Inventory;
|
||||
|
||||
public final class GiantFryingPanScreen extends AbstractContainerScreen<GiantFryingPanMenu> {
|
||||
private static final ResourceLocation INVENTORY_TEXTURE = ResourceLocation.withDefaultNamespace("textures/gui/container/inventory.png");
|
||||
private static final ResourceLocation CONTAINER_TEXTURE = ResourceLocation.withDefaultNamespace("textures/gui/container/generic_54.png");
|
||||
private static final int PAN_SECTION_HEIGHT = 35;
|
||||
private static final int INVENTORY_SECTION_HEIGHT = 96;
|
||||
private static final int PROGRESS_COLOR = 0xC0FF8A2A;
|
||||
|
||||
public GiantFryingPanScreen(GiantFryingPanMenu menu, Inventory inventory, Component title) {
|
||||
super(menu, inventory, title);
|
||||
imageWidth = 176;
|
||||
imageHeight = 132;
|
||||
inventoryLabelY = 40;
|
||||
this.imageWidth = 176;
|
||||
this.imageHeight = 132;
|
||||
this.inventoryLabelY = this.imageHeight - 94;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void render(GuiGraphics graphics, int mouseX, int mouseY, float partialTick) {
|
||||
super.render(graphics, mouseX, mouseY, partialTick);
|
||||
this.renderTooltip(graphics, mouseX, mouseY);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void renderBg(GuiGraphics graphics, float partialTick, int mouseX, int mouseY) {
|
||||
graphics.blit(INVENTORY_TEXTURE, leftPos, topPos, 0, 0, imageWidth, imageHeight);
|
||||
graphics.blit(CONTAINER_TEXTURE, this.leftPos, this.topPos, 0, 0, this.imageWidth, PAN_SECTION_HEIGHT);
|
||||
graphics.blit(CONTAINER_TEXTURE, this.leftPos, this.topPos + PAN_SECTION_HEIGHT, 0, 126, this.imageWidth, INVENTORY_SECTION_HEIGHT);
|
||||
GiantFryingPanStorage storage = this.menu.storage();
|
||||
for (int slot = 0; slot < GiantFryingPanStorage.SLOT_COUNT; slot++) {
|
||||
float progress = storage.cookProgress(slot);
|
||||
if (progress <= 0.0F) continue;
|
||||
int x = this.leftPos + 8 + slot * 18;
|
||||
int y = this.topPos + GiantFryingPanMenu.PAN_ROW_Y + 16;
|
||||
graphics.fill(x, y, x + Math.round(16 * progress), y + 1, PROGRESS_COLOR);
|
||||
}
|
||||
}
|
||||
}
|
||||
+6
-6
@@ -452,17 +452,13 @@ public final class CreativeTabContents {
|
||||
entry("royal_guardian_shield", "combat"),
|
||||
entry("royal_assailant_battleaxe", "combat"),
|
||||
entry("royal_assailant_staff", "combat"),
|
||||
entry("temporal_tuner", "combat"),
|
||||
entry("royal_assailant_helmet", "combat"),
|
||||
entry("royal_assailant_chestplate", "combat"),
|
||||
entry("royal_assailant_leggings", "combat"),
|
||||
entry("royal_assailant_boots", "combat"),
|
||||
entry("prince_egg", "functional_blocks"),
|
||||
entry("princess_egg", "functional_blocks"),
|
||||
entry("king_spawn_egg", "spawn_eggs"),
|
||||
entry("queen_spawn_egg", "spawn_eggs"),
|
||||
entry("manticore_spawn_egg", "spawn_eggs"),
|
||||
entry("prince_spawn_egg", "spawn_eggs"),
|
||||
entry("princess_spawn_egg", "spawn_eggs"),
|
||||
entry("tigers_eye_helmet", "combat"),
|
||||
entry("tigers_eye_chestplate", "combat"),
|
||||
entry("tigers_eye_leggings", "combat"),
|
||||
@@ -492,7 +488,6 @@ public final class CreativeTabContents {
|
||||
entry("mud_pie", "ingredients"),
|
||||
entry("lucid_eye", "ingredients"),
|
||||
entry("blood_crystal_shard", "ingredients"),
|
||||
entry("temporal_tuner", "ingredients"),
|
||||
entry("tigers_eye", "ingredients"),
|
||||
entry("tigers_eye_block", "building_blocks"),
|
||||
entry("blood_crystal_apple", "ingredients"),
|
||||
@@ -554,6 +549,11 @@ public final class CreativeTabContents {
|
||||
entry("hoverboard_red", "building_blocks"),
|
||||
entry("hoverboard_black", "building_blocks"),
|
||||
entry("ant_trap", "building_blocks"),
|
||||
entry("king_spawn_egg", "spawn_eggs"),
|
||||
entry("queen_spawn_egg", "spawn_eggs"),
|
||||
entry("manticore_spawn_egg", "spawn_eggs"),
|
||||
entry("prince_spawn_egg", "spawn_eggs"),
|
||||
entry("princess_spawn_egg", "spawn_eggs"),
|
||||
entry("easter_bunny_spawn_egg", "spawn_eggs"),
|
||||
entry("flying_squirrel_spawn_egg", "spawn_eggs"),
|
||||
entry("caterpillar_spawn_egg", "spawn_eggs"),
|
||||
|
||||
+89
-23
@@ -24,6 +24,15 @@ import net.minecraft.world.item.component.ItemAttributeModifiers;
|
||||
import net.minecraft.network.chat.Component;
|
||||
import net.minecraft.world.SimpleMenuProvider;
|
||||
import net.minecraft.world.level.Level;
|
||||
import net.minecraft.world.InteractionHand;
|
||||
import net.minecraft.world.InteractionResult;
|
||||
import net.minecraft.world.InteractionResultHolder;
|
||||
import net.minecraft.world.entity.SlotAccess;
|
||||
import net.minecraft.world.entity.player.Inventory;
|
||||
import net.minecraft.world.inventory.ClickAction;
|
||||
import net.minecraft.world.inventory.Slot;
|
||||
import com.craisinlord.antarchy.Antarchy;
|
||||
import com.craisinlord.antarchy.content.menu.GiantFryingPanMenu;
|
||||
import net.minecraft.world.phys.Vec3;
|
||||
import software.bernie.geckolib.animatable.GeoItem;
|
||||
import software.bernie.geckolib.animatable.client.GeoRenderProvider;
|
||||
@@ -96,32 +105,89 @@ public class GiantFryingPanItem extends SwordItem implements GeoItem {
|
||||
}
|
||||
|
||||
@Override
|
||||
public net.minecraft.world.InteractionResultHolder<ItemStack> use(Level level, Player player, net.minecraft.world.InteractionHand hand) {
|
||||
public InteractionResultHolder<ItemStack> use(Level level, Player player, InteractionHand hand) {
|
||||
ItemStack pan = player.getItemInHand(hand);
|
||||
if (player.isShiftKeyDown()) {
|
||||
if (!level.isClientSide) {
|
||||
player.openMenu(new SimpleMenuProvider(
|
||||
(containerId, inventory, ignored) -> new com.craisinlord.antarchy.content.menu.GiantFryingPanMenu(containerId, inventory),
|
||||
Component.translatable("item.antarchy.giant_frying_pan")));
|
||||
}
|
||||
return net.minecraft.world.InteractionResultHolder.sidedSuccess(pan, level.isClientSide);
|
||||
}
|
||||
net.minecraft.world.InteractionHand foodHand = hand == net.minecraft.world.InteractionHand.MAIN_HAND
|
||||
? net.minecraft.world.InteractionHand.OFF_HAND : net.minecraft.world.InteractionHand.MAIN_HAND;
|
||||
InteractionHand foodHand = hand == InteractionHand.MAIN_HAND ? InteractionHand.OFF_HAND : InteractionHand.MAIN_HAND;
|
||||
ItemStack food = player.getItemInHand(foodHand);
|
||||
if (!GiantFryingPanStorage.isCampfireInput(player, food)) return net.minecraft.world.InteractionResultHolder.pass(pan);
|
||||
GiantFryingPanStorage storage = new GiantFryingPanStorage(pan, player);
|
||||
for (int slot = 0; slot < GiantFryingPanStorage.SLOT_COUNT; slot++) {
|
||||
if (storage.getItem(slot).isEmpty()) {
|
||||
if (!level.isClientSide) {
|
||||
storage.setItem(slot, food.copyWithCount(1));
|
||||
food.shrink(1);
|
||||
level.playSound(null, player.blockPosition(), SoundEvents.CAMPFIRE_CRACKLE, SoundSource.PLAYERS, 0.8F, 1.0F);
|
||||
}
|
||||
return net.minecraft.world.InteractionResultHolder.sidedSuccess(pan, level.isClientSide);
|
||||
}
|
||||
Antarchy.LOGGER.info("[FryingPan] use client={} hand={} shift={} pan={} otherHand={}",
|
||||
level.isClientSide, hand, player.isShiftKeyDown(), pan, food);
|
||||
if (player.isShiftKeyDown()) {
|
||||
openMenu(level, player, hand);
|
||||
return InteractionResultHolder.sidedSuccess(pan, level.isClientSide);
|
||||
}
|
||||
return net.minecraft.world.InteractionResultHolder.fail(pan);
|
||||
if (!GiantFryingPanStorage.isCampfireInput(player, food)) {
|
||||
Antarchy.LOGGER.info("[FryingPan] use client={} other hand item is not a campfire input", level.isClientSide);
|
||||
return InteractionResultHolder.pass(pan);
|
||||
}
|
||||
return insertFromHand(level, player, pan, food)
|
||||
? InteractionResultHolder.sidedSuccess(pan, level.isClientSide)
|
||||
: InteractionResultHolder.fail(pan);
|
||||
}
|
||||
|
||||
public static InteractionResult handleMainHandUse(Level level, Player player, InteractionHand hand) {
|
||||
if (hand != InteractionHand.MAIN_HAND) return InteractionResult.PASS;
|
||||
ItemStack pan = player.getOffhandItem();
|
||||
ItemStack held = player.getMainHandItem();
|
||||
if (!(pan.getItem() instanceof GiantFryingPanItem) || held.getItem() instanceof GiantFryingPanItem) return InteractionResult.PASS;
|
||||
if (player.isShiftKeyDown()) {
|
||||
Antarchy.LOGGER.info("[FryingPan] offhand pan shift-use client={} mainHand={}", level.isClientSide, held);
|
||||
openMenu(level, player, InteractionHand.OFF_HAND);
|
||||
return InteractionResult.sidedSuccess(level.isClientSide);
|
||||
}
|
||||
if (!GiantFryingPanStorage.isCampfireInput(player, held)) return InteractionResult.PASS;
|
||||
Antarchy.LOGGER.info("[FryingPan] offhand pan insert client={} mainHand={}", level.isClientSide, held);
|
||||
return insertFromHand(level, player, pan, held) ? InteractionResult.sidedSuccess(level.isClientSide) : InteractionResult.FAIL;
|
||||
}
|
||||
|
||||
private static void openMenu(Level level, Player player, InteractionHand hand) {
|
||||
if (level.isClientSide) return;
|
||||
int panSlot = hand == InteractionHand.MAIN_HAND ? player.getInventory().selected : Inventory.SLOT_OFFHAND;
|
||||
Antarchy.LOGGER.info("[FryingPan] opening menu for {} panSlot={}", player.getName().getString(), panSlot);
|
||||
player.openMenu(new SimpleMenuProvider(
|
||||
(containerId, inventory, ignored) -> new GiantFryingPanMenu(containerId, inventory, panSlot),
|
||||
Component.translatable("item.antarchy.giant_frying_pan")));
|
||||
}
|
||||
|
||||
private static boolean insertFromHand(Level level, Player player, ItemStack pan, ItemStack food) {
|
||||
GiantFryingPanStorage storage = new GiantFryingPanStorage(pan, player);
|
||||
ItemStack single = food.copyWithCount(1);
|
||||
if (!storage.insertOne(single)) {
|
||||
Antarchy.LOGGER.info("[FryingPan] insert failed client={} food={} (pan full or not cookable)", level.isClientSide, food);
|
||||
return false;
|
||||
}
|
||||
if (!player.getAbilities().instabuild) food.shrink(1);
|
||||
Antarchy.LOGGER.info("[FryingPan] inserted client={} food={}", level.isClientSide, single.getItem());
|
||||
if (!level.isClientSide) {
|
||||
level.playSound(null, player.blockPosition(), SoundEvents.CAMPFIRE_CRACKLE, SoundSource.PLAYERS, 0.8F, 1.0F);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean overrideStackedOnOther(ItemStack pan, Slot slot, ClickAction action, Player player) {
|
||||
if (action != ClickAction.SECONDARY) return false;
|
||||
ItemStack food = slot.getItem();
|
||||
if (!GiantFryingPanStorage.isCampfireInput(player, food) || !slot.mayPickup(player)) return false;
|
||||
GiantFryingPanStorage storage = new GiantFryingPanStorage(pan, player);
|
||||
boolean inserted = storage.hasSpace() && storage.insertOne(slot.safeTake(1, 1, player));
|
||||
Antarchy.LOGGER.info("[FryingPan] cursor pan onto slot client={} food={} inserted={}", player.level().isClientSide, food.getItem(), inserted);
|
||||
if (inserted) player.playSound(SoundEvents.CAMPFIRE_CRACKLE, 0.8F, 1.0F);
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean overrideOtherStackedOnMe(ItemStack pan, ItemStack other, Slot slot, ClickAction action, Player player, SlotAccess access) {
|
||||
if (action != ClickAction.SECONDARY || other.isEmpty() || !slot.allowModification(player)) return false;
|
||||
if (!GiantFryingPanStorage.isCampfireInput(player, other)) return false;
|
||||
GiantFryingPanStorage storage = new GiantFryingPanStorage(pan, player);
|
||||
ItemStack single = other.copyWithCount(1);
|
||||
boolean inserted = storage.insertOne(single);
|
||||
if (inserted) {
|
||||
other.shrink(1);
|
||||
player.playSound(SoundEvents.CAMPFIRE_CRACKLE, 0.8F, 1.0F);
|
||||
}
|
||||
Antarchy.LOGGER.info("[FryingPan] cursor food onto pan client={} food={} inserted={}", player.level().isClientSide, single.getItem(), inserted);
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
+167
-80
@@ -1,14 +1,16 @@
|
||||
package com.craisinlord.antarchy.content.item;
|
||||
|
||||
import java.util.Optional;
|
||||
import net.minecraft.core.HolderLookup;
|
||||
import net.minecraft.core.NonNullList;
|
||||
import net.minecraft.core.component.DataComponents;
|
||||
import net.minecraft.nbt.CompoundTag;
|
||||
import net.minecraft.nbt.ListTag;
|
||||
import net.minecraft.nbt.Tag;
|
||||
import net.minecraft.world.Container;
|
||||
import net.minecraft.world.SimpleContainer;
|
||||
import net.minecraft.world.entity.item.ItemEntity;
|
||||
import net.minecraft.world.entity.player.Player;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
import net.minecraft.world.item.component.CustomData;
|
||||
import net.minecraft.world.item.crafting.CampfireCookingRecipe;
|
||||
import net.minecraft.world.item.crafting.RecipeHolder;
|
||||
import net.minecraft.world.item.crafting.RecipeType;
|
||||
@@ -17,27 +19,51 @@ import net.minecraft.world.level.Level;
|
||||
|
||||
public final class GiantFryingPanStorage implements Container {
|
||||
public static final int SLOT_COUNT = 9;
|
||||
public static final int COOK_TIME = 600;
|
||||
private static final String SLOTS = "antarchy.giant_frying_pan_slots";
|
||||
private static final String SLOT = "Slot";
|
||||
private static final String ITEM = "Item";
|
||||
private static final String TIME = "Time";
|
||||
private final ItemStack pan;
|
||||
private static final String START = "Start";
|
||||
private final Player player;
|
||||
private final int panSlot;
|
||||
private final ItemStack fixedPan;
|
||||
private final NonNullList<ItemStack> items = NonNullList.withSize(SLOT_COUNT, ItemStack.EMPTY);
|
||||
private final long[] startTimes = new long[SLOT_COUNT];
|
||||
private final ItemStack[] startItems = new ItemStack[SLOT_COUNT];
|
||||
private CustomData loadedFrom;
|
||||
private ItemStack loadedPan = ItemStack.EMPTY;
|
||||
|
||||
public GiantFryingPanStorage(ItemStack pan, Player player) {
|
||||
this.pan = pan;
|
||||
this.player = player;
|
||||
this.panSlot = -1;
|
||||
this.fixedPan = pan;
|
||||
this.reloadIfChanged();
|
||||
}
|
||||
|
||||
public GiantFryingPanStorage(Player player, int panSlot) {
|
||||
this.player = player;
|
||||
this.panSlot = panSlot;
|
||||
this.fixedPan = null;
|
||||
this.reloadIfChanged();
|
||||
}
|
||||
|
||||
public ItemStack pan() {
|
||||
if (this.fixedPan != null) return this.fixedPan;
|
||||
if (this.panSlot < 0 || this.panSlot >= this.player.getInventory().getContainerSize()) return ItemStack.EMPTY;
|
||||
return this.player.getInventory().getItem(this.panSlot);
|
||||
}
|
||||
|
||||
public int panSlot() {
|
||||
return this.panSlot;
|
||||
}
|
||||
|
||||
public boolean hasPan() {
|
||||
return this.pan().getItem() instanceof GiantFryingPanItem;
|
||||
}
|
||||
|
||||
public static ItemStack findPan(Player player) {
|
||||
ItemStack selected = player.getMainHandItem();
|
||||
if (selected.getItem() instanceof GiantFryingPanItem) return selected;
|
||||
ItemStack offhand = player.getOffhandItem();
|
||||
if (offhand.getItem() instanceof GiantFryingPanItem) return offhand;
|
||||
for (ItemStack stack : player.getInventory().items) {
|
||||
if (stack.getItem() instanceof GiantFryingPanItem) return stack;
|
||||
}
|
||||
return ItemStack.EMPTY;
|
||||
int slot = findPanSlot(player);
|
||||
return slot < 0 ? ItemStack.EMPTY : player.getInventory().getItem(slot);
|
||||
}
|
||||
|
||||
public static int findPanSlot(Player player) {
|
||||
@@ -51,124 +77,185 @@ public final class GiantFryingPanStorage implements Container {
|
||||
|
||||
public static void tick(Player player, ItemStack pan, Level level) {
|
||||
if (level.isClientSide || !(pan.getItem() instanceof GiantFryingPanItem)) return;
|
||||
if (!pan.has(DataComponents.CUSTOM_DATA)) return;
|
||||
GiantFryingPanStorage storage = new GiantFryingPanStorage(pan, player);
|
||||
if (storage.isEmpty()) return;
|
||||
long now = level.getGameTime();
|
||||
boolean changed = false;
|
||||
for (int slot = 0; slot < SLOT_COUNT; slot++) {
|
||||
ItemStack input = storage.getItem(slot);
|
||||
if (input.isEmpty()) continue;
|
||||
Optional<RecipeHolder<CampfireCookingRecipe>> recipe = level.getServer().getRecipeManager().getRecipeFor(
|
||||
ItemStack input = storage.items.get(slot);
|
||||
if (input.isEmpty() || now - storage.startTimes[slot] < COOK_TIME) continue;
|
||||
Optional<RecipeHolder<CampfireCookingRecipe>> recipe = level.getRecipeManager().getRecipeFor(
|
||||
RecipeType.CAMPFIRE_COOKING, new SingleRecipeInput(input), level);
|
||||
if (recipe.isEmpty()) {
|
||||
storage.setCookTime(slot, 0);
|
||||
continue;
|
||||
}
|
||||
int time = storage.getCookTime(slot) + 1;
|
||||
if (time < 600) {
|
||||
storage.setCookTime(slot, time);
|
||||
continue;
|
||||
}
|
||||
if (recipe.isEmpty()) continue;
|
||||
ItemStack cooked = recipe.get().value().assemble(new SingleRecipeInput(input), level.registryAccess());
|
||||
input.shrink(1);
|
||||
storage.setItem(slot, input);
|
||||
storage.setCookTime(slot, 0);
|
||||
storage.startTimes[slot] = now;
|
||||
changed = true;
|
||||
if (!cooked.isEmpty()) {
|
||||
var output = new net.minecraft.world.entity.item.ItemEntity(level, player.getX(), player.getY() + 1.2D, player.getZ(), cooked);
|
||||
ItemEntity output = new ItemEntity(level, player.getX(), player.getY() + 1.2D, player.getZ(), cooked);
|
||||
output.setDeltaMovement(player.getLookAngle().scale(0.35D).add(0.0D, 0.2D, 0.0D));
|
||||
output.setPickUpDelay(10);
|
||||
level.addFreshEntity(output);
|
||||
}
|
||||
}
|
||||
if (changed) storage.setChanged();
|
||||
}
|
||||
|
||||
public static boolean isCampfireInput(Player player, ItemStack stack) {
|
||||
return !stack.isEmpty() && (player.getServer() == null || player.getServer().getRecipeManager().getRecipeFor(
|
||||
RecipeType.CAMPFIRE_COOKING, new SingleRecipeInput(stack), player.level()).isPresent());
|
||||
if (stack.isEmpty() || stack.getItem() instanceof GiantFryingPanItem) return false;
|
||||
Level level = player.level();
|
||||
return level.getRecipeManager().getRecipeFor(RecipeType.CAMPFIRE_COOKING, new SingleRecipeInput(stack), level).isPresent();
|
||||
}
|
||||
|
||||
private ListTag slotList() {
|
||||
return pan.getOrDefault(net.minecraft.core.component.DataComponents.CUSTOM_DATA, net.minecraft.world.item.component.CustomData.EMPTY)
|
||||
.copyTag().getList(SLOTS, Tag.TAG_COMPOUND);
|
||||
}
|
||||
|
||||
private CompoundTag slotTag(int slot) {
|
||||
for (Tag raw : slotList()) {
|
||||
CompoundTag tag = (CompoundTag) raw;
|
||||
if (tag.getInt(SLOT) == slot) return tag;
|
||||
public boolean insertOne(ItemStack food) {
|
||||
if (!isCampfireInput(this.player, food)) return false;
|
||||
this.reloadIfChanged();
|
||||
for (int slot = 0; slot < SLOT_COUNT; slot++) {
|
||||
if (this.items.get(slot).isEmpty()) {
|
||||
this.setItem(slot, food.split(1));
|
||||
return true;
|
||||
}
|
||||
}
|
||||
CompoundTag tag = new CompoundTag();
|
||||
tag.putInt(SLOT, slot);
|
||||
return tag;
|
||||
return false;
|
||||
}
|
||||
|
||||
private void writeSlot(int slot, ItemStack stack, int cookTime) {
|
||||
HolderLookup.Provider registries = player.registryAccess();
|
||||
net.minecraft.world.item.component.CustomData.update(net.minecraft.core.component.DataComponents.CUSTOM_DATA, pan, root -> {
|
||||
ListTag list = root.getList(SLOTS, Tag.TAG_COMPOUND);
|
||||
for (int i = list.size() - 1; i >= 0; i--) {
|
||||
if (list.getCompound(i).getInt(SLOT) == slot) list.remove(i);
|
||||
public boolean hasSpace() {
|
||||
this.reloadIfChanged();
|
||||
for (ItemStack stack : this.items) {
|
||||
if (stack.isEmpty()) return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public float cookProgress(int slot) {
|
||||
this.reloadIfChanged();
|
||||
if (this.items.get(slot).isEmpty()) return 0.0F;
|
||||
long elapsed = this.player.level().getGameTime() - this.startTimes[slot];
|
||||
return Math.max(0.0F, Math.min(1.0F, elapsed / (float) COOK_TIME));
|
||||
}
|
||||
|
||||
private void reloadIfChanged() {
|
||||
ItemStack pan = this.pan();
|
||||
CustomData data = pan.get(DataComponents.CUSTOM_DATA);
|
||||
if (pan == this.loadedPan && data == this.loadedFrom) return;
|
||||
this.loadedPan = pan;
|
||||
this.loadedFrom = data;
|
||||
for (int slot = 0; slot < SLOT_COUNT; slot++) {
|
||||
this.items.set(slot, ItemStack.EMPTY);
|
||||
this.startTimes[slot] = 0L;
|
||||
this.startItems[slot] = null;
|
||||
}
|
||||
if (data == null) return;
|
||||
ListTag list = data.copyTag().getList(SLOTS, Tag.TAG_COMPOUND);
|
||||
for (int i = 0; i < list.size(); i++) {
|
||||
CompoundTag tag = list.getCompound(i);
|
||||
int slot = tag.getInt(SLOT);
|
||||
if (slot < 0 || slot >= SLOT_COUNT || !tag.contains(ITEM, Tag.TAG_COMPOUND)) continue;
|
||||
ItemStack stack = ItemStack.parseOptional(this.player.registryAccess(), tag.getCompound(ITEM));
|
||||
this.items.set(slot, stack);
|
||||
this.startTimes[slot] = tag.getLong(START);
|
||||
this.startItems[slot] = stack;
|
||||
}
|
||||
}
|
||||
|
||||
private void refreshStartTimes() {
|
||||
long now = this.player.level().getGameTime();
|
||||
for (int slot = 0; slot < SLOT_COUNT; slot++) {
|
||||
ItemStack stack = this.items.get(slot);
|
||||
if (stack.isEmpty()) {
|
||||
this.startItems[slot] = null;
|
||||
this.startTimes[slot] = 0L;
|
||||
} else if (this.startItems[slot] == null || !ItemStack.isSameItemSameComponents(this.startItems[slot], stack)) {
|
||||
this.startItems[slot] = stack;
|
||||
this.startTimes[slot] = now;
|
||||
}
|
||||
if (!stack.isEmpty()) {
|
||||
CompoundTag tag = new CompoundTag();
|
||||
tag.putInt(SLOT, slot);
|
||||
tag.putInt(TIME, cookTime);
|
||||
tag.put(ITEM, stack.save(registries));
|
||||
list.add(tag);
|
||||
}
|
||||
root.put(SLOTS, list);
|
||||
});
|
||||
}
|
||||
|
||||
public int getCookTime(int slot) {
|
||||
return slotTag(slot).getInt(TIME);
|
||||
}
|
||||
|
||||
public void setCookTime(int slot, int value) {
|
||||
ItemStack stack = getItem(slot);
|
||||
if (!stack.isEmpty()) writeSlot(slot, stack, value);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getContainerSize() { return SLOT_COUNT; }
|
||||
public int getContainerSize() {
|
||||
return SLOT_COUNT;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isEmpty() {
|
||||
for (int i = 0; i < SLOT_COUNT; i++) if (!getItem(i).isEmpty()) return false;
|
||||
this.reloadIfChanged();
|
||||
for (ItemStack stack : this.items) {
|
||||
if (!stack.isEmpty()) return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemStack getItem(int slot) {
|
||||
CompoundTag tag = slotTag(slot);
|
||||
if (!tag.contains(ITEM, Tag.TAG_COMPOUND)) return ItemStack.EMPTY;
|
||||
return ItemStack.parseOptional(player.registryAccess(), tag.getCompound(ITEM));
|
||||
this.reloadIfChanged();
|
||||
return this.items.get(slot);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemStack removeItem(int slot, int amount) {
|
||||
ItemStack stack = getItem(slot);
|
||||
if (stack.isEmpty()) return ItemStack.EMPTY;
|
||||
this.reloadIfChanged();
|
||||
ItemStack stack = this.items.get(slot);
|
||||
if (stack.isEmpty() || amount <= 0) return ItemStack.EMPTY;
|
||||
ItemStack result = stack.split(amount);
|
||||
writeSlot(slot, stack, 0);
|
||||
this.setChanged();
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemStack removeItemNoUpdate(int slot) {
|
||||
ItemStack result = getItem(slot);
|
||||
writeSlot(slot, ItemStack.EMPTY, 0);
|
||||
this.reloadIfChanged();
|
||||
ItemStack result = this.items.get(slot);
|
||||
this.items.set(slot, ItemStack.EMPTY);
|
||||
this.setChanged();
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setItem(int slot, ItemStack stack) { writeSlot(slot, stack, 0); }
|
||||
public void setItem(int slot, ItemStack stack) {
|
||||
this.reloadIfChanged();
|
||||
this.items.set(slot, stack);
|
||||
this.setChanged();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setChanged() { }
|
||||
public int getMaxStackSize() {
|
||||
return 1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean stillValid(Player player) { return player.isAlive(); }
|
||||
public void setChanged() {
|
||||
ItemStack pan = this.pan();
|
||||
if (!(pan.getItem() instanceof GiantFryingPanItem)) return;
|
||||
this.refreshStartTimes();
|
||||
ListTag list = new ListTag();
|
||||
for (int slot = 0; slot < SLOT_COUNT; slot++) {
|
||||
ItemStack stack = this.items.get(slot);
|
||||
if (stack.isEmpty()) continue;
|
||||
CompoundTag tag = new CompoundTag();
|
||||
tag.putInt(SLOT, slot);
|
||||
tag.putLong(START, this.startTimes[slot]);
|
||||
tag.put(ITEM, stack.save(this.player.registryAccess()));
|
||||
list.add(tag);
|
||||
}
|
||||
CustomData.update(DataComponents.CUSTOM_DATA, pan, root -> {
|
||||
if (list.isEmpty()) root.remove(SLOTS);
|
||||
else root.put(SLOTS, list);
|
||||
});
|
||||
this.loadedPan = pan;
|
||||
this.loadedFrom = pan.get(DataComponents.CUSTOM_DATA);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean stillValid(Player player) {
|
||||
return player.isAlive() && this.hasPan();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void clearContent() {
|
||||
for (int i = 0; i < SLOT_COUNT; i++) writeSlot(i, ItemStack.EMPTY, 0);
|
||||
this.reloadIfChanged();
|
||||
for (int slot = 0; slot < SLOT_COUNT; slot++) this.items.set(slot, ItemStack.EMPTY);
|
||||
this.setChanged();
|
||||
}
|
||||
}
|
||||
+62
-16
@@ -1,53 +1,99 @@
|
||||
package com.craisinlord.antarchy.content.menu;
|
||||
|
||||
import com.craisinlord.antarchy.Antarchy;
|
||||
import com.craisinlord.antarchy.content.AntarchyObjects;
|
||||
import com.craisinlord.antarchy.content.item.GiantFryingPanItem;
|
||||
import com.craisinlord.antarchy.content.item.GiantFryingPanStorage;
|
||||
import net.minecraft.world.entity.player.Inventory;
|
||||
import net.minecraft.world.entity.player.Player;
|
||||
import net.minecraft.world.inventory.AbstractContainerMenu;
|
||||
import net.minecraft.world.inventory.ClickType;
|
||||
import net.minecraft.world.inventory.Slot;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
|
||||
public final class GiantFryingPanMenu extends AbstractContainerMenu {
|
||||
public static final int PAN_ROW_Y = 18;
|
||||
public static final int INVENTORY_Y = 49;
|
||||
public static final int HOTBAR_Y = 107;
|
||||
private final GiantFryingPanStorage panStorage;
|
||||
private final int panSlot;
|
||||
|
||||
public GiantFryingPanMenu(int containerId, Inventory inventory) {
|
||||
this(containerId, inventory, GiantFryingPanStorage.findPanSlot(inventory.player));
|
||||
}
|
||||
|
||||
public GiantFryingPanMenu(int containerId, Inventory inventory, int panSlot) {
|
||||
super(AntarchyObjects.GIANT_FRYING_PAN_MENU.get(), containerId);
|
||||
ItemStack pan = GiantFryingPanStorage.findPan(inventory.player);
|
||||
this.panStorage = new GiantFryingPanStorage(pan, inventory.player);
|
||||
Player player = inventory.player;
|
||||
this.panSlot = panSlot;
|
||||
this.panStorage = new GiantFryingPanStorage(player, panSlot);
|
||||
Antarchy.LOGGER.info("[FryingPan] Menu created client={} containerId={} panSlot={} pan={}",
|
||||
player.level().isClientSide, containerId, panSlot, this.panStorage.pan());
|
||||
for (int slot = 0; slot < GiantFryingPanStorage.SLOT_COUNT; slot++) {
|
||||
this.addSlot(new Slot(panStorage, slot, 8 + slot * 18, 18) {
|
||||
this.addSlot(new Slot(this.panStorage, slot, 8 + slot * 18, PAN_ROW_Y) {
|
||||
@Override
|
||||
public boolean mayPlace(ItemStack stack) {
|
||||
return GiantFryingPanStorage.isCampfireInput(inventory.player, stack);
|
||||
return GiantFryingPanStorage.isCampfireInput(player, stack);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getMaxStackSize() { return 1; }
|
||||
public int getMaxStackSize() {
|
||||
return 1;
|
||||
}
|
||||
});
|
||||
}
|
||||
for (int row = 0; row < 3; row++) {
|
||||
for (int col = 0; col < 9; col++) {
|
||||
this.addSlot(new Slot(inventory, col + row * 9 + 9, 8 + col * 18, 50 + row * 18));
|
||||
this.addSlot(this.inventorySlot(inventory, col + row * 9 + 9, 8 + col * 18, INVENTORY_Y + row * 18));
|
||||
}
|
||||
}
|
||||
for (int col = 0; col < 9; col++) this.addSlot(new Slot(inventory, col, 8 + col * 18, 108));
|
||||
for (int col = 0; col < 9; col++) {
|
||||
this.addSlot(this.inventorySlot(inventory, col, 8 + col * 18, HOTBAR_Y));
|
||||
}
|
||||
}
|
||||
|
||||
private Slot inventorySlot(Inventory inventory, int index, int x, int y) {
|
||||
return new Slot(inventory, index, x, y) {
|
||||
@Override
|
||||
public boolean mayPickup(Player player) {
|
||||
return index != GiantFryingPanMenu.this.panSlot && super.mayPickup(player);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean mayPlace(ItemStack stack) {
|
||||
return index != GiantFryingPanMenu.this.panSlot && super.mayPlace(stack);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
public GiantFryingPanStorage storage() {
|
||||
return this.panStorage;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean stillValid(Player player) { return player.isAlive() && !panStorage.isEmpty() || GiantFryingPanStorage.findPan(player).getItem() instanceof GiantFryingPanItem; }
|
||||
public void clicked(int slotId, int button, ClickType clickType, Player player) {
|
||||
if (clickType == ClickType.SWAP && button == this.panSlot) return;
|
||||
super.clicked(slotId, button, clickType, player);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean stillValid(Player player) {
|
||||
return this.panStorage.stillValid(player);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemStack quickMoveStack(Player player, int index) {
|
||||
if (index < 0 || index >= slots.size()) return ItemStack.EMPTY;
|
||||
Slot slot = slots.get(index);
|
||||
if (!slot.hasItem()) return ItemStack.EMPTY;
|
||||
ItemStack original = slot.getItem().copy();
|
||||
if (index < 0 || index >= this.slots.size()) return ItemStack.EMPTY;
|
||||
Slot slot = this.slots.get(index);
|
||||
if (!slot.hasItem() || !slot.mayPickup(player)) return ItemStack.EMPTY;
|
||||
ItemStack current = slot.getItem();
|
||||
ItemStack original = current.copy();
|
||||
if (index < GiantFryingPanStorage.SLOT_COUNT) {
|
||||
if (!moveItemStackTo(slot.getItem(), GiantFryingPanStorage.SLOT_COUNT, slots.size(), true)) return ItemStack.EMPTY;
|
||||
} else if (!moveItemStackTo(slot.getItem(), 0, GiantFryingPanStorage.SLOT_COUNT, false)) return ItemStack.EMPTY;
|
||||
if (slot.getItem().isEmpty()) slot.setByPlayer(ItemStack.EMPTY);
|
||||
if (!this.moveItemStackTo(current, GiantFryingPanStorage.SLOT_COUNT, this.slots.size(), true)) return ItemStack.EMPTY;
|
||||
} else if (!GiantFryingPanStorage.isCampfireInput(player, current)
|
||||
|| !this.moveItemStackTo(current, 0, GiantFryingPanStorage.SLOT_COUNT, false)) {
|
||||
return ItemStack.EMPTY;
|
||||
}
|
||||
if (current.isEmpty()) slot.setByPlayer(ItemStack.EMPTY);
|
||||
else slot.setChanged();
|
||||
return original;
|
||||
}
|
||||
|
||||
+16
-15
@@ -16,6 +16,11 @@ import net.minecraft.world.level.biome.BiomeSource;
|
||||
import net.minecraft.world.level.biome.Climate;
|
||||
import net.minecraft.world.level.biome.MultiNoiseBiomeSource;
|
||||
|
||||
/**
|
||||
* Plain multi-noise biome source with one addition: everything at or above
|
||||
* {@code cloud_sea_min_y} is the cloud sea. Below that line, biome selection is
|
||||
* identical to {@code minecraft:multi_noise} over the same list minus the cloud sea entry.
|
||||
*/
|
||||
public final class ElythiaBiomeSource extends BiomeSource {
|
||||
private static final ResourceKey<Biome> CLOUD_SEA = ResourceKey.create(
|
||||
Registries.BIOME,
|
||||
@@ -29,24 +34,25 @@ public final class ElythiaBiomeSource extends BiomeSource {
|
||||
|
||||
private final Climate.ParameterList<Holder<Biome>> parameters;
|
||||
private final MultiNoiseBiomeSource delegate;
|
||||
private final int cloudSeaMinY;
|
||||
private final int cloudSeaMinQuartY;
|
||||
private final Holder<Biome> cloudSeaHolder;
|
||||
private final Holder<Biome> fallbackHolder;
|
||||
|
||||
public ElythiaBiomeSource(Climate.ParameterList<Holder<Biome>> parameters, int cloudSeaMinY) {
|
||||
this.parameters = parameters;
|
||||
this.delegate = MultiNoiseBiomeSource.createFromList(parameters);
|
||||
this.cloudSeaMinY = cloudSeaMinY;
|
||||
this.cloudSeaMinQuartY = QuartPos.fromBlock(cloudSeaMinY);
|
||||
this.cloudSeaHolder = parameters.values().stream()
|
||||
.map(Pair::getSecond)
|
||||
.filter(holder -> holder.is(CLOUD_SEA))
|
||||
.findFirst()
|
||||
.orElse(null);
|
||||
this.fallbackHolder = parameters.values().stream()
|
||||
.map(Pair::getSecond)
|
||||
.filter(holder -> !holder.is(CLOUD_SEA))
|
||||
.findFirst()
|
||||
.orElse(null);
|
||||
// Keep the cloud sea out of the noise search so terrain biomes resolve exactly as before.
|
||||
this.delegate = MultiNoiseBiomeSource.createFromList(new Climate.ParameterList<>(
|
||||
parameters.values().stream()
|
||||
.filter(entry -> !entry.getSecond().is(CLOUD_SEA))
|
||||
.toList()
|
||||
));
|
||||
}
|
||||
|
||||
private Climate.ParameterList<Holder<Biome>> parameters() {
|
||||
@@ -54,7 +60,7 @@ public final class ElythiaBiomeSource extends BiomeSource {
|
||||
}
|
||||
|
||||
private int cloudSeaMinY() {
|
||||
return this.cloudSeaMinQuartY * 4;
|
||||
return this.cloudSeaMinY;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -64,7 +70,7 @@ public final class ElythiaBiomeSource extends BiomeSource {
|
||||
|
||||
@Override
|
||||
protected Stream<Holder<Biome>> collectPossibleBiomes() {
|
||||
return this.delegate.possibleBiomes().stream();
|
||||
return this.parameters.values().stream().map(Pair::getSecond).distinct();
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -72,11 +78,6 @@ public final class ElythiaBiomeSource extends BiomeSource {
|
||||
if (this.cloudSeaHolder != null && y >= this.cloudSeaMinQuartY) {
|
||||
return this.cloudSeaHolder;
|
||||
}
|
||||
|
||||
Holder<Biome> biome = this.delegate.getNoiseBiome(x, y, z, sampler);
|
||||
if (biome != null && !biome.is(CLOUD_SEA)) {
|
||||
return biome;
|
||||
}
|
||||
return this.fallbackHolder != null ? this.fallbackHolder : biome;
|
||||
return this.delegate.getNoiseBiome(x, y, z, sampler);
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user