Jump to content

shultzy

Members
  • Posts

    15
  • Joined

  • Last visited

Everything posted by shultzy

  1. There is a bug in my mod that causes a large frame drop and a lighting glitch appears at the same Y level of where my custom entity is spawned whenever it is rendered. I have a quite a fast computer with an Intel Core i7 and Nvidia GForceGTX 1060 graphics. This is the code for the ModelEagle.class https://pastebin.com/KyVZnyj3
  2. Looking at your event handler, the original item is not destroyed when its duplicated. As for why its only spawning EntityItems, I'm not entirely sure, but my guess is how EntityItemFireproof's constructor is called. This essentially means that the item that spawns causes the event to fire again thus repeating indefinitely. Hopefully this was some help. *Edit* Something else I had thought of is you could change this line: EntityItemFireproof fireproofItem = new EntityItemFireproof(world, item.posX, item.posY, item.posZ, item.getItem()); To this: EntityItemFireproof fireproofItem = (EntityItemFireproof) ent;
  3. I'm trying to figure out how to add entities and spawn them with using a mod item. Nothing happens though manual testing when I use the item on a block, nor can I spawn it directly with the summon command since its as though the entity was never actually registered. I have confirmed that its executing the required registration commands for both client and server. See mod project for details: https://github.com/jshultz/WagonsMod
  4. Actucally, according to the source code this refers to WorldInfo#worldTime which is in the range of 0-23999 (in ticks) or a full day.
  5. I have an item with metadata to be textured, I can get the items to show in the creative menu but are showing up with the default textures. I am using registry events to handle registration of items and loading on client side as shown here. Here is the JSON file associated with the item. Upon launch, forge does not complain at all about texture loading but does output this line in fml-client-latest.log:
  6. I'm trying to have horses respond when interacted with especially when holding a custom item which will work similar to the vanilla lead. But the only thing that the horses do is rear when my item is active in the hotbar. And the message is not being sent to the console (shown with the arrow). Code fragment for my event handler: @SubscribeEvent(receiveCanceled=true) public void onEntityInteract(EntityInteractEvent evt) { if (evt.entityLiving instanceof EntityHorse) { -->System.out.println("[Wagon Mod] player interacted with " + evt.entityLiving.toString() + " using lasso"); } }
  7. Thanks, at first I did try the UUID because it is immutable, but it seemed that this was inconsistent between the client and the server and so the horse would never be added to my entity. I would like to be sure this is true, since I can't find out anything about it. The way I'm thinking about it, I could in theory send a packet server side with the temporary ID, but without being saved to NBT and use that to get the ID of the entity client side.
  8. I read about ways to save information to an NBT tag that identifies an entity using its UUID or Minecraft's own IDs. I tried this in my mod but I can't tell if it saved this data from the console output. I do need the UUID of my custom entity to persist after exiting the world but I am not able to get the vanilla horses to move while they should be attached to my wagon entity. I currently have my own server command to spawn and "attach" them to the wagon. EntityWagon.addAnimal() /** * assigns this animal a slot on this entity and saves custom entity data to * its NBT tag, animal can be referenced via the respective field. * * @param animal * @param slot */ public void addAnimal(EntityAnimal animal, byte slot) { if (!worldObj.isRemote) { ExtendedAnimal extHorse = (ExtendedAnimal) animal.getExtendedProperties("WagonAnimal"); extHorse.setAssignToWagon(this, slot); WagonsMod.network.sendToAll(new SyncEntityTag(animal, animal.getEntityData())); } animals.add((EntityHorse) animal); // set each entities' position and rotation switch (slot) { case 0: animal.setPositionAndRotation( posX + Math.cos((double) (rotationYaw * Math.PI / 180.0D) - 0.5D) * -2.0D, posY, posZ + Math.sin((double) (rotationYaw * Math.PI / 180.0D) - 0.5D) * -2.0D, rotationYaw, rotationPitch); break; case 1: animal.setPositionAndRotation( posX + Math.cos((double) (rotationYaw * Math.PI / 180.0D) + 0.5D) * -2.0D, posY, posZ + Math.sin((double) (rotationYaw * Math.PI / 180.D) + 0.5D) * -2.0D, rotationYaw, rotationPitch); break; } } ExtendedAnimal class package com.shultzy88.wagonsmod.entity; import java.util.*; import cpw.mods.fml.common.registry.IEntityAdditionalSpawnData; import io.netty.buffer.ByteBuf; import net.minecraft.client.Minecraft; import net.minecraft.entity.*; import net.minecraft.entity.passive.*; import net.minecraft.nbt.NBTTagCompound; import net.minecraft.server.MinecraftServer; import net.minecraft.util.AxisAlignedBB; import net.minecraft.world.World; import net.minecraftforge.common.IExtendedEntityProperties; /** * Extends vanilla horse properties as well as other draft type animals to ensure it is properly connected to the * wagon when this data changes (such as when the memory is released upon leaving the world). The slot helps set * the position of the animal mob in relation to the custom entity, the string is the * immutable entity ID for the next time a player visits a world. To maintain the link with the two entities, * we must also have the temporary ID since it is the same on both sides. As soon as the data is saved, we send a * packet (see {@code SyncEntityTag} for more) to any clients that require this (i.e rendering GUIs). * - Note: The temporary ID Minecraft uses only serves to ensure both sides refer to the same entity, we can't * use this when constructing the wagon because it changes at every game session * * @author Shultzy */ public class ExtendedAnimal implements IExtendedEntityProperties { /** name of the tag that will be holding our data */ private static final String EXT_ANIMAL_TAG_NAME = "WagonAnimal"; /** the EntityHorse that our custom properties is bound to (cannot be reassigned) */ private EntityAnimal animal; /** the world that our entity exists */ private World world; /** slot assigned to entity (valid range is 0-3) [default: -1] */ private byte slot; /** persistent ID for our wagon [default: 0-0] */ private UUID wagonStaticID; /** temporary ID for our wagon */ private int wagonDynamicID; @Override public void saveNBTData(NBTTagCompound compound) { // We need to create a new tag that will save everything for our extended properties on the server NBTTagCompound draftAnimalProperties = new NBTTagCompound(); draftAnimalProperties.setByte("SlotAssigned", slot); draftAnimalProperties.setString("WagonUUID", wagonStaticID.toString()); draftAnimalProperties.setInteger("WagonID", wagonDynamicID); // This sets the entity's tag to compound.setTag(EXT_ANIMAL_TAG_NAME, draftAnimalProperties); } @Override public void loadNBTData(NBTTagCompound compound) { // After we have our NBT tag saved, we must load our extended properties client-side NBTTagCompound draftAnimalProperties = (NBTTagCompound) compound.getTag(EXT_ANIMAL_TAG_NAME); // assign data to what was saved on the server slot = draftAnimalProperties.getByte("SlotAssigned"); wagonStaticID = UUID.fromString(draftAnimalProperties.getString("WagonUUID")); wagonDynamicID = draftAnimalProperties.getInteger("WagonID"); // check that everything is working fine System.out.println("[WagonCraft] Entity is assigned to " + slot + " to " + wagonStaticID.toString()); } @Override public void init(Entity animal, World world) { this.animal = (EntityAnimal) animal; this.world = world; this.slot = -1; this.wagonStaticID = new UUID(0L, 0L); this.wagonDynamicID = 0; } public byte getSlot() { return slot; } public UUID getWagonStaticID() { return wagonStaticID; } public int getWagonDynamicID() { return wagonDynamicID; } /** * Sets the extended entity's properties as preparing to be saved to NBT */ public void setAssignToWagon(EntityWagon wagonAssigned, byte slot) { this.wagonStaticID = wagonAssigned.getPersistentID(); this.wagonDynamicID = wagonAssigned.getEntityId(); this.slot = slot; } public static final void register(EntityAnimal animal) { animal.registerExtendedProperties(EXT_ANIMAL_TAG_NAME, new ExtendedAnimal()); } public static final ExtendedAnimal getProperties(EntityAnimal animal) { return (ExtendedAnimal) animal.getExtendedProperties(EXT_ANIMAL_TAG_NAME); } } SyncEntityTag class package com.shultzy88.wagonsmod.network; import java.util.List; import java.util.UUID; import com.shultzy88.wagonsmod.entity.*; import com.shultzy88.wagonsmod.network.*; import cpw.mods.fml.common.network.ByteBufUtils; import cpw.mods.fml.common.network.simpleimpl.*; import cpw.mods.fml.relauncher.Side; import net.minecraftforge.common.MinecraftForge; import net.minecraftforge.event.entity.living.LivingEvent.LivingUpdateEvent; import io.netty.buffer.ByteBuf; import net.minecraft.client.Minecraft; import net.minecraft.entity.Entity; import net.minecraft.entity.EntityLivingBase; import net.minecraft.entity.passive.EntityAnimal; import net.minecraft.entity.passive.EntityHorse; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.nbt.NBTTagCompound; import net.minecraft.server.MinecraftServer; import net.minecraft.world.World; public class SyncEntityTag implements IMessage { private NBTTagCompound animalTag; /** required for automatic packet handling */ public SyncEntityTag() { } public SyncEntityTag(EntityAnimal draftAnimal, NBTTagCompound animalTag) { this.animalTag = animalTag; ExtendedAnimal.getProperties(draftAnimal).saveNBTData(animalTag); } @Override public void fromBytes(ByteBuf buf) { animalTag = ByteBufUtils.readTag(buf); } @Override public void toBytes(ByteBuf buf) { ByteBufUtils.writeTag(buf, animalTag); } public static class Handler implements IMessageHandler<SyncEntityTag, IMessage> { @Override public IMessage onMessage(SyncEntityTag message, MessageContext ctx) { if (ctx.side == Side.CLIENT) { // We have to interate through the list of loaded entities and load the data for each since the client // is run on a separate thread. Which ensures that the client has the necessary custom data we have given. List<Entity> loadedEntities = Minecraft.getMinecraft().theWorld.getLoadedEntityList(); for (Entity entity : loadedEntities) { if (entity instanceof EntityHorse) { LivingUpdateEvent evt = new LivingUpdateEvent((EntityLivingBase) entity); MinecraftForge.EVENT_BUS.post(evt); ExtendedAnimal extHorseProps = ExtendedAnimal.getProperties((EntityHorse) evt.entityLiving); extHorseProps.loadNBTData(evt.entityLiving.getEntityData().getCompoundTag("WagonAnimal")); } } return null; } return null; } } } Final note: I have the extended properties registered and use a LivingUpdateEvent method to intercept the vanilla horse update logic and search for the wagon it is assigned to using custom properties that is saved via this tag to the horse. I have suspected that it may not be able to find the wagon because the client and server are using different UUIDs and thought using the temporary ID would help to find it but still not sure what I am doing wrong.
  9. Per your advice I modified the code to use NBT data, also I have considered extending EntityAIBase as an alternative for the update event. I am able to get the data synced to the client but I have tried to have the entity search the loaded entities for the UUID that matches the one that is in my extended entity properties. In short, the entity is never found and the horses I coupled to the wagon behave like normal. I even checked with NBTExplorer and found the identifier to be different for both my custom entity and the extended entity properties which is supposed to reference it. Extended Horse AI package com.shultzy88.wagonsmod.entity.ai; import java.util.List; import java.util.UUID; import com.shultzy88.wagonsmod.entity.*; import net.minecraft.entity.*; import net.minecraft.entity.ai.EntityAIBase; import net.minecraft.entity.passive.EntityHorse; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.nbt.NBTTagCompound; import net.minecraft.util.AxisAlignedBB; import net.minecraft.world.World; import net.minecraftforge.event.entity.EntityEvent; /** * Allows the player to control horses via a wagon while mounted. * Uses an algorithm to calculate the positions of each animal based on * a byte tag saved to the horse. The horses only will resume vanilla * tasks when removed. * Pigs use player-controlled AI, but only when the player is riding and * holding a carrot on a stick. * @author Shultzy * */ public class EntityAIControlledByWagon extends EntityAIBase { private final EntityHorse horse; private final float maxSpeed; private float currentSpeed; /** Whether the entity's speed is boosted. */ private boolean speedBoosted; /** Counter for speed boosting, upon reaching maxSpeedBoostTime the speed boost will be disabled */ private int speedBoostTime; /** Maximum time the entity's speed should be boosted for. */ private int maxSpeedBoostTime; private ExtendedHorse extendedHorseData; private static final String __OBFID = "CL_00001580"; private EntityWagon wagon; private boolean isAssigned; private byte slot; public EntityAIControlledByWagon(EntityHorse horse, float maxSpeed) { this.horse = horse; this.maxSpeed = maxSpeed; this.setMutexBits(7); this.extendedHorseData = (ExtendedHorse) this.horse.getExtendedProperties("ExtHorseProps"); } @Override public void startExecuting() { speedBoosted = false; currentSpeed = 0.0F; slot = extendedHorseData.getSlot(); isAssigned = extendedHorseData.getIsAssigned(); wagon = getAssignedWagon(); } @Override public void resetTask() { speedBoosted = false; currentSpeed = 0.0F; slot = extendedHorseData.getSlot(); isAssigned = extendedHorseData.getIsAssigned(); wagon = getAssignedWagon(); } @Override public void updateTask() { // check that the entity has been assigned a valid slot on the wagon if (slot != -1 && isAssigned && wagon != null) { // TODO !DEBUG! System.out.println("Updating EntityHorse position"); // set each entities' position and rotation switch (slot) { case 0: horse.setPositionAndRotation( wagon.posX + Math.cos((double) (wagon.rotationYaw * Math.PI / 180.0D) - 0.5D) * -2.0D, wagon.posY, wagon.posZ + Math.sin((double) (wagon.rotationYaw * Math.PI / 180.0D) - 0.5D) * -2.0D, wagon.rotationYaw, wagon.rotationPitch); break; case 1: horse.setPositionAndRotation( wagon.posX + Math.cos((double) (wagon.rotationYaw * Math.PI / 180.0D) + 0.5D) * -2.0D, wagon.posY, wagon.posZ + Math.sin((double) (wagon.rotationYaw * Math.PI / 180.D) + 0.5D) * -2.0D, wagon.rotationYaw, wagon.rotationPitch); break; } } } private EntityWagon getAssignedWagon() { List<Entity> loadedEntities = horse.worldObj.getLoadedEntityList(); for (Entity entity : loadedEntities) { if (entity instanceof EntityWagon & extendedHorseData.getWagonAssignUniqueID().equals(entity.getUniqueID())) { return (EntityWagon) entity; } } return null; } @Override public boolean continueExecuting() { return this.shouldExecute(); } @Override public boolean shouldExecute() { return this.horse.isEntityAlive() && extendedHorseData.getSlot() != -1 && extendedHorseData.getIsAssigned() && !extendedHorseData.getWagonAssignUniqueID().equals(new UUID(0L, 0L)) ? true : false; } } Add Horse Method @Override public void addAnimal(EntityHorse animal, byte slot) { animals.add(animal); ExtendedHorse extHorse = (ExtendedHorse) animal.getExtendedProperties("ExtHorseProps"); extHorse.setAssignToWagon(getUniqueID(), slot, true); // set each entities' position and rotation switch (slot) { case 0: animal.setPositionAndRotation( posX + Math.cos((double) (rotationYaw * Math.PI / 180.0D) - 0.5D) * -2.0D, posY, posZ + Math.sin((double) (rotationYaw * Math.PI / 180.0D) - 0.5D) * -2.0D, rotationYaw, rotationPitch); break; case 1: animal.setPositionAndRotation( posX + Math.cos((double) (rotationYaw * Math.PI / 180.0D) + 0.5D) * -2.0D, posY, posZ + Math.sin((double) (rotationYaw * Math.PI / 180.D) + 0.5D) * -2.0D, rotationYaw, rotationPitch); break; } WagonsMod.network.sendToAll(new SyncEntityTag(animal, animal.getEntityData().getCompoundTag("ExtHorseProps"))); }
  10. Another option could be with Minecraft.getMinecraft().objectMouseOver which is the data type MovingObjectPosition. It can be used to reference not only the block position, but the side that was hit as well. I have used this to find the entity that a player is looking at, but should work just as well with blocks. Hope this helps
  11. I have an event class that is supposed to modify existing horse behavior to allow a custom wagon entity to be "pulled by" it while the player is mounting the wagon. However during the world initialization phase, the client crashes when attempting to retrieve a byte value set by the horse entity's datawatcher object, which is used to help position the horse relative to my entity. I have tried to do this within the onUpdate method of my entity class and the horses linked to it don't appear to move with the wagon at all. package com.shultzy88.wagons.event; import com.shultzy88.wagons.entity.*; import cpw.mods.fml.common.eventhandler.SubscribeEvent; import net.minecraft.entity.*; import net.minecraft.entity.passive.EntityHorse; import net.minecraft.world.World; import net.minecraftforge.event.entity.EntityEvent.EntityConstructing; import net.minecraftforge.event.entity.living.LivingEvent.LivingUpdateEvent; public class EntityEventHandler { @SubscribeEvent public void onEntityConstructing(EntityConstructing evt) { if (evt.entity instanceof EntityHorse) { // !DEBUG! System.out.println("Registering entity properties for EntityHorse"); evt.entity.getDataWatcher().addObject(23, -1); } } @SubscribeEvent public void onLivingUpdate(LivingUpdateEvent evt) { if (evt.entity instanceof EntityHorse) { // !DEBUG! System.out.println("Event fired: LivingUpdateEvent"); World world = evt.entity.worldObj; byte slot = 0; if (!world.isRemote) { slot = evt.entity.getDataWatcher().getWatchableObjectByte(23); } EntityWagon wagon = (EntityWagon) world.findNearestEntityWithinAABB(EntityWagon.class, evt.entity.boundingBox.expand(3.0D, 3.0D, 3.0D), evt.entity); // check that the entity has been assigned a valid slot on the wagon if (slot != -1) { // set each entities' position and rotation switch (slot) { case 0: evt.entity.setPositionAndRotation( wagon.posX + Math.cos((double) (wagon.rotationYaw * Math.PI / 180.0D) - 0.5D) * 1.6D, wagon.posY, wagon.posZ + Math.sin((double) (wagon.rotationYaw * Math.PI / 180.0D) - 0.5D) * 1.6D, wagon.rotationYaw, wagon.rotationPitch); case 1: evt.entity.setPositionAndRotation( wagon.posX + Math.cos((double) (wagon.rotationYaw * Math.PI / 180.0D) + 0.5D) * 1.6D, wagon.posY, wagon.posZ + Math.sin((double) (wagon.rotationYaw * Math.PI / 180.D) + 0.5D) * 1.6D, wagon.rotationYaw, wagon.rotationPitch); } } } } }
  12. I want my custom wagon entity to add an instance of EntityAnimal and add it to a field like an array or list for my custom entity and have the passive entity move while the wagon is moving. When getEntitiesWithinAABB is called, it's not returning any entities in the list, I am fairly new to entity processing. I am using similar code found in the method interactFirst of the EntityLeashKnot class. Here is the source code: /** * First layer of player interaction */ public boolean interactFirst(EntityPlayer playerEntity) { double minMaxAABB = 7.0D; // Get list of all entities leashed by player List leashedList = this.worldObj.getEntitiesWithinAABB( EntityAnimal.class, AxisAlignedBB.getBoundingBox((double) this.posX - minMaxAABB, (double) this.posY - minMaxAABB, (double) this.posZ - minMaxAABB, (double) this.posX - minMaxAABB, (double) this.posY + minMaxAABB, (double) this.posZ + minMaxAABB)); // if there are up to 2 entities leashed anchor them to the wagon if (leashedList != null && leashedList.size() <= 2) { System.out.println("Returned list of leashed entities on interaction with wagon entity"); Iterator iterator = leashedList.iterator(); while (iterator.hasNext()) { EntityAnimal entity = (EntityAnimal) iterator.next(); if (entity.getLeashed() && entity.getLeashedToEntity() == playerEntity) { // break leash from player entity.clearLeashed(true, true); // add entity to wagon this.entityHorses.add(entity); // DEBUG: to know the correct entities are referenced System.out.println(this.entityHorses.isEmpty()); } } } return true; }
  13. Hey everyone, I'm new here. I am working on a new mod that adds horse-drawn wagons and carriages. I have run into a small bug that happens when I turn towards the entity a there is an GL rendering error in the console "Post Render 1284 Stack Overflow" constantly until the entity is out of view. Additionally, the water in rivers are invisible and sometimes the client stops responding for 1-2 seconds and reloads the terrain. I have included two links with the classes responsible for rendering the entity and both classes are copied from the vanilla boat entity with the respect to its Render and Model classes. http://pastebin.com/Xn94rdZV http://pastebin.com/Z4HhURsa
×
×
  • Create New...

Important Information

By using this site, you agree to our Terms of Use.