July 18, 20178 yr Author In the Render class Spoiler package com.ninja3659.explorationexpansion.client.renders; import com.ninja3659.explorationexpansion.client.entities.EntityBeelzebook; import com.ninja3659.explorationexpansion.client.model.ModelBeelzebook; import net.minecraft.client.model.ModelBase; import net.minecraft.client.renderer.entity.RenderLiving; import net.minecraft.client.renderer.entity.RenderManager; import net.minecraft.util.ResourceLocation; public class RenderBeelzebook extends RenderLiving<EntityBeelzebook>{ private static final ResourceLocation TEXTURES = new ResourceLocation("neem:textures/entity/beelzebook/beelzebook.png"); public RenderBeelzebook(RenderManager manager) { super(manager, new ModelBeelzebook(), 3); } @Override protected ResourceLocation getEntityTexture(EntityBeelzebook entity) { return TEXTURES; } } And then in ClientProxy: Spoiler @Override public void registerRenders() { ModItems.registerRenders(); ModTools.registerRenders(); ModBlocks.registerRenders(); RenderingRegistry.registerEntityRenderingHandler(EntityChimera.class, new IRenderFactory<EntityChimera>() { @Override public Render<? super EntityChimera> createRenderFor(RenderManager manager) { return new RenderChimera(manager); } }); RenderingRegistry.registerEntityRenderingHandler(EntityMindFlayer.class, new IRenderFactory<EntityMindFlayer>() { @Override public Render<? super EntityMindFlayer> createRenderFor(RenderManager manager) { return new RenderFlayer(manager); } }); RenderingRegistry.registerEntityRenderingHandler(EntityBeelzebook.class, new IRenderFactory<EntityBeelzebook>() { @Override public Render<? super EntityBeelzebook> createRenderFor(RenderManager manager) { // TODO Auto-generated method stub return new RenderBeelzebook(manager); } }); Utils.getLogger().info("Rendered Chimera"); } Edited July 18, 20178 yr by GooberGunter
July 18, 20178 yr Your render class returns a new instance of ModelBeelzebook, but your packet updates the model which you have stored in a field in the entity and which does nothing. Instead you should make the model render depending on the entity's awake status, and use the packet to update the entity itself.
July 18, 20178 yr Author So, like, have a getModel method in the entity class and then in render call said method and have the packet store the entity not the boolean? If so, then how would I go about that writing the entity to bytes? And wouldn't the entity be a lot to write back and forth? Edited July 18, 20178 yr by GooberGunter
July 18, 20178 yr user action -> entity on server gets awake -> send packet -> packet handler sets the same value on the client entity -> renderer reads the data in the entity when rendering the model Apparently I'm a complete and utter jerk and come to this forum just like to make fun of people, be confrontational, and make your personal life miserable. If you think this is the case, JUST REPORT ME. Otherwise you're just going to get reported when you reply to my posts and point it out, because odds are, I was trying to be nice. Exception: If you do not understand Java, I WILL NOT HELP YOU and your thread will get locked. DO NOT PM ME WITH PROBLEMS. No help will be given.
July 18, 20178 yr It's run on both. But most behaviour is controlled from the server, so if the client needs to know something you have to send it.
July 18, 20178 yr And specifically, the LivingHurtEvent only runs server-side. Apparently I'm a complete and utter jerk and come to this forum just like to make fun of people, be confrontational, and make your personal life miserable. If you think this is the case, JUST REPORT ME. Otherwise you're just going to get reported when you reply to my posts and point it out, because odds are, I was trying to be nice. Exception: If you do not understand Java, I WILL NOT HELP YOU and your thread will get locked. DO NOT PM ME WITH PROBLEMS. No help will be given.
July 18, 20178 yr Author Ok so since I had the server-sided LivingHurtEvent change a boolean, it only changed it on the server side, so I need to update the entire entity on the clientside through packets, right?
July 18, 20178 yr Just now, GooberGunter said: Ok so since I had the server-sided LivingHurtEvent change a boolean, it only changed it on the server side, so I need to update the entire entity on the clientside through packets, right? That's it!
July 18, 20178 yr Author I never thought I'd get it. So...one last question. How do I set up a packet to handle an entity since it's not a basic field
July 18, 20178 yr 9 minutes ago, GooberGunter said: I never thought I'd get it. So...one last question. How do I set up a packet to handle an entity since it's not a basic field You've already got a packet that handles an entity - it finds the correct one using its id. You just need to set the boolean in the entity itself, rather than setting in the entity's model field (which is unused and pointless anyway).
July 18, 20178 yr Author Alright it works! Kinda. When I trigger the event, it updates all the entities of the same type Here is the updated packet Spoiler void proccessMessage(PacketReturnAwaken message, MessageContext ctx) { try { EntityBeelzebook eb = (EntityBeelzebook) Minecraft.getMinecraft().world.getEntityByID(message.entityid); eb.setEntityAwake(message.awake); Utils.getLogger().info("packet set: " + eb.getentityAwake()); }catch(Exception e) { Utils.getLogger().catching(e); } }
July 18, 20178 yr Is your model checking the entity's boolean field when it needs to know the awake status? Can you show where you do this?
July 19, 20178 yr Author Yeah here: Spoiler public void AwakeAnimation(EntityBeelzebook entity) { if(entity.getentityAwake()) { this.setRotation(Eye1, 33, 0, 0); this.setRotation(Eye2, 33, 0, 0); Utils.getLogger().info("animation!"); } }//opens the book's eyes I should also note that right now, in the render class, it is still marked as new ModelBeelzebook(); Edited July 19, 20178 yr by GooberGunter
July 19, 20178 yr Author Also. Side-note: how to I isolate every change to the model class per entity?
July 19, 20178 yr 7 hours ago, GooberGunter said: Also. Side-note: how to I isolate every change to the model class per entity? Could you post your whole Render class. VANILLA MINECRAFT CLASSES ARE THE BEST RESOURCES WHEN MODDING I will be posting 1.15.2 modding tutorials on this channel. If you want to be notified of it do the normal YouTube stuff like subscribing, ect. Forge and vanilla BlockState generator.
July 19, 20178 yr Author Render class: Spoiler package com.ninja3659.explorationexpansion.client.renders; import com.ninja3659.explorationexpansion.client.entities.EntityBeelzebook; import com.ninja3659.explorationexpansion.client.model.ModelBeelzebook; import net.minecraft.client.Minecraft; import net.minecraft.client.model.ModelBase; import net.minecraft.client.renderer.entity.RenderLiving; import net.minecraft.client.renderer.entity.RenderManager; import net.minecraft.util.ResourceLocation; public class RenderBeelzebook extends RenderLiving<EntityBeelzebook>{ private static final ResourceLocation TEXTURES = new ResourceLocation("neem:textures/entity/beelzebook/beelzebook.png"); public RenderBeelzebook(RenderManager manager) { super(manager, new EntityBeelzebook(Minecraft.getMinecraft().world).getModel(), 3); } @Override protected ResourceLocation getEntityTexture(EntityBeelzebook entity) { return TEXTURES; } }
July 19, 20178 yr 4 minutes ago, GooberGunter said: Render class: Reveal hidden contents package com.ninja3659.explorationexpansion.client.renders; import com.ninja3659.explorationexpansion.client.entities.EntityBeelzebook; import com.ninja3659.explorationexpansion.client.model.ModelBeelzebook; import net.minecraft.client.Minecraft; import net.minecraft.client.model.ModelBase; import net.minecraft.client.renderer.entity.RenderLiving; import net.minecraft.client.renderer.entity.RenderManager; import net.minecraft.util.ResourceLocation; public class RenderBeelzebook extends RenderLiving<EntityBeelzebook>{ private static final ResourceLocation TEXTURES = new ResourceLocation("neem:textures/entity/beelzebook/beelzebook.png"); public RenderBeelzebook(RenderManager manager) { super(manager, new EntityBeelzebook(Minecraft.getMinecraft().world).getModel(), 3); } @Override protected ResourceLocation getEntityTexture(EntityBeelzebook entity) { return TEXTURES; } } In your constructor the second pararmeter of the super needs to be a new Model. VANILLA MINECRAFT CLASSES ARE THE BEST RESOURCES WHEN MODDING I will be posting 1.15.2 modding tutorials on this channel. If you want to be notified of it do the normal YouTube stuff like subscribing, ect. Forge and vanilla BlockState generator.
July 19, 20178 yr Migrate the awake field to your entity class from your model then. Most likely your model is a singleton(and it should be) so a change to this field will change the model of all your entities. EDIT: haven't noticed all other classes you've posted with those changes. Could you please post your entity class? Edited July 19, 20178 yr by V0idWa1k3r
July 19, 20178 yr Author Here's the entity class Spoiler package com.ninja3659.explorationexpansion.client.entities; import com.ninja3659.explorationexpansion.client.ai.EntityAIWander3d; import com.ninja3659.explorationexpansion.client.model.ModelBeelzebook; import com.ninja3659.explorationexpansion.networking.NeemPacketHandler; import com.ninja3659.explorationexpansion.networking.PacketReturnAwaken; import com.ninja3659.explorationexpansion.util.Utils; import net.minecraft.enchantment.EnumEnchantmentType; import net.minecraft.entity.EntityCreature; import net.minecraft.entity.EntityFlying; import net.minecraft.entity.ai.EntityAIAttackMelee; import net.minecraft.entity.ai.EntityAIBase; import net.minecraft.entity.ai.EntityAIFindEntityNearestPlayer; import net.minecraft.entity.ai.EntityAILookIdle; import net.minecraft.entity.ai.EntityAINearestAttackableTarget; import net.minecraft.entity.ai.EntityAIWander; import net.minecraft.entity.ai.EntityAIWanderAvoidWater; import net.minecraft.entity.ai.EntityAIWatchClosest; import net.minecraft.entity.ai.EntityMoveHelper; import net.minecraft.entity.item.EntityXPOrb; import net.minecraft.entity.monster.EntityGhast; import net.minecraft.entity.monster.IMob; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.util.EnumParticleTypes; import net.minecraft.util.math.AxisAlignedBB; import net.minecraft.util.math.MathHelper; import net.minecraft.world.World; import net.minecraftforge.event.entity.living.LivingHurtEvent; import net.minecraftforge.fml.common.eventhandler.SubscribeEvent; public class EntityBeelzebook extends EntityFlying implements IMob { ModelBeelzebook bookmodel = new ModelBeelzebook(); public boolean entityAwake; public int sync; public EntityBeelzebook(World worldIn) { super(worldIn); this.experienceValue = 200; this.setSize(2, .5f); this.moveHelper = new BeelzebookMoveHelper(this); moveHelper.setMoveTo(0, 10, 0, 1D); this.entityAwake = false; sync = 0; } @Override protected void entityInit() { super.entityInit(); } @Override public void onUpdate() { super.onUpdate(); if(entityAwake) { //Utils.getLogger().info("AWAKENED"); } } @Override protected void initEntityAI() { if(entityAwake) { applyAttackAI(); Utils.getLogger().info("AI updated"); } } public boolean getentityAwake() { return entityAwake; } public void setEntityAwake(boolean truth) { this.entityAwake = truth; } public ModelBeelzebook getModel() { return this.bookmodel; } protected void applyAttackAI() { this.tasks.addTask(0, new EntityAIDeath(this, deathTime)); this.targetTasks.addTask(1, new EntityAIWatchClosest(this, EntityPlayer.class, 32)); this.targetTasks.addTask(0, new EntityAIFindEntityNearestPlayer(this)); this.tasks.addTask(0, new EntityAIWander3d(this, 1.0D, 1)); //Utils.getLogger().info("now we work"); } @Override protected void onDeathUpdate() { ++this.deathTime; if (this.deathTime != 0) { } if (this.deathTime == 200) { if (!this.world.isRemote && (this.isPlayer() || this.recentlyHit > 0 && this.canDropLoot() && this.world.getGameRules().getBoolean("doMobLoot"))) { int i = this.getExperiencePoints(this.attackingPlayer); i = net.minecraftforge.event.ForgeEventFactory.getExperienceDrop(this, this.attackingPlayer, i); while (i > 0) { int j = EntityXPOrb.getXPSplit(i); i -= j; this.world.spawnEntity(new EntityXPOrb(this.world, this.posX, this.posY, this.posZ, j)); } } this.setDead(); for (int k = 0; k < 20; ++k) { double d2 = this.rand.nextGaussian() * 0.02D; double d0 = this.rand.nextGaussian() * 0.02D; double d1 = this.rand.nextGaussian() * 0.02D; this.world.spawnParticle(EnumParticleTypes.EXPLOSION_NORMAL, this.posX + (double)(this.rand.nextFloat() * this.width * 2.0F) - (double)this.width, this.posY + (double)(this.rand.nextFloat() * this.height), this.posZ + (double)(this.rand.nextFloat() * this.width * 2.0F) - (double)this.width, d2, d0, d1, new int[0]); } } } public int getdeathTime() { return this.deathTime; } @Override public void onLivingUpdate() { super.onLivingUpdate(); if(entityAwake) { applyAttackAI(); } sync++; sync %= 20; if(sync == 0 && entityAwake) { NeemPacketHandler.INSTANCE.sendToAll(new PacketReturnAwaken(this.getentityAwake(), this.getEntityId())); Utils.getLogger().info("synched!: " + entityAwake); } } public double getPosX() { return this.posX; } public double getPosY() { return this.posY; } public double getPosZ() { return this.posZ; } public EntityBeelzebook getEntity() { return this; } static class BeelzebookMoveHelper extends EntityMoveHelper { private final EntityBeelzebook parentEntity; private int courseCooldown; public BeelzebookMoveHelper(EntityBeelzebook book) { super(book); this.parentEntity = book; } public void onUpdateMoveHelper() { if (this.action == EntityMoveHelper.Action.MOVE_TO) { double dx = this.posX - this.parentEntity.posX; double dy = this.posY - this.parentEntity.posY; double dz = this.posZ - this.parentEntity.posZ; double df = dx * dx + dy * dy + dz * dz; if(this.courseCooldown-- <=0) { this.courseCooldown += this.parentEntity.getRNG().nextInt(5) + 2; df = (double)MathHelper.sqrt(df); if(this.isNotColliding(this.posX, this.posY, this.posZ, df)) { this.parentEntity.motionX += dx/df * .1D; this.parentEntity.motionY += dy/df * .1D; this.parentEntity.motionZ += dz/df * .1D; } else { this.action = EntityMoveHelper.Action.WAIT; } } } } private boolean isNotColliding(double x, double y, double z, double dividend) { double d0 = (x - this.parentEntity.posX) / dividend; double d1 = (y - this.parentEntity.posY) / dividend; double d2 = (z - this.parentEntity.posZ) / dividend; AxisAlignedBB ax = this.parentEntity.getEntityBoundingBox(); for (int i =1; (double)i < dividend; ++i) { ax = ax.offset(d0, d1, d2); if(!this.parentEntity.world.getCollisionBoxes(this.parentEntity, ax).isEmpty()) { return false; } } return true; } } } class EntityAIDeath extends EntityAIBase{ protected int death; protected EntityBeelzebook book; public EntityAIDeath(EntityBeelzebook entity, int deathT) { this.death = deathT; this.book = entity; setMutexBits(8); } @Override public boolean shouldExecute() { if (death != 0) { return true; } else { return false; } } @Override public boolean continueExecuting() { // TODO Auto-generated method stub return false; } @Override public void startExecuting() { this.book.getMoveHelper().setMoveTo(book.posX, book.posY + 10, book.posZ, 1D); } }
July 19, 20178 yr Don't create a new instance of your model in your entity class, models should be singletons. Models are also client-side only. If your model class haven't changed since you've last posted it then the problem lies in the fact that you need to handle both cases on your AwakeAnimation method - if the entity is awake, and if they are not. Currently you are changing the rotation angles on the model if the entity is awake... which changes them for all entities as models are singletons.
July 19, 20178 yr Author Alright, that worked; man, I need to practice my java. Thanks! I can finally check that off the list.
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.