Solved Custom potion duration

Discussion in 'Plugin Development' started by duker02, Mar 28, 2014.

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

    duker02

    Hello, is it possible to make a splash potion have a custom duration?

    I've searched through PotionMeta, Potion, etc.
     
  2. Offline

    Scizzr

    Code:
    //30-second Speed I
    PotionEffect SPEED_1_30 = new PotionEffect(PotionEffectType.SPEED, 20*30, 0);
    //120-second Strength II
    PotionEffect STREN_3_120 = new PotionEffect(PotionEffectType.INCREASE_DAMAGE, 20*120, 2);
    
    The duration is in ticks, so multiply seconds by 20.
    The amplifier starts with 0 being a I potion, so 1 would be II, etc
     
  3. Offline

    KingFaris11

    Not sure if this will work as I haven't tried it but you could do the following:
    1. Listen to PotionSplashEvent.
    2. Cancel the event.
    3. After event.setCancelled(true); type in the following code:
    Code:
    for (PotionEffect potionEffect : event.getPotion().getEffects()) {
        PotionEffect newPotionEffect = new PotionEffect(potionEffect.getType(), <duration>, potionEffect.getAmplifier());
        for (LivingEntity livingEntity : event.getAffectedEntities()) {
            newPotionEffect.apply(livingEntity);
        }
    }
    
    He wants to set the custom duration to a splash potion.

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

    Scizzr

    All he has to do is then summon a splash potion and set the effect.

    Code:
    PotionEffect SPEED_1_30 = new PotionEffect(PotionEffectType.SPEED, 20*30, 0);
    PotionEffect STREN_3_120 = new PotionEffect(PotionEffectType.INCREASE_DAMAGE, 20*120, 2);
     
    Location loc = null; //you need to specify this location
    World world = loc.getWorld();
    ThrownPotion pot = (ThrownPotion)world.spawnEntity(loc, EntityType.SPLASH_POTION);
    pot.getEffects().add(SPEED_1_30);
    
    Or to change the time on a potion, you can make a listener for the PotionSplashEvent and then modify the effect.
    Code:
    public void onPotionSplash(PotionSplashEvent event) {
        PotionEffect SPEED_1_30 = new PotionEffect(PotionEffectType.SPEED, 20*30, 0);   
        event.getPotion().getEffects().clear();
        event.getPotion().getEffects().add(SPEED_1_30);
    }
    
     
    KingFaris11 likes this.
  5. Offline

    duker02

    KingFaris11 Thanks, this seems to be correct. I will let you know if it works once I can test my plugin.
     
    KingFaris11 likes this.
  6. Offline

    KingFaris11

    I actually think Scizzr second way is most effective. His onPotionSplash() method although I'm not sure if getEffects() can be directly modified. My way probably would work, but his way is better performance-wise as it does not do any loops. Especially not a loop inside another loop, and if there were 50 players in the same spot, it may take even longer.

    JBoss925
    That doesn't even make sense, you can't convert a Collection of LivingEntities into one Player object.
    Not only that, it clears all the player's previous potion effects, which is even worse.

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

    JBoss925

    My god I didn't even realize I did that. I'd have to add a loop. Wow I blanked there. Sorry bukkit users?
     
    KingFaris11 likes this.
  8. Offline

    KingFaris11

    People always make mistakes :p I usually re-read my comment more than 10 times and make sure it looks legit before pressing the reply button. Most of the threads I comment on I actually type the first comment, but it just takes me a while to re-read what I wrote and so people comment in the mean time.
     
  9. Offline

    JBoss925

    Lol well yeah same here.
     
  10. Offline

    duker02

    I have to check if the potion's effect is poison, so I guess I'll have to use yours.
     
    KingFaris11 likes this.
  11. Offline

    FabeGabeMC

  12. Offline

    duker02

    Nope.

    KingFaris11 Hey, this seems to not work. When I throw down a poison potion, nothing happens at all.
    Here's the code:
    Code:java
    1. @EventHandler
    2. public void onPotionSplash(PotionSplashEvent ev) {
    3. for (PotionEffect potionEffect : ev.getPotion().getEffects()) {
    4. if (potionEffect.equals(PotionEffectType.POISON)) {
    5. PotionEffect newPotionEffect = new PotionEffect(
    6. potionEffect.getType(), 10 * 20,
    7. potionEffect.getAmplifier());
    8. ev.setCancelled(true);
    9. for (LivingEntity livingEntity : ev.getAffectedEntities()) {
    10. newPotionEffect.apply(livingEntity);
    11. }
    12. }
    13. }
    14. }

    Should I place ev.setCancelled(true); after everything else?

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

    foodyling

    duker02
    Are you trying to make all potion effects last 2 minutes or just custom ones?
     
  14. Offline

    duker02

    foodyling I am trying to make all Poison splash potions last 10 seconds.
     
  15. Offline

    KingFaris11

    Dude you're cancelling the event per potion effect that will be applied. Use break; under the } after newPotionEffect.apply(livingEntity);
    The reason it probably isn't working is because it's not applying the potion effect to the entities. Try using livingEntity.addPotionEffect(newPotionEffect) or something.
     
  16. Offline

    duker02

    KingFaris11 I found a way to do it using PotionMeta.
     
  17. Offline

    KingFaris11

    Code:
    System.out.println("Poison Splash Event");
    Does it print that out?! You may have not registered the listener... make sure in your onEnable() you're registering it.
     
  18. Offline

    duker02

    KingFaris11 It was registered. Nothing was being printed out to the console.
    I've decided to use PotionMeta. I guess I didn't search through that long enough :p
     
    KingFaris11 likes this.
  19. Offline

    KingFaris11

    Okay but I know why it wasn't working, very silly mistake. You were checking a PotionEffect equals a PotionEffectType, not potionEffect.getType(). You were meant to do:
    Code:
    @EventHandler
    public void onPotionSplash(PotionSplashEvent event) {
        for (PotionEffect potionEffect : event.getPotion().getEffects()) {
            if (potionEffect.getType().equals(PotionEffectType.POISON)) {
                PotionEffect newPotionEffect = new PotionEffect(potionEffect.getType(), 10 * 20, potionEffect.getAmplifier());
                event.setCancelled(true);
                for (LivingEntity livingEntity : event.getAffectedEntities()) {
                    newPotionEffect.apply(livingEntity);
                }
                break;
            }
        }
    }
    
     
Thread Status:
Not open for further replies.

Share This Page