Skip to content

Commit

Permalink
Add entity trophy model handler
Browse files Browse the repository at this point in the history
  • Loading branch information
glowredman committed Oct 29, 2023
1 parent b35da65 commit 9071e1b
Show file tree
Hide file tree
Showing 8 changed files with 187 additions and 18 deletions.
5 changes: 2 additions & 3 deletions run/config/amazingtrophies/trophies/test/achievement.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,7 @@
"id": "achievement.openInventory"
},
"model": {
"type": "advanced",
"model": "model.obj",
"texture": "texture.png"
"type": "entity",
"entity": "Zombie"
}
}
6 changes: 3 additions & 3 deletions run/config/amazingtrophies/trophies/test/death.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@
"isSourcesAllowList": true
},
"model": {
"type": "advanced",
"model": "model.obj",
"texture": "texture.png"
"type": "entity",
"entity": "EnderDragon",
"scale": 0.06
}
}
7 changes: 4 additions & 3 deletions run/config/amazingtrophies/trophies/test/fall.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,9 @@
"distance": 20.0
},
"model": {
"type": "advanced",
"model": "model.obj",
"texture": "texture.png"
"type": "entity",
"entity": "net.minecraft.entity.projectile.EntityFishHook",
"yOffset": 0.0625,
"scale": 1
}
}
7 changes: 4 additions & 3 deletions run/config/amazingtrophies/trophies/test/heal.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,9 @@
"amount": 5.0
},
"model": {
"type": "advanced",
"model": "model.obj",
"texture": "texture.png"
"type": "entity",
"entity": "Boat",
"yawOffset": 90,
"yOffset": -0.021484375
}
}
8 changes: 5 additions & 3 deletions run/config/amazingtrophies/trophies/test/interact.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,10 @@
"targets": "net.minecraft.entity.item.EntityItemFrame"
},
"model": {
"type": "advanced",
"model": "model.obj",
"texture": "texture.png"
"type": "entity",
"entity": "MinecartSpawner",
"nbt": "{EntityId:MinecartCommandBlock}",
"yawOffset": 90,
"yOffset": -0.04296875
}
}
6 changes: 3 additions & 3 deletions run/config/amazingtrophies/trophies/test/kill.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@
"isTargetsAllowList": true
},
"model": {
"type": "advanced",
"model": "model.obj",
"texture": "texture.png"
"type": "entity",
"entity": "Squid",
"yOffset": 0.236328125
}
}
2 changes: 2 additions & 0 deletions src/main/java/glowredman/amazingtrophies/ClientHandler.java
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
import cpw.mods.fml.common.Loader;
import glowredman.amazingtrophies.api.AmazingTrophiesAPI;
import glowredman.amazingtrophies.model.BasicTrophyModelHandler;
import glowredman.amazingtrophies.model.EntityTrophyModelHandler;
import glowredman.amazingtrophies.model.PedestalTrophyModelHandler;
import glowredman.amazingtrophies.trophy.RendererTrophy;
import glowredman.amazingtrophies.trophy.TileEntityTrophy;
Expand All @@ -35,6 +36,7 @@ static void registerTrophyModelHandlers() {
// spotless:off
AmazingTrophiesAPI.registerTrophyModelHandlerProvider(PedestalTrophyModelHandler.ID, PedestalTrophyModelHandler::new);
AmazingTrophiesAPI.registerTrophyModelHandlerProvider(BasicTrophyModelHandler.ID, BasicTrophyModelHandler::new);
AmazingTrophiesAPI.registerTrophyModelHandlerProvider(EntityTrophyModelHandler.ID, EntityTrophyModelHandler::new);
// spotless:on
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,164 @@
package glowredman.amazingtrophies.model;

import java.util.Arrays;
import java.util.function.Consumer;

import javax.annotation.Nullable;

import net.minecraft.client.Minecraft;
import net.minecraft.client.renderer.OpenGlHelper;
import net.minecraft.client.renderer.entity.Render;
import net.minecraft.client.renderer.entity.RenderManager;
import net.minecraft.entity.Entity;
import net.minecraft.entity.EntityLivingBase;
import net.minecraft.entity.boss.BossStatus;
import net.minecraft.entity.boss.EntityDragon;
import net.minecraft.entity.boss.IBossDisplayData;
import net.minecraft.nbt.JsonToNBT;
import net.minecraft.nbt.NBTBase;
import net.minecraft.nbt.NBTException;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.world.World;

import org.lwjgl.opengl.GL11;

import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonSyntaxException;

import glowredman.amazingtrophies.ConfigHandler;

public class EntityTrophyModelHandler extends PedestalTrophyModelHandler {

public static final String ID = "entity";
public static final String PROPERTY_ENTITY = "entity";
public static final String PROPERTY_Y_OFFSET = "yOffset";
public static final String PROPERTY_YAW_OFFSET = "yawOffset";
public static final String PROPERTY_SCALE = "scale";
public static final String PROPERTY_NBT = "nbt";

private Entity entity;
private Render render;
private Consumer<Float> yawHandler;
// -0.1875 = -3/16 -> moves the model down to the top of the pedestal
private double yOffset = -0.1875;
private float yawOffset = 180.0f;
// 0.34375 = 11/32 -> scales a two block high model down to fit in the space over the pedestal
private float scale = 0.34375f;
private boolean setsBossStatus;

public EntityTrophyModelHandler() {}

public EntityTrophyModelHandler(Entity entity) {
this.entity = entity;
this.render = RenderManager.instance.getEntityRenderObject(entity);
this.setsBossStatus = this.entity instanceof IBossDisplayData;
this.setYawHandler();
}

public EntityTrophyModelHandler(Entity entity, float yOffset, float yawOffset, float scale) {
this(entity);
this.yOffset = yOffset;
this.yawOffset = yawOffset;
this.scale = scale;
}

@Override
public void parse(String id, JsonObject json) throws JsonSyntaxException {
JsonElement entityJson = json.get(PROPERTY_ENTITY);
if (entityJson == null) {
throw new JsonSyntaxException("Required property \"" + PROPERTY_ENTITY + "\" is missing!");
}
Class<? extends Entity> clazz = ConfigHandler.parseEntityClass(entityJson);
try {
this.entity = clazz.getConstructor(World.class)
.newInstance((World) null);
} catch (Exception e) {
throw new IllegalStateException("Could not create a new instance of " + clazz.getName() + "!", e);
}
this.render = RenderManager.instance.getEntityRenderObject(entity);
if (this.render == null) {
throw new NullPointerException("Could not find render object for " + clazz.getName() + "!");
}
this.yOffset = ConfigHandler.getDoubleProperty(json, PROPERTY_Y_OFFSET, this.yOffset);
this.yawOffset = ConfigHandler.getFloatProperty(json, PROPERTY_YAW_OFFSET, this.yawOffset);
this.scale = ConfigHandler.getFloatProperty(json, PROPERTY_SCALE, this.scale);
NBTBase nbt = null;
try {
nbt = JsonToNBT.func_150315_a(ConfigHandler.getStringProperty(json, PROPERTY_NBT, "{}"));
} catch (NBTException e) {
throw new IllegalArgumentException("Could not parse NBT", e);
}
if (nbt instanceof NBTTagCompound compound && !compound.func_150296_c() // getKeySet
.isEmpty()) {
this.entity.readFromNBT(compound);
}
this.setsBossStatus = this.entity instanceof IBossDisplayData;
this.setYawHandler();
}

@Override
public void render(double x, double y, double z, int rotation, @Nullable String name, long time,
float partialTickTime) {
super.render(x, y, z, rotation, name, time, partialTickTime);

if (this.render.getFontRendererFromRenderManager() == null) {
return;
}

GL11.glPushMatrix();
GL11.glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
GL11.glTranslated(x, y + this.yOffset, z);
GL11.glScalef(this.scale, this.scale, this.scale);
GL11.glPushAttrib(GL11.GL_ALL_ATTRIB_BITS);
OpenGlHelper.setActiveTexture(OpenGlHelper.lightmapTexUnit);
GL11.glEnable(GL11.GL_TEXTURE_2D);
OpenGlHelper.setActiveTexture(OpenGlHelper.defaultTexUnit);

float rotationDeg = this.yawOffset - 22.5f * rotation;
synchronized (this.entity) {
this.yawHandler.accept(rotationDeg);
this.entity.setWorld(Minecraft.getMinecraft().theWorld);

if (this.setsBossStatus) {
// boss entities usually call BossStatus.setBossStatus in their Render.doRender method so we need to
// cache and reset the BossStatus fields
String bossName = BossStatus.bossName;
boolean hasColorModifier = BossStatus.hasColorModifier;
float healthScale = BossStatus.healthScale;
int statusBarTime = BossStatus.statusBarTime;
this.render.doRender(this.entity, 0.0, 0.0, 0.0, rotationDeg, partialTickTime);
BossStatus.bossName = bossName;
BossStatus.hasColorModifier = hasColorModifier;
BossStatus.healthScale = healthScale;
BossStatus.statusBarTime = statusBarTime;
} else {
this.render.doRender(this.entity, 0.0, 0.0, 0.0, rotationDeg, partialTickTime);
}
}

GL11.glPopAttrib();
GL11.glPopMatrix();
}

private void setYawHandler() {
this.yawHandler = rotation -> {
this.entity.rotationYaw = rotation;
this.entity.prevRotationYaw = rotation;
};
if (this.entity instanceof EntityLivingBase) {
this.yawHandler = this.yawHandler.andThen(rotation -> {
EntityLivingBase living = (EntityLivingBase) this.entity;
living.renderYawOffset = rotation;
living.prevRenderYawOffset = rotation;
living.rotationYawHead = rotation;
living.prevRotationYawHead = rotation;
});
if (this.entity instanceof EntityDragon) {
this.yawHandler = this.yawHandler.andThen(
rotation -> Arrays
.fill(((EntityDragon) this.entity).ringBuffer, new double[] { rotation - 180.0, 0.0, 0.0 }));
}
}
}
}

0 comments on commit 9071e1b

Please sign in to comment.