Solved Making custom entity "Unpushable"

Discussion in 'Plugin Development' started by thepaperboy99, Jun 4, 2014.

Thread Status:
Not open for further replies.
  1. Offline

    thepaperboy99

    Hello Bukkit! I was just wondering how you would be able to stop players from pushing a custom entity. Is there a method that detects collision that I can override? Or should I just always set the entity to walk to the location? Any help is appreciated, Thanks!
     
  2. Offline

    Garris0n

    Is this implying that you're using NMS?
     
  3. Offline

    thepaperboy99


    Yes
     
  4. Offline

    Garris0n

    Look around for different things involving bounding boxes etc and try to figure out which it is. I don't currently have time to look for it or I would.
     
  5. Offline

    ResultStatic

    Garris0n thepaperboy99 i found this method in a npc api that detects when someone collides or touches the fake player. it overrides it and calls an EntityCollisionEvent. not sure if its in the Entity EntityLiving or EntityPlayer class but it calls the EnityPlayer that touched it. you could mess with it and try to cancel it. anyway u do it, it will be difficult. also if its in the Entity class or the EntityLiving class it will work for all zombies players skeletons etc.

    Code:
     @Override
        public void b_(EntityHuman entity) {
        if ((lastBounceId != entity.getId() || System.currentTimeMillis() - lastBounceTick > 1000)
            && entity.getBukkitEntity().getLocation().distanceSquared(getBukkitEntity().getLocation()) <= 1) {
          //this is when you collide with the entity. Basically EntityCollideEvent event = new EntityCollideEvent();
            lastBounceTick = System.currentTimeMillis();
            lastBounceId = entity.getId();
        }
     
        if (lastTargetId == -1 || lastTargetId != entity.getId()) {
            lastTargetId = entity.getId();
        }
        super.b_(entity);
        }
     
  6. Offline

    Garris0n

    ResultStatic That seems to be used for things like picking up items/experience. And also in the Slime's damage system for who knows what reason. But I don't think (not positive) that it's related to pushing entities around.
     
  7. Offline

    Ultimate_n00b

    Code:java
    1. boolean collides = true; // or false
    2.  
    3. Entity entity = ((CraftEntity)bukkitEntity).getHandle();
    4. entity.collidesWithEntities = collides
    5. entity.k = collides;


    Credit goes to md_5
    (if the collidesWithEntities field doesn't exist, try it on EntityPlayer. Couldn't locate it)
     
  8. Offline

    ResultStatic

    Garris0n thepaperboy99 i did some debug and its called while ur touching the entity. http://gyazo.com/88f705fb6b3bb80de6411e4a630433b0

    also im 1.7.9
    debug code
    Code:
     @Override
        public void b_(EntityHuman entity) {
        if ((lastBounceId != entity.getId() || System.currentTimeMillis() - lastBounceTick > 1000)
            && entity.getBukkitEntity().getLocation().distanceSquared(getBukkitEntity().getLocation()) <= 1) {
          Bukkit.broadcastMessage("b_" + " has been called");
            lastBounceTick = System.currentTimeMillis();
            lastBounceId = entity.getId();
        }
     
        if (lastTargetId == -1 || lastTargetId != entity.getId()) {
            lastTargetId = entity.getId();
        }
        super.b_(entity);
        }
     
  9. Offline

    SuppaTim

    If all above fails:

    This piece of code looks interesting to me:
    Code:java
    1. public void g(double d0, double d1, double d2) {
    2. this.motX += d0;
    3. this.motY += d1;
    4. this.motZ += d2;
    5. this.al = true;
    6. }
    7.  


    I changed it to:
    Code:java
    1. @Override
    2. public void g(double d0, double d1, double d2) {
    3. return;
    4. }
    5.  

    Result: Couldn't push my custom entities
     
  10. Offline

    Garris0n

    SuppaTim That's probably a generic 'setVelocity()' method, I'd assume you broke all velocities in the process.
     
  11. Offline

    ResultStatic

    Garris0n SuppaTim u could listen on b_() and cancel all velocity changes like his method
     
  12. Offline

    lenis0012

    Cancel g ( double, double, double)

    No g is push only

    EDIT by Moderator: merged posts, please use the edit button instead of double posting.
     
    Last edited by a moderator: Jun 30, 2016
  13. Offline

    SuppaTim

    Nope, as said above: g method is push only :)
     
  14. Offline

    Garris0n

    That's, uh...interesting. They made a whole method specifically to set the velocity after being pushed? Then again it's the MC source, that's not even close to the weirdest thing in there :p

    Thanks for the info you two :)
     
  15. Garris0n Maybe they had some idea of a cast that'd be useful in, who knows. Come to think of it, I should probably get round to properly looking at the source, I'm sure that there are plenty of things I'd learn. :p
     
  16. Offline

    fireblast709

    thepaperboy99 Garris0n SuppaTim ResultStatic Ultimate_n00b (did I tag everyone that suggested code?)
    Why not override public void collide(Entity e) from Entity... Sounds even better to me since you have full control over what is counted as collision, plus you know which Entity it collided with
     
  17. fireblast709 Chances are he just want to make his entity stay where he wants it, meaning the entity wouldn't be helpful. Makes me wonder why there are so many damn ways to prevent a simple mob collision, though!
     
  18. Offline

    zackpollard

    Ummm, what fireblast709 said could do that :p
     
  19. Offline

    fireblast709

    AdamQpzm override method, simply return ( or do nothing since its void)
     
  20. zackpollard fireblast709 Yes, but doing that means that the solution is no better or worse than the already proposed ones - merely an alternative, which was not the way it was suggested. :)
     
  21. Offline

    fireblast709

    AdamQpzm *coughs* my method gives you total control over the collision, not to mention that g is called by this. If you want zombies to push it, but not players, then the aforementioned solutions won't help (yes kinda out of scope, but still)
     
  22. fireblast709 Yes, but that was my point, your solution is only better under the assumption that you want total control. If you do not, it is not any better.
     
  23. Offline

    fireblast709

    AdamQpzm less code run would imply more efficient in this specific case.
     
  24. Offline

    lenis0012

    public void g was created because pushing does not necesarry have to be by an entity.
    and a collision doesn't allways result in a push.

    What if it collides with an errow or fireball?
     
  25. Offline

    fireblast709

  26. Offline

    lenis0012

    Like i said.
    It could eb that its not being pushed by an entity.
     
  27. fireblast709 Or just handle the push by overriding g... Which of those two options seems the better one? Thanks for clearing that up lenis0012 - now, in my opinion, collide and g both have times that they'll be better.
     
  28. Offline

    lenis0012

    If you cancel collide, no collision evewnts will be called for the entity.
    If you want all bukkit code the be executed properly but not actualy push the entity, overide g
     
    AdamQpzm likes this.
  29. Offline

    fireblast709

    Your events are lying, since there was no collision. Want code to execute? Execute it yourself, scrap all the unnecessary code, end up with code that does what you want while having an efficiency greater or equal to the original method.

    Since we are talking about a custom entity, where I will only assume the base class Entity, your code would execute:
    Code:java
    1. if (entity.passenger != this && entity.vehicle != this) {
    2. double d0 = entity.locX - this.locX;
    3. double d1 = entity.locZ - this.locZ;
    4. double d2 = MathHelper.a(d0, d1);
    5.  
    6. if (d2 >= 0.009999999776482582D) {
    7. d2 = (double) MathHelper.sqrt(d2);
    8. d0 /= d2;
    9. d1 /= d2;
    10. double d3 = 1.0D / d2;
    11.  
    12. if (d3 > 1.0D) {
    13. d3 = 1.0D;
    14. }
    15.  
    16. d0 *= d3;
    17. d1 *= d3;
    18. d0 *= 0.05000000074505806D;
    19. d1 *= 0.05000000074505806D;
    20. d0 *= (double) (1.0F - this.Y);
    21. d1 *= (double) (1.0F - this.Y);
    22. this.g(-d0, 0.0D, -d1);
    23. entity.g(d0, 0.0D, d1);
    24. }
    25. }
    While my code will execute:
    Code:java
    1. // Insert any optional code you like
    lenis0012 no Bukkit code found in this one. AdamQpzm Where is your efficiency? Now I will probably get the nag that I used the Entity class only. Well that is the exact specification, since there was no subclass specified, just any arbitrary Entity class.

    O I have to admit one thing. lenis0012 's case would only properly hold when overriding the EntityEnderdragon, the rest has events in front of them most likely cancelled (wooh more efficiency due to less code to execute). The only other use case for overriding g would be to create a dummy target entity that does not move at all but can be attacked and such.
     
  30. Offline

    lenis0012

    fireblast709 Very impressive statement there.
    I gues it depends on the situation then.
     
Thread Status:
Not open for further replies.

Share This Page