diff --git a/src/main/java/noppes/npcs/CustomNpcs.java b/src/main/java/noppes/npcs/CustomNpcs.java index 17bb45199..6bbe14b8e 100644 --- a/src/main/java/noppes/npcs/CustomNpcs.java +++ b/src/main/java/noppes/npcs/CustomNpcs.java @@ -156,6 +156,7 @@ public class CustomNpcs { registerNpc(EntityNPCEnderman.class, "npcEnderman"); registerNpc(EntityNPCGolem.class, "npcGolem"); registerNpc(EntityCustomNpc.class, "CustomNpc"); + registerCustomModel(EntityGeckoModel.class, "CustomModel"); registerNewEntity(EntityChairMount.class, "CustomNpcChairMount", 64, 10, false); registerNewEntity(EntityProjectile.class, "throwableitem", 64, 3, true); @@ -254,6 +255,11 @@ public class CustomNpcs { EntityList.stringToClassMapping.put(name, cl); } + private void registerCustomModel(Class cl, String name) { + EntityRegistry.registerModEntity(cl, name, NewEntityStartId++, this, 64, 10, false); + EntityList.stringToClassMapping.put(name, cl); + } + private void registerNewEntity(Class cl, String name, int range, int update, boolean velocity) { EntityRegistry.registerModEntity(cl, name, NewEntityStartId++, this, range, update, velocity); } diff --git a/src/main/java/noppes/npcs/DataDisplay.java b/src/main/java/noppes/npcs/DataDisplay.java index 565b4bbbe..db2daa2c8 100644 --- a/src/main/java/noppes/npcs/DataDisplay.java +++ b/src/main/java/noppes/npcs/DataDisplay.java @@ -37,6 +37,13 @@ public class DataDisplay { public String texture = "customnpcs:textures/entity/humanmale/Steve.png"; public String cloakTexture = ""; + public String model = "geckolib3:geo/npc.geo.json"; + public String animFile = "custom:geo_npc.animation.json"; + public String idleAnim = ""; + public String walkAnim = ""; + public String attackAnim = ""; + public String hurtAnim = ""; + public DataSkinOverlays skinOverlayData; public long overlayRenderTicks = 0; @@ -45,7 +52,7 @@ public class DataDisplay { public String glowTexture = ""; public int visible = 0; //0:visible 1:Invisible 2:semi-invisible - + public int modelSize = 5; public int showName = 0; @@ -53,7 +60,7 @@ public class DataDisplay { public int modelType = 0; public boolean disableLivingAnimation = false; - + public byte showBossBar = 0; public ArrayList invisibleToList = new ArrayList<>(); @@ -80,6 +87,15 @@ public class DataDisplay { nbttagcompound.setString("Title", title); nbttagcompound.setString("SkinUrl", url); nbttagcompound.setString("Texture", texture); + + // Custom Model + nbttagcompound.setString("Model", model); + nbttagcompound.setString("AnimFile", animFile); + nbttagcompound.setString("IdleAnim", idleAnim); + nbttagcompound.setString("WalkAnim", walkAnim); + nbttagcompound.setString("AttackAnim", attackAnim); + nbttagcompound.setString("HurtAnim", hurtAnim); + nbttagcompound.setString("CloakTexture", cloakTexture); nbttagcompound.setByte("UsingSkinUrl", skinType); nbttagcompound.setString("GlowTexture", glowTexture); @@ -94,7 +110,7 @@ public class DataDisplay { NBTUtil.func_152460_a(nbttagcompound1, this.playerProfile); nbttagcompound.setTag("SkinUsername", nbttagcompound1); } - + nbttagcompound.setInteger("Size", modelSize); nbttagcompound.setInteger("modelType", modelType); @@ -121,12 +137,12 @@ public class DataDisplay { setMarkovGender(nbttagcompound.getInteger("MarkovGender")); title = nbttagcompound.getString("Title"); - + url = nbttagcompound.getString("SkinUrl"); int prevSkinType = skinType; skinType = nbttagcompound.getByte("UsingSkinUrl"); - + this.playerProfile = null; if(skinType == 1){ if (nbttagcompound.hasKey("SkinUsername", 10)){ @@ -139,8 +155,18 @@ public class DataDisplay { } String prevTexture = texture; - + texture = nbttagcompound.getString("Texture"); + + // Custom Model + model = nbttagcompound.getString("Model"); + animFile = nbttagcompound.getString("AnimFile"); + idleAnim = nbttagcompound.getString("IdleAnim"); + walkAnim = nbttagcompound.getString("WalkAnim"); + hurtAnim = nbttagcompound.getString("HurtAnim"); + attackAnim = nbttagcompound.getString("AttackAnim"); + + cloakTexture = nbttagcompound.getString("CloakTexture"); glowTexture = nbttagcompound.getString("GlowTexture"); @@ -169,7 +195,7 @@ public class DataDisplay { modelSize = ConfigMain.NpcSizeLimit; modelType = nbttagcompound.getInteger("modelType"); - + showName = nbttagcompound.getInteger("ShowName"); visible = nbttagcompound.getInteger("NpcVisible"); @@ -197,7 +223,7 @@ public class DataDisplay { npc.textureLocation = null; npc.updateHitbox(); } - + public void loadProfile(){ if (this.playerProfile != null && !StringUtils.isNullOrEmpty(this.playerProfile.getName()) && MinecraftServer.getServer() != null){ if (!this.playerProfile.isComplete() || !this.playerProfile.getProperties().containsKey("textures")){ @@ -215,7 +241,7 @@ public class DataDisplay { } } } - + public boolean showName() { if(npc.isKilled()) return false; diff --git a/src/main/java/noppes/npcs/client/ClientProxy.java b/src/main/java/noppes/npcs/client/ClientProxy.java index fbdc87dfd..1cffb9659 100644 --- a/src/main/java/noppes/npcs/client/ClientProxy.java +++ b/src/main/java/noppes/npcs/client/ClientProxy.java @@ -53,7 +53,6 @@ import noppes.npcs.client.renderer.blocks.*; import noppes.npcs.client.renderer.customitem.CustomItemRenderer; import noppes.npcs.config.ConfigClient; import noppes.npcs.config.ConfigMain; -import noppes.npcs.config.ConfigScript; import noppes.npcs.config.StringCache; import noppes.npcs.constants.EnumGuiType; import noppes.npcs.containers.*; @@ -88,6 +87,7 @@ public class ClientProxy extends CommonProxy { new ScriptSoundController(); RenderingRegistry.registerEntityRenderingHandler(EntityNpcPony.class, new RenderNPCPony()); + RenderingRegistry.registerEntityRenderingHandler(EntityGeckoModel.class, new RenderGeckolib()); RenderingRegistry.registerEntityRenderingHandler(EntityNpcCrystal.class, new RenderNpcCrystal(new ModelNpcCrystal(0.5F))); RenderingRegistry.registerEntityRenderingHandler(EntityNpcDragon.class, new RenderNpcDragon(new ModelNpcDragon(0.0F), 0.5F)); RenderingRegistry.registerEntityRenderingHandler(EntityNpcSlime.class, new RenderNpcSlime(new ModelNpcSlime(16), new ModelNpcSlime(0), 0.25F)); @@ -548,7 +548,7 @@ public class ClientProxy extends CommonProxy { public FontContainer(String fontType, int fontSize) { textFont = new StringCache(); - textFont.setDefaultFont("Arial Unicode MS", fontSize, true); + textFont.setDefaultFont("Arial", fontSize, true); useCustomFont = !fontType.equalsIgnoreCase("minecraft"); try { if(!useCustomFont || fontType.isEmpty() || fontType.equalsIgnoreCase("default")) @@ -556,7 +556,7 @@ public class ClientProxy extends CommonProxy { else textFont.setDefaultFont(fontType, fontSize, true); } catch (Exception e) { - LogWriter.info("Failed loading font so using Arial Unicode MS"); + LogWriter.info("Failed loading font so using Arial"); } } diff --git a/src/main/java/noppes/npcs/client/EntityUtil.java b/src/main/java/noppes/npcs/client/EntityUtil.java index 05954bce4..23aab1882 100644 --- a/src/main/java/noppes/npcs/client/EntityUtil.java +++ b/src/main/java/noppes/npcs/client/EntityUtil.java @@ -4,6 +4,8 @@ import net.minecraft.entity.EntityLivingBase; import net.minecraft.entity.boss.EntityDragon; import net.minecraft.entity.passive.EntityChicken; import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.util.ResourceLocation; +import noppes.npcs.entity.EntityGeckoModel; import noppes.npcs.entity.EntityNPCInterface; public class EntityUtil { @@ -83,7 +85,14 @@ public class EntityUtil { for(int i = 0; i < 5; i++){ entity.setCurrentItemOrArmor(i, copied.getEquipmentInSlot(i)); } - + + if(entity instanceof EntityGeckoModel && copied instanceof EntityNPCInterface){ + ((EntityGeckoModel) entity).textureResLoc=new ResourceLocation(((EntityNPCInterface) copied).display.texture); + ((EntityGeckoModel) entity).modelResLoc=new ResourceLocation(((EntityNPCInterface) copied).display.model); + ((EntityGeckoModel) entity).animResLoc=new ResourceLocation(((EntityNPCInterface) copied).display.animFile); + ((EntityGeckoModel) entity).idleAnim=((EntityNPCInterface) copied).display.idleAnim; + } + if(copied instanceof EntityNPCInterface && entity instanceof EntityNPCInterface){ EntityNPCInterface npc = (EntityNPCInterface) copied; EntityNPCInterface target = (EntityNPCInterface) entity; diff --git a/src/main/java/noppes/npcs/client/gui/model/GuiCreationScreen.java b/src/main/java/noppes/npcs/client/gui/model/GuiCreationScreen.java index 866b1e84e..0962a1178 100644 --- a/src/main/java/noppes/npcs/client/gui/model/GuiCreationScreen.java +++ b/src/main/java/noppes/npcs/client/gui/model/GuiCreationScreen.java @@ -14,6 +14,7 @@ import net.minecraft.nbt.NBTTagByte; import net.minecraft.nbt.NBTTagCompound; import net.minecraft.world.World; import noppes.npcs.client.Client; +import noppes.npcs.client.NoppesUtil; import noppes.npcs.client.gui.util.*; import noppes.npcs.constants.EnumPacketServer; import noppes.npcs.compat.PixelmonHelper; @@ -42,8 +43,7 @@ public class GuiCreationScreen extends GuiModelInterface implements ICustomScrol for(Object name : mapping.keySet()){ Class c = (Class) mapping.get(name); try { - if(!EntityCustomNpc.class.isAssignableFrom(c) && EntityLiving.class.isAssignableFrom(c) && c.getConstructor(new Class[] {World.class}) != null && !Modifier.isAbstract(c.getModifiers())){ - if(RenderManager.instance.getEntityClassRenderObject(c) instanceof RendererLivingEntity) + if(!EntityCustomNpc.class.isAssignableFrom(c) && EntityLiving.class.isAssignableFrom(c) && c.getConstructor(World.class) != null && !Modifier.isAbstract(c.getModifiers())){ if(RenderManager.instance.getEntityClassRenderObject(c) instanceof RendererLivingEntity) data.put(name.toString(),c.asSubclass(EntityLivingBase.class)); } } catch (SecurityException e) { @@ -166,6 +166,13 @@ public class GuiCreationScreen extends GuiModelInterface implements ICustomScrol addLabel(new GuiNpcLabel(201, "Breed", guiLeft, y + 5 + i * 22, 0xFFFFFF)); addButton(new GuiNpcButton(201, guiLeft + 80, y + i * 22, 50, 20, new String[]{"0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12", "13", "14", "15", "16"}, breed)); } + + if(EntityList.getEntityString(entity).equals("customnpcs.CustomModel") || EntityList.getEntityString(entity).equals("CustomModel")){ + this.addButton(new GuiNpcButton(202, guiLeft, y + i * 22, 120, 20, "Select model")); + this.addButton(new GuiNpcButton(203, guiLeft, y + i * 22+20, 120, 20, "Select animation file")); + this.addButton(new GuiNpcButton(204, guiLeft, y + i * 22+40, 120, 20, "Select idle animation")); + //this.addButton(new GuiNpcButton(203, guiLeft, y + i * 22+60, 120, 20, "Select animation file")); + } } private boolean isIgnored(String tag){ for(String s : ignoredTags) @@ -316,6 +323,18 @@ public class GuiCreationScreen extends GuiModelInterface implements ICustomScrol updateTexture(); } catch (Exception ignored) {} } + + if(button.id == 202){ + NoppesUtil.openGUI(player, new GuiGeckoModelSelection(npc, this)); + } + + if(button.id == 203){ + NoppesUtil.openGUI(player, new GuiGeckoAnimFileSelection(npc, this)); + } + + if(button.id == 204){ + NoppesUtil.openGUI(player, new GuiGeckoAnimationSelection(npc, this, (name)-> npc.display.idleAnim=name)); + } } private void updateTexture(){ diff --git a/src/main/java/noppes/npcs/client/gui/model/GuiGeckoAnimFileSelection.java b/src/main/java/noppes/npcs/client/gui/model/GuiGeckoAnimFileSelection.java new file mode 100644 index 000000000..caaba8155 --- /dev/null +++ b/src/main/java/noppes/npcs/client/gui/model/GuiGeckoAnimFileSelection.java @@ -0,0 +1,72 @@ +package noppes.npcs.client.gui.model; + +import net.minecraft.client.gui.GuiButton; +import net.minecraft.client.gui.GuiScreen; +import net.minecraft.util.ResourceLocation; +import noppes.npcs.client.NoppesUtil; +import noppes.npcs.client.gui.util.*; +import noppes.npcs.entity.EntityNPCInterface; +import software.bernie.geckolib3.resource.GeckoLibCache; + +import java.util.Collections; +import java.util.HashSet; +import java.util.Vector; + +public class GuiGeckoAnimFileSelection extends GuiNPCInterface { + public GuiNPCStringSlot slot; + public GuiScreen parent; + + public GuiGeckoAnimFileSelection(EntityNPCInterface npc, GuiScreen parent){ + super(npc); + drawDefaultBackground = false; + title = ""; + this.parent = parent; + } + + @Override + public void initGui(){ + super.initGui(); + String ss = "Selecting geckolib animation file:"; + addLabel(new GuiNpcLabel(0,ss, width / 2 - (this.fontRendererObj.getStringWidth(ss)/2), 20, 0xffffff)); + Vector list = new Vector(); + for(ResourceLocation resLoc : GeckoLibCache.getInstance().getAnimations().keySet()){ + list.add(resLoc.toString()); + } + Collections.sort(list,String.CASE_INSENSITIVE_ORDER); + slot = new GuiNPCStringSlot(list,this,false,18); + slot.registerScrollButtons(4, 5); + + this.addButton(new GuiNpcButton(2, width / 2 - 100, height - 44,98, 20, "gui.back")); + } + + @Override + public void drawScreen(int i, int j, float f) + { + slot.drawScreen(i, j, f); + super.drawScreen(i, j, f); + } + + @Override + public void elementClicked(){ + } + + @Override + public void doubleClicked(){ + npc.display.animFile=slot.selected; + close(); + NoppesUtil.openGUI(player, parent); + } + + @Override + protected void actionPerformed(GuiButton guibutton){ + int id = guibutton.id; + if(id == 2){ + close(); + NoppesUtil.openGUI(player, parent); + } + } + + @Override + public void save() { + } +} \ No newline at end of file diff --git a/src/main/java/noppes/npcs/client/gui/model/GuiGeckoAnimationSelection.java b/src/main/java/noppes/npcs/client/gui/model/GuiGeckoAnimationSelection.java new file mode 100644 index 000000000..64c398e3b --- /dev/null +++ b/src/main/java/noppes/npcs/client/gui/model/GuiGeckoAnimationSelection.java @@ -0,0 +1,81 @@ +package noppes.npcs.client.gui.model; + +import net.minecraft.client.gui.GuiButton; +import net.minecraft.client.gui.GuiScreen; +import net.minecraft.util.ResourceLocation; +import noppes.npcs.client.NoppesUtil; +import noppes.npcs.client.gui.util.*; +import noppes.npcs.entity.EntityNPCInterface; +import software.bernie.geckolib3.core.builder.Animation; +import software.bernie.geckolib3.file.AnimationFile; +import software.bernie.geckolib3.resource.GeckoLibCache; + +import java.util.Collections; +import java.util.HashSet; +import java.util.Vector; +import java.util.function.Consumer; + +public class GuiGeckoAnimationSelection extends GuiNPCInterface { + public GuiNPCStringSlot slot; + public GuiScreen parent; + public Consumer action; + + public GuiGeckoAnimationSelection(EntityNPCInterface npc, GuiScreen parent, Consumer action){ + super(npc); + drawDefaultBackground = false; + title = ""; + this.parent = parent; + this.action=action; + } + + @Override + public void initGui(){ + super.initGui(); + String ss = "Selecting geckolib animation:"; + addLabel(new GuiNpcLabel(0,ss, width / 2 - (this.fontRendererObj.getStringWidth(ss)/2), 20, 0xffffff)); + Vector list = new Vector(); + AnimationFile file = GeckoLibCache.getInstance().getAnimations().get(new ResourceLocation(npc.display.animFile)); + if(file!=null) { + for (Animation anim : file.getAllAnimations()) { + list.add(anim.animationName); + } + } + Collections.sort(list,String.CASE_INSENSITIVE_ORDER); + slot = new GuiNPCStringSlot(list,this,false,18); + slot.registerScrollButtons(4, 5); + + this.addButton(new GuiNpcButton(2, width / 2 - 100, height - 44,98, 20, "gui.back")); + } + + @Override + public void drawScreen(int i, int j, float f) + { + slot.drawScreen(i, j, f); + super.drawScreen(i, j, f); + } + + @Override + public void elementClicked(){ + } + + @Override + public void doubleClicked(){ + //npc.display.animFile=slot.selected; + action.accept(slot.selected); + close(); + NoppesUtil.openGUI(player, parent); + } + + @Override + protected void actionPerformed(GuiButton guibutton){ + int id = guibutton.id; + if(id == 2){ + close(); + NoppesUtil.openGUI(player, parent); + } + } + + @Override + public void save() { + } +} \ No newline at end of file diff --git a/src/main/java/noppes/npcs/client/gui/model/GuiGeckoModelSelection.java b/src/main/java/noppes/npcs/client/gui/model/GuiGeckoModelSelection.java new file mode 100644 index 000000000..06160f426 --- /dev/null +++ b/src/main/java/noppes/npcs/client/gui/model/GuiGeckoModelSelection.java @@ -0,0 +1,72 @@ +package noppes.npcs.client.gui.model; + +import net.minecraft.client.gui.GuiButton; +import net.minecraft.client.gui.GuiScreen; +import net.minecraft.util.ResourceLocation; +import noppes.npcs.client.NoppesUtil; +import noppes.npcs.client.gui.util.*; +import noppes.npcs.entity.EntityNPCInterface; +import software.bernie.geckolib3.resource.GeckoLibCache; + +import java.util.Collections; +import java.util.HashSet; +import java.util.Vector; + +public class GuiGeckoModelSelection extends GuiNPCInterface { + public GuiNPCStringSlot slot; + public GuiScreen parent; + + public GuiGeckoModelSelection(EntityNPCInterface npc, GuiScreen parent){ + super(npc); + drawDefaultBackground = false; + title = ""; + this.parent = parent; + } + + @Override + public void initGui(){ + super.initGui(); + String ss = "Selecting geckolib model:"; + addLabel(new GuiNpcLabel(0,ss, width / 2 - (this.fontRendererObj.getStringWidth(ss)/2), 20, 0xffffff)); + Vector list = new Vector(); + for(ResourceLocation resLoc : GeckoLibCache.getInstance().getGeoModels().keySet()){ + list.add(resLoc.toString()); + } + Collections.sort(list,String.CASE_INSENSITIVE_ORDER); + slot = new GuiNPCStringSlot(list,this,false,18); + slot.registerScrollButtons(4, 5); + + this.addButton(new GuiNpcButton(2, width / 2 - 100, height - 44,98, 20, "gui.back")); + } + + @Override + public void drawScreen(int i, int j, float f) + { + slot.drawScreen(i, j, f); + super.drawScreen(i, j, f); + } + + @Override + public void elementClicked(){ + } + + @Override + public void doubleClicked(){ + npc.display.model=slot.selected; + close(); + NoppesUtil.openGUI(player, parent); + } + + @Override + protected void actionPerformed(GuiButton guibutton){ + int id = guibutton.id; + if(id == 2){ + close(); + NoppesUtil.openGUI(player, parent); + } + } + + @Override + public void save() { + } +} \ No newline at end of file diff --git a/src/main/java/noppes/npcs/client/model/GuiGeckoAnimFileSelection.java b/src/main/java/noppes/npcs/client/model/GuiGeckoAnimFileSelection.java new file mode 100644 index 000000000..dbccc392c --- /dev/null +++ b/src/main/java/noppes/npcs/client/model/GuiGeckoAnimFileSelection.java @@ -0,0 +1,72 @@ +package noppes.npcs.client.model; + +import net.minecraft.client.gui.GuiButton; +import net.minecraft.client.gui.GuiScreen; +import net.minecraft.util.ResourceLocation; +import noppes.npcs.client.NoppesUtil; +import noppes.npcs.client.gui.util.*; +import noppes.npcs.entity.EntityNPCInterface; +import software.bernie.geckolib3.resource.GeckoLibCache; + +import java.util.Collections; +import java.util.HashSet; +import java.util.Vector; + +public class GuiGeckoAnimFileSelection extends GuiNPCInterface { + public GuiNPCStringSlot slot; + public GuiScreen parent; + + public GuiGeckoAnimFileSelection(EntityNPCInterface npc, GuiScreen parent){ + super(npc); + drawDefaultBackground = false; + title = ""; + this.parent = parent; + } + + @Override + public void initGui(){ + super.initGui(); + String ss = "Selecting geckolib animation file:"; + addLabel(new GuiNpcLabel(0,ss, width / 2 - (this.fontRendererObj.getStringWidth(ss)/2), 20, 0xffffff)); + Vector list = new Vector(); + for(ResourceLocation resLoc : GeckoLibCache.getInstance().getAnimations().keySet()){ + list.add(resLoc.toString()); + } + Collections.sort(list,String.CASE_INSENSITIVE_ORDER); + slot = new GuiNPCStringSlot(list,this,false,18); + slot.registerScrollButtons(4, 5); + + this.addButton(new GuiNpcButton(2, width / 2 - 100, height - 44,98, 20, "gui.back")); + } + + @Override + public void drawScreen(int i, int j, float f) + { + slot.drawScreen(i, j, f); + super.drawScreen(i, j, f); + } + + @Override + public void elementClicked(){ + } + + @Override + public void doubleClicked(){ + npc.display.animFile=slot.selected; + close(); + NoppesUtil.openGUI(player, parent); + } + + @Override + protected void actionPerformed(GuiButton guibutton){ + int id = guibutton.id; + if(id == 2){ + close(); + NoppesUtil.openGUI(player, parent); + } + } + + @Override + public void save() { + } +} \ No newline at end of file diff --git a/src/main/java/noppes/npcs/client/model/ModelGeckolib.java b/src/main/java/noppes/npcs/client/model/ModelGeckolib.java new file mode 100644 index 000000000..4d4dfe884 --- /dev/null +++ b/src/main/java/noppes/npcs/client/model/ModelGeckolib.java @@ -0,0 +1,23 @@ +package noppes.npcs.client.model; + +import net.minecraft.util.ResourceLocation; +import noppes.npcs.entity.EntityGeckoModel; +import software.bernie.geckolib3.GeckoLib; +import software.bernie.geckolib3.model.AnimatedGeoModel; + +public class ModelGeckolib extends AnimatedGeoModel { + @Override + public ResourceLocation getAnimationFileLocation(EntityGeckoModel entity) { + return entity.animResLoc;//new ResourceLocation(GeckoLib.ModID, "animations/bike.animation.json"); + } + + @Override + public ResourceLocation getModelLocation(EntityGeckoModel entity) { + return entity.modelResLoc;//new ResourceLocation(GeckoLib.ModID, "geo/bike.geo.json"); + } + + @Override + public ResourceLocation getTextureLocation(EntityGeckoModel entity) { + return entity.textureResLoc;//new ResourceLocation(GeckoLib.ModID, "textures/model/entity/bike.png"); + } +} \ No newline at end of file diff --git a/src/main/java/noppes/npcs/client/renderer/RenderGeckolib.java b/src/main/java/noppes/npcs/client/renderer/RenderGeckolib.java new file mode 100644 index 000000000..c13b63b2a --- /dev/null +++ b/src/main/java/noppes/npcs/client/renderer/RenderGeckolib.java @@ -0,0 +1,65 @@ +package noppes.npcs.client.renderer; + +import net.minecraft.client.renderer.entity.RenderManager; +import net.minecraft.item.ItemStack; +import net.minecraftforge.client.IItemRenderer; +import noppes.npcs.client.model.ModelGeckolib; +import noppes.npcs.entity.EntityGeckoModel; +import org.lwjgl.opengl.GL11; +import software.bernie.geckolib3.geo.render.built.GeoBone; +import software.bernie.geckolib3.geo.render.built.GeoModel; +import software.bernie.geckolib3.renderers.geo.GeoEntityRenderer; + +import java.util.ArrayList; + +public class RenderGeckolib extends GeoEntityRenderer { + + public RenderGeckolib() { + super(new ModelGeckolib()); + } + public void renderAfter(GeoModel model, EntityGeckoModel animatable, float ticks, float red, float green, float blue, float alpha) { + super.renderAfter(model, animatable, ticks, red, green, blue, alpha); + if (model.getBone("held_item").isPresent() && animatable.getHeldItem() != null) { + GeoBone bone = model.getBone("held_item").get(); + this.renderItem(animatable, bone, ticks); + } + } + + public GeoBone[] getPathFromRoot(GeoBone bone) { + ArrayList bones; + for(bones = new ArrayList(); bone != null; bone = bone.parent) { + bones.add(0, bone); + } + + return (GeoBone[])bones.toArray(new GeoBone[0]); + } + + public void renderItem(EntityGeckoModel animatable, GeoBone locator, float ticks) { + GL11.glPushMatrix(); + float scale = 0.5F; + GL11.glScaled(scale, scale, scale); + GeoBone[] bonePath = this.getPathFromRoot(locator); + + for(int i = 0; i < bonePath.length; ++i) { + GeoBone b = bonePath[i]; + GL11.glTranslatef(b.getPositionX() / (16.0F * scale), b.getPositionY() / (16.0F * scale), b.getPositionZ() / (16.0F * scale)); + GL11.glTranslatef(b.getPivotX() / (16.0F * scale), b.getPivotY() / (16.0F * scale), b.getPivotZ() / (16.0F * scale)); + GL11.glRotated((double)b.getRotationZ() / Math.PI * 180.0, 0.0, 0.0, 1.0); + GL11.glRotated((double)b.getRotationY() / Math.PI * 180.0, 0.0, 1.0, 0.0); + GL11.glRotated((double)b.getRotationX() / Math.PI * 180.0, 1.0, 0.0, 0.0); + GL11.glScalef(b.getScaleX(), b.getScaleY(), b.getScaleZ()); + GL11.glTranslatef(-b.getPivotX() / (16.0F * scale), -b.getPivotY() / (16.0F * scale), -b.getPivotZ() / (16.0F * scale)); + } + + GL11.glRotatef(250.0F, 1.0F, 0.0F, 0.0F); + GL11.glRotatef(40.0F, 0.0F, 1.0F, 0.0F); + GL11.glTranslatef(-0.4F, -0.55F, 1.7F); + ItemStack stack = animatable.getHeldItem(); + RenderManager.instance.itemRenderer.renderItem(animatable, stack, 0, IItemRenderer.ItemRenderType.INVENTORY); + GL11.glPopMatrix(); + } + + public boolean isBoneRenderOverriden(EntityGeckoModel entity, GeoBone bone) { + return bone.name.equals("held_item"); + } +} \ No newline at end of file diff --git a/src/main/java/noppes/npcs/client/renderer/RenderNPCInterface.java b/src/main/java/noppes/npcs/client/renderer/RenderNPCInterface.java index cdbae56c2..b24a70d12 100644 --- a/src/main/java/noppes/npcs/client/renderer/RenderNPCInterface.java +++ b/src/main/java/noppes/npcs/client/renderer/RenderNPCInterface.java @@ -29,6 +29,7 @@ import noppes.npcs.controllers.data.SkinOverlay; import noppes.npcs.entity.EntityCustomNpc; import noppes.npcs.entity.EntityNPCInterface; import org.lwjgl.opengl.GL11; +import software.bernie.geckolib3.core.IAnimatable; import javax.imageio.ImageIO; import java.awt.image.BufferedImage; @@ -217,9 +218,35 @@ public class RenderNPCInterface extends RenderLiving{ super.doRender(entityliving, d, d1, d2, f, f1); } + private void renderGeoModel(EntityNPCInterface npc, float rot, float partial) + { + if (!npc.isInvisible()) + { + RenderManager.instance.renderEntityWithPosYaw(((ModelMPM) mainModel).entity, 0,0,0,rot,partial); + } + else if (!npc.isInvisibleToPlayer(Minecraft.getMinecraft().thePlayer)) + { + GL11.glPushMatrix(); + GL11.glColor4f(1.0F, 1.0F, 1.0F, 0.15F); + GL11.glDepthMask(false); + GL11.glEnable(GL11.GL_BLEND); + GL11.glBlendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA); + GL11.glAlphaFunc(GL11.GL_GREATER, 0.003921569F); + RenderManager.instance.renderEntityWithPosYaw(((ModelMPM) mainModel).entity, 0,0,0,rot,partial); + GL11.glDisable(GL11.GL_BLEND); + GL11.glAlphaFunc(GL11.GL_GREATER, 0.1F); + GL11.glPopMatrix(); + GL11.glDepthMask(true); + } + } + protected void renderModel(EntityLivingBase entityliving, float par2, float par3, float par4, float par5, float par6, float par7) { EntityNPCInterface npc = (EntityNPCInterface) entityliving; - if (this.getEntityTexture(entityliving) != null) { + if(mainModel instanceof ModelMPM && ((ModelMPM) mainModel).entity instanceof IAnimatable){ + GL11.glRotatef(180, 1,0,0); + GL11.glTranslated(0, -1.5,0); + renderGeoModel(npc, npc.rotationYaw, Minecraft.getMinecraft().timer.renderPartialTicks); + } else if (this.getEntityTexture(entityliving) != null) { super.renderModel(entityliving, par2, par3, par4, par5, par6, par7); } diff --git a/src/main/java/noppes/npcs/entity/EntityGeckoModel.java b/src/main/java/noppes/npcs/entity/EntityGeckoModel.java new file mode 100644 index 000000000..36630bf41 --- /dev/null +++ b/src/main/java/noppes/npcs/entity/EntityGeckoModel.java @@ -0,0 +1,77 @@ +package noppes.npcs.entity; + +import net.minecraft.entity.EntityCreature; +import net.minecraft.entity.ai.EntityAIWatchClosest; +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.util.ResourceLocation; +import net.minecraft.world.World; +import software.bernie.geckolib3.core.IAnimatable; +import software.bernie.geckolib3.core.IAnimationTickable; +import software.bernie.geckolib3.core.PlayState; +import software.bernie.geckolib3.core.builder.AnimationBuilder; +import software.bernie.geckolib3.core.controller.AnimationController; +import software.bernie.geckolib3.core.event.predicate.AnimationEvent; +import software.bernie.geckolib3.core.manager.AnimationData; +import software.bernie.geckolib3.core.manager.AnimationFactory; + +import java.util.Objects; + +public class EntityGeckoModel extends EntityCreature implements IAnimatable, IAnimationTickable { + private AnimationFactory factory = new AnimationFactory(this); + public ResourceLocation modelResLoc=new ResourceLocation("geckolib3", "geo/npc.geo.json"); + public ResourceLocation animResLoc=new ResourceLocation("custom", "geo_npc.animation.json"); + public ResourceLocation textureResLoc = new ResourceLocation("geckolib3", "textures/model/entity/geo_npc.png"); + public String idleAnim = ""; + public String walkAnim = ""; + public String hurtAnim = ""; + public String attackAnim = ""; + private PlayState predicateMovement(AnimationEvent event) { + if(!event.isMoving()){ + if(!Objects.equals(idleAnim, "")) { + event.getController().setAnimation(new AnimationBuilder().addAnimation(idleAnim, true)); + } + }else{ + if(!Objects.equals(idleAnim, "")) { + event.getController().setAnimation(new AnimationBuilder().addAnimation(walkAnim, true)); + } + } + //event.getController().setAnimation(new AnimationBuilder().addAnimation("animation.bat.fly", true)); + return PlayState.CONTINUE; + } + private PlayState predicateAttack(AnimationEvent event) { + //event.getController().setAnimation(new AnimationBuilder().addAnimation("animation.bat.fly", true)); + return PlayState.CONTINUE; + } + private PlayState predicateManual(AnimationEvent event) { + return PlayState.CONTINUE; + } + + public EntityGeckoModel(World worldIn) { + super(worldIn); + this.ignoreFrustumCheck = true; + this.tasks.addTask(6, new EntityAIWatchClosest(this, EntityPlayer.class, 8.0F)); + this.setSize(0.7F, 2F); + } + + @Override + public void registerControllers(AnimationData data) { + data.addAnimationController(new AnimationController<>(this, "movement", 10, this::predicateMovement)); + data.addAnimationController(new AnimationController<>(this, "attack", 10, this::predicateAttack)); + data.addAnimationController(new AnimationController<>(this, "manual", 10, this::predicateManual)); + } + + @Override + public AnimationFactory getFactory() { + return this.factory; + } + + @Override + public int tickTimer() { + return ticksExisted; + } + + @Override + public void tick() { + super.onUpdate(); + } +} \ No newline at end of file