• 0

    posted a message on [1.7.2] /summon command and custom entities
    I used to register my entities using the registerGlobalID() method, and it was possible to use the /summon command to properly spawn them.

    However, after a lot of discussion with some people I trust to know better I have switched to the registerModEntityID() method, but I can't seem to use the vanilla /summon command for my custom entities.

    I was able to create my own command (/conjure) which could basically do the thing for my custom entities. I also could probably figure out how to intercept the /summon command.

    But I'm simply wondering if the /summon command can be used as-is with the custom entities. Like maybe I need to reference the entity differently, maybe "modid.entity_name" or something?

    I don't mind creating my own commands, but I prefer to hook into vanilla whenever possible.
    Posted in: Modification Development
  • 0

    posted a message on [1.7.2]Spawning my entity on top of another one crashes game
    It seems to me that it has to either do with the interact() method (since technically I'm right-clicking on an entity), in particular in the case where I right-click with a spawn egg in hand.

    But in any case, since the discussion also got me thinking about proper way to register entities I'm sort of starting grounds up again with changing the way I register entities (changing to only use modEntityID) and using my own custom spawn eggs. I have both of those working so far.

    So didn't really solve the problem, but figure at some point I'll figure it out.
    Posted in: Modification Development
  • 1

    posted a message on [1.7.2]Proper way to register entities (conflicting tutorials)
    Okay, I'm getting confused between the use of the EntityRegistry.registerGlobalEntityID() and the EntityRegistry.registerModEntity() methods for entity registration because I looked at four tutorials that give conflicting advice:A tutorial here (http://www.minecraftforge.net/wiki/How_to_register_a_mob_entity#Registering_an_Entity) indicates to only use the registerGlobalEntityID(). It says:
    Put the following in your mod file's load() method:EntityRegistry.registerGlobalEntityID(MyEntity.class, "MyEntityName", myentityid)[/size]Where MyEntity is the name of your entity's class, "MyEntityName" is the name of the entity, and myentityid will be the number Minecraft uses to identify the mob. You can get a unique, unused entity id by calling EntityRegistry.findGlobalUniqueEntityId() instead of myentityid.
    A tutorial here (http://www.minecraftforum.net/topic/1417041-mod-entity-problem/page__st__140#entry18822284) says to only use registerModEntity(). It says:
    There is only one method for registering and adding tracking.EntityRegistry.registerModEntity(Class entityClass, String entityName, int id, Object mod, int trackingRange, int updateFrequency, boolean sendsVelocityUpdates) : void
    At tutorial here (http://www.minecraftforum.net/topic/2389683-172-forge-add-new-block-item-entity-ai-creative-tab-language-localization-block-textures-side-textures/) says to use both methods, but to use the same entityID for both. It says:
    EntityRegistry.registerGlobalEntityID(entityClass, name, entityID);EntityRegistry.registerModEntity(entityClass, name, entityID, instance, 64, 1, true);[/size]EntityList.entityEggs.put(Integer.valueOf(entityID), new EntityList.EntityEggInfo(entityID, primaryColor, secondaryColor));
    A message here (http://www.minecraftforum.net/topic/2564566-172spawning-my-entity-on-top-of-another-one-crashes-game/) indicates to use both methods, but use different ID in each:
    You also need to register your entity as a mod entity, using a mod-specific id. I do so using a static int modEntityIndex that I just iterate each time, and a custom helper method that I use for entities that have spawn eggs:public static void registerEntity(Class entityClass, String name, int primaryColor, int secondaryColor) { int id = EntityRegistry.findGlobalUniqueEntityId(); EntityRegistry.registerGlobalEntityID(entityClass, name, id, primaryColor, secondaryColor); EntityRegistry.registerModEntity(entityClass, name, ++modEntityIndex, ZSSMain.instance, 80, 3, false); }
    So which way is correct? The weird thing is they all kinda work -- I tried all three and can spawn the entities -- but I assume there is some invisible bad stuff going on if you do it the wrong way.
    Posted in: Modification Development
  • 0

    posted a message on [1.7.2]Spawning my entity on top of another one crashes game
    Actually, this post about a similar problem is interesting: http://www.minecraftforum.net/topic/1417041-mod-entity-problem/page__st__140#entry18822284

    It basically it is saying that the global id list is limited to 255 and if you read up in the thread you'll see that this is caused by some (byte) casting type behavior in the packets.

    It actually says that you should ONLY register using the mod registry (and also manually register your own spawn eggs).

    In any case, I have tried all three combinations of -- registering with only globalID, registering with both globalID and modEntityIndex, and also only modEntityIndex (plus manually added spawn egg) -- and ALL of these continue to have the same problem -- exactly the same crash where trying to spawn on top of another causes the crash with warning about skipping entity with ID 0.

    I'm beginning to think it is not a registration problem (although now I need to rethink registration to ensure I am doing it properly), but either an issue with interaction with existing entity or an issue with two entities trying to occupy the same space (maybe some sort of collision or obstacle resolution code having trouble?)
    Posted in: Modification Development
  • 0

    posted a message on [1.7.2]Spawning my entity on top of another one crashes game
    Quote from coolAlias

    You also need to register your entity as a mod entity, using a mod-specific id. I do so using a static int modEntityIndex that I just iterate each time, and a custom helper method that I use for entities that have spawn eggs:
    public static void registerEntity(Class entityClass, String name, int primaryColor, int secondaryColor) {
    int id = EntityRegistry.findGlobalUniqueEntityId();
    EntityRegistry.registerGlobalEntityID(entityClass, name, id, primaryColor, secondaryColor);
    EntityRegistry.registerModEntity(entityClass, name, ++modEntityIndex, ZSSMain.instance, 80, 3, false);
    }



    Hmm, this is example of how I usually get tripped up -- I was following some tutorial that didn't have the registerModEntity and furthermore the mod kinda works without it.

    Did you mean for the modEnityIndex to be its own index different than id from global ID? Any reason not to use same id as the global one? Maybe because you want to iterate through them at some point? Anyway, my registration method looks like this now:
        public void registerEntities()
        {
            modEntityIndex = -1 ; // since increment on first use to start at zero
    
         // Big cats
         EntityRegistry.registerGlobalEntityID(EntityTiger.class, "tiger", EntityRegistry.findGlobalUniqueEntityId(), 0xFF9933, 0x000000);     
            EntityRegistry.registerModEntity(EntityTiger.class, "tiger", ++modEntityIndex, WildAnimals.instance, 80, 3, false);
    
            EntityRegistry.registerGlobalEntityID(EntityManEatingTiger.class, "maneatingtiger", EntityRegistry.findGlobalUniqueEntityId());
            EntityRegistry.registerModEntity(EntityManEatingTiger.class, "maneatingtiger", ++modEntityIndex, WildAnimals.instance, 80, 3, false);
    
            EntityRegistry.registerGlobalEntityID(EntityLion.class, "lion", EntityRegistry.findGlobalUniqueEntityId(), 0xE3D8B6, 0x000000);     
            EntityRegistry.registerModEntity(EntityLion.class, "lion", ++modEntityIndex, WildAnimals.instance, 80, 3, false);
    
            EntityRegistry.registerGlobalEntityID(EntityLynx.class, "lynx", EntityRegistry.findGlobalUniqueEntityId(), 0xE3D8B6, 0xFFFFFF);     
            EntityRegistry.registerModEntity(EntityLynx.class, "lynx", ++modEntityIndex, WildAnimals.instance, 80, 3, false);
    
            EntityRegistry.registerGlobalEntityID(EntityJaguar.class, "jaguar", EntityRegistry.findGlobalUniqueEntityId(), 0x000000, 0x000000);     
            EntityRegistry.registerModEntity(EntityJaguar.class, "jaguar", ++modEntityIndex, WildAnimals.instance, 80, 3, false);
         // Herd animals
         EntityRegistry.registerGlobalEntityID(EntityElephant.class, "elephant", EntityRegistry.findGlobalUniqueEntityId(), 0xBDBDBD, 0xD1D1D1);     
            EntityRegistry.registerModEntity(EntityElephant.class, "elephant", ++modEntityIndex, WildAnimals.instance, 80, 3, false);
    
        }


    But it still has the same message"[Client thread/WARN]: Skipping Entity with id 0 "

    Is caused (I'm pretty sure) because you didn't register your entity with the registerModEntity method. That's the method that tells the client side which class of entity to spawn, among other tracking related things.


    The weird thing is that the mod worked pretty decently without that registration. I mean the entities appeared, they each behaved as individuals, if you saved a game and reloaded they were still there. So I'm not quite sure what this registry is really doing.

    But I still must be doing something wrong with registration. Did my code above implement what you suggested?


    On a side note, if you want to clear the AI, you can do so simply by invoking "clear()" on the task list:
    tasks.taskEntries.clear();

    Same for target tasks. :P


    Thanks yeah. I had originally been being selective with what was removed but then eventually it became a full clear.

    Anyway, it is still failing with same symptoms and error message.
    Posted in: Modification Development
  • 0

    posted a message on [1.7.2]Spawning my entity on top of another one crashes game
    (I'm using Forge version 1056)

    I have a custom EntityTiger (basically a wolf that has new texture) and registered with a spawn egg. This works generally, the tiger will spawn naturally and will also spawn with the egg if I just right-click once. However, if I hold down right-click (to spawn multiple entities) the game crashes with the following error:


    [17:40:28] [Client thread/WARN]: Skipping Entity with id 0
    [17:40:28] [Server thread/INFO]: Stopping server
    [17:40:28] [Server thread/INFO]: Saving players
    [17:40:28] [Server thread/INFO]: Saving worlds
    [17:40:28] [Server thread/INFO]: Saving chunks for level 'New World'/Overworld
    [17:40:28] [Server thread/INFO]: Saving chunks for level 'New World'/Nether
    [17:40:28] [Server thread/INFO]: Saving chunks for level 'New World'/The End
    [17:40:29] [Server thread/INFO] [FML]: Unloading dimension 0
    [17:40:29] [Server thread/INFO] [FML]: Unloading dimension -1
    [17:40:29] [Server thread/INFO] [FML]: Unloading dimension 1
    [17:40:29] [Client thread/FATAL]: Unreported exception thrown!
    java.lang.NullPointerException
    at net.minecraft.client.network.NetHandlerPlayClient.handleSpawnMob(NetHandlerPlayClient.java:853) ~[NetHandlerPlayClient.class:?]
    at net.minecraft.network.play.server.S0FPacketSpawnMob.processPacket(S0FPacketSpawnMob.java:129) ~[S0FPacketSpawnMob.class:?]
    at net.minecraft.network.play.server.S0FPacketSpawnMob.processPacket(S0FPacketSpawnMob.java:222) ~[S0FPacketSpawnMob.class:?]
    at net.minecraft.network.NetworkManager.processReceivedPackets(NetworkManager.java:232) ~[NetworkManager.class:?]
    at net.minecraft.client.multiplayer.PlayerControllerMP.updateController(PlayerControllerMP.java:321) ~[PlayerControllerMP.class:?]
    at net.minecraft.client.Minecraft.runTick(Minecraft.java:1647) ~[Minecraft.class:?]
    at net.minecraft.client.Minecraft.runGameLoop(Minecraft.java:994) ~[Minecraft.class:?]
    at net.minecraft.client.Minecraft.run(Minecraft.java:910) [Minecraft.class:?]
    at net.minecraft.client.main.Main.main(Main.java:112) [Main.class:?]
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[?:1.7.0_51]
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57) ~[?:1.7.0_51]
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[?:1.7.0_51]
    at java.lang.reflect.Method.invoke(Method.java:606) ~[?:1.7.0_51]
    at net.minecraft.launchwrapper.Launch.launch(Launch.java:134) [launchwrapper-1.9.jar:?]
    at net.minecraft.launchwrapper.Launch.main(Launch.java:28) [launchwrapper-1.9.jar:?]



    However, this also occurs if I try to spawn my tiger right on top of another tiger. I have other entities too that are behaving the same, even though they are extended from different classes. Vanilla entities spawn fine (on top of each other, with babies, etc.)

    Anyway, here is some of my code that might be relevant.

    Main class:

    package wildanimals;
    import wildanimals.proxy.CommonProxy;
    import cpw.mods.fml.common.Mod;
    import cpw.mods.fml.common.Mod.EventHandler;
    import cpw.mods.fml.common.SidedProxy;
    import cpw.mods.fml.common.event.FMLInitializationEvent;
    import cpw.mods.fml.common.event.FMLPostInitializationEvent;
    import cpw.mods.fml.common.event.FMLPreInitializationEvent;
    @Mod(modid = WildAnimals.MODID, name = WildAnimals.MODNAME, version = WildAnimals.VERSION)
    public class WildAnimals
    {
    public static final String MODID = "wildanimals";
    public static final String MODNAME = "WildAnimals+";
    public static final String VERSION = "0.0.1";
    // create custom creativetab for mod items
    //public static CreativeTabs tabWildAnimalsPlus = new WildAnimalsCreativeTab("WildAnimals+");
    
    // instantiate blocks
    //public final static Block blockTomato = new BlockTomato();
    // instantiate items
    //public final static Item tomato = new ItemTomato();
    
    // Says where the client and server 'proxy' code is loaded.
    @SidedProxy(clientSide="wildanimals.proxy.client.ClientProxy", serverSide="wildanimals.proxy.server.ServerProxy")
    public static CommonProxy proxy;
    	
    @EventHandler
    // preInit "Run before anything else. Read your config, create blocks, items, etc, and register them with the GameRegistry."
    public void preInit(FMLPreInitializationEvent event)
    {
    	 // DEBUG
    	 System.out.println("preInit()");
    	 proxy.preInit();
    }
    @EventHandler
    // load "Do your mod setup. Build whatever data structures you care about. Register recipes."
    public void load(FMLInitializationEvent event)
    {
    	
    	 // DEBUG
    	 System.out.println("load()");
    	
    	 proxy.load();
    }
    @EventHandler
    // postInit "Handle interaction with other mods, complete your setup based on this."
    public void postInit(FMLPostInitializationEvent event)
    {
    	 // DEBUG
    	 System.out.println("postInit()");
    	
    	 proxy.postInit();
    }
    }



    Here is where I register the entities in my proxies.
    CommonProxy:

    package wildanimals.proxy;
    import net.minecraft.entity.EnumCreatureType;
    import net.minecraft.world.biome.BiomeGenBase;
    import net.minecraftforge.common.MinecraftForge;
    import wildanimals.WildAnimalsEventHandler;
    import wildanimals.WildAnimalsFMLEventHandler;
    import wildanimals.WildAnimalsOreGenEventHandler;
    import wildanimals.WildAnimalsTerrainGenEventHandler;
    import wildanimals.entities.bigcats.EntityJaguar;
    import wildanimals.entities.bigcats.EntityLion;
    import wildanimals.entities.bigcats.EntityLynx;
    import wildanimals.entities.bigcats.EntityManEatingTiger;
    import wildanimals.entities.bigcats.EntityTiger;
    import wildanimals.entities.herdanimals.EntityElephant;
    import cpw.mods.fml.common.FMLCommonHandler;
    import cpw.mods.fml.common.registry.EntityRegistry;
    
    public class CommonProxy
    {
    
    public void preInit()
    {
    	 registerBlocks();
    	 registerItems();
    	 registerTileEntities();
    	 registerRecipes();
    	 registerEntities();
    	 registerEntitySpawns();
    	 registerFuelHandlers();
    }
    
    public void load()
    {
    	 // register custom event listeners
    	 registerEventListeners();
    }
    
    public void postInit()
    {
    // can do some inter-mod stuff here
    }
    // register blocks
    public void registerBlocks()
    {
    //example: GameRegistry.registerBlock(blockTomato, "tomatoes");
    	 }
    
    // register items
    private void registerItems()
    {
    //example: GameRegistry.registerItem(tomato, "tomato");
    	
    	 // example: GameRegistry.registerCustomItemStack(name, itemStack);
    }
    
    // register tileentities
    public void registerTileEntities()
    {
    	 // example: GameRegistry.registerTileEntity(TileEntityStove.class, "stove_tile_entity");
    }
    // register recipes
    public void registerRecipes()
    {
    // examples:
    	 //	 GameRegistry.addRecipe(recipe);
    //	 GameRegistry.addShapedRecipe(output, params);
    //	 GameRegistry.addShapelessRecipe(output, params);
    //	 GameRegistry.addSmelting(input, output, xp);
    }
    // register entities
    // more info at http://www.minecraftforge.net/wiki/How_to_register_a_mob_entity#Registering_an_Entity
    // EntityRegistry.registerGlobalEntityID(MyEntity.class, "MyEntityName", myentityid, backgroundcolor, spotcolor)
    // You can leave out the two colors if you don't want any spawn egg
    public void registerEntities()
    {
    	 // Big cats
    	 EntityRegistry.registerGlobalEntityID(EntityTiger.class, "tiger", EntityRegistry.findGlobalUniqueEntityId(), 0xFF9933, 0x000000);	
    	 EntityRegistry.registerGlobalEntityID(EntityManEatingTiger.class, "maneatingtiger", EntityRegistry.findGlobalUniqueEntityId());
    	 EntityRegistry.registerGlobalEntityID(EntityLion.class, "lion", EntityRegistry.findGlobalUniqueEntityId(), 0xE3D8B6, 0x000000);	
    	 EntityRegistry.registerGlobalEntityID(EntityLynx.class, "lynx", EntityRegistry.findGlobalUniqueEntityId(), 0xE3D8B6, 0xFFFFFF);	
    	 EntityRegistry.registerGlobalEntityID(EntityJaguar.class, "jaguar", EntityRegistry.findGlobalUniqueEntityId(), 0x000000, 0x000000);	
    	 // Herd animals
    	 EntityRegistry.registerGlobalEntityID(EntityElephant.class, "elephant", EntityRegistry.findGlobalUniqueEntityId(), 0xBDBDBD, 0xD1D1D1);	
    	
    }
    
    public void registerEntitySpawns()
    {
    	 // register natural spawns for entities
    	 // EntityRegistry.addSpawn(MyEntity.class, spawnProbability, minSpawn, maxSpawn, enumCreatureType, [spawnBiome]);
    	 // See the constructor in BiomeGenBase.java to see the rarity of vanilla mobs; Sheep are probability 10 while Endermen are probability 1
    	 // minSpawn and maxSpawn are about how groups of the entity spawn
    	 // enumCreatureType represents the "rules" Minecraft uses to determine spawning, based on creature type. By default, you have three choices:
    	 // EnumCreatureType.creature uses rules for animals: spawn everywhere it is light out.
    	 // EnumCreatureType.monster uses rules for monsters: spawn everywhere it is dark out.
    	 // EnumCreatureType.waterCreature uses rules for water creatures: spawn only in water.
    	 // [spawnBiome] is an optional parameter of type BiomeGenBase that limits the creature spawn to a single biome type. Without this parameter, it will spawn everywhere.
    	 // Big cats
    	 // savanna cats
    	 EntityRegistry.addSpawn(EntityLion.class, 6, 0, 5, EnumCreatureType.creature, BiomeGenBase.savanna); //change the values to vary the spawn rarity, biome, etc.			
    	 EntityRegistry.addSpawn(EntityLion.class, 6, 0, 5, EnumCreatureType.creature, BiomeGenBase.savannaPlateau); //change the values to vary the spawn rarity, biome, etc.			
    	 // hill cats
    	 EntityRegistry.addSpawn(EntityLynx.class, 5, 0, 1, EnumCreatureType.creature, BiomeGenBase.birchForestHills); //change the values to vary the spawn rarity, biome, etc.			
    	 EntityRegistry.addSpawn(EntityLynx.class, 5, 0, 1, EnumCreatureType.creature, BiomeGenBase.coldTaigaHills); //change the values to vary the spawn rarity, biome, etc.			
    	 EntityRegistry.addSpawn(EntityLynx.class, 5, 0, 1, EnumCreatureType.creature, BiomeGenBase.desertHills); //change the values to vary the spawn rarity, biome, etc.			
    	 EntityRegistry.addSpawn(EntityLynx.class, 5, 0, 1, EnumCreatureType.creature, BiomeGenBase.extremeHills); //change the values to vary the spawn rarity, biome, etc.			
    	 EntityRegistry.addSpawn(EntityLynx.class, 5, 0, 1, EnumCreatureType.creature, BiomeGenBase.extremeHillsEdge); //change the values to vary the spawn rarity, biome, etc.			
    	 EntityRegistry.addSpawn(EntityLynx.class, 5, 0, 1, EnumCreatureType.creature, BiomeGenBase.extremeHillsPlus); //change the values to vary the spawn rarity, biome, etc.			
    	 EntityRegistry.addSpawn(EntityLynx.class, 5, 0, 1, EnumCreatureType.creature, BiomeGenBase.forestHills); //change the values to vary the spawn rarity, biome, etc.			
    	 EntityRegistry.addSpawn(EntityLynx.class, 5, 0, 1, EnumCreatureType.creature, BiomeGenBase.iceMountains); //change the values to vary the spawn rarity, biome, etc.			
    	 EntityRegistry.addSpawn(EntityLynx.class, 5, 0, 1, EnumCreatureType.creature, BiomeGenBase.megaTaigaHills); //change the values to vary the spawn rarity, biome, etc.			
    	 EntityRegistry.addSpawn(EntityLynx.class, 5, 0, 1, EnumCreatureType.creature, BiomeGenBase.mesaPlateau); //change the values to vary the spawn rarity, biome, etc.			
    	 EntityRegistry.addSpawn(EntityLynx.class, 5, 0, 1, EnumCreatureType.creature, BiomeGenBase.mesaPlateau_F); //change the values to vary the spawn rarity, biome, etc.			
    	 // swamp cats
    	 EntityRegistry.addSpawn(EntityLynx.class, 5, 0, 1, EnumCreatureType.creature, BiomeGenBase.swampland); //change the values to vary the spawn rarity, biome, etc.				
    	 // jungle cats
    	 EntityRegistry.addSpawn(EntityJaguar.class, 6, 0, 1, EnumCreatureType.creature, BiomeGenBase.jungle); //change the values to vary the spawn rarity, biome, etc.			
    	 EntityRegistry.addSpawn(EntityJaguar.class, 3, 0, 1, EnumCreatureType.creature, BiomeGenBase.jungleHills); //change the values to vary the spawn rarity, biome, etc.			
    	 EntityRegistry.addSpawn(EntityJaguar.class, 1, 0, 1, EnumCreatureType.creature, BiomeGenBase.jungleEdge); //change the values to vary the spawn rarity, biome, etc.			
    	 // Jaden didn't want tigers! EntityRegistry.addSpawn(EntityTiger.class, 1, 0, 1, EnumCreatureType.creature, BiomeGenBase.jungle); //change the values to vary the spawn rarity, biome, etc.			
    	 EntityRegistry.addSpawn(EntityManEatingTiger.class, 1, 0, 1, EnumCreatureType.creature, BiomeGenBase.jungle); //change the values to vary the spawn rarity, biome, etc.
    	 // Herd animals
    	 // savanna herds
    	 EntityRegistry.addSpawn(EntityElephant.class, 10, 0, 1, EnumCreatureType.creature, BiomeGenBase.savanna); //change the values to vary the spawn rarity, biome, etc.			
    	 EntityRegistry.addSpawn(EntityElephant.class, 10, 0, 1, EnumCreatureType.creature, BiomeGenBase.savannaPlateau); //change the values to vary the spawn rarity, biome, etc.			
    }
    
    public void registerFuelHandlers()
    {
    	 // example: GameRegistry.registerFuelHandler(handler);
    }
    
    public void registerEventListeners()
    {
    	 MinecraftForge.EVENT_BUS.register(new WildAnimalsEventHandler());
    	 MinecraftForge.TERRAIN_GEN_BUS.register(new WildAnimalsTerrainGenEventHandler());;
    	 MinecraftForge.ORE_GEN_BUS.register(new WildAnimalsOreGenEventHandler());	
    	 // some events, especially tick, is handled on FML bus
    	 FMLCommonHandler.instance().bus().register(new WildAnimalsFMLEventHandler());
    }
    }



    ClientProxy:

    package wildanimals.proxy.client;
    import net.minecraft.util.ResourceLocation;
    import wildanimals.entities.bigcats.EntityJaguar;
    import wildanimals.entities.bigcats.EntityLion;
    import wildanimals.entities.bigcats.EntityLynx;
    import wildanimals.entities.bigcats.EntityManEatingTiger;
    import wildanimals.entities.bigcats.EntityTiger;
    import wildanimals.entities.herdanimals.EntityElephant;
    import wildanimals.models.ModelBigCat;
    import wildanimals.models.ModelElephant;
    import wildanimals.proxy.CommonProxy;
    import wildanimals.renderers.RenderBigCat;
    import wildanimals.renderers.RenderHerdAnimal;
    import cpw.mods.fml.client.registry.RenderingRegistry;
    public class ClientProxy extends CommonProxy
    {
    @Override
    public void preInit()
    {
    // DEBUG
    	 System.out.println("on Client side");
    	
    // do common stuff
    super.preInit();
    	 // do client-specific stuff
    	 registerRenderers();
    }
    @Override
    public void load()
    {
    // DEBUG
    	 System.out.println("on Client side");
    	 // do common stuff
    super.load();
    // do client-specific stuff
    }
    
    @Override
    public void postInit()
    {
    // DEBUG
    	 System.out.println("on Client side");
    	 // do common stuff
    super.postInit();
    // do client-specific stuff
    }
    public void registerRenderers()
    {
    	
    	 // Big cats
    	 RenderingRegistry.registerEntityRenderingHandler(EntityTiger.class, new RenderBigCat(new ModelBigCat(), new ModelBigCat(),
    	 0.5F,
    	 new ResourceLocation("wildanimals:textures/entity/tiger/tiger.png"),
    	 new ResourceLocation("wildanimals:textures/entity/tiger/tiger_tamed.png"),
    	 new ResourceLocation("wildanimals:textures/entity/tiger/tiger_angry.png"),
    	 new ResourceLocation("wildanimals:textures/entity/tiger/tiger_collar.png"))); // not sure about second model
    	 RenderingRegistry.registerEntityRenderingHandler(EntityManEatingTiger.class, new RenderBigCat(new ModelBigCat(), new ModelBigCat(),
    	 0.5F,
    	 new ResourceLocation("wildanimals:textures/entity/tiger/tiger.png"),
    	 new ResourceLocation("wildanimals:textures/entity/tiger/tiger_tamed.png"),
    	 new ResourceLocation("wildanimals:textures/entity/tiger/tiger_angry.png"),
    	 new ResourceLocation("wildanimals:textures/entity/tiger/tiger_collar.png"))); // not sure about second model
    	 RenderingRegistry.registerEntityRenderingHandler(EntityLion.class, new RenderBigCat(new ModelBigCat(), new ModelBigCat(),
    	 0.5F,
    	 new ResourceLocation("wildanimals:textures/entity/lion/lion.png"),
    	 new ResourceLocation("wildanimals:textures/entity/lion/lion_tamed.png"),
    	 new ResourceLocation("wildanimals:textures/entity/lion/lion_angry.png"),
    	 new ResourceLocation("wildanimals:textures/entity/tiger/tiger_collar.png"))); // not sure about second model
    	 RenderingRegistry.registerEntityRenderingHandler(EntityLynx.class, new RenderBigCat(new ModelBigCat(), new ModelBigCat(),
    	 0.5F,
    	 new ResourceLocation("wildanimals:textures/entity/lion/lion.png"),
    	 new ResourceLocation("wildanimals:textures/entity/lion/lion_tamed.png"),
    	 new ResourceLocation("wildanimals:textures/entity/lion/lion_angry.png"),
    	 new ResourceLocation("wildanimals:textures/entity/tiger/tiger_collar.png"))); // not sure about second model
    	 RenderingRegistry.registerEntityRenderingHandler(EntityJaguar.class, new RenderBigCat(new ModelBigCat(), new ModelBigCat(),
    	 0.5F,
    	 new ResourceLocation("wildanimals:textures/entity/panther/panther.png"),
    	 new ResourceLocation("wildanimals:textures/entity/panther/panther_tamed.png"),
    	 new ResourceLocation("wildanimals:textures/entity/panther/panther_angry.png"),
    	 new ResourceLocation("wildanimals:textures/entity/tiger/tiger_collar.png"))); // not sure about second model
    	
    	 // Herd animals
    	 RenderingRegistry.registerEntityRenderingHandler(EntityElephant.class, new RenderHerdAnimal(new ModelElephant(), 0.5F));
    	
    }
    }



    The superclass for the entity:


    package wildanimals.entities.bigcats;
    import net.minecraft.block.Block;
    import net.minecraft.block.BlockColored;
    import net.minecraft.entity.Entity;
    import net.minecraft.entity.EntityAgeable;
    import net.minecraft.entity.EntityLivingBase;
    import net.minecraft.entity.SharedMonsterAttributes;
    import net.minecraft.entity.ai.EntityAIAttackOnCollide;
    import net.minecraft.entity.ai.EntityAIBase;
    import net.minecraft.entity.ai.EntityAIFollowOwner;
    import net.minecraft.entity.ai.EntityAIHurtByTarget;
    import net.minecraft.entity.ai.EntityAILeapAtTarget;
    import net.minecraft.entity.ai.EntityAILookIdle;
    import net.minecraft.entity.ai.EntityAIMate;
    import net.minecraft.entity.ai.EntityAIOwnerHurtByTarget;
    import net.minecraft.entity.ai.EntityAIOwnerHurtTarget;
    import net.minecraft.entity.ai.EntityAISwimming;
    import net.minecraft.entity.ai.EntityAITargetNonTamed;
    import net.minecraft.entity.ai.EntityAIWander;
    import net.minecraft.entity.ai.EntityAIWatchClosest;
    import net.minecraft.entity.monster.EntityCreeper;
    import net.minecraft.entity.monster.EntityGhast;
    import net.minecraft.entity.passive.EntityAnimal;
    import net.minecraft.entity.passive.EntityHorse;
    import net.minecraft.entity.passive.EntityTameable;
    import net.minecraft.entity.player.EntityPlayer;
    import net.minecraft.entity.projectile.EntityArrow;
    import net.minecraft.init.Items;
    import net.minecraft.item.Item;
    import net.minecraft.item.ItemFood;
    import net.minecraft.item.ItemStack;
    import net.minecraft.nbt.NBTTagCompound;
    import net.minecraft.pathfinding.PathEntity;
    import net.minecraft.util.DamageSource;
    import net.minecraft.util.MathHelper;
    import net.minecraft.world.World;
    import wildanimals.entities.ai.EntityAIBegBigCat;
    import cpw.mods.fml.relauncher.Side;
    import cpw.mods.fml.relauncher.SideOnly;
    public class EntityBigCat extends EntityTameable
    {
    protected float field_70926_e;
    protected float field_70924_f;
    /**
    	 * true if the bigCat is wet else false
    	 */
    protected boolean isShaking;
    protected boolean field_70928_h;
    /**
    	 * This time increases while bigCat is shaking and emitting water particles.
    	 */
    protected float timeBigCatIsShaking;
    protected float prevTimeBigCatIsShaking;
    // protected static final String __OBFID = "CL_00001654";
    
    // good to have instances of AI so task list can be modified, including in sub-classes
    protected EntityAIBase aiSwimming = new EntityAISwimming(this);
    protected EntityAIBase aiLeapAtTarget = new EntityAILeapAtTarget(this, 0.4F);
    protected EntityAIBase aiAttackOnCollide = new EntityAIAttackOnCollide(this, 1.0D, true);
    protected EntityAIBase aiFollowOwner = new EntityAIFollowOwner(this, 1.0D, 10.0F, 2.0F);
    protected EntityAIBase aiMate = new EntityAIMate(this, 1.0D);
    protected EntityAIBase aiWander = new EntityAIWander(this, 1.0D);
    protected EntityAIBase aiBeg = new EntityAIBegBigCat(this, 8.0F); // in vanilla begging is only for wolf
    protected EntityAIBase aiWatchClosest = new EntityAIWatchClosest(this, EntityPlayer.class, 8.0F);
    protected EntityAIBase aiLookIdle = new EntityAILookIdle(this);
    protected EntityAIBase aiOwnerHurtByTarget = new EntityAIOwnerHurtByTarget(this);
    protected EntityAIBase aiOwnerHurtTarget = new EntityAIOwnerHurtTarget(this);
    protected EntityAIBase aiHurtByTarget = new EntityAIHurtByTarget(this, true);
    protected final EntityAIBase aiTargetNonTamedAnimal = new EntityAITargetNonTamed(this, EntityAnimal.class, 200, false);
    public EntityBigCat(World par1World)
    {
    	 super(par1World);
    	
    	 // DEBUG
    	 System.out.println("EntityBigCat constructor(), on Client="+par1World.isRemote);
    	 this.setSize(0.6F, 0.8F);
    	 this.getNavigator().setAvoidsWater(true);
    	 this.tasks.addTask(1, this.aiSwimming);
    	 this.tasks.addTask(2, this.aiSit);
    	 this.tasks.addTask(3, this.aiLeapAtTarget);
    	 this.tasks.addTask(4, this.aiAttackOnCollide);
    	 this.tasks.addTask(5, this.aiFollowOwner);
    	 this.tasks.addTask(6, this.aiMate);
    	 this.tasks.addTask(7, this.aiWander);
    	 this.tasks.addTask(8, this.aiBeg); // in vanilla begging is only for wolf
    	 this.tasks.addTask(9, this.aiWatchClosest);
    	 this.tasks.addTask(10, this.aiLookIdle);
    	 this.targetTasks.addTask(1, this.aiOwnerHurtByTarget);
    	 this.targetTasks.addTask(2, this.aiOwnerHurtTarget);
    	 this.targetTasks.addTask(3, this.aiHurtByTarget);
    	 this.targetTasks.addTask(4, this.aiTargetNonTamedAnimal);
    	 this.setTamed(false);
    }
    
    // use clear tasks for subclasses then build up their ai task list specifically
    protected void clearAITasks()
    {
    	 this.tasks.removeTask(this.aiSwimming);
    	 this.tasks.removeTask(this.aiSit);
    	 this.tasks.removeTask(this.aiLeapAtTarget);
    	 this.tasks.removeTask(this.aiAttackOnCollide);
    	 this.tasks.removeTask(this.aiFollowOwner);
    	 this.tasks.removeTask(this.aiMate);
    	 this.tasks.removeTask(this.aiWander);
    	 this.tasks.removeTask(this.aiBeg); // in vanilla begging is only for wolf
    	 this.tasks.removeTask(this.aiWatchClosest);
    	 this.tasks.removeTask(this.aiLookIdle);
    	 this.targetTasks.removeTask(this.aiOwnerHurtByTarget);
    	 this.targetTasks.removeTask(this.aiOwnerHurtTarget);
    	 this.targetTasks.removeTask(this.aiHurtByTarget);
    	 this.targetTasks.removeTask(this.aiTargetNonTamedAnimal);
    }
    @Override
    protected void applyEntityAttributes()
    {
    	 super.applyEntityAttributes();
    	 this.getEntityAttribute(SharedMonsterAttributes.movementSpeed).setBaseValue(0.30000001192092896D);
    	 if (this.isTamed())
    	 {
    		 this.getEntityAttribute(SharedMonsterAttributes.maxHealth).setBaseValue(20.0D);
    	 }
    	 else
    	 {
    		 this.getEntityAttribute(SharedMonsterAttributes.maxHealth).setBaseValue(8.0D);
    	 }
    }
    /**
    	 * Returns true if the newer Entity AI code should be run
    	 */
    @Override
    public boolean isAIEnabled()
    {
    	 return true;
    }
    /**
    	 * Sets the active target the Task system uses for tracking
    	 */
    @Override
    public void setAttackTarget(EntityLivingBase par1EntityLivingBase)
    {
    	 super.setAttackTarget(par1EntityLivingBase);
    	 if (par1EntityLivingBase == null)
    	 {
    		 this.setAngry(false);
    	 }
    	 else if (!this.isTamed())
    	 {
    		 this.setAngry(true);
    	 }
    }
    /**
    	 * main AI tick function, replaces updateEntityActionState
    	 */
    @Override
    protected void updateAITick()
    {
    	 this.dataWatcher.updateObject(18, Float.valueOf(this.getHealth()));
    }
    @Override
    protected void entityInit()
    {
    	 super.entityInit();
    	 this.dataWatcher.addObject(18, new Float(this.getHealth()));
    	 this.dataWatcher.addObject(19, new Byte((byte)0));
    	 this.dataWatcher.addObject(20, new Byte((byte)BlockColored.func_150032_b(1)));
    }
    @Override
    protected void func_145780_a(int p_145780_1_, int p_145780_2_, int p_145780_3_, Block p_145780_4_)
    {
    	 this.playSound("wildanimals:mob.bigCat.step", 0.15F, 1.0F); // this is randomized from 1 to 5
    }
    /**
    	 * (abstract) Protected helper method to write subclass entity data to NBT.
    	 */
    @Override
    public void writeEntityToNBT(NBTTagCompound par1NBTTagCompound)
    {
    	 super.writeEntityToNBT(par1NBTTagCompound);
    	 par1NBTTagCompound.setBoolean("Angry", this.isAngry());
    	 par1NBTTagCompound.setByte("CollarColor", (byte)this.getCollarColor());
    }
    /**
    	 * (abstract) Protected helper method to read subclass entity data from NBT.
    	 */
    @Override
    public void readEntityFromNBT(NBTTagCompound par1NBTTagCompound)
    {
    	 super.readEntityFromNBT(par1NBTTagCompound);
    	 this.setAngry(par1NBTTagCompound.getBoolean("Angry"));
    	 if (par1NBTTagCompound.hasKey("CollarColor", 99))
    	 {
    		 this.setCollarColor(par1NBTTagCompound.getByte("CollarColor"));
    	 }
    }
    /**
    	 * Returns the sound this mob makes while it's alive.
    	 */
    @Override
    protected String getLivingSound()
    {
    	 return this.isAngry() ? "wildanimals:mob.bigCat.growl" : (this.rand.nextInt(3) == 0 ? (this.isTamed() && this.dataWatcher.getWatchableObjectFloat(18) < 10.0F ? "wildanimals:mob.bigCat.whine" : "wildanimals:mob.bigCat.panting") : "wildanimals:mob.bigCat.bark");
    }
    /**
    	 * Returns the sound this mob makes when it is hurt.
    	 */
    @Override
    protected String getHurtSound()
    {
    	 return "wildanimals:mob.bigCat.hurt"; // It uses sounds.json file to randomize and adds 1, 2 or 3 and .ogg
    }
    /**
    	 * Returns the sound this mob makes on death.
    	 */
    @Override
    protected String getDeathSound()
    {
    	 return "wildanimals:mob.bigCat.death";
    }
    /**
    	 * Returns the volume for the sounds this mob makes.
    	 */
    @Override
    protected float getSoundVolume()
    {
    	 return 0.4F;
    }
    @Override
    protected Item getDropItem()
    {
    	 return Item.getItemById(-1);
    }
    /**
    	 * Called frequently so the entity can update its state every tick as required. For example, zombies and skeletons
    	 * use this to react to sunlight and start to burn.
    	 */
    @Override
    public void onLivingUpdate()
    {
    	 super.onLivingUpdate();
    	 if (!this.worldObj.isRemote && this.isShaking && !this.field_70928_h && !this.hasPath() && this.onGround)
    	 {
    		 this.field_70928_h = true;
    		 this.timeBigCatIsShaking = 0.0F;
    		 this.prevTimeBigCatIsShaking = 0.0F;
    		 this.worldObj.setEntityState(this, (byte)8);
    	 }
    }
    /**
    	 * Called to update the entity's position/logic.
    	 */
    @Override
    public void onUpdate()
    {
    	 super.onUpdate();
    	 this.field_70924_f = this.field_70926_e;
    	 if (this.func_70922_bv())
    	 {
    		 this.field_70926_e += (1.0F - this.field_70926_e) * 0.4F;
    	 }
    	 else
    	 {
    		 this.field_70926_e += (0.0F - this.field_70926_e) * 0.4F;
    	 }
    	 if (this.func_70922_bv())
    	 {
    		 this.numTicksToChaseTarget = 10;
    	 }
    	 if (this.isWet())
    	 {
    		 this.isShaking = true;
    		 this.field_70928_h = false;
    		 this.timeBigCatIsShaking = 0.0F;
    		 this.prevTimeBigCatIsShaking = 0.0F;
    	 }
    	 else if ((this.isShaking || this.field_70928_h) && this.field_70928_h)
    	 {
    		 if (this.timeBigCatIsShaking == 0.0F)
    		 {
    			 this.playSound("wildanimals:mob.bigCat.shake", this.getSoundVolume(), (this.rand.nextFloat() - this.rand.nextFloat()) * 0.2F + 1.0F);
    		 }
    		 this.prevTimeBigCatIsShaking = this.timeBigCatIsShaking;
    		 this.timeBigCatIsShaking += 0.05F;
    		 if (this.prevTimeBigCatIsShaking >= 2.0F)
    		 {
    			 this.isShaking = false;
    			 this.field_70928_h = false;
    			 this.prevTimeBigCatIsShaking = 0.0F;
    			 this.timeBigCatIsShaking = 0.0F;
    		 }
    		 if (this.timeBigCatIsShaking > 0.4F)
    		 {
    			 float f = (float)this.boundingBox.minY;
    			 int i = (int)(MathHelper.sin((this.timeBigCatIsShaking - 0.4F) * (float)Math.PI) * 7.0F);
    			 for (int j = 0; j < i; ++j)
    			 {
    				 float f1 = (this.rand.nextFloat() * 2.0F - 1.0F) * this.width * 0.5F;
    				 float f2 = (this.rand.nextFloat() * 2.0F - 1.0F) * this.width * 0.5F;
    				 this.worldObj.spawnParticle("splash", this.posX + f1, f + 0.8F, this.posZ + f2, this.motionX, this.motionY, this.motionZ);
    			 }
    		 }
    	 }
    }
    @SideOnly(Side.CLIENT)
    public boolean getBigCatShaking()
    {
    	 return this.isShaking;
    }
    /**
    	 * Used when calculating the amount of shading to apply while the bigCat is shaking.
    	 */
    @SideOnly(Side.CLIENT)
    public float getShadingWhileShaking(float par1)
    {
    	 return 0.75F + (this.prevTimeBigCatIsShaking + (this.timeBigCatIsShaking - this.prevTimeBigCatIsShaking) * par1) / 2.0F * 0.25F;
    }
    @SideOnly(Side.CLIENT)
    public float getShakeAngle(float par1, float par2)
    {
    	 float f2 = (this.prevTimeBigCatIsShaking + (this.timeBigCatIsShaking - this.prevTimeBigCatIsShaking) * par1 + par2) / 1.8F;
    	 if (f2 < 0.0F)
    	 {
    		 f2 = 0.0F;
    	 }
    	 else if (f2 > 1.0F)
    	 {
    		 f2 = 1.0F;
    	 }
    	 return MathHelper.sin(f2 * (float)Math.PI) * MathHelper.sin(f2 * (float)Math.PI * 11.0F) * 0.15F * (float)Math.PI;
    }
    @Override
    public float getEyeHeight()
    {
    	 return this.height * 0.8F;
    }
    @SideOnly(Side.CLIENT)
    public float getInterestedAngle(float par1)
    {
    	 return (this.field_70924_f + (this.field_70926_e - this.field_70924_f) * par1) * 0.15F * (float)Math.PI;
    }
    /**
    	 * The speed it takes to move the entityliving's rotationPitch through the faceEntity method. This is only currently
    	 * use in wolves.
    	 */
    @Override
    public int getVerticalFaceSpeed()
    {
    	 return this.isSitting() ? 20 : super.getVerticalFaceSpeed();
    }
    /**
    	 * Called when the entity is attacked.
    	 */
    @Override
    public boolean attackEntityFrom(DamageSource par1DamageSource, float par2)
    {
    	 if (this.isEntityInvulnerable())
    	 {
    		 return false;
    	 }
    	 else
    	 {
    		 Entity entity = par1DamageSource.getEntity();
    		 this.aiSit.setSitting(false);
    		 if (entity != null && !(entity instanceof EntityPlayer) && !(entity instanceof EntityArrow))
    		 {
    			 par2 = (par2 + 1.0F) / 2.0F;
    		 }
    		 return super.attackEntityFrom(par1DamageSource, par2);
    	 }
    }
    @Override
    public boolean attackEntityAsMob(Entity par1Entity)
    {
    	 int i = this.isTamed() ? 4 : 2;
    	 return par1Entity.attackEntityFrom(DamageSource.causeMobDamage(this), i);
    }
    @Override
    public void setTamed(boolean par1)
    {
    	 super.setTamed(par1);
    	 if (par1)
    	 {
    		 this.getEntityAttribute(SharedMonsterAttributes.maxHealth).setBaseValue(20.0D);
    	 }
    	 else
    	 {
    		 this.getEntityAttribute(SharedMonsterAttributes.maxHealth).setBaseValue(8.0D);
    	 }
    }
    /**
    	 * Called when a player interacts with a mob. e.g. gets milk from a cow, gets into the saddle on a pig.
    	 */
    @Override
    public boolean interact(EntityPlayer par1EntityPlayer)
    {
    	
    	 // DEBUG
    	 System.out.println("EntityBigCat interact()");
    
    	 ItemStack itemstack = par1EntityPlayer.inventory.getCurrentItem();
    	 if (this.isTamed())
    	 {
    		 if (itemstack != null)
    		 {
    			 if (itemstack.getItem() instanceof ItemFood)
    			 {
    				 ItemFood itemfood = (ItemFood)itemstack.getItem();
    				 if (itemfood.isWolfsFavoriteMeat() && this.dataWatcher.getWatchableObjectFloat(18) < 20.0F)
    				 {
    					 if (!par1EntityPlayer.capabilities.isCreativeMode)
    					 {
    						 --itemstack.stackSize;
    					 }
    					 this.heal(itemfood.func_150905_g(itemstack));
    					 if (itemstack.stackSize <= 0)
    					 {
    						 par1EntityPlayer.inventory.setInventorySlotContents(par1EntityPlayer.inventory.currentItem, (ItemStack)null);
    					 }
    					 return true;
    				 }
    			 }
    			 else if (itemstack.getItem() == Items.dye)
    			 {
    				 int i = BlockColored.func_150032_b(itemstack.getItemDamage());
    				 if (i != this.getCollarColor())
    				 {
    					 this.setCollarColor(i);
    					 if (!par1EntityPlayer.capabilities.isCreativeMode && --itemstack.stackSize <= 0)
    					 {
    						 par1EntityPlayer.inventory.setInventorySlotContents(par1EntityPlayer.inventory.currentItem, (ItemStack)null);
    					 }
    					 return true;
    				 }
    			 }
    		 }
    		 if (par1EntityPlayer.getCommandSenderName().equalsIgnoreCase(this.getOwnerName()) && !this.worldObj.isRemote && !this.isBreedingItem(itemstack))
    		 {
    			 this.aiSit.setSitting(!this.isSitting());
    			 this.isJumping = false;
    			 this.setPathToEntity((PathEntity)null);
    			 this.setTarget((Entity)null);
    			 this.setAttackTarget((EntityLivingBase)null);
    		 }
    	 }
    	 else if (itemstack != null && itemstack.getItem() == Items.bone && !this.isAngry())
    	 {
    		 if (!par1EntityPlayer.capabilities.isCreativeMode)
    		 {
    			 --itemstack.stackSize;
    		 }
    		 if (itemstack.stackSize <= 0)
    		 {
    			 par1EntityPlayer.inventory.setInventorySlotContents(par1EntityPlayer.inventory.currentItem, (ItemStack)null);
    		 }
    		 if (!this.worldObj.isRemote)
    		 {
    			 if (this.rand.nextInt(3) == 0)
    			 {
    				 this.setTamed(true);
    				 this.setPathToEntity((PathEntity)null);
    				 this.setAttackTarget((EntityLivingBase)null);
    				 this.aiSit.setSitting(true);
    				 this.setHealth(20.0F);
    				 this.setOwner(par1EntityPlayer.getCommandSenderName());
    				 this.playTameEffect(true);
    				 this.worldObj.setEntityState(this, (byte)7);
    			 }
    			 else
    			 {
    				 this.playTameEffect(false);
    				 this.worldObj.setEntityState(this, (byte)6);
    			 }
    		 }
    		 return true;
    	 }
    	 return super.interact(par1EntityPlayer);
    }
    @Override
    @SideOnly(Side.CLIENT)
    public void handleHealthUpdate(byte par1)
    {
    	 if (par1 == 8)
    	 {
    		 this.field_70928_h = true;
    		 this.timeBigCatIsShaking = 0.0F;
    		 this.prevTimeBigCatIsShaking = 0.0F;
    	 }
    	 else
    	 {
    		 super.handleHealthUpdate(par1);
    	 }
    }
    @SideOnly(Side.CLIENT)
    public float getTailRotation()
    {
    	 return this.isAngry() ? 1.5393804F : (this.isTamed() ? (0.55F - (20.0F - this.dataWatcher.getWatchableObjectFloat(18)) * 0.02F) * (float)Math.PI : ((float)Math.PI / 5F));
    }
    /**
    	 * Checks if the parameter is an item which this animal can be fed to breed it (wheat, carrots or seeds depending on
    	 * the animal type)
    	 */
    @Override
    public boolean isBreedingItem(ItemStack par1ItemStack)
    {
    	 return par1ItemStack == null ? false : (!(par1ItemStack.getItem() instanceof ItemFood) ? false : ((ItemFood)par1ItemStack.getItem()).isWolfsFavoriteMeat());
    }
    /**
    	 * Will return how many at most can spawn in a chunk at once.
    	 */
    @Override
    public int getMaxSpawnedInChunk()
    {
    	 return 8;
    }
    /**
    	 * Determines whether this bigCat is angry or not.
    	 */
    public boolean isAngry()
    {
    	 return (this.dataWatcher.getWatchableObjectByte(16) & 2) != 0;
    }
    /**
    	 * Sets whether this bigCat is angry or not.
    	 */
    public void setAngry(boolean par1)
    {
    	 byte b0 = this.dataWatcher.getWatchableObjectByte(16);
    	 if (par1)
    	 {
    		 this.dataWatcher.updateObject(16, Byte.valueOf((byte)(b0 | 2)));
    	 }
    	 else
    	 {
    		 this.dataWatcher.updateObject(16, Byte.valueOf((byte)(b0 & -3)));
    	 }
    }
    /**
    	 * Return this bigCat's collar color.
    	 */
    public int getCollarColor()
    {
    	 return this.dataWatcher.getWatchableObjectByte(20) & 15;
    }
    /**
    	 * Set this bigCat's collar color.
    	 */
    public void setCollarColor(int par1)
    {
    	 this.dataWatcher.updateObject(20, Byte.valueOf((byte)(par1 & 15)));
    }
    @Override
    public EntityBigCat createChild(EntityAgeable par1EntityAgeable)
    {
    	
    	 // DEBUG
    	 System.out.println("EntityBigCat createChild()");
    
    	 EntityBigCat entitybigCat = new EntityBigCat(this.worldObj);
    	 String s = this.getOwnerName();
    	 if (s != null && s.trim().length() > 0)
    	 {
    		 entitybigCat.setOwner(s);
    		 entitybigCat.setTamed(true);
    	 }
    	 return entitybigCat;
    }
    public void func_70918_i(boolean par1)
    {
    	 if (par1)
    	 {
    		 this.dataWatcher.updateObject(19, Byte.valueOf((byte)1));
    	 }
    	 else
    	 {
    		 this.dataWatcher.updateObject(19, Byte.valueOf((byte)0));
    	 }
    }
    /**
    	 * Returns true if the mob is currently able to mate with the specified mob.
    	 */
    @Override
    public boolean canMateWith(EntityAnimal par1EntityAnimal)
    {
    	 if (par1EntityAnimal == this)
    	 {
    		 return false;
    	 }
    	 else if (!this.isTamed())
    	 {
    		 return false;
    	 }
    	 else if (!(par1EntityAnimal instanceof EntityBigCat))
    	 {
    		 return false;
    	 }
    	 else
    	 {
    		 EntityBigCat entitybigCat = (EntityBigCat)par1EntityAnimal;
    		 return !entitybigCat.isTamed() ? false : (entitybigCat.isSitting() ? false : this.isInLove() && entitybigCat.isInLove());
    	 }
    }
    public boolean func_70922_bv()
    {
    	 return this.dataWatcher.getWatchableObjectByte(19) == 1;
    }
    /**
    	 * Determines if an entity can be despawned, used on idle far away entities
    	 */
    @Override
    protected boolean canDespawn()
    {
    	 return !this.isTamed() && this.ticksExisted > 2400;
    }
    @Override
    public boolean func_142018_a(EntityLivingBase par1EntityLivingBase, EntityLivingBase par2EntityLivingBase)
    {
    	 if (!(par1EntityLivingBase instanceof EntityCreeper) && !(par1EntityLivingBase instanceof EntityGhast))
    	 {
    		 if (par1EntityLivingBase instanceof EntityBigCat)
    		 {
    			 EntityBigCat entitybigCat = (EntityBigCat)par1EntityLivingBase;
    			 if (entitybigCat.isTamed() && entitybigCat.getOwner() == par2EntityLivingBase)
    			 {
    				 return false;
    			 }
    		 }
    		 return par1EntityLivingBase instanceof EntityPlayer && par2EntityLivingBase instanceof EntityPlayer && !((EntityPlayer)par2EntityLivingBase).canAttackPlayer((EntityPlayer)par1EntityLivingBase) ? false : !(par1EntityLivingBase instanceof EntityHorse) || !((EntityHorse)par1EntityLivingBase).isTame();
    	 }
    	 else
    	 {
    		 return false;
    	 }
    }
    }


    And the EntityTiger:

    package wildanimals.entities.bigcats;
    import net.minecraft.world.World;
    public class EntityTiger extends EntityBigCat
    {
    public EntityTiger(World par1World)
    {
    super(par1World);
    	
    // DEBUG
    	 System.out.println("EntityTiger constructor()");
    	
    }
    }


    Probably important note: based on the console message I've got in the code, that the crash happens after the constructor for the spawned entity is called on server side but before it is called on the Client side.
    Posted in: Modification Development
  • To post a comment, please .