Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ PurpurClient is designed to work together with [Purpur](https://github.com/Purpu

</div>

### Current Features in 1.21.5:
### Current Features in 1.21.6:

* Customizable mob passenger offsets
* Adds bee counts inside beehives to debug screen¹
Expand Down
8 changes: 4 additions & 4 deletions gradle.properties
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
org.gradle.jvmargs=-Xmx2G

minecraft_version=1.21.5
loader_version=0.16.13
minecraft_version=1.21.6
loader_version=0.16.14
# parchment_version=2025.02.16 # TODO: update when available
fabric_version=0.120.0+1.21.5
modmenu_version=14.0.0-rc.2
fabric_version=0.128.0+1.21.6
modmenu_version=15.0.0-beta.3
configurate_version=4.1.2

maven_group=org.purpurmc.purpur.client
Expand Down
3 changes: 3 additions & 0 deletions src/main/java/org/purpurmc/purpur/client/config/Seats.java
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ public class Seats {
public Seat glowSquid = new Seat(0.0D, 0.0D, 0.0D);
public Seat goat = new Seat(0.0D, 0.0D, 0.0D);
public Seat guardian = new Seat(0.0D, 0.0D, 0.0D);
public Seat happyGhast = new Seat(0.0D, 0.0D, 0.0D);
public Seat hoglin = new Seat(0.0D, 0.0D, 0.0D);
public Seat horse = new Seat(0.0D, 0.0D, 0.0D);
public Seat husk = new Seat(0.0D, 0.0D, 0.0D);
Expand Down Expand Up @@ -122,6 +123,7 @@ public void setAllSeats(double x, double y, double z) {
glowSquid.setSeat(z, y, z);
goat.setSeat(z, y, z);
guardian.setSeat(z, y, z);
happyGhast.setSeat(z, y, z);
hoglin.setSeat(z, y, z);
horse.setSeat(z, y, z);
husk.setSeat(z, y, z);
Expand Down Expand Up @@ -208,6 +210,7 @@ public Seat getSeat(Mob mob) {
case GLOW_SQUID -> this.glowSquid;
case GOAT -> this.goat;
case GUARDIAN -> this.guardian;
case HAPPY_GHAST -> this.happyGhast;
case HOGLIN -> this.hoglin;
case HORSE -> this.horse;
case HUSK -> this.husk;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
package org.purpurmc.purpur.client.config.options;

import java.util.ArrayList;
import java.util.List;
import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.screens.inventory.tooltip.ClientTooltipComponent;
import net.minecraft.network.chat.Component;
import net.minecraft.util.FormattedCharSequence;

public class BooleanOption implements Option<Boolean> {
private final String key;
private final List<FormattedCharSequence> tooltip;
private final List<ClientTooltipComponent> tooltip = new ArrayList<>();
private final Getter getter;
private final Setter setter;

Expand All @@ -16,7 +17,9 @@ public class BooleanOption implements Option<Boolean> {

public BooleanOption(String key, Getter getter, Setter setter) {
this.key = "purpurclient.options." + key;
this.tooltip = Minecraft.getInstance().font.split(Component.translatable(this.key + ".tooltip"), 170);
Minecraft.getInstance().font.split(Component.translatable(this.key + ".tooltip"), 170).forEach(splitTooltip -> {
tooltip.add(ClientTooltipComponent.create(splitTooltip));
});
this.on = Component.translatable("purpurclient.options.on", Component.translatable(this.key));
this.off = Component.translatable("purpurclient.options.off", Component.translatable(this.key));
this.getter = getter;
Expand All @@ -35,7 +38,7 @@ public Component text() {
}

@Override
public List<FormattedCharSequence> tooltip() {
public List<ClientTooltipComponent> tooltip() {
return this.tooltip;
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,21 +1,24 @@
package org.purpurmc.purpur.client.config.options;

import java.util.ArrayList;
import java.util.List;
import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.screens.inventory.tooltip.ClientTooltipComponent;
import net.minecraft.network.chat.Component;
import net.minecraft.util.FormattedCharSequence;

public class DoubleOption implements Option<Double> {
private final String key;
private final List<FormattedCharSequence> tooltip;
private final List<ClientTooltipComponent> tooltip = new ArrayList<>();
private final Getter getter;
private final Setter setter;

private Component text;

public DoubleOption(String key, Getter getter, Setter setter) {
this.key = "purpurclient.options." + key;
this.tooltip = Minecraft.getInstance().font.split(Component.translatable(this.key + ".tooltip"), 170);
Minecraft.getInstance().font.split(Component.translatable(this.key + ".tooltip"), 170).forEach(splitTooltip -> {
tooltip.add(ClientTooltipComponent.create(splitTooltip));
});
this.getter = getter;
this.setter = setter;

Expand All @@ -34,7 +37,7 @@ public Component text() {
}

@Override
public List<FormattedCharSequence> tooltip() {
public List<ClientTooltipComponent> tooltip() {
return this.tooltip;
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,16 +1,17 @@
package org.purpurmc.purpur.client.config.options;

import java.util.List;

import net.minecraft.client.gui.screens.inventory.tooltip.ClientTooltipComponent;
import net.minecraft.network.chat.Component;
import net.minecraft.util.FormattedCharSequence;

@SuppressWarnings("unused")
public interface Option<T> {
String key();

Component text();

List<FormattedCharSequence> tooltip();
List<ClientTooltipComponent> tooltip();

T get();

Expand Down
1 change: 1 addition & 0 deletions src/main/java/org/purpurmc/purpur/client/entity/Mob.java
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ public enum Mob {
GLOW_SQUID(EntityType.GLOW_SQUID, 5, 1),
GOAT(EntityType.GOAT, 6, 1),
GUARDIAN(EntityType.GUARDIAN, 7, 1),
HAPPY_GHAST(EntityType.HAPPY_GHAST, 2, 5), // TODO: update mobs.png
HOGLIN(EntityType.HOGLIN, 8, 1),
HORSE(EntityType.HORSE, 9, 1),
HUSK(EntityType.HUSK, 10, 1),
Expand Down
57 changes: 37 additions & 20 deletions src/main/java/org/purpurmc/purpur/client/gui/screen/MobScreen.java
Original file line number Diff line number Diff line change
@@ -1,16 +1,21 @@
package org.purpurmc.purpur.client.gui.screen;

import com.mojang.blaze3d.platform.Lighting;
import com.mojang.blaze3d.systems.RenderSystem;
import com.mojang.blaze3d.vertex.PoseStack;
import com.mojang.math.Axis;
import java.util.List;
import net.minecraft.client.gui.components.AbstractWidget;
import net.minecraft.client.gui.screens.options.OptionsSubScreen;
import net.minecraft.client.renderer.MultiBufferSource;
import net.minecraft.client.renderer.entity.EntityRenderer;
import net.minecraft.client.renderer.entity.state.LivingEntityRenderState;
import net.minecraft.client.renderer.entity.state.PlayerRenderState;
import net.minecraft.world.entity.EntitySpawnReason;
import net.minecraft.world.entity.LivingEntity;
import org.joml.Matrix3x2fStack;
import org.joml.Matrix4fStack;
import org.joml.Quaternionf;
import org.joml.Vector3f;
import org.purpurmc.purpur.client.PurpurClient;
import org.purpurmc.purpur.client.config.options.DoubleOption;
import org.purpurmc.purpur.client.entity.Mob;
Expand Down Expand Up @@ -64,7 +69,7 @@ public class MobScreen extends OptionsSubScreen {
private double mouseDownY;

private double previewX = -80;
private double previewY = 200;
private double previewY = 70;
private float previewYaw = -145;
private float previewPitch = -20;
private float previewZoom = 60;
Expand Down Expand Up @@ -157,15 +162,13 @@ protected void addOptions() {

@Override
public void render(GuiGraphics context, int mouseX, int mouseY, float delta) {
context.fillGradient(0, 0, this.width, this.height, 0x800F4863, 0x80370038);
if (this.minecraft.level == null) {
super.renderPanorama(context, delta);
} else {
super.renderBlurredBackground();
}
RenderSystem.setShaderColor(1.0F, 1.0F, 1.0F, 1.0F);

if (this.fakePlayer != null && this.fakeEntity != null) {
drawPreviewModel(this.fakePlayer, this.fakeEntity);
drawPreviewModel(this.fakePlayer, this.fakeEntity, context);
} else {
if (this.minecraft.level != null) {
context.drawCenteredString(this.font, this.experimentDisabled, this.centerX - 80, 125, 0xFFFFFFFF);
Expand All @@ -174,9 +177,9 @@ public void render(GuiGraphics context, int mouseX, int mouseY, float delta) {
}
}

PoseStack matrices = context.pose();
matrices.pushPose();
matrices.translate(0, 0, 900);
Matrix3x2fStack matrices = context.pose();
matrices.pushMatrix();
//matrices.translate(900, 0);
context.drawCenteredString(this.font, this.title, this.centerX, 15, 0xFFFFFFFF);
context.drawCenteredString(this.font, this.subtitle, this.centerX, 30, 0xFFFFFFFF);
if (this.options == null || this.options.isEmpty()) {
Expand All @@ -186,8 +189,7 @@ public void render(GuiGraphics context, int mouseX, int mouseY, float delta) {
drawable.render(context, mouseX, mouseY, delta);
}
}
matrices.popPose();
context.fillGradient(0, 0, this.width, this.height, 0x800F4863, 0x80370038);
matrices.popMatrix();
}

@Override
Expand All @@ -196,13 +198,12 @@ public void renderBackground(GuiGraphics context, int mouseX, int mouseY, float
context.fillGradient(0, 0, this.width, this.height, 0x800F4863, 0x80370038);
}

public void drawPreviewModel(FakePlayer player, Entity vehicle) {
public void drawPreviewModel(FakePlayer player, Entity vehicle, GuiGraphics context) {
Matrix4fStack matrixStack = RenderSystem.getModelViewStack();
matrixStack.pushMatrix();
matrixStack.translate((float) (this.centerX + this.previewX), (float) this.previewY, 1500);
matrixStack.scale(1.0F, 1.0F, -1.0F);


PoseStack matrixStack2 = new PoseStack();
matrixStack2.translate(0.0D, 0.0D, 1000.0D);
float zoom = this.previewZoom * this.previewZoomMultiplier;
Expand All @@ -216,22 +217,38 @@ public void drawPreviewModel(FakePlayer player, Entity vehicle) {
quaternion2.conjugate();
matrixStack2.mulPose(quaternion);

Lighting.setupForEntityInInventory();
EntityRenderDispatcher renderer = Minecraft.getInstance().getEntityRenderDispatcher();
renderer.overrideCameraOrientation(quaternion2);
renderer.setRenderShadow(false);
MultiBufferSource.BufferSource immediate = Minecraft.getInstance().renderBuffers().bufferSource();

Minecraft.getInstance().execute(() -> {
fixEntityRender(vehicle, matrixStack2, () -> renderer.render(vehicle, vehicle.getX(), vehicle.getY(), vehicle.getZ(), 0.0F, matrixStack2, immediate, 0xF000F0));
renderer.render(player, player.getX(), player.getY(), player.getZ(), 0.0F, matrixStack2, immediate, 0xF000F0);
});
/*
TODO: FIX THIS
Issues we are currently having:
- The screen only shows one entity at a time
- The player won't move even if something is configured
*/
EntityRenderDispatcher entityRenderDispatcher = Minecraft.getInstance().getEntityRenderDispatcher();

EntityRenderer<? super LivingEntity, ?> entityRenderer = entityRenderDispatcher.getRenderer(vehicle);
LivingEntityRenderState entityRenderState = (LivingEntityRenderState) entityRenderer.createRenderState((LivingEntity) vehicle, 1.0F);
entityRenderState.hitboxesRenderState = null;

context.submitEntityRenderState(
entityRenderState, previewZoom, new Vector3f(), quaternion, quaternion2, (int) previewX, (int) previewY, (int) (previewX + width), (int) (previewY + height)
);

EntityRenderer<? super LivingEntity, ?> playerRenderer = entityRenderDispatcher.getRenderer(player);
PlayerRenderState playerRenderState = (PlayerRenderState) playerRenderer.createRenderState(player, 1.0F);
playerRenderState.hitboxesRenderState = null;

context.submitEntityRenderState(
playerRenderState, previewZoom, new Vector3f(), quaternion, quaternion2, (int) previewX, (int) previewY, (int) (previewX + width), (int) (previewY + height)
);

immediate.endBatch();
renderer.setRenderShadow(true);
matrixStack.popMatrix();

Lighting.setupFor3DItems();
}

private void fixEntityRender(Entity entity, PoseStack matrixStack, Runnable runnable) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,9 @@
import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.GuiGraphics;
import net.minecraft.client.gui.components.Button;
import net.minecraft.client.gui.screens.inventory.tooltip.DefaultTooltipPositioner;
import net.minecraft.network.chat.Component;
import net.minecraft.resources.ResourceLocation;
import org.purpurmc.purpur.client.config.options.BooleanOption;

public class BooleanButton extends Button implements Tickable {
Expand All @@ -17,7 +19,8 @@ public BooleanButton(int x, int y, int width, int height, BooleanOption option)

public void renderTooltip(GuiGraphics context, int mouseX, int mouseY) {
if (this.isHovered && this.tooltipDelay > 15 && Minecraft.getInstance().screen != null) {
context.renderTooltip(Minecraft.getInstance().font, this.option.tooltip(), mouseX, mouseY);
// TODO: resource location of the default tooltip
context.renderTooltip(Minecraft.getInstance().font, this.option.tooltip(), mouseX, mouseY, DefaultTooltipPositioner.INSTANCE, null); // nulled it temp. until I find a solution so it won't crash
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,8 @@
import net.minecraft.client.gui.components.AbstractWidget;
import net.minecraft.client.gui.components.WidgetSprites;
import net.minecraft.client.gui.narration.NarrationElementOutput;
import net.minecraft.client.renderer.RenderType;
import net.minecraft.client.gui.screens.inventory.tooltip.DefaultTooltipPositioner;
import net.minecraft.client.renderer.RenderPipelines;
import net.minecraft.network.chat.Component;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.util.Mth;
Expand Down Expand Up @@ -59,8 +60,7 @@ public void renderWidget(GuiGraphics context, int mouseX, int mouseY, float delt
}

private void drawButton(GuiGraphics context, Component text, int x, boolean i) {
RenderSystem.setShaderColor(1.0F, 1.0F, 1.0F, this.alpha);
context.blitSprite(RenderType::guiTextured, TEXTURES.get(this.active, i), x, this.getY(), this.height, this.height);
context.blitSprite(RenderPipelines.GUI_TEXTURED, TEXTURES.get(this.active, i), x, this.getY(), this.height, this.height);
context.drawCenteredString(Minecraft.getInstance().font, text, x + this.height / 2, this.getY() + (this.height - 8) / 2, (this.active ? 0xFFFFFF : 0xA0A0A0) | Mth.ceil(this.alpha * 255.0f) << 24);
}

Expand Down Expand Up @@ -97,11 +97,13 @@ public void onRelease(double mouseX, double mouseY) {

public void renderTooltip(GuiGraphics context, int mouseX, int mouseY) {
if (this.tooltipDelay > 15 && Minecraft.getInstance().screen != null) {
PoseStack matrices = context.pose();
matrices.pushPose();
matrices.translate(0, 0, -399);
context.renderTooltip(Minecraft.getInstance().font, this.option.tooltip(), mouseX, mouseY);
matrices.popPose();
// TODO: check what to do with the matrices
//PoseStack matrices = context.pose();
//matrices.pushPose();
//matrices.translate(0, 0, -399);
// TODO: resource location of the default tooltip
context.renderTooltip(Minecraft.getInstance().font, this.option.tooltip(), mouseX, mouseY, DefaultTooltipPositioner.INSTANCE, null); // nulled it temp. until I find a solution so it won't crash
//matrices.popPose();
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
import net.minecraft.client.gui.components.SpriteIconButton;
import net.minecraft.client.gui.components.Tooltip;
import net.minecraft.client.gui.screens.Screen;
import net.minecraft.client.renderer.RenderType;
import net.minecraft.client.renderer.RenderPipelines;
import net.minecraft.resources.ResourceLocation;
import org.purpurmc.purpur.client.entity.Mob;
import org.purpurmc.purpur.client.gui.screen.MobScreen;
Expand All @@ -31,7 +31,7 @@ public MobButton(Minecraft client, Screen screen, Mob mob) {
public void renderWidget(GuiGraphics context, int mouseX, int mouseY, float delta) {
super.renderWidget(context, mouseX, mouseY, delta);
context.blit(
RenderType::guiTextured,
RenderPipelines.GUI_TEXTURED,
MOBS_TEXTURE,
this.getX(),
this.getY(),
Expand Down
Loading