Advertisement
  1. This site uses cookies. By continuing to use this site, you are agreeing to our use of cookies. Learn More.

Unbreakable Items

Comments in 'Plugin Development' started by thebigsmileXD, Sep 1, 2015.

  1. thebigsmileXD
    Offline

    thebigsmileXD Banned

    Joined:
    May 19, 2015
    Posts:
    845
    Plugins:
    1
    Minecraft User:
    XenialDan
    I just got a problem on my plugin:
    I want the items (in my case a bow and a sword) to be unbreakable.
    i have a method which controls if a player hits a player:
    PHP:
        public function onPlayerDamage(EntityDamageEvent $event){
            
    $cause $event->getEntity()->getLastDamageCause();
            if(
    $cause instanceof EntityDamageByEntityEvent){
                
    $killer $cause->getDamager();
                
    $victim $cause->getEntity();
                if(
    $killer instanceof Player && $victim instanceof Player){
                    if(
    $this->isPlaying($killer) && $this->isPlaying($victim) && $this->inSameLobby(array($killer,$victim))){
                        
    $victim->getServer()->broadcastMessage(TextFormat::RED $killer->getDisplayName() . " killed " $victim->getDisplayName(), $this->games[strtolower($victim->getLevel()->getName())]["players"]);
                        
    $this->games[strtolower($killer->getLevel()->getName())]["players"][$killer->getName()]["kills"]++;
                        
    $this->games[strtolower($victim->getLevel()->getName())]["players"][$victim->getName()]["deaths"]++;
                        if(
    $this->games[strtolower($killer->getLevel()->getName())]["players"][$killer->getName()]["kills"] >= 15){
                            
    $this->stopGame(array($strtolower($killer->getLevel()->getName())), $killer);
                        }
                        else{
                            
    $killer->getInventory()->addItem(Item::fromString("Arrow"));
                        }
                    }
                }
            }
            else{
                return 
    false;
            }
        }
    So, now if i use the Bow, i dont want the duration to change. what event do i have to cancel?
  2. aliuly
    Offline

    aliuly Notable Member Plugin Developer

    Joined:
    Feb 8, 2014
    Posts:
    1,086
    Plugins:
    17
    You don't cancel an event (that would cancel the damage being dealt). What I have done before is get the bow (or sword) from the $attacker->getInventory()->getItemInHand() and set the damage to 0.
  3. Creeperface
    Offline

    Creeperface Notable Member Plugin Developer

    Joined:
    Nov 8, 2014
    Posts:
    1,346
    Plugins:
    4
    Minecraft User:
    CreeperFace
  4. thebigsmileXD
    Offline

    thebigsmileXD Banned

    Joined:
    May 19, 2015
    Posts:
    845
    Plugins:
    1
    Minecraft User:
    XenialDan
    Oh, thats right.
    By the way, what is the event if i hit with a sword or shoot with a bow? i can only find PlayerItemConsumeEvent, is that the correct one?
  5. PEMapModder
    Offline

    PEMapModder Notable Member Plugin Developer

    Joined:
    Oct 9, 2013
    Posts:
    7,294
    Plugins:
    11
    Minecraft User:
    PEMapModder
    I don't think so.
  6. Creeperface
    Offline

    Creeperface Notable Member Plugin Developer

    Joined:
    Nov 8, 2014
    Posts:
    1,346
    Plugins:
    4
    Minecraft User:
    CreeperFace
    0 is better
  7. thebigsmileXD
    Offline

    thebigsmileXD Banned

    Joined:
    May 19, 2015
    Posts:
    845
    Plugins:
    1
    Minecraft User:
    XenialDan
    By the way, this is my current function:
    PHP:
        public function onItemUse(PlayerItemConsumeEvent $event){
            
    $item $event->getItem();
            
    $player $event->getPlayer();
            
    $item->setDamage(0);
            
    $player->getInventory()->sendSlot($player->getInventory()->getHeldItemSlot(), $player);
        }
    Creeperface likes this.
  8. Creeperface
    Offline

    Creeperface Notable Member Plugin Developer

    Joined:
    Nov 8, 2014
    Posts:
    1,346
    Plugins:
    4
    Minecraft User:
    CreeperFace
    why consumeEvent?
  9. thebigsmileXD
    Offline

    thebigsmileXD Banned

    Joined:
    May 19, 2015
    Posts:
    845
    Plugins:
    1
    Minecraft User:
    XenialDan
    I wasn't able to find any ItemUse event..
  10. Creeperface
    Offline

    Creeperface Notable Member Plugin Developer

    Joined:
    Nov 8, 2014
    Posts:
    1,346
    Plugins:
    4
    Minecraft User:
    CreeperFace
    BlockBreakEvent/PlayerInteractEvent
  11. thebigsmileXD
    Offline

    thebigsmileXD Banned

    Joined:
    May 19, 2015
    Posts:
    845
    Plugins:
    1
    Minecraft User:
    XenialDan
    Thats for blocks. This does not check for bows, but i just figured it out:
    PHP:
        public function onBowUse(EntityShootBowEvent $event){
            
    $item $event->getItem();
            
    $player $event->getPlayer();
            
    $item->setDamage(0);
            
    $player->getInventory()->sendSlot($player->getInventory()->getHeldItemSlot(), $player);
        }
    Works for bow, for sword i have to insert it in my onPlayerDamage function.
  12. thebigsmileXD
    Offline

    thebigsmileXD Banned

    Joined:
    May 19, 2015
    Posts:
    845
    Plugins:
    1
    Minecraft User:
    XenialDan
    Got this whole thing working now, thanks alot to all of you!
    Code:
    PHP:
        public function onPlayerDamage(EntityDamageEvent $event){
            
    $cause $event->getEntity()->getLastDamageCause();
            if(
    $cause instanceof EntityDamageByEntityEvent){
                
    $killer $cause->getDamager();
                
    $victim $cause->getEntity();
                if(
    $killer instanceof Player && $victim instanceof Player){
                    if(
    $killer->getName() === $victim->getName()){
                        
    $event->setDamage(0);
                        
    $killer->sendMessage(TextFormat::RED "You cant hit yourself!");
                        if(!
    $killer->getInventory()->contains(Item::fromString("Arrow"))){
                            
    $killer->getInventory()->addItem(Item::fromString("Arrow"));
                        }
                        return 
    false;
                    }
                    if(
    $this->isPlaying($killer) && $this->isPlaying($victim) && $this->inSameLobby(array($killer,$victim))){
                        
    $item $killer->getInventory()->getItemInHand();
                        
    $item->setDamage(0);
                        
    $killer->getInventory()->sendSlot($player->getInventory()->getHeldItemSlot(), $killer);
                        
    $victim->getServer()->broadcastMessage(TextFormat::RED $killer->getDisplayName() . " killed " $victim->getDisplayName(), $this->games[strtolower($victim->getLevel()->getName())]["players"]);
                        
    $this->games[strtolower($killer->getLevel()->getName())]["players"][$killer->getName()]["kills"]++;
                        
    $this->games[strtolower($victim->getLevel()->getName())]["players"][$victim->getName()]["deaths"]++;
                        if(
    $this->games[strtolower($killer->getLevel()->getName())]["players"][$killer->getName()]["kills"] >= 15){
                            
    $this->stopGame(array($strtolower($killer->getLevel()->getName())), $killer);
                        }
                        else{
                            
    $killer->getInventory()->addItem(Item::fromString("Arrow"));
                            
    $victim->getInventory()->clearAll();
                            
    $victim->kill();
                        }
                        if(
    $this->games[strtolower($victim->getLevel()->getName())]["players"][$victim->getName()]["deaths"] >= 15){
                            
    $this->stopGame(array($strtolower($killer->getLevel()->getName())), $killer);
                        }
                        else{
                            
    $killer->getInventory()->addItem(Item::fromString("Arrow"));
                        }
                    }
                }
            }
            else{
                return 
    false;
            }
        }

        public function 
    onBowUse(EntityShootBowEvent $event){
            
    $item $event->getItem();
            
    $player $event->getPlayer();
            
    $item->setDamage(0);
            
    $player->getInventory()->sendSlot($player->getInventory()->getHeldItemSlot(), $player);
        }
  13. PEMapModder
    Offline

    PEMapModder Notable Member Plugin Developer

    Joined:
    Oct 9, 2013
    Posts:
    7,294
    Plugins:
    11
    Minecraft User:
    PEMapModder
    I don't think this works. You have to set the item again after setting the damage.
    Also, I think the event is before the item actually loses damage.
  14. PEMapModder
    Offline

    PEMapModder Notable Member Plugin Developer

    Joined:
    Oct 9, 2013
    Posts:
    7,294
    Plugins:
    11
    Minecraft User:
    PEMapModder
    $item is just a clone of its real part in the player inventory. When you rejoin the game, you would find that the bow is actually consumed.
  15. thebigsmileXD
    Offline

    thebigsmileXD Banned

    Joined:
    May 19, 2015
    Posts:
    845
    Plugins:
    1
    Minecraft User:
    XenialDan
    This will not be a problem, the inventory of players which are playing this game are resetted after leaving the server / when the game stops.
    No idea, i'll have to test again
  16. PEMapModder
    Offline

    PEMapModder Notable Member Plugin Developer

    Joined:
    Oct 9, 2013
    Posts:
    7,294
    Plugins:
    11
    Minecraft User:
    PEMapModder
    Then why need to make unbreakable?
    Also, they will see the item disappear after durability is used up.
  17. thebigsmileXD
    Offline

    thebigsmileXD Banned

    Joined:
    May 19, 2015
    Posts:
    845
    Plugins:
    1
    Minecraft User:
    XenialDan
    Because i don't want the bow to break while they are still in a game.
  18. CavinMiana
    Offline

    CavinMiana Active Member

    Joined:
    Aug 26, 2015
    Posts:
    101
    Minecraft User:
    CavinMiana
    Ok so i think you should do : $player->getInventory()->getItem(//ID # for item)->setDurability(//set it to 0);
    I think that should work if it does not then idk
  19. PEMapModder
    Offline

    PEMapModder Notable Member Plugin Developer

    Joined:
    Oct 9, 2013
    Posts:
    7,294
    Plugins:
    11
    Minecraft User:
    PEMapModder
    No, that doesn't work. As I said, Item objects returned by the PocketMine API are always clones, and you can't do anything related to players if you only call functions upon an item - an Item class is simply a structure with no actual APIs.
    thebigsmileXD and jojoe77777 like this.

Share This Page

Advertisement