Skip to content

Commit

Permalink
Entity icon element (#18)
Browse files Browse the repository at this point in the history
* Add Entity icon
  • Loading branch information
uecasm authored Jun 4, 2022
1 parent 0ece900 commit 800755e
Show file tree
Hide file tree
Showing 5 changed files with 236 additions and 2 deletions.
1 change: 1 addition & 0 deletions src/main/java/com/ldtteam/blockui/Loader.java
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ private Loader()
register("imagerepeat", ImageRepeatable::new);
register("box", Box::new);
register("itemicon", ItemIcon::new);
register("entityicon", EntityIcon::new);
register("switch", SwitchView::new);
register("dropdown", DropDownList::new);
register("overlay", OverlayView::new);
Expand Down
63 changes: 63 additions & 0 deletions src/main/java/com/ldtteam/blockui/UiRenderMacros.java
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,15 @@
import com.mojang.blaze3d.vertex.Tesselator;
import com.mojang.blaze3d.vertex.VertexFormat.Mode;
import com.mojang.math.Matrix4f;
import com.mojang.math.Quaternion;
import com.mojang.math.Vector3f;
import net.minecraft.client.Minecraft;
import net.minecraft.client.renderer.GameRenderer;
import net.minecraft.client.renderer.MultiBufferSource;
import net.minecraft.client.renderer.entity.EntityRenderDispatcher;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.LivingEntity;

/**
* Our replacement for GuiComponent.
Expand Down Expand Up @@ -601,4 +607,61 @@ public static void populateBlitTriangles(final BufferBuilder buffer,
buffer.vertex(mat, xStart, yEnd, 0).uv(uMin, vMax).endVertex();
buffer.vertex(mat, xEnd, yEnd, 0).uv(uMax, vMax).endVertex();
}

/**
* Render an entity on a GUI.
* @param poseStack matrix
* @param x horizontal center position
* @param y vertical bottom position
* @param scale scaling factor
* @param headYaw adjusts look rotation
* @param yaw adjusts body rotation
* @param pitch adjusts look rotation
* @param entity the entity to render
*/
public static void drawEntity(final PoseStack poseStack, final int x, final int y, final double scale,
final float headYaw, final float yaw, final float pitch, final Entity entity)
{
final LivingEntity livingEntity = (entity instanceof LivingEntity) ? (LivingEntity) entity : null;
final Minecraft mc = Minecraft.getInstance();
if (entity.level == null) entity.level = mc.level;
poseStack.pushPose();
poseStack.translate((float) x, (float) y, 1050.0F);
poseStack.scale(1.0F, 1.0F, -1.0F);
poseStack.translate(0.0D, 0.0D, 1000.0D);
poseStack.scale((float) scale, (float) scale, (float) scale);
final Quaternion pitchRotation = Vector3f.XP.rotationDegrees(pitch);
poseStack.mulPose(Vector3f.ZP.rotationDegrees(180.0F));
poseStack.mulPose(pitchRotation);
final float oldYaw = entity.getYRot();
final float oldPitch = entity.getXRot();
final float oldYawOffset = livingEntity == null ? 0F : livingEntity.yBodyRot;
final float oldPrevYawHead = livingEntity == null ? 0F : livingEntity.yHeadRotO;
final float oldYawHead = livingEntity == null ? 0F : livingEntity.yHeadRot;
entity.setYRot(180.0F + (float) headYaw);
entity.setXRot(-pitch);
if (livingEntity != null)
{
livingEntity.yBodyRot = 180.0F + yaw;
livingEntity.yHeadRot = entity.getYRot();
livingEntity.yHeadRotO = entity.getYRot();
}
final EntityRenderDispatcher dispatcher = mc.getEntityRenderDispatcher();
pitchRotation.conj();
dispatcher.overrideCameraOrientation(pitchRotation);
dispatcher.setRenderShadow(false);
final MultiBufferSource.BufferSource buffers = mc.renderBuffers().bufferSource();
RenderSystem.runAsFancy(() -> dispatcher.render(entity, 0.0D, 0.0D, 0.0D, 0.0F, 1.0F, poseStack, buffers, 0x00F000F0));
buffers.endBatch();
dispatcher.setRenderShadow(true);
entity.setYRot(oldYaw);
entity.setXRot(oldPitch);
if (livingEntity != null)
{
livingEntity.yBodyRot = oldYawOffset;
livingEntity.yHeadRotO = oldPrevYawHead;
livingEntity.yHeadRot = oldYawHead;
}
poseStack.popPose();
}
}
156 changes: 156 additions & 0 deletions src/main/java/com/ldtteam/blockui/controls/EntityIcon.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,156 @@
package com.ldtteam.blockui.controls;

import com.ldtteam.blockui.Pane;
import com.ldtteam.blockui.PaneBuilders;
import com.ldtteam.blockui.PaneParams;
import com.mojang.blaze3d.vertex.PoseStack;
import com.mojang.blaze3d.vertex.Tesselator;
import net.minecraft.client.renderer.MultiBufferSource;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.EntityType;
import net.minecraft.world.phys.AABB;
import net.minecraftforge.registries.ForgeRegistries;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

/**
* Control to render an entity as an icon
*/
public class EntityIcon extends Pane
{
@Nullable
private Entity entity;
private int count = 1;
private float yaw = 30;
private float pitch = -10;
private float headyaw = 0;

public EntityIcon()
{
super();
}

public EntityIcon(@NotNull PaneParams params)
{
super(params);

final String entityName = params.getString("entity");
if (entityName != null)
{
setEntity(new ResourceLocation(entityName));
}

this.count = params.getInteger("count", this.count);
this.yaw = params.getFloat("yaw", this.yaw);
this.pitch = params.getFloat("pitch", this.pitch);
this.headyaw = params.getFloat("head", this.headyaw);
}

public void setEntity(@NotNull ResourceLocation entityId)
{
final EntityType<?> entityType = ForgeRegistries.ENTITIES.getValue(entityId);
if (entityType != null)
{
setEntity(entityType);
}
else
{
resetEntity();
}
}

public void setEntity(@NotNull EntityType<?> type)
{
final Entity entity = type.create(mc.level);

if (entity != null)
{
setEntity(entity);
}
else
{
resetEntity();
}
}

public void setEntity(@NotNull Entity entity)
{
this.entity = entity;
if (onHover instanceof final Tooltip tooltip)
{
tooltip.setText(this.entity.getDisplayName());
}
}

public void resetEntity()
{
this.entity = null;
if (onHover instanceof final Tooltip tooltip)
{
tooltip.clearText();
}
}

public void setCount(final int count)
{
this.count = count;
}

public void setYaw(final float yaw)
{
this.yaw = yaw;
}

public void setPitch(final float pitch)
{
this.pitch = pitch;
}

@Override
public void drawSelf(final PoseStack ms, final double mx, final double my)
{
if (this.entity != null)
{
ms.pushPose();
ms.translate(x, y, -50);

final AABB bb = this.entity.getBoundingBox();
final float scale = (float) (getHeight() / bb.getYsize() / 1.5);
final int cx = (getWidth() / 2);
final int by = getHeight();
final int offsetY = 2;
drawEntity(ms, cx, by - offsetY, scale, this.headyaw, this.yaw, this.pitch, this.entity);

if (this.count != 1)
{
String s = String.valueOf(this.count);
ms.translate(getWidth(), getHeight(), 100.0D);
ms.scale(0.75F, 0.75F, 0.75F);
MultiBufferSource.BufferSource buffer = MultiBufferSource.immediate(Tesselator.getInstance().getBuilder());
mc.font.drawInBatch(s,
(float) (-4 - mc.font.width(s)),
(float) (-mc.font.lineHeight),
16777215,
true,
ms.last().pose(),
buffer,
false,
0,
15728880);
buffer.endBatch();
}

ms.popPose();
}
}

@Override
public void onUpdate()
{
if (this.onHover == null && this.entity != null)
{
PaneBuilders.tooltipBuilder().hoverPane(this).build().setText(this.entity.getDisplayName());
}
}
}
4 changes: 2 additions & 2 deletions src/main/java/com/ldtteam/blockui/controls/ItemIcon.java
Original file line number Diff line number Diff line change
Expand Up @@ -68,9 +68,9 @@ public ItemIcon(final PaneParams params)
public void setItem(final ItemStack itemStackIn)
{
this.itemStack = itemStackIn;
if (onHover instanceof Tooltip)
if (onHover instanceof final Tooltip tooltip)
{
((Tooltip) onHover).setTextOld(getModifiedItemStackTooltip());
tooltip.setTextOld(getModifiedItemStackTooltip());
}
}

Expand Down
14 changes: 14 additions & 0 deletions src/main/resources/assets/blockui/gui/blockOut.xsd
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,7 @@
<xs:element name="gradient" type="gradientType"/>
<xs:element name="box" type="boxType"/>
<xs:element name="itemicon" type="itemIconType"/>
<xs:element name="entityicon" type="entityIconType"/>
<xs:element name="switch" type="switchType"/>
<xs:element name="dropdown" type="dropdownType"/>
</xs:choice>
Expand Down Expand Up @@ -217,6 +218,19 @@
</xs:complexContent>
</xs:complexType>

<!-- <entityicon> -->
<xs:complexType name="entityIconType">
<xs:complexContent>
<xs:extension base="paneType">
<xs:attribute name="entity" type="xs:string"/>
<xs:attribute name="count" type="xs:integer"/>
<xs:attribute name="yaw" type="xs:float"/>
<xs:attribute name="pitch" type="xs:float"/>
<xs:attribute name="head" type="xs:float"/>
</xs:extension>
</xs:complexContent>
</xs:complexType>

<!-- <buttonimage> -->
<xs:complexType name="buttonImageType">
<xs:complexContent>
Expand Down

0 comments on commit 800755e

Please sign in to comment.