Pass variables onto PathFinderGoals on mob instantiation?

Discussion in 'Spigot Plugin Development' started by SirLich, Oct 24, 2017.

  1. Hey guys,
    I am having trouble passing information into pathFinderGoals on Mob instantiation. It appears that because I call super() in my constructor, that any other private variables I might want to set (so that I can pass them into the PathFinders) don't get set. This means that I end up passing a few zeroes into my pathfinder, instead of the asked for Params.

    Example using an RpgCow. This line here is a custom PathFinderGoal I wrote.
    Code (Text):

    this.goalSelector.a(2,new PathFinderGoalRpgMeleeAttack(this,2,damage,defaultKnockback));
     
    Code (Text):

    package me.sirlich.AsmodeusRpg.mobs.monsters;

    import me.sirlich.AsmodeusRpg.mobs.pathfinders.PathFinderGoalRpgMeleeAttack;
    import net.minecraft.server.v1_12_R1.*;
    import org.bukkit.craftbukkit.v1_12_R1.CraftServer;
    import org.bukkit.craftbukkit.v1_12_R1.entity.CraftCow;

    public class RpgCow extends EntityCow
    {
        private double damage;
        private double defaultKnockback;

        public RpgCow(World world, double damage, double defaultKnockback)
        {
            super(world);
            this.damage = damage;
            this.defaultKnockback = defaultKnockback;
            this.bukkitEntity = new CraftRpgCow(this.world.getServer(), this);

        }

        @Override
        protected void r()
        {
            this.goalSelector.a(0, new PathfinderGoalFloat(this));
            this.goalSelector.a(1, new PathfinderGoalTargetNearestPlayer(this));
            this.goalSelector.a(2,new PathFinderGoalRpgMeleeAttack(this,2,damage,defaultKnockback));
            this.goalSelector.a(5, new PathfinderGoalMoveTowardsRestriction(this, 1.0D));
            this.goalSelector.a(7, new PathfinderGoalRandomStrollLand(this, 1.0D));
            this.goalSelector.a(8, new PathfinderGoalLookAtPlayer(this, EntityHuman.class, 8.0F));
            this.goalSelector.a(8, new PathfinderGoalRandomLookaround(this));
        }

        private static class CraftRpgCow extends CraftCow
        {

            private CraftRpgCow(CraftServer server, EntityCow parent)
            {
                super(server, parent);
            }

        }
    }
    [/spoiler]
    Any thoughts on how I can workaround this issue and actually pass information into my PathFinders?? For example higher levels cows should deal more damage. I could handle this outside of the PathFinder (have the pathfinder just trigger the event but not actually handle the damage) but that is kind of akward in its own way.

    Help?
     
  2. Use Reflections? Or use a custom class extending/implementing that Pathfinder
     
  3. Hey Spigot!
    (Small necro I know)
    Its been a month and I am sinking back into my project.

    The above question is still kind of bugging me. If I had to go down the path of reflection, could I get some information on what that would look like?

    Cheers,
    ~Lich
     
  4. Which class PathFinderGoalRpgMeleeAttack extends?
    What fields are in zero?
     
  5. Make separate getter and setter methods for damage and knockback within RpgCow class, dont set them within the constructor. After you instantiate an RpgCow object, set the damage and knockback with <objectname>.setDamage(<value>) etc.

    Then in your MeleeAttack pathfinder when it goes to apply damage and knockback grab the values from the RpgCow object you pass to the pathfinder

    Also why are you setting .bukkitEntity? Pretty sure that's already handled by the superclass

    Also if you want the damage and knockback values you set to persist through a restart you will have to write and read the values to and from the entity's nbt
     
  6. "Then in your MeleeAttack pathfinder when it goes to apply damage and knockback grab the values from the RpgCow object you pass to the pathfinder"

    This sort of works.

    So lets say I am going to use this PathFinder on just one entity. For example. RpgCow. When I create the pathFinder, I would pass in an instance of RpgCow. Then I would call rpgCow.getDamage (or whatever other methods I create for whataver data I need [walking speed, locations, etc]). This works. I have tested this and its a viable method.

    The issue is that I would then need to create a new PathFinder for each mob I created (I could no longer reuse the code). For example lets say I make a new mob, RpgZombie. Now the MeleeAttack pathfinder is hard-coded to take a RpgCow (so I can call rpgCow.damage). The pathFinder no longer works on RpgZombies.

    Now how pathfinders NORMALLY work, is instead of passing in a specific mob (i.e. RpgCow) you pass in LivingEntity. This allows the method to work for ANY living entity (not just a specific one). The issue here is then I can't call any custom mob specific methods (like .damage) because I don't have a copy of the unique mobs.. I have a copy of EntityLiving.

    Any thoughts?

    One thing I am thinking of trying is make a new class called RpgMob which mobs can extend Entity and has all the random methods/data ANY mob in the game might need. All my mobs can then extend that mob.
     
  7. Make an interface called RpgMob or something with methods getDamage getKnockback etc. Then make your mobs implement that interface and in the pathfinder check if your mob is and instance of RpgMob and then call getDamage getKnockback etc.

    Think you can also do it by making RpgCow a superclass