Repeat explosions...

Discussion in 'Plugin Development' started by Jnorr44, Sep 15, 2013.

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

    Jnorr44

    I have a grenade class (that I will post below), and for some reason the grenades are multiplying at an alarming rate. The class is created onProjectileHit of an ender pearl, and my current issue is that the pearls are being multiplied, and so are the explosions, meaning each pearl is a grenade class, and is live. Does anyone see anything in here that would make this problem occur, I have been looking for a few minutes, and have yet to see anything...

    Grenade.java:
    Code:
    public class Grenade {// does not need to be a gameobject, as the explosion is linked to the player that throws the grenade.
        private float yield = 2F;// Can be changed to make a larger explosion.
        private Entity entity;
        private ZAPlayer owner;
        private boolean live = true, sticky = false;
        private float momentumX, momentumY, momentumZ;
        private HashMap<String, Long> messagesSent = new HashMap<String, Long>();
        private DataContainer data = Ablockalypse.getData();
     
        public Grenade(Entity entity, ZAPlayer owner) {
            this(entity, owner, 100, true, false, 0, 0, 0);
        }
     
        public Grenade(Entity entity, ZAPlayer owner, int countdownTicks, boolean live, boolean sticky) {
            this(entity, owner, countdownTicks, live, sticky, 0, 0, 0);
        }
     
        /* 1 > momentumX, Y, Z > -1
        * percentage of force towards that direction */
        public Grenade(Entity entity, ZAPlayer owner, int countdownTicks, boolean live, boolean sticky, float momentumX, float momentumY, float momentumZ) {
            this.entity = entity;
            this.owner = owner;
            this.live = live;
            this.momentumX = momentumX;
            this.momentumY = momentumY;
            this.momentumZ = momentumZ;
            triggerPhysics(countdownTicks);
        }
     
        private void triggerPhysics(final int ticks) {
            Ablockalypse.getMainThread().scheduleRepeatingTask(new ZAThread() {
                int time = ticks;
     
                private void roll(double dist) {
                    Location start = entity.getLocation();
                    Location force = start.clone().add(dist * momentumX, dist * momentumY, dist * momentumZ);
                    if (!force.getBlock().isEmpty()) {
                        if (BukkitUtility.locationMatch(force, force)) {
                            if (momentumX > momentumY && momentumX > momentumZ) {
                                momentumX *= -.75;
                            } else if (momentumY > momentumX && momentumY > momentumZ) {
                                momentumY *= -.75;
                            } else if (momentumZ > momentumY && momentumZ > momentumX) {
                                momentumZ *= -.75;
                            }
                        }
                    }
                    entity.teleport(force);
                }
     
                @Override public void remove() {
                    Location loc = entity.getLocation();
                    if (live) {
                        EntityExplode.createNonBlockDestructionExplosionWithPoints(owner, loc, yield);
                    } else {
                        ZAEffect.EXTINGUISH.play(loc);
                    }
                    messagesSent.clear();
                    entity.remove();
                    data.objects.remove(this);
                }
     
                @Override public void run() {
                    time--;
                    if (!sticky) {// TODO if sticky, stick to the hit object, and follow it while it is moving
                        roll((((time * 100) / ticks) / 100) * .4);
                        // example:
                        // ticks = 50, time = 30
                        // 30 * 100 = 3000
                        // 3000 / 50 = 60
                        // 60 / 100 = .6 (percentage of time left from original ticks)
                        // .6 * .4 = .24 (that percentage of .4, which is max move speed)
                    }
                    for (Entity nearby : entity.getNearbyEntities(2, 3.5, 2)) {
                        if (nearby instanceof Player && data.isZAPlayer((Player) nearby)) {
                            Player player = (Player) nearby;
                            String name = player.getName();
                            if (messagesSent.containsKey(name)) {
                                long timePast = System.currentTimeMillis() - messagesSent.get(name);
                                if (timePast >= 10000) {
                                    messagesSent.remove(name);
                                }
                            } else {
                                messagesSent.put(name, System.currentTimeMillis());
    //                            if ((Boolean) Setting.ITEM_NAME_MESSAGES.getSetting()) {
    //                                new PopupMessage(player, "Press SHIFT to pick up grenade.", 5);
    //                            } else {
                                    player.sendMessage(ChatColor.GRAY + "Press " + ChatColor.AQUA + "SHIFT" + ChatColor.GRAY + " to pick up grenade.");
    //                            }
                            }
                            if (player.isSneaking()) {
                                Ablockalypse.getExternal().getItemFileManager().giveItem(player, new ItemStack(Material.ENDER_PEARL, 1));
                                live = false;
                                remove();
                            }
                        }
                    }
                    if (time <= 0) {
                        remove();
                    }
                }
            }, 1);
        }
     
        public ZAPlayer getOwner() {
            return owner;
        }
     
        public void setYield(float yield) {
            this.yield = yield;
        }
     
        public float getYield() {
            return yield;
        }
     
        public Entity getGrenadeEntity() {
            return entity;
        }
     
        public boolean isLive() {
            return live;
        }
     
        public void setLive(boolean live) {
            this.live = live;
        }
    }
     
  2. Offline

    blablubbabc

    I see at least one potential bug there:

    You are calling remove() multiple times, if there are multiple sneaking players near the grenade -> you should probably add a return, when the first player picks up the grenade, and stop your ZAThread, when the grenade is no longer "live"
     
  3. Offline

    Jnorr44

    This:
    Code:
    data.objects.remove(this);
    cancels the ZAThread, as the thread is run by my main thread, which calls the run method in all ZAThreads inside of the objects copyonwritearraylist.

    Although, I have added a return after the grenade is picked up, to stop the for loop.
     
Thread Status:
Not open for further replies.

Share This Page