> */ private static $knownTiles = []; /** * @var string[][] * @phpstan-var array, list> */ private static $saveNames = []; /** * @var string[] base class => overridden class * @phpstan-var array, class-string> */ private static $classMapping = []; private function __construct(){ //NOOP } public static function init() : void{ self::register(Banner::class, ["Banner", "minecraft:banner"]); self::register(Bed::class, ["Bed", "minecraft:bed"]); self::register(BrewingStand::class, ["BrewingStand", "minecraft:brewing_stand"]); self::register(Chest::class, ["Chest", "minecraft:chest"]); self::register(Comparator::class, ["Comparator", "minecraft:comparator"]); self::register(DaylightSensor::class, ["DaylightDetector", "minecraft:daylight_detector"]); self::register(EnchantTable::class, ["EnchantTable", "minecraft:enchanting_table"]); self::register(EnderChest::class, ["EnderChest", "minecraft:ender_chest"]); self::register(FlowerPot::class, ["FlowerPot", "minecraft:flower_pot"]); self::register(Furnace::class, ["Furnace", "minecraft:furnace"]); self::register(Hopper::class, ["Hopper", "minecraft:hopper"]); self::register(ItemFrame::class, ["ItemFrame"]); //this is an entity in PC self::register(MonsterSpawner::class, ["MobSpawner", "minecraft:mob_spawner"]); self::register(Note::class, ["Music", "minecraft:noteblock"]); self::register(Sign::class, ["Sign", "minecraft:sign"]); self::register(Skull::class, ["Skull", "minecraft:skull"]); //TODO: Barrel //TODO: Beacon //TODO: Bell //TODO: BlastFurnace //TODO: Campfire //TODO: Cauldron //TODO: ChalkboardBlock //TODO: ChemistryTable //TODO: CommandBlock //TODO: Conduit //TODO: Dispenser //TODO: Dropper //TODO: EndGateway //TODO: EndPortal //TODO: JigsawBlock //TODO: Jukebox //TODO: Lectern //TODO: MovingBlock //TODO: NetherReactor //TODO: PistonArm //TODO: ShulkerBox //TODO: Smoker //TODO: StructureBlock } /** * @param string[] $saveNames * @phpstan-param class-string $className */ public static function register(string $className, array $saveNames = []) : void{ Utils::testValidInstance($className, Tile::class); self::$classMapping[$className] = $className; $shortName = (new \ReflectionClass($className))->getShortName(); if(!in_array($shortName, $saveNames, true)){ $saveNames[] = $shortName; } foreach($saveNames as $name){ self::$knownTiles[$name] = $className; } self::$saveNames[$className] = $saveNames; } /** * @param string $baseClass Already-registered tile class to override * @param string $newClass Class which extends the base class * * TODO: use an explicit template for param1 * @phpstan-param class-string $baseClass * @phpstan-param class-string $newClass * * @throws \InvalidArgumentException if the base class is not a registered tile */ public static function override(string $baseClass, string $newClass) : void{ if(!isset(self::$classMapping[$baseClass])){ throw new \InvalidArgumentException("Class $baseClass is not a registered tile"); } Utils::testValidInstance($newClass, $baseClass); self::$classMapping[$baseClass] = $newClass; } /** * @phpstan-template TTile of Tile * @phpstan-param class-string $baseClass * * @return Tile (will be an instanceof $baseClass) * @phpstan-return TTile * * @throws \InvalidArgumentException if the specified class is not a registered tile */ public static function create(string $baseClass, World $world, Vector3 $pos) : Tile{ if(isset(self::$classMapping[$baseClass])){ $class = self::$classMapping[$baseClass]; assert(is_a($class, $baseClass, true)); /** * @var Tile $tile * @phpstan-var TTile $tile * @see Tile::__construct() */ $tile = new $class($world, $pos); return $tile; } throw new \InvalidArgumentException("Class $baseClass is not a registered tile"); } /** * @internal */ public static function createFromData(World $world, CompoundTag $nbt) : ?Tile{ $type = $nbt->getString(Tile::TAG_ID, ""); if(!isset(self::$knownTiles[$type])){ return null; } $class = self::$knownTiles[$type]; assert(is_a($class, Tile::class, true)); /** * @var Tile $tile * @see Tile::__construct() */ $tile = new $class($world, new Vector3($nbt->getInt(Tile::TAG_X), $nbt->getInt(Tile::TAG_Y), $nbt->getInt(Tile::TAG_Z))); $tile->readSaveData($nbt); return $tile; } /** * @phpstan-param class-string $class */ public static function getSaveId(string $class) : string{ if(isset(self::$saveNames[$class])){ return reset(self::$saveNames[$class]); } throw new \InvalidArgumentException("Tile $class is not registered"); } }