Flatten Item variants, remove Item->setDamage()

This commit is contained in:
Dylan K. Taylor
2018-10-06 20:09:11 +01:00
parent 14ef4558c2
commit 5fb7825485
9 changed files with 138 additions and 49 deletions

View File

@ -25,6 +25,8 @@ namespace pocketmine\item;
use pocketmine\block\Block;
use pocketmine\block\BlockFactory;
use pocketmine\entity\Entity;
use pocketmine\entity\Living;
use pocketmine\nbt\tag\CompoundTag;
/**
@ -45,7 +47,8 @@ class ItemFactory{
self::registerItem(new Apple());
self::registerItem(new Bow());
self::registerItem(new Arrow());
self::registerItem(new Coal());
self::registerItem(new Coal(Item::COAL, 0, "Coal"));
self::registerItem(new Coal(Item::COAL, 1, "Charcoal"));
self::registerItem(new Item(Item::DIAMOND, 0, "Diamond"));
self::registerItem(new Item(Item::IRON_INGOT, 0, "Iron Ingot"));
self::registerItem(new Item(Item::GOLD_INGOT, 0, "Gold Ingot"));
@ -107,13 +110,19 @@ class ItemFactory{
self::registerItem(new GoldenApple());
self::registerItem(new Sign());
self::registerItem(new ItemBlock(Block::OAK_DOOR_BLOCK, 0, Item::OAK_DOOR));
self::registerItem(new Bucket());
self::registerItem(new Bucket(Item::BUCKET, 0, "Bucket", Block::AIR));
self::registerItem(new Bucket(Item::BUCKET, 1, "Milk Bucket", null)); //TODO: this ought to get its own class, it has completely different behaviour
//TODO: fix metadata for buckets with still liquid in them
//the meta values are intentionally hardcoded because block IDs will change in the future
self::registerItem(new Bucket(Item::BUCKET, 8, "Water Bucket", Block::FLOWING_WATER));
self::registerItem(new Bucket(Item::BUCKET, 10, "Lava Bucket", Block::FLOWING_LAVA));
self::registerItem(new Minecart());
//TODO: SADDLE
self::registerItem(new ItemBlock(Block::IRON_DOOR_BLOCK, 0, Item::IRON_DOOR));
self::registerItem(new Redstone());
self::registerItem(new Snowball());
self::registerItem(new Boat());
self::registerItem(new Item(Item::LEATHER, 0, "Leather"));
//TODO: KELP
@ -132,7 +141,10 @@ class ItemFactory{
self::registerItem(new Item(Item::GLOWSTONE_DUST, 0, "Glowstone Dust"));
self::registerItem(new RawFish());
self::registerItem(new CookedFish());
self::registerItem(new Dye());
for($i = 0; $i < 16; ++$i){
//TODO: add colour constants (this is messy)
self::registerItem(new Dye($i));
}
self::registerItem(new Item(Item::BONE, 0, "Bone"));
self::registerItem(new Item(Item::SUGAR, 0, "Sugar"));
self::registerItem(new ItemBlock(Block::CAKE_BLOCK, 0, Item::CAKE));
@ -154,7 +166,12 @@ class ItemFactory{
self::registerItem(new Item(Item::GHAST_TEAR, 0, "Ghast Tear"));
self::registerItem(new Item(Item::GOLD_NUGGET, 0, "Gold Nugget"));
self::registerItem(new ItemBlock(Block::NETHER_WART_PLANT, 0, Item::NETHER_WART));
self::registerItem(new Potion());
foreach(Potion::ALL as $type){
self::registerItem(new Potion($type));
self::registerItem(new SplashPotion($type));
//TODO: LINGERING_POTION
}
self::registerItem(new GlassBottle());
self::registerItem(new SpiderEye());
self::registerItem(new Item(Item::FERMENTED_SPIDER_EYE, 0, "Fermented Spider Eye"));
@ -164,7 +181,14 @@ class ItemFactory{
self::registerItem(new ItemBlock(Block::CAULDRON_BLOCK, 0, Item::CAULDRON));
//TODO: ENDER_EYE
self::registerItem(new Item(Item::GLISTERING_MELON, 0, "Glistering Melon"));
self::registerItem(new SpawnEgg());
foreach(Entity::getKnownEntityTypes() as $className){
/** @var Living $className */
if(is_a($className, Living::class, true) and $className::NETWORK_ID !== -1){
self::registerItem(new SpawnEgg(Item::SPAWN_EGG, $className::NETWORK_ID, "Spawn Egg"));
}
}
self::registerItem(new ExperienceBottle());
//TODO: FIREBALL
self::registerItem(new WritableBook());
@ -217,9 +241,7 @@ class ItemFactory{
self::registerItem(new Item(Item::CHORUS_FRUIT_POPPED, 0, "Popped Chorus Fruit"));
self::registerItem(new Item(Item::DRAGON_BREATH, 0, "Dragon's Breath"));
self::registerItem(new SplashPotion());
//TODO: LINGERING_POTION
//TODO: SPARKLER
//TODO: COMMAND_BLOCK_MINECART
//TODO: ELYTRA
@ -279,11 +301,19 @@ class ItemFactory{
*/
public static function registerItem(Item $item, bool $override = false){
$id = $item->getId();
if(!$override and self::isRegistered($id)){
$variant = $item->getDamage();
if(!$override and self::isRegistered($id, $variant)){
throw new \RuntimeException("Trying to overwrite an already registered item");
}
self::$list[self::getListOffset($id)] = clone $item;
$offset = self::getListOffset($id);
$sublist = self::$list[$offset] ?? new \SplFixedArray();
if($sublist->getSize() < $variant + 1){
$sublist->setSize($variant + 1);
}
$sublist[$variant] = clone $item;
self::$list[$offset] = $sublist;
}
/**
@ -303,24 +333,28 @@ class ItemFactory{
}
try{
$sublist = self::$list[self::getListOffset($id)];
/** @var Item|null $listed */
$listed = self::$list[self::getListOffset($id)];
if($listed !== null){
$item = clone $listed;
if($sublist !== null and isset($sublist[$meta])){
$item = clone $sublist[$meta];
}elseif($id < 256){ //intentionally includes negatives, for extended block IDs
/* Blocks must have a damage value 0-15, but items can have damage value -1 to indicate that they are
* crafting ingredients with any-damage. */
$item = new ItemBlock($id, $meta);
}else{
//negative damage values will fallthru to here, to avoid crazy shit with crafting wildcard hacks
$item = new Item($id, $meta);
}
}catch(\RuntimeException $e){
throw new \InvalidArgumentException("Item ID $id is invalid or out of bounds");
}
$item->setDamage($meta);
$item->setCount($count);
$item->setCompoundTag($tags);
if($item instanceof Durable){ //nasty, but necessary for BC reasons
$item->setDamage($meta);
}
return $item;
}
@ -376,13 +410,17 @@ class ItemFactory{
* Returns whether the specified item ID is already registered in the item factory.
*
* @param int $id
* @param int $variant
*
* @return bool
*/
public static function isRegistered(int $id) : bool{
public static function isRegistered(int $id, int $variant = 0) : bool{
if($id < 256){
return BlockFactory::isRegistered($id);
}
return self::$list[self::getListOffset($id)] !== null;
$sublist = self::$list[self::getListOffset($id)];
return $sublist !== null and isset($sublist[$variant]);
}
private static function getListOffset(int $id) : int{