jabelar Posted March 30, 2014 Posted March 30, 2014 (Using Forge 1047) Okay, I'm doing something that should be simple but have gotten confused. I am creating a tiger entity which is essentially a re-textured wolf at the moment (I plan to more drastically mod the behavior later but for now it is pretty much just an orange striped wolf). This works great -- nothing wrong with tiger entity. Next I wanted to extend the tiger class to create special case of a "man-eating" tiger that basically is always hostile and cannot be tamed. The problem is that the AI task list is set up in the superclass EntityTiger but I want to override some of the AI. I'm getting stuck because my constructor for EntityManEatingTiger would add additional AI tasks but would still have the superclass tasks (I think). There is a removeTask method but it seems to reference an instance of the AI class which isn't really available at the sub-class (I suppose I could store instances in variables and pass them, but seems clumsy). So basically my main issue is I want to remove a specific AI task from the superclass's AI task list during the subclass constructor. Here is constructor of EntityTiger: Reveal hidden contents public EntityTiger(World par1World) { super(par1World); this.setSize(0.6F, 0.8F); this.getNavigator().setAvoidsWater(true); this.tasks.addTask(1, new EntityAISwimming(this)); this.tasks.addTask(2, this.aiSit); this.tasks.addTask(3, new EntityAILeapAtTarget(this, 0.4F)); this.tasks.addTask(4, new EntityAIAttackOnCollide(this, 1.0D, true)); this.tasks.addTask(5, new EntityAIFollowOwner(this, 1.0D, 10.0F, 2.0F)); this.tasks.addTask(6, new EntityAIMate(this, 1.0D)); this.tasks.addTask(7, new EntityAIWander(this, 1.0D)); this.tasks.addTask(8, new EntityAIBegTiger(this, 8.0F)); // in vanilla begging is only for wolf this.tasks.addTask(9, new EntityAIWatchClosest(this, EntityPlayer.class, 8.0F)); this.tasks.addTask(10, new EntityAILookIdle(this)); this.targetTasks.addTask(1, new EntityAIOwnerHurtByTarget(this)); this.targetTasks.addTask(2, new EntityAIOwnerHurtTarget(this)); this.targetTasks.addTask(3, new EntityAIHurtByTarget(this, true)); this.targetTasks.addTask(4, new EntityAITargetNonTamed(this, EntitySheep.class, 200, false)); this.setTamed(false); } And suppose I want to remove the begging task in the subclass EntityManEatingTiger (which extends EntityTiger) constructor: Reveal hidden contents public EntityManEatingTiger(World par1World) { super(par1World); this.tasks.removeTask(new EntityAIBegTiger(this, 8.0F)); // I know this is wrong, just giving idea of what I want to do this.setTamed(false); // make him a man-eater by starting angry this.setAngry(true); // make him hunt the player super.setAttackTarget(Minecraft.getMinecraft().thePlayer); } I know the removeTask must be wrong because it is referencing a new instance of the EntityAIBegTiger rather than whatever instance was added in superclass constructor. Is the only solution to record the instance in the superclass and reference it here? Or is there some better way to organize the AI task list generation? Maybe create some other method or even superclass constructor to call? Quote Check out my tutorials here: http://jabelarminecraft.blogspot.com/
sequituri Posted March 30, 2014 Posted March 30, 2014 EntityLiving#tasks.removeTask(EntityAIBase base) does indeed use == for the comparison when seeking the object to remove and new Object() is always a different instance, so you probably won't find it as easy as you noted. But, EntityAnimal and EntityTameable (as well as EntityAgeable) do not suffer from preassigned tasks, so you could override EntityAnimal and assign your own AI tasks. Others may know more or do it differently, so don't take this a gospel. Just trying to help. Quote -S- (if I helped, please click Thank and applaud) http://6upnqa.dm2301.livefilestore.com/y2mtf-vG7Tqq1TiiVpIm53KWj7294NDPoHfSHHb4PzZiMAUfRCfK0UY0MwOu7Q3zTBNVTKqWjr2-xgBfFRpQT5p-QivtvknPpoABMNUw9br9WuZcBFkjePhnAbW500gVm-P/sequiturian.png[/img]
coolAlias Posted March 30, 2014 Posted March 30, 2014 Like sequituri said, you will not be able to remove it due to the '==' operator; however, what you can do is cheat and keep a local instance of the AI in your class, like EntityTameable does with the AI for sitting. This way, you have access to the memory location and '==' will be able to return true. protected EntityAISit aiSit = new EntityAISit(this); // you can now use tasks.remove(aiSit) and it should work Another option is to use List#clear() to remove all AI tasks, and simply add the ones back that you want. Quote http://i.imgur.com/NdrFdld.png[/img]
jabelar Posted March 30, 2014 Author Posted March 30, 2014 On 3/30/2014 at 2:31 AM, coolAlias said: Like sequituri said, you will not be able to remove it due to the '==' operator; however, what you can do is cheat and keep a local instance of the AI in your class, like EntityTameable does with the AI for sitting. This way, you have access to the memory location and '==' will be able to return true. protected EntityAISit aiSit = new EntityAISit(this); // you can now use tasks.remove(aiSit) and it should work Another option is to use List#clear() to remove all AI tasks, and simply add the ones back that you want. Thanks. Yeah, the first idea is pretty much what I expected when I asked "Is the only solution to record the instance in the superclass and reference it here?". But I like the second idea better gives me more specific control especially since I plan to override much of the behavior (can't have a man-eating tiger act like a regular tiger after all...) Quote Check out my tutorials here: http://jabelarminecraft.blogspot.com/
Recommended Posts
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.