Jump to content

[1.7.10] Crash on LivingUpdateEvent


shultzy

Recommended Posts

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);
	}
    }

}
    }
}

Link to comment
Share on other sites

  • 4 weeks later...

And don't use the DataWatcher on entity's that are not yours. it is bad practice and has a high risk of incompatibility.

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")));
    }

Link to comment
Share on other sites

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.

Guest
Unfortunately, your content contains terms that we do not allow. Please edit your content to remove the highlighted words below.
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Announcements



×
×
  • Create New...

Important Information

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