Solved Spawn Snowball/Fireball with velocity!?

Discussion in 'Plugin Development' started by Ahmet094, Jan 22, 2013.

Thread Status:
Not open for further replies.
  1. I tried so many ways and have been trying to figure it out since hours...

    All I want to do is to get the nearby entities and make something like an auto-turret, which shoots snowballs e.g. every second.
    I let an entity (skeleton e.g.) spawn and let it launch projctiles with Snowball.class and set it's velocity to one of the players location.
    Velocity etc. is one of the only things I haven't worked with yet! haha


    Code:
          private void mg(final int x, final Location l) {
     
            final Entity skel = l.getWorld().spawnEntity(l, EntityType.SKELETON);
     
            this.getServer().getScheduler().scheduleSyncRepeatingTask(this, new Runnable() {
     
                @Override
                public void run() {
                    List<Entity> lEnt = skel.getNearbyEntities(10, 10, 10);
                    for (Entity ent : lEnt) {
                        if (ent instanceof Player) {
                            Player p = (Player) ent;
                            Entity snowball = skel.getWorld().spawnEntity(skel.getLocation().add(0, 2, 0), EntityType.SNOWBALL);
                            Vector v = p.getLocation().toVector();
                            snowball.setVelocity(v);
                        }
                    }
                }
            }, 1, 15);
        }
    Let's say that on location l as parameter is a cauldron, which looks like a turret if it's standing on a cauldron.
    I just used the skeleton as an entity in order to get the nearby entities.

    Thanks in advance for your help!
     
  2. skel.launchProjectile(Snowball.class);
    The only thing left is making the skeleton look at the player. In which case, get the vector from the skeleton and reverse the following calculation (from the Location class, getDirection()):
    Code:
    /**
     * Gets a Vector pointing in the direction that this Location is facing
     *
     * @return Vector
     */
    public Vector getDirection() 
    {
        Vector vector = new Vector();
     
        double rotX = this.getYaw();
        double rotY = this.getPitch();
     
        vector.setY(-Math.sin(Math.toRadians(rotY)));
     
        double h = Math.cos(Math.toRadians(rotY));
     
        vector.setX(-h * Math.sin(Math.toRadians(rotX)));
        vector.setZ(h * Math.cos(Math.toRadians(rotX)));
     
        return vector;
    }
     
  3. :0 i also tried to set the skeletons target to the player then get the player from it's line of sight and in the end it's direction to vectot.. but somehow it didn't work. Sorry, but that was a bit too complicated. Could you implement it in my code?
    I got your basic idea, but don't know how to realize it.

    I'm on my mobilephone, so sorry for any failures..

    Ed.: got it. On pc it looks totally different..
    Thanks! :)

    Still doesn't work.. Somehow I can't set the skeletons target. In the repeating task I let the yaw and pitch show, but they stay at 0.0...

    EDIT by Moderator: merged posts, please use the edit button instead of double posting.
     
    Last edited by a moderator: May 31, 2016
  4. how do you set the new yaw and pitch? You know you need to teleport them to the same coords with a different yaw and pitch ;D
     
  5. fireblast709
    Ah^^ I just use the skeleton there to make it launch a projectile, that it looks like the brewing stand is shooting it^
    And the setTarget is just to make it look to the player in order to make the launching snowball in this case make thrown to the right direction. I don't know if I missunderstood me or you just me^^
     
  6. if it looks like they are targeting the player, that is enough :3. The rest is getting the Vector from skeleton to Player and applying it as a velocity
     
  7. That still doesn't work..
    Seems like with setTarget() the skeleton doesn't turn right or left to the players direction, so the snowball gets shot always to the same direction.

    Code:
        private void mg(final int x, final Location l) {
     
            final Skeleton skel = (Skeleton) l.getWorld().spawnEntity(l.subtract(0, 1, 0), EntityType.SKELETON);
            this.getServer().getScheduler().scheduleSyncRepeatingTask(this, new Runnable() {
     
                @Override
                public void run() {
                    List<Entity> lEnt = skel.getNearbyEntities(10, 10, 10);
                    for (Entity ent : lEnt) {
                        if (ent instanceof Player) {
                            Player p = (Player) ent;
                            skel.setTarget(p);
                            Vector vc = skel.getLocation().getDirection();
                            Snowball sb = skel.launchProjectile(Snowball.class);
                            sb.setVelocity(vc);
                        }
                    }
                }
            }, 1, 15);
        }

    The snowball there is coming out of the cauldron, right where I spawned the skeleton and getting shooted always in the same direction. (Pitch = Yaw = 0).

    Ed.: Need to find out how to get the way between the skeleton and player as vector in order to set it as velocity to the snowball, but sadly I never worked with vectors before and don't know how..

    [​IMG]
     
  8. I only just learnt the existance of vectors and will be following this thread.

    I've made code up to now that shoots 99 additional arrows when you shoot and the blocks the arrows hit get removed. There's some vector issues with that that I need to fix.

    Tonight I'll be making skeletons shoot 99 additional arrows too :p
     
  9. Haha nice^^
    It's so bad that I can't find a solution but need it for my Team Deathmatch plugin and it should be sth really simple.
     
  10. I already made this ;-) And nope, it wasn't that simple.. Made me some headache.
    Check out the turrets of my paintball plugin. link
    Just install it, invite a friend, play a round paintball, put both of you into creative mode, and place a pumpkin on the ground, and see the magic happen :)

    Edit: Might even already be the kind of Team Deathmatch plugin you are looking for..

    Edit:
    To get the snowball shoot in the right direction (it will still not hit the target..), you will have to set the velocity to the directional vector from your turrets location to the targets location. You can get this vector by subtracting the location vectors of your target and the turret. And normalize it. As the length of the vector you set as velocity will define the strength of the momentum. (Or you could try to rotate your entity and get the direction.. like you are currently trying.. but this sounds as it makes problems..)

    After that, it will shoot in the right direction with a strength of 1. To hit the target, you could make the strength (the vector length) higher, or (for example if you are shoting with a fixed strength) calculate the right angle.
    You turret is like a tank. You can set the strength and the angle of the projectile. There will sometimes be multiple possibilities to hit your target, like you could chose a direct, low (fast) launch or a high (long-taking) one with higher angle (for example if you want to hit a target behind a wall..). For information on that, google for "ballistics".

    For the physical parameters if you want to calculate stuff, take a look here. link
    And as hint: Minecraft is a game, but there is still "air friction". You will have to use that inside your calculations ;-) So the basic formulas won't help you .. At least they didn't help me. This was the part which made me headache.
     
    Ahmet094 likes this.
  11. Thanks alot for your long answer and help!
    I already tried it with subtract(vector) yesterday and saw, that it's the right way, although the snowball got shot always in the opposite direction. So if for example I was standing left from the brewing stand and 2 blocks below, the snowball got shot on the right site and 2 blocks above my head.

    Today I did it like this and it worked! :)
    The code itself is really easy. It was just really hard to find out that it can be done that easy^^ :D took me at least 8h.

    Code:
    private void mg(final int x, final Location l) {
     
            final Bat bat = (Bat) l.getWorld().spawnEntity(l.add(1, 0, 0), EntityType.BAT);
     
            this.getServer().getScheduler().scheduleSyncRepeatingTask(this, new Runnable() {
     
                @Override
                public void run() {
                    List<Entity> lEnt = bat.getNearbyEntities(10, 10, 10);
                    for (Entity ent : lEnt) {
                        if (ent instanceof Player) {
                            Player p = (Player) ent;
     
                            int h = 1;
                            if (p.getLocation().distance(bat.getLocation()) >= 8) {
                                h = 2;
                            }
                            if (p.isFlying()) {
                                h = 1;
                            }
     
                            Vector v1 = l.toVector();
                            Vector v2 = p.getLocation().add(0, h, 0).toVector();
     
                            Vector st = v1.subtract(v2).normalize();
                            st.setX(st.getX() * -1);
                            st.setY(st.getY() * -1);
                            st.setZ(st.getZ() * -1);
     
                            Snowball sb = bat.launchProjectile(Snowball.class);
                            sb.setVelocity(st);
                            bat.remove();
                        }
                    }
                }
            }, 1, 12);
        }
    Thanks again for your help!
     
  12. Offline

    Cjreek

    But this only works once, doesn't it? You're spawning the bat once but you're using/removing it every 12 gameticks...
    Or am I missing something?
     
  13. It is/was in the wrong direction because you are subtracting the turrets location from the targets one. Now it works because you are turning all vector-values around with the * -1 . Easier way would be to just turn the subtraction around:
    Code:
    Vector v1 = l.toVector();
     
    Vector v2 = p.getLocation().add(0, h, 0).toVector();
     
    Vector st = [B]v2[/B].subtract([B]v1[/B]).normalize();
    sb.setVelocity(st);
    
    Edit: And something else: You don't need that bat (or any other entity) to spawn and "shoot" a snowball.. The only thing you would change without an "hidden" entity there, would be the "getNearbyPlayers"-thing.. Me for example, I am comparing the distances from each player inside a match to see, if I should target them. Distance-calculations are always bad looking at performance, but I guess the getNearbyEntities-Method is doing similar calculations but for all entites in the world (?) (but this is just a guess as I didn't take a look at the implemention of this method..).
     
  14. Cjreek Nope, every time I want to use bat after removing it again, it spawns a new bat^^

    blablubbabc
    Yes I know^^ :)

    I tried to subtract it the other way around yesterday, but it didn't work.. maybe because then I didn't use normalize yet. I'll try it.

    Ed.: Doesn't work to subtract it the other way around.. not even a snowball gets launched^^
    Also no error messages.
     
  15. hmm.. Something else that could make problems when working with vector objects: clone them/create a copy, a new vector with the same values, when you do operations on it. As often you can ;-) Othervise you are changing the object and wonder why it does strange things later..

    Edit:
    Code:
    Vector dir = targetVec.clone().subtract(turretVec).normalize();
     
  16. Offline

    Cjreek

    Ahmet094: Does it do it automaticaly? because you're spawning the bat outside the repeating task.
     
  17. Works now. Linux.. was in the wrong screen and reloaded the main-server.. the players should be angry now^^ haha.
    Thanks :)

    Cjreek
    Yeah it does. Doesn't matter if it's outside the repeating task^^ Every time the task is calling it, it spawns a new one.

    EDIT by Moderator: merged posts, please use the edit button instead of double posting.
     
    Last edited by a moderator: May 31, 2016
Thread Status:
Not open for further replies.

Share This Page