Enchantment: Split up enchantment type data and enchantment instance data (#1825)

* Enchantment: Split enchantment type data from instance data
This commit splits enchantments into (effectively) enchantment TYPES vs enchantment INSTANCES.

When applying an enchantment to an item, it only needs to know 2 things:
1. the enchantment ID (identifier) which is used to identify the TYPE
2. the enchantment LEVEL which is used to modify the enchantment's power IN THIS INSTANCE.

Therefore, the LEVEL is not an immutable property. However, all other properties of the currently-named "Enchantment" class are immutable type properties.
Currently, when applying an enchantment to an item, a copy of the enchantment object is created from the registry, and returned. This copies all of the properties contained by the type, which is obviously sub optimal.
This commit is contained in:
Dylan K. Taylor
2017-12-21 12:40:33 +00:00
committed by GitHub
parent 1b4b832c8c
commit 0e538ee51d
4 changed files with 96 additions and 38 deletions

View File

@ -31,6 +31,7 @@ use pocketmine\block\BlockFactory;
use pocketmine\block\BlockToolType;
use pocketmine\entity\Entity;
use pocketmine\item\enchantment\Enchantment;
use pocketmine\item\enchantment\EnchantmentInstance;
use pocketmine\level\Level;
use pocketmine\math\Vector3;
use pocketmine\nbt\NBT;
@ -310,9 +311,9 @@ class Item implements ItemIds, \JsonSerializable{
/**
* @param int $id
*
* @return Enchantment|null
* @return EnchantmentInstance|null
*/
public function getEnchantment(int $id) : ?Enchantment{
public function getEnchantment(int $id) : ?EnchantmentInstance{
$ench = $this->getNamedTagEntry(self::TAG_ENCH);
if(!($ench instanceof ListTag)){
return null;
@ -323,8 +324,7 @@ class Item implements ItemIds, \JsonSerializable{
if($entry->getShort("id") === $id){
$e = Enchantment::getEnchantment($entry->getShort("id"));
if($e !== null){
$e->setLevel($entry->getShort("lvl"));
return $e;
return new EnchantmentInstance($e, $entry->getShort("lvl"));
}
}
}
@ -358,9 +358,9 @@ class Item implements ItemIds, \JsonSerializable{
}
/**
* @param Enchantment $enchantment
* @param EnchantmentInstance $enchantment
*/
public function addEnchantment(Enchantment $enchantment) : void{
public function addEnchantment(EnchantmentInstance $enchantment) : void{
$found = false;
$ench = $this->getNamedTagEntry(self::TAG_ENCH);
@ -391,10 +391,10 @@ class Item implements ItemIds, \JsonSerializable{
}
/**
* @return Enchantment[]
* @return EnchantmentInstance[]
*/
public function getEnchantments() : array{
/** @var Enchantment[] $enchantments */
/** @var EnchantmentInstance[] $enchantments */
$enchantments = [];
$ench = $this->getNamedTagEntry(self::TAG_ENCH);
@ -403,8 +403,7 @@ class Item implements ItemIds, \JsonSerializable{
foreach($ench as $entry){
$e = Enchantment::getEnchantment($entry->getShort("id"));
if($e !== null){
$e->setLevel($entry->getShort("lvl"));
$enchantments[] = $e;
$enchantments[] = new EnchantmentInstance($e, $entry->getShort("lvl"));
}
}
}