diff --git a/src/pocketmine/command/SimpleCommandMap.php b/src/pocketmine/command/SimpleCommandMap.php index da16e26f8..243354131 100644 --- a/src/pocketmine/command/SimpleCommandMap.php +++ b/src/pocketmine/command/SimpleCommandMap.php @@ -29,6 +29,7 @@ use pocketmine\command\defaults\DeopCommand; use pocketmine\command\defaults\DifficultyCommand; use pocketmine\command\defaults\DumpMemoryCommand; use pocketmine\command\defaults\EffectCommand; +use pocketmine\command\defaults\EnchantCommand; use pocketmine\command\defaults\GamemodeCommand; use pocketmine\command\defaults\GarbageCollectorCommand; use pocketmine\command\defaults\GiveCommand; @@ -105,6 +106,7 @@ class SimpleCommandMap implements CommandMap{ $this->register("pocketmine", new SaveCommand("save-all")); $this->register("pocketmine", new GiveCommand("give")); $this->register("pocketmine", new EffectCommand("effect")); + $this->register("pocketmine", new EnchantCommand("enchant")); $this->register("pocketmine", new ParticleCommand("particle")); $this->register("pocketmine", new GamemodeCommand("gamemode")); $this->register("pocketmine", new KillCommand("kill")); diff --git a/src/pocketmine/command/defaults/EnchantCommand.php b/src/pocketmine/command/defaults/EnchantCommand.php new file mode 100644 index 000000000..55ac5d5bf --- /dev/null +++ b/src/pocketmine/command/defaults/EnchantCommand.php @@ -0,0 +1,86 @@ +setPermission("pocketmine.command.enchant"); + } + + public function execute(CommandSender $sender, $currentAlias, array $args){ + if(!$this->testPermission($sender)){ + return true; + } + + if(count($args) < 2){ + $sender->sendMessage(new TranslationContainer("commands.generic.usage", [$this->usageMessage])); + + return true; + } + + $player = $sender->getServer()->getPlayer($args[0]); + + if($player === null){ + $sender->sendMessage(new TranslationContainer(TextFormat::RED . "%commands.generic.player.notFound")); + return true; + } + + $enchantId = (int) $args[1]; + $enchantLevel = isset($args[2]) ? (int) $args[2] : 1; + + $enchantment = Enchantment::getEnchantment($enchantId); + if($enchantment->getId() === Enchantment::TYPE_INVALID){ + $sender->sendMessage(new TranslationContainer("commands.enchant.notFound", [$enchantId])); + return true; + } + + $enchantment->setLevel($enchantLevel); + + $item = $player->getInventory()->getItemInHand(); + + if($item->getId() <= 0){ + $sender->sendMessage(new TranslationContainer("commands.enchant.noItem")); + return true; + } + + $item->addEnchantment($enchantment); + $player->getInventory()->setItemInHand($item); + + + self::broadcastCommandMessage($sender, new TranslationContainer("%commands.enchant.success")); + return true; + } +} \ No newline at end of file diff --git a/src/pocketmine/item/Item.php b/src/pocketmine/item/Item.php index 1cd7043ea..ed4f4877a 100644 --- a/src/pocketmine/item/Item.php +++ b/src/pocketmine/item/Item.php @@ -31,7 +31,10 @@ use pocketmine\entity\Squid; use pocketmine\entity\Villager; use pocketmine\entity\Zombie; use pocketmine\inventory\Fuel; +use pocketmine\item\enchantment\Enchantment; use pocketmine\level\Level; +use pocketmine\nbt\tag\Enum; +use pocketmine\nbt\tag\Short; use pocketmine\nbt\tag\String; use pocketmine\Player; use pocketmine\nbt\tag\Compound; @@ -1027,6 +1030,99 @@ class Item{ return null; } + public function hasEnchantments(){ + if(!$this->hasCompoundTag()){ + return false; + } + + $tag = $this->getNamedTag(); + if(isset($tag->ench)){ + $tag = $tag->ench; + if($tag instanceof Enum){ + return true; + } + } + + return false; + } + + /** + * @param $id + * @return Enchantment|null + */ + public function getEnchantment($id){ + if(!$this->hasEnchantments()){ + return null; + } + + foreach($this->getNamedTag()->ench as $entry){ + if($entry["id"] === $id){ + $e = Enchantment::getEnchantment($entry["id"]); + $e->setLevel($entry["lvl"]); + return $e; + } + } + + return null; + } + + /** + * @param Enchantment $ench + */ + public function addEnchantment(Enchantment $ench){ + if(!$this->hasCompoundTag()){ + $tag = new Compound("", []); + }else{ + $tag = $this->getNamedTag(); + } + + if(!isset($tag->ench)){ + $tag->ench = new Enum("ench", []); + $tag->ench->setTagType(NBT::TAG_Compound); + } + + $found = false; + + foreach($tag->ench as $k => $entry){ + if($entry["id"] === $ench->getId()){ + $tag->ench->{$k} = new Compound("", [ + "id" => new Short("id", $ench->getId()), + "lvl" => new Short("lvl", $ench->getLevel()) + ]); + $found = true; + break; + } + } + + if(!$found){ + $tag->ench->{count($tag->ench) + 1} = new Compound("", [ + "id" => new Short("id", $ench->getId()), + "lvl" => new Short("lvl", $ench->getLevel()) + ]); + } + + $this->setNamedTag($tag); + } + + /** + * @return Enchantment[] + */ + public function getEnchantments(){ + if(!$this->hasEnchantments()){ + return []; + } + + $enchantments = []; + + foreach($this->getNamedTag()->ench as $entry){ + $e = Enchantment::getEnchantment($entry["id"]); + $e->setLevel($entry["lvl"]); + $enchantments[] = $e; + } + + return $enchantments; + } + public function hasCustomName(){ if(!$this->hasCompoundTag()){ return false; diff --git a/src/pocketmine/item/enchantment/Enchantment.php b/src/pocketmine/item/enchantment/Enchantment.php index d4c06e206..9393445f6 100644 --- a/src/pocketmine/item/enchantment/Enchantment.php +++ b/src/pocketmine/item/enchantment/Enchantment.php @@ -24,6 +24,8 @@ namespace pocketmine\item\enchantment; class Enchantment{ + const TYPE_INVALID = -1; + const TYPE_ARMOR_PROTECTION = 0; const TYPE_ARMOR_FIRE_PROTECTION = 1; const TYPE_ARMOR_FALL_PROTECTION = 2; @@ -98,7 +100,7 @@ class Enchantment{ if(isset(self::$enchantments[$id])){ return clone self::$enchantments[(int) $id]; } - return null; + return new Enchantment(self::TYPE_INVALID, "unknown", 0, 0, 0); } public static function getEffectByName($name){ diff --git a/src/pocketmine/lang/locale b/src/pocketmine/lang/locale index 2ba10606b..5aeb31318 160000 --- a/src/pocketmine/lang/locale +++ b/src/pocketmine/lang/locale @@ -1 +1 @@ -Subproject commit 2ba10606bccbf448af33ebba5c5ffa294c6f515d +Subproject commit 5aeb3131893c01643ef36cff0e72898e0036bd77 diff --git a/src/pocketmine/permission/DefaultPermissions.php b/src/pocketmine/permission/DefaultPermissions.php index 5fa6b5740..b4bcebe7f 100644 --- a/src/pocketmine/permission/DefaultPermissions.php +++ b/src/pocketmine/permission/DefaultPermissions.php @@ -103,6 +103,7 @@ abstract class DefaultPermissions{ self::registerPermission(new Permission(self::ROOT . ".command.say", "Allows the user to talk as the console", Permission::DEFAULT_OP), $commands); self::registerPermission(new Permission(self::ROOT . ".command.give", "Allows the user to give items to players", Permission::DEFAULT_OP), $commands); self::registerPermission(new Permission(self::ROOT . ".command.effect", "Allows the user to give/take potion effects", Permission::DEFAULT_OP), $commands); + self::registerPermission(new Permission(self::ROOT . ".command.enchant", "Allows the user to enchant items", Permission::DEFAULT_OP), $commands); self::registerPermission(new Permission(self::ROOT . ".command.particle", "Allows the user to create particle effects", Permission::DEFAULT_OP), $commands); self::registerPermission(new Permission(self::ROOT . ".command.teleport", "Allows the user to teleport players", Permission::DEFAULT_OP), $commands); self::registerPermission(new Permission(self::ROOT . ".command.kick", "Allows the user to kick players", Permission::DEFAULT_OP), $commands);