From ba76a33ea65404a77eb2eb5878ca3baeb2b184ae Mon Sep 17 00:00:00 2001 From: IvanCraft623 Date: Fri, 16 Dec 2022 02:24:08 -0500 Subject: [PATCH 01/50] Implement Firework Rocket & Firework Star --- src/data/bedrock/FireworkRocketTypeIdMap.php | 67 +++++++ src/data/bedrock/FireworkRocketTypeIds.php | 32 ++++ .../ItemSerializerDeserializerRegistrar.php | 10 + .../animation/FireworkParticlesAnimation.php | 39 ++++ src/entity/object/FireworkRocket.php | 174 ++++++++++++++++++ src/item/FireworkRocket.php | 129 +++++++++++++ src/item/FireworkRocketExplosion.php | 117 ++++++++++++ src/item/FireworkRocketType.php | 71 +++++++ src/item/FireworkStar.php | 67 +++++++ src/item/ItemTypeIds.php | 4 +- src/item/StringToItemParser.php | 3 + src/item/VanillaItems.php | 4 + src/world/sound/FireworkBigExplosionSound.php | 35 ++++ src/world/sound/FireworkExplosionSound.php | 35 ++++ src/world/sound/FireworkLaunchSound.php | 35 ++++ src/world/sound/FireworkTwinkleSound.php | 35 ++++ 16 files changed, 856 insertions(+), 1 deletion(-) create mode 100644 src/data/bedrock/FireworkRocketTypeIdMap.php create mode 100644 src/data/bedrock/FireworkRocketTypeIds.php create mode 100644 src/entity/animation/FireworkParticlesAnimation.php create mode 100644 src/entity/object/FireworkRocket.php create mode 100644 src/item/FireworkRocket.php create mode 100644 src/item/FireworkRocketExplosion.php create mode 100644 src/item/FireworkRocketType.php create mode 100644 src/item/FireworkStar.php create mode 100644 src/world/sound/FireworkBigExplosionSound.php create mode 100644 src/world/sound/FireworkExplosionSound.php create mode 100644 src/world/sound/FireworkLaunchSound.php create mode 100644 src/world/sound/FireworkTwinkleSound.php diff --git a/src/data/bedrock/FireworkRocketTypeIdMap.php b/src/data/bedrock/FireworkRocketTypeIdMap.php new file mode 100644 index 00000000000..70dc033d1dc --- /dev/null +++ b/src/data/bedrock/FireworkRocketTypeIdMap.php @@ -0,0 +1,67 @@ + + */ + private array $idToEnum; + + /** + * @var int[] + * @phpstan-var array + */ + private array $enumToId; + + private function __construct(){ + $this->register(FireworkRocketTypeIds::SMALL_SPHERE, FireworkRocketType::SMALL_SPHERE()); + $this->register(FireworkRocketTypeIds::BIG_SPHERE, FireworkRocketType::BIG_SPHERE()); + $this->register(FireworkRocketTypeIds::STAR, FireworkRocketType::STAR()); + $this->register(FireworkRocketTypeIds::CREEPER, FireworkRocketType::CREEPER()); + $this->register(FireworkRocketTypeIds::BURST, FireworkRocketType::BURST()); + } + + private function register(int $id, FireworkRocketType $type) : void{ + $this->idToEnum[$id] = $type; + $this->enumToId[$type->id()] = $id; + } + + public function fromId(int $id) : ?FireworkRocketType{ + return $this->idToEnum[$id] ?? null; + } + + public function toId(FireworkRocketType $type) : int{ + if(!isset($this->enumToId[$type->id()])){ + throw new \InvalidArgumentException("Type does not have a mapped ID"); + } + return $this->enumToId[$type->id()]; + } +} diff --git a/src/data/bedrock/FireworkRocketTypeIds.php b/src/data/bedrock/FireworkRocketTypeIds.php new file mode 100644 index 00000000000..ae49aa594d7 --- /dev/null +++ b/src/data/bedrock/FireworkRocketTypeIds.php @@ -0,0 +1,32 @@ +map1to1Item(Ids::FEATHER, Items::FEATHER()); $this->map1to1Item(Ids::FERMENTED_SPIDER_EYE, Items::FERMENTED_SPIDER_EYE()); $this->map1to1Item(Ids::FIRE_CHARGE, Items::FIRE_CHARGE()); + $this->map1to1Item(Ids::FIREWORK_ROCKET, Items::FIREWORK_ROCKET()); $this->map1to1Item(Ids::FISHING_ROD, Items::FISHING_ROD()); $this->map1to1Item(Ids::FLINT, Items::FLINT()); $this->map1to1Item(Ids::FLINT_AND_STEEL, Items::FLINT_AND_STEEL()); @@ -462,6 +464,14 @@ function(Banner $item, int $meta) : void{ }, fn(Banner $item) => DyeColorIdMap::getInstance()->toInvertedId($item->getColor()) ); + $this->map1to1ItemWithMeta( + Ids::FIREWORK_STAR, + Items::FIREWORK_STAR(), + function(FireworkStar $item, int $meta) : void{ + $item->getExplosion()->setColor(DyeColorIdMap::getInstance()->fromInvertedId($meta) ?? throw new ItemTypeDeserializeException("Unknown firework star meta $meta")); + }, + fn(FireworkStar $item) => DyeColorIdMap::getInstance()->toInvertedId($item->getExplosion()->getColor()) + ); $this->map1to1ItemWithMeta( Ids::POTION, Items::POTION(), diff --git a/src/entity/animation/FireworkParticlesAnimation.php b/src/entity/animation/FireworkParticlesAnimation.php new file mode 100644 index 00000000000..cd9d56c8509 --- /dev/null +++ b/src/entity/animation/FireworkParticlesAnimation.php @@ -0,0 +1,39 @@ +entity->getId(), ActorEvent::FIREWORK_PARTICLES, 0) + ]; + } +} diff --git a/src/entity/object/FireworkRocket.php b/src/entity/object/FireworkRocket.php new file mode 100644 index 00000000000..b25e330f341 --- /dev/null +++ b/src/entity/object/FireworkRocket.php @@ -0,0 +1,174 @@ +lifeTicks = $lifeTicks; + $this->item = $item; + + parent::__construct($location, $nbt); + } + + protected function getInitialSizeInfo() : EntitySizeInfo{ return new EntitySizeInfo(0.25, 0.25); } + + protected function getInitialDragMultiplier() : float{ return 0.0; } + + protected function getInitialGravity() : float{ return 0.0; } + + /** + * Returns maximum number of ticks this will live for. + */ + public function getLifeTicks() : int{ + return $this->lifeTicks; + } + + /** + * Sets maximum number of ticks this will live for. + */ + public function setLifeTicks(int $lifeTicks) : void{ + if ($lifeTicks < 0) { + throw new \InvalidArgumentException("Life ticks cannot be negative"); + } + $this->lifeTicks = $lifeTicks; + } + + public function getItem() : Fireworks{ + return clone $this->item; + } + + public function setItem(Fireworks $item) : void{ + $this->item = $item; + } + + /** + * TODO: The entity should be saved and loaded, but this is not possible. + * @see https://bugs.mojang.com/browse/MCPE-165230 + */ + public function canSaveWithChunk() : bool{ + return false; + } + + protected function onFirstUpdate(int $currentTick) : void{ + $this->broadcastSound(new FireworkLaunchSound()); + } + + protected function entityBaseTick(int $tickDiff = 1) : bool{ + $hasUpdate = parent::entityBaseTick($tickDiff); + + if(!$this->isFlaggedForDespawn()){ + $this->motion->x *= 1.15; + $this->motion->y += 0.04; + $this->motion->z *= 1.15; + + if($this->ticksLived >= $this->lifeTicks){ + $this->explode(); + } + } + + return $hasUpdate; + } + + public function explode() : void{ + $explosions = $this->item->getExplosions(); + if(($expCount = count($explosions)) !== 0){ + $this->broadcastAnimation(new FireworkParticlesAnimation($this)); + foreach($explosions as $explosion){ + $this->broadcastSound($explosion->getType()->getSound()); + if($explosion->willTwinkle()){ + $this->broadcastSound(new FireworkTwinkleSound()); + } + } + + $force = ($expCount * 2) + 5; + foreach($this->getWorld()->getCollidingEntities($this->getBoundingBox()->expandedCopy(5, 5, 5), $this) as $entity){ + if(!$entity instanceof Living){ + continue; + } + + $position = $entity->getEyePos(); + $distance = $position->distance($this->location); + if($distance > 5){ + continue; + } + + $world = $this->getWorld(); + $obstructed = false; + foreach(VoxelRayTrace::betweenPoints($this->location, $position) as $pos){ + if($world->getBlockAt((int) $pos->x, (int) $pos->y, (int) $pos->z)->isSolid()){ + $obstructed = true; + break; + } + } + if($obstructed){ + continue; + } + + $ev = new EntityDamageByEntityEvent($this, $entity, EntityDamageEvent::CAUSE_ENTITY_EXPLOSION, $force * sqrt((5 - $distance) / 5)); + $entity->attack($ev); + } + } + + $this->flagForDespawn(); + } + + public function canBeCollidedWith() : bool{ + return false; + } + + protected function syncNetworkData(EntityMetadataCollection $properties) : void{ + parent::syncNetworkData($properties); + + $properties->setCompoundTag(EntityMetadataProperties::MINECART_DISPLAY_BLOCK, new CacheableNbt($this->item->getNamedTag())); + } +} diff --git a/src/item/FireworkRocket.php b/src/item/FireworkRocket.php new file mode 100644 index 00000000000..d366a0384a4 --- /dev/null +++ b/src/item/FireworkRocket.php @@ -0,0 +1,129 @@ +flightDuration; + } + + public function setFlightDuration(int $duration) : void{ + if($duration < 1 || $duration > 255){ + throw new \InvalidArgumentException("Flight duration must be in range 1-255"); + } + $this->flightDuration = $duration; + } + + /** + * @return FireworkRocketExplosion[] + */ + public function getExplosions() : array{ + return $this->explosions; + } + + /** + * @param FireworkRocketExplosion[] $explosions + */ + public function setExplosions(array $explosions) : void{ + Utils::validateArrayValueType($explosions, function(FireworkRocketExplosion $_) : void{}); + $this->explosions = $explosions; + } + + public function onInteractBlock(Player $player, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, array &$returnedItems) : ItemUseResult{ + $correction = 0.15; + $position = $blockClicked->getPosition()->addVector($clickVector); + $position = match($face){ + Facing::DOWN => $position->add(0, -$correction, 0), + Facing::UP => $position->add(0, $correction, 0), + Facing::NORTH => $position->add(0, 0, -$correction), + Facing::SOUTH => $position->add(0, 0, $correction), + Facing::WEST => $position->add(-$correction, 0, 0), + Facing::EAST => $position->add($correction, 0, 0) + }; + + $randomDuration = (($this->flightDuration + 1) * 10) + mt_rand(0, 12); + + $entity = new FireworkEntity(Location::fromObject($position, $player->getWorld(), lcg_value() * 360, 90), $randomDuration, $this->pop()); + $entity->setOwningEntity($player); + $entity->setMotion(new Vector3(lcg_value() * 0.001, 0.05, lcg_value() * 0.001)); + $entity->spawnToAll(); + + return ItemUseResult::SUCCESS(); + } + + protected function deserializeCompoundTag(CompoundTag $tag) : void{ + parent::deserializeCompoundTag($tag); + + $fireworksTag = $tag->getCompoundTag(self::TAG_FIREWORK_DATA); + if($fireworksTag === null){ + throw new SavedDataLoadingException("Missing firework data"); + } + + $this->flightDuration = $fireworksTag->getByte(self::TAG_FLIGH_DURATION, 1); + + if(($explosions = $fireworksTag->getListTag(self::TAG_EXPLOSIONS)) instanceof ListTag){ + /** @var CompoundTag $explosion */ + foreach($explosions as $explosion){ + $this->explosions[] = FireworkRocketExplosion::fromCompoundTag($explosion); + } + } + } + + protected function serializeCompoundTag(CompoundTag $tag) : void{ + parent::serializeCompoundTag($tag); + + $fireworksTag = CompoundTag::create(); + $fireworksTag->setByte(self::TAG_FLIGH_DURATION, $this->flightDuration); + + $explosions = new ListTag(); + foreach($this->explosions as $explosion){ + $explosions->push($explosion->toCompoundTag()); + } + $fireworksTag->setTag(self::TAG_EXPLOSIONS, $explosions); + + $tag->setTag(self::TAG_FIREWORK_DATA, $fireworksTag); + } +} diff --git a/src/item/FireworkRocketExplosion.php b/src/item/FireworkRocketExplosion.php new file mode 100644 index 00000000000..40d65fb33b5 --- /dev/null +++ b/src/item/FireworkRocketExplosion.php @@ -0,0 +1,117 @@ +getByteArray(self::TAG_FADE)) !== "") { + $fade = $dyeColorIdMap->fromInvertedId(Binary::readByte($fadeTag)) ?? throw new SavedDataLoadingException("Invalid fade color"); + } + + return new self( + FireworkRocketTypeIdMap::getInstance()->fromId($tag->getByte(self::TAG_TYPE)) ?? throw new SavedDataLoadingException("Invalid firework type"), + $dyeColorIdMap->fromInvertedId(Binary::readByte($tag->getByteArray(self::TAG_COLOR))) ?? throw new SavedDataLoadingException("Invalid dye color"), + $fade, + $tag->getByte(self::TAG_TWINKLE, 0) !== 0, + $tag->getByte(self::TAG_TRAIL, 0) !== 0 + ); + } + + public function __construct( + protected FireworkRocketType $type, + protected DyeColor $color, + protected ?DyeColor $fade, + protected bool $twinkle, + protected bool $trail + ){} + + public function getType() : FireworkRocketType{ + return $this->type; + } + + public function setType(FireworkRocketType $type) : void{ + $this->type = $type; + } + + public function getColor() : DyeColor{ + return $this->color; + } + + public function setColor(DyeColor $color) : void{ + $this->color = $color; + } + + public function getFade() : DyeColor{ + return $this->fade; + } + + public function setFade(DyeColor $fade) : void{ + $this->fade = $fade; + } + + public function willTwinkle() : bool{ + return $this->twinkle; + } + + public function setTwinkle(bool $twinkle) : void{ + $this->twinkle = $twinkle; + } + + public function getTrail() : bool{ + return $this->trail; + } + + public function setTrail(bool $trail) : void{ + $this->trail = $trail; + } + + public function toCompoundTag() : CompoundTag{ + $dyeColorIdMap = DyeColorIdMap::getInstance(); + + return CompoundTag::create() + ->setByte(self::TAG_TYPE, FireworkRocketTypeIdMap::getInstance()->toId($this->type)) + ->setByteArray(self::TAG_COLOR, Binary::writeByte($dyeColorIdMap->toInvertedId($this->color))) + ->setByteArray(self::TAG_FADE, $this->fade === null ? "" : Binary::writeByte($dyeColorIdMap->toInvertedId($this->fade))) + ->setByte(self::TAG_TWINKLE, $this->twinkle ? 1 : 0) + ->setByte(self::TAG_TRAIL, $this->trail ? 1 : 0) + ; + } +} diff --git a/src/item/FireworkRocketType.php b/src/item/FireworkRocketType.php new file mode 100644 index 00000000000..dc5397fb0fe --- /dev/null +++ b/src/item/FireworkRocketType.php @@ -0,0 +1,71 @@ + new FireworkExplosionSound()), + new self("big_sphere", fn() => new FireworkBigExplosionSound()), + new self("star", fn() => new FireworkExplosionSound()), + new self("creeper", fn() => new FireworkExplosionSound()), + new self("burst", fn() => new FireworkExplosionSound()), + ); + } + + /** + * @phpstan-param \Closure() : Sound + */ + private function __construct( + string $enumName, + private \Closure $soundGetter + ){ + $this->Enum___construct($enumName); + } + + public function getSound() : Sound{ + return ($this->soundGetter)(); + } +} diff --git a/src/item/FireworkStar.php b/src/item/FireworkStar.php new file mode 100644 index 00000000000..a86f5dd1f86 --- /dev/null +++ b/src/item/FireworkStar.php @@ -0,0 +1,67 @@ +explosion = new FireworksExplosion(FireworksType::SMALL_SPHERE(), DyeColor::BLACK(), null, false, false); + } + + public function getExplosion() : FireworksExplosion{ + return $this->explosion; + } + + public function setExplosion(FireworksExplosion $explosion) : void{ + $this->explosion = $explosion; + } + + protected function deserializeCompoundTag(CompoundTag $tag) : void{ + parent::deserializeCompoundTag($tag); + + $explosionTag = $tag->getTag(self::TAG_EXPLOSION); + if (!$explosionTag instanceof CompoundTag) { + throw new SavedDataLoadingException("Missing explosion data"); + } + $this->explosion = FireworksExplosion::fromCompoundTag($explosionTag); + } + + protected function serializeCompoundTag(CompoundTag $tag) : void{ + parent::serializeCompoundTag($tag); + + $tag->setTag(self::TAG_EXPLOSION, $this->explosion->toCompoundTag()); + $tag->setInt(self::TAG_COLOR, Binary::signInt($this->explosion->getColor()->getRgbValue()->toARGB())); + } +} diff --git a/src/item/ItemTypeIds.php b/src/item/ItemTypeIds.php index cc4be26d4e0..e8b1b5ee858 100644 --- a/src/item/ItemTypeIds.php +++ b/src/item/ItemTypeIds.php @@ -299,8 +299,10 @@ private function __construct(){ public const FIRE_CHARGE = 20260; public const SUSPICIOUS_STEW = 20261; public const TURTLE_HELMET = 20262; + public const FIREWORK_ROCKET = 20263; + public const FIREWORK_STAR = 20264; - public const FIRST_UNUSED_ITEM_ID = 20263; + public const FIRST_UNUSED_ITEM_ID = 20265; private static int $nextDynamicId = self::FIRST_UNUSED_ITEM_ID; diff --git a/src/item/StringToItemParser.php b/src/item/StringToItemParser.php index b1ff4000b25..256cfefdfc2 100644 --- a/src/item/StringToItemParser.php +++ b/src/item/StringToItemParser.php @@ -1257,6 +1257,9 @@ private static function registerItems(self $result) : void{ $result->register("fire_charge", fn() => Items::FIRE_CHARGE()); $result->register("fire_resistance_potion", fn() => Items::POTION()->setType(PotionType::FIRE_RESISTANCE())); $result->register("fire_resistance_splash_potion", fn() => Items::SPLASH_POTION()->setType(PotionType::FIRE_RESISTANCE())); + $result->register("firework_rocket", fn() => Items::FIREWORKS()); + $result->register("firework_star", fn() => Items::FIREWORK_STAR()); + $result->register("fireworks", fn() => Items::FIREWORKS()); $result->register("fish", fn() => Items::RAW_FISH()); $result->register("fishing_rod", fn() => Items::FISHING_ROD()); $result->register("flint", fn() => Items::FLINT()); diff --git a/src/item/VanillaItems.php b/src/item/VanillaItems.php index f9e7862373f..daefdfb0f75 100644 --- a/src/item/VanillaItems.php +++ b/src/item/VanillaItems.php @@ -157,6 +157,8 @@ * @method static Item FEATHER() * @method static Item FERMENTED_SPIDER_EYE() * @method static FireCharge FIRE_CHARGE() + * @method static FireworkRocket FIREWORK_ROCKET() + * @method static FireworkStar FIREWORK_STAR() * @method static FishingRod FISHING_ROD() * @method static Item FLINT() * @method static FlintSteel FLINT_AND_STEEL() @@ -428,6 +430,8 @@ protected static function setup() : void{ self::register("feather", new Item(new IID(Ids::FEATHER), "Feather")); self::register("fermented_spider_eye", new Item(new IID(Ids::FERMENTED_SPIDER_EYE), "Fermented Spider Eye")); self::register("fire_charge", new FireCharge(new IID(Ids::FIRE_CHARGE), "Fire Charge")); + self::register("firework_rocket", new FireworkRocket(new IID(Ids::FIREWORKS), "Firework Rocket")); + self::register("firework_star", new FireworkStar(new IID(Ids::FIREWORK_STAR), "Firework Star")); self::register("fishing_rod", new FishingRod(new IID(Ids::FISHING_ROD), "Fishing Rod")); self::register("flint", new Item(new IID(Ids::FLINT), "Flint")); self::register("flint_and_steel", new FlintSteel(new IID(Ids::FLINT_AND_STEEL), "Flint and Steel")); diff --git a/src/world/sound/FireworkBigExplosionSound.php b/src/world/sound/FireworkBigExplosionSound.php new file mode 100644 index 00000000000..462b7ded2b2 --- /dev/null +++ b/src/world/sound/FireworkBigExplosionSound.php @@ -0,0 +1,35 @@ + Date: Fri, 16 Dec 2022 02:40:54 -0500 Subject: [PATCH 02/50] Fix PHPStan --- src/entity/object/FireworkRocket.php | 13 +++++++------ src/item/FireworkRocket.php | 6 +++--- src/item/FireworkStar.php | 10 +++++----- src/item/StringToItemParser.php | 4 ++-- src/item/VanillaItems.php | 2 +- 5 files changed, 18 insertions(+), 17 deletions(-) diff --git a/src/entity/object/FireworkRocket.php b/src/entity/object/FireworkRocket.php index b25e330f341..058ecaa78d5 100644 --- a/src/entity/object/FireworkRocket.php +++ b/src/entity/object/FireworkRocket.php @@ -25,12 +25,12 @@ use pocketmine\entity\animation\FireworkParticlesAnimation; use pocketmine\entity\Entity; -use pocketmine\entity\Living; use pocketmine\entity\EntitySizeInfo; +use pocketmine\entity\Living; use pocketmine\entity\Location; use pocketmine\event\entity\EntityDamageByEntityEvent; use pocketmine\event\entity\EntityDamageEvent; -use pocketmine\item\Fireworks; +use pocketmine\item\FireworkRocket as FireworkItem; use pocketmine\math\VoxelRayTrace; use pocketmine\nbt\tag\CompoundTag; use pocketmine\network\mcpe\protocol\types\CacheableNbt; @@ -39,6 +39,7 @@ use pocketmine\network\mcpe\protocol\types\entity\EntityMetadataProperties; use pocketmine\world\sound\FireworkLaunchSound; use pocketmine\world\sound\FireworkTwinkleSound; +use function count; use function sqrt; class FireworkRocket extends Entity{ @@ -48,9 +49,9 @@ public static function getNetworkTypeId() : string{ return EntityIds::FIREWORKS_ /* Maximum number of ticks this will live for. */ protected int $lifeTicks; - protected Fireworks $item; + protected FireworkItem $item; - public function __construct(Location $location, int $lifeTicks, Fireworks $item, ?CompoundTag $nbt = null){ + public function __construct(Location $location, int $lifeTicks, FireworkItem $item, ?CompoundTag $nbt = null){ if ($lifeTicks < 0) { throw new \InvalidArgumentException("Life ticks cannot be negative"); } @@ -83,11 +84,11 @@ public function setLifeTicks(int $lifeTicks) : void{ $this->lifeTicks = $lifeTicks; } - public function getItem() : Fireworks{ + public function getItem() : FireworkItem{ return clone $this->item; } - public function setItem(Fireworks $item) : void{ + public function setItem(FireworkItem $item) : void{ $this->item = $item; } diff --git a/src/item/FireworkRocket.php b/src/item/FireworkRocket.php index d366a0384a4..fa569bb622a 100644 --- a/src/item/FireworkRocket.php +++ b/src/item/FireworkRocket.php @@ -32,6 +32,8 @@ use pocketmine\nbt\tag\ListTag; use pocketmine\player\Player; use pocketmine\utils\Utils; +use function lcg_value; +use function mt_rand; class FireworkRocket extends Item{ @@ -41,9 +43,7 @@ class FireworkRocket extends Item{ protected int $flightDuration = 1; - /** - * @var FireworkRocketExplosion[] - */ + /** @var FireworkRocketExplosion[] */ protected array $explosions = []; public function getFlightDuration() : int{ diff --git a/src/item/FireworkStar.php b/src/item/FireworkStar.php index a86f5dd1f86..e0a4709e211 100644 --- a/src/item/FireworkStar.php +++ b/src/item/FireworkStar.php @@ -32,19 +32,19 @@ class FireworkStar extends Item{ protected const TAG_EXPLOSION = "FireworksItem"; //TAG_Compound protected const TAG_COLOR = "customColor"; //TAG_Int - protected FireworksExplosion $explosion; + protected FireworkRocketExplosion $explosion; public function __construct(ItemIdentifier $identifier, string $name){ parent::__construct($identifier, $name); - $this->explosion = new FireworksExplosion(FireworksType::SMALL_SPHERE(), DyeColor::BLACK(), null, false, false); + $this->explosion = new FireworkRocketExplosion(FireworkRocketType::SMALL_SPHERE(), DyeColor::BLACK(), null, false, false); } - public function getExplosion() : FireworksExplosion{ + public function getExplosion() : FireworkRocketExplosion{ return $this->explosion; } - public function setExplosion(FireworksExplosion $explosion) : void{ + public function setExplosion(FireworkRocketExplosion $explosion) : void{ $this->explosion = $explosion; } @@ -55,7 +55,7 @@ protected function deserializeCompoundTag(CompoundTag $tag) : void{ if (!$explosionTag instanceof CompoundTag) { throw new SavedDataLoadingException("Missing explosion data"); } - $this->explosion = FireworksExplosion::fromCompoundTag($explosionTag); + $this->explosion = FireworkRocketExplosion::fromCompoundTag($explosionTag); } protected function serializeCompoundTag(CompoundTag $tag) : void{ diff --git a/src/item/StringToItemParser.php b/src/item/StringToItemParser.php index 256cfefdfc2..03bf78f5370 100644 --- a/src/item/StringToItemParser.php +++ b/src/item/StringToItemParser.php @@ -1257,9 +1257,9 @@ private static function registerItems(self $result) : void{ $result->register("fire_charge", fn() => Items::FIRE_CHARGE()); $result->register("fire_resistance_potion", fn() => Items::POTION()->setType(PotionType::FIRE_RESISTANCE())); $result->register("fire_resistance_splash_potion", fn() => Items::SPLASH_POTION()->setType(PotionType::FIRE_RESISTANCE())); - $result->register("firework_rocket", fn() => Items::FIREWORKS()); + $result->register("firework_rocket", fn() => Items::FIREWORK_ROCKET()); $result->register("firework_star", fn() => Items::FIREWORK_STAR()); - $result->register("fireworks", fn() => Items::FIREWORKS()); + $result->register("fireworks", fn() => Items::FIREWORK_ROCKET()); $result->register("fish", fn() => Items::RAW_FISH()); $result->register("fishing_rod", fn() => Items::FISHING_ROD()); $result->register("flint", fn() => Items::FLINT()); diff --git a/src/item/VanillaItems.php b/src/item/VanillaItems.php index daefdfb0f75..09965aa2b04 100644 --- a/src/item/VanillaItems.php +++ b/src/item/VanillaItems.php @@ -430,7 +430,7 @@ protected static function setup() : void{ self::register("feather", new Item(new IID(Ids::FEATHER), "Feather")); self::register("fermented_spider_eye", new Item(new IID(Ids::FERMENTED_SPIDER_EYE), "Fermented Spider Eye")); self::register("fire_charge", new FireCharge(new IID(Ids::FIRE_CHARGE), "Fire Charge")); - self::register("firework_rocket", new FireworkRocket(new IID(Ids::FIREWORKS), "Firework Rocket")); + self::register("firework_rocket", new FireworkRocket(new IID(Ids::FIREWORK_ROCKET), "Firework Rocket")); self::register("firework_star", new FireworkStar(new IID(Ids::FIREWORK_STAR), "Firework Star")); self::register("fishing_rod", new FishingRod(new IID(Ids::FISHING_ROD), "Fishing Rod")); self::register("flint", new Item(new IID(Ids::FLINT), "Flint")); From bd83e995c5124641441786edfabeb5dbc6cdce37 Mon Sep 17 00:00:00 2001 From: IvanCraft623 Date: Fri, 16 Dec 2022 12:11:53 -0500 Subject: [PATCH 03/50] Make PHPStan happy --- src/item/FireworkRocket.php | 5 ++++- src/item/FireworkRocketExplosion.php | 4 ++-- src/item/FireworkRocketType.php | 2 +- src/item/FireworkStar.php | 1 + src/item/StringToItemParser.php | 6 +++--- src/item/VanillaItems.php | 4 ++-- 6 files changed, 13 insertions(+), 9 deletions(-) diff --git a/src/item/FireworkRocket.php b/src/item/FireworkRocket.php index fa569bb622a..688f73e21eb 100644 --- a/src/item/FireworkRocket.php +++ b/src/item/FireworkRocket.php @@ -24,6 +24,7 @@ namespace pocketmine\item; use pocketmine\block\Block; +use pocketmine\data\SavedDataLoadingException; use pocketmine\entity\Location; use pocketmine\entity\object\FireworkRocket as FireworkEntity; use pocketmine\math\Facing; @@ -31,6 +32,7 @@ use pocketmine\nbt\tag\CompoundTag; use pocketmine\nbt\tag\ListTag; use pocketmine\player\Player; +use pocketmine\utils\AssumptionFailedError; use pocketmine\utils\Utils; use function lcg_value; use function mt_rand; @@ -81,7 +83,8 @@ public function onInteractBlock(Player $player, Block $blockReplace, Block $bloc Facing::NORTH => $position->add(0, 0, -$correction), Facing::SOUTH => $position->add(0, 0, $correction), Facing::WEST => $position->add(-$correction, 0, 0), - Facing::EAST => $position->add($correction, 0, 0) + Facing::EAST => $position->add($correction, 0, 0), + default => throw new AssumptionFailedError("Invalid facing $facing") }; $randomDuration = (($this->flightDuration + 1) * 10) + mt_rand(0, 12); diff --git a/src/item/FireworkRocketExplosion.php b/src/item/FireworkRocketExplosion.php index 40d65fb33b5..498db6303ef 100644 --- a/src/item/FireworkRocketExplosion.php +++ b/src/item/FireworkRocketExplosion.php @@ -79,11 +79,11 @@ public function setColor(DyeColor $color) : void{ $this->color = $color; } - public function getFade() : DyeColor{ + public function getFade() : ?DyeColor{ return $this->fade; } - public function setFade(DyeColor $fade) : void{ + public function setFade(?DyeColor $fade) : void{ $this->fade = $fade; } diff --git a/src/item/FireworkRocketType.php b/src/item/FireworkRocketType.php index dc5397fb0fe..ea37244ad00 100644 --- a/src/item/FireworkRocketType.php +++ b/src/item/FireworkRocketType.php @@ -56,7 +56,7 @@ protected static function setup() : void{ } /** - * @phpstan-param \Closure() : Sound + * @phpstan-param \Closure() : Sound $soundGetter */ private function __construct( string $enumName, diff --git a/src/item/FireworkStar.php b/src/item/FireworkStar.php index e0a4709e211..aa3148b33c7 100644 --- a/src/item/FireworkStar.php +++ b/src/item/FireworkStar.php @@ -24,6 +24,7 @@ namespace pocketmine\item; use pocketmine\block\utils\DyeColor; +use pocketmine\data\SavedDataLoadingException; use pocketmine\nbt\tag\CompoundTag; use pocketmine\utils\Binary; diff --git a/src/item/StringToItemParser.php b/src/item/StringToItemParser.php index 03bf78f5370..fd158e1b919 100644 --- a/src/item/StringToItemParser.php +++ b/src/item/StringToItemParser.php @@ -1254,12 +1254,12 @@ private static function registerItems(self $result) : void{ $result->register("experience_bottle", fn() => Items::EXPERIENCE_BOTTLE()); $result->register("feather", fn() => Items::FEATHER()); $result->register("fermented_spider_eye", fn() => Items::FERMENTED_SPIDER_EYE()); - $result->register("fire_charge", fn() => Items::FIRE_CHARGE()); - $result->register("fire_resistance_potion", fn() => Items::POTION()->setType(PotionType::FIRE_RESISTANCE())); - $result->register("fire_resistance_splash_potion", fn() => Items::SPLASH_POTION()->setType(PotionType::FIRE_RESISTANCE())); $result->register("firework_rocket", fn() => Items::FIREWORK_ROCKET()); $result->register("firework_star", fn() => Items::FIREWORK_STAR()); $result->register("fireworks", fn() => Items::FIREWORK_ROCKET()); + $result->register("fire_charge", fn() => Items::FIRE_CHARGE()); + $result->register("fire_resistance_potion", fn() => Items::POTION()->setType(PotionType::FIRE_RESISTANCE())); + $result->register("fire_resistance_splash_potion", fn() => Items::SPLASH_POTION()->setType(PotionType::FIRE_RESISTANCE())); $result->register("fish", fn() => Items::RAW_FISH()); $result->register("fishing_rod", fn() => Items::FISHING_ROD()); $result->register("flint", fn() => Items::FLINT()); diff --git a/src/item/VanillaItems.php b/src/item/VanillaItems.php index 09965aa2b04..fbd096f23d9 100644 --- a/src/item/VanillaItems.php +++ b/src/item/VanillaItems.php @@ -156,9 +156,9 @@ * @method static ExperienceBottle EXPERIENCE_BOTTLE() * @method static Item FEATHER() * @method static Item FERMENTED_SPIDER_EYE() - * @method static FireCharge FIRE_CHARGE() * @method static FireworkRocket FIREWORK_ROCKET() * @method static FireworkStar FIREWORK_STAR() + * @method static FireCharge FIRE_CHARGE() * @method static FishingRod FISHING_ROD() * @method static Item FLINT() * @method static FlintSteel FLINT_AND_STEEL() @@ -429,9 +429,9 @@ protected static function setup() : void{ self::register("experience_bottle", new ExperienceBottle(new IID(Ids::EXPERIENCE_BOTTLE), "Bottle o' Enchanting")); self::register("feather", new Item(new IID(Ids::FEATHER), "Feather")); self::register("fermented_spider_eye", new Item(new IID(Ids::FERMENTED_SPIDER_EYE), "Fermented Spider Eye")); - self::register("fire_charge", new FireCharge(new IID(Ids::FIRE_CHARGE), "Fire Charge")); self::register("firework_rocket", new FireworkRocket(new IID(Ids::FIREWORK_ROCKET), "Firework Rocket")); self::register("firework_star", new FireworkStar(new IID(Ids::FIREWORK_STAR), "Firework Star")); + self::register("fire_charge", new FireCharge(new IID(Ids::FIRE_CHARGE), "Fire Charge")); self::register("fishing_rod", new FishingRod(new IID(Ids::FISHING_ROD), "Fishing Rod")); self::register("flint", new Item(new IID(Ids::FLINT), "Flint")); self::register("flint_and_steel", new FlintSteel(new IID(Ids::FLINT_AND_STEEL), "Flint and Steel")); From 58605e7ef3a8f941f7646c8d10ed696af74ada30 Mon Sep 17 00:00:00 2001 From: IvanCraft623 Date: Fri, 16 Dec 2022 12:58:22 -0500 Subject: [PATCH 04/50] ... --- src/item/FireworkRocket.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/item/FireworkRocket.php b/src/item/FireworkRocket.php index 688f73e21eb..4a86936f870 100644 --- a/src/item/FireworkRocket.php +++ b/src/item/FireworkRocket.php @@ -84,7 +84,7 @@ public function onInteractBlock(Player $player, Block $blockReplace, Block $bloc Facing::SOUTH => $position->add(0, 0, $correction), Facing::WEST => $position->add(-$correction, 0, 0), Facing::EAST => $position->add($correction, 0, 0), - default => throw new AssumptionFailedError("Invalid facing $facing") + default => throw new AssumptionFailedError("Invalid facing $face") }; $randomDuration = (($this->flightDuration + 1) * 10) + mt_rand(0, 12); @@ -105,7 +105,7 @@ protected function deserializeCompoundTag(CompoundTag $tag) : void{ throw new SavedDataLoadingException("Missing firework data"); } - $this->flightDuration = $fireworksTag->getByte(self::TAG_FLIGH_DURATION, 1); + $this->setFlightDuration($fireworksTag->getByte(self::TAG_FLIGH_DURATION, 1)); if(($explosions = $fireworksTag->getListTag(self::TAG_EXPLOSIONS)) instanceof ListTag){ /** @var CompoundTag $explosion */ From d01a8c352aae7e99ce208e8467000c428c88ca98 Mon Sep 17 00:00:00 2001 From: IvanCraft623 Date: Fri, 16 Dec 2022 23:18:12 -0500 Subject: [PATCH 05/50] Implement explosion multi-color & firework star custom color --- .../ItemSerializerDeserializerRegistrar.php | 6 +- src/item/FireworkRocketExplosion.php | 131 +++++++++++++++--- src/item/FireworkStar.php | 48 ++++++- 3 files changed, 156 insertions(+), 29 deletions(-) diff --git a/src/data/bedrock/item/ItemSerializerDeserializerRegistrar.php b/src/data/bedrock/item/ItemSerializerDeserializerRegistrar.php index 9e9507bf928..c31ca0e8051 100644 --- a/src/data/bedrock/item/ItemSerializerDeserializerRegistrar.php +++ b/src/data/bedrock/item/ItemSerializerDeserializerRegistrar.php @@ -224,8 +224,8 @@ private function register1to1ItemMappings() : void{ $this->map1to1Item(Ids::EXPERIENCE_BOTTLE, Items::EXPERIENCE_BOTTLE()); $this->map1to1Item(Ids::FEATHER, Items::FEATHER()); $this->map1to1Item(Ids::FERMENTED_SPIDER_EYE, Items::FERMENTED_SPIDER_EYE()); - $this->map1to1Item(Ids::FIRE_CHARGE, Items::FIRE_CHARGE()); $this->map1to1Item(Ids::FIREWORK_ROCKET, Items::FIREWORK_ROCKET()); + $this->map1to1Item(Ids::FIRE_CHARGE, Items::FIRE_CHARGE()); $this->map1to1Item(Ids::FISHING_ROD, Items::FISHING_ROD()); $this->map1to1Item(Ids::FLINT, Items::FLINT()); $this->map1to1Item(Ids::FLINT_AND_STEEL, Items::FLINT_AND_STEEL()); @@ -468,9 +468,9 @@ function(Banner $item, int $meta) : void{ Ids::FIREWORK_STAR, Items::FIREWORK_STAR(), function(FireworkStar $item, int $meta) : void{ - $item->getExplosion()->setColor(DyeColorIdMap::getInstance()->fromInvertedId($meta) ?? throw new ItemTypeDeserializeException("Unknown firework star meta $meta")); + $item->getExplosion()->setColors([DyeColorIdMap::getInstance()->fromInvertedId($meta) ?? throw new ItemTypeDeserializeException("Unknown firework star meta $meta")]); }, - fn(FireworkStar $item) => DyeColorIdMap::getInstance()->toInvertedId($item->getExplosion()->getColor()) + fn(FireworkStar $item) => DyeColorIdMap::getInstance()->toInvertedId($item->getExplosion()->getMainColor()) ); $this->map1to1ItemWithMeta( Ids::POTION, diff --git a/src/item/FireworkRocketExplosion.php b/src/item/FireworkRocketExplosion.php index 498db6303ef..69e337cf39a 100644 --- a/src/item/FireworkRocketExplosion.php +++ b/src/item/FireworkRocketExplosion.php @@ -24,44 +24,81 @@ namespace pocketmine\item; use pocketmine\block\utils\DyeColor; +use pocketmine\color\Color; use pocketmine\data\bedrock\DyeColorIdMap; use pocketmine\data\bedrock\FireworkRocketTypeIdMap; use pocketmine\data\SavedDataLoadingException; use pocketmine\nbt\tag\CompoundTag; use pocketmine\utils\Binary; +use pocketmine\utils\Utils; +use function array_key_first; +use function array_values; +use function count; +use function strlen; class FireworkRocketExplosion{ protected const TAG_TYPE = "FireworkType"; //TAG_Byte - protected const TAG_COLOR = "FireworkColor"; //TAG_ByteArray - protected const TAG_FADE = "FireworkFade"; //TAG_ByteArray + protected const TAG_COLORS = "FireworkColor"; //TAG_ByteArray + protected const TAG_FADE_COLORS = "FireworkFade"; //TAG_ByteArray protected const TAG_TWINKLE = "FireworkFlicker"; //TAG_Byte protected const TAG_TRAIL = "FireworkTrail"; //TAG_Byte public static function fromCompoundTag(CompoundTag $tag) : self{ - $dyeColorIdMap = DyeColorIdMap::getInstance(); - - $fade = null; - if (($fadeTag = $tag->getByteArray(self::TAG_FADE)) !== "") { - $fade = $dyeColorIdMap->fromInvertedId(Binary::readByte($fadeTag)) ?? throw new SavedDataLoadingException("Invalid fade color"); + $colors = self::decodeColors($tag->getByteArray(self::TAG_COLORS)); + if(count($colors) === 0){ + throw new SavedDataLoadingException("Colors list cannot be empty"); } return new self( FireworkRocketTypeIdMap::getInstance()->fromId($tag->getByte(self::TAG_TYPE)) ?? throw new SavedDataLoadingException("Invalid firework type"), - $dyeColorIdMap->fromInvertedId(Binary::readByte($tag->getByteArray(self::TAG_COLOR))) ?? throw new SavedDataLoadingException("Invalid dye color"), - $fade, + $colors, + self::decodeColors($tag->getByteArray(self::TAG_FADE_COLORS)), $tag->getByte(self::TAG_TWINKLE, 0) !== 0, $tag->getByte(self::TAG_TRAIL, 0) !== 0 ); } + /** + * @return DyeColor[] + */ + protected static function decodeColors(string $colorsBytes) : array{ + $colors = []; + + $dyeColorIdMap = DyeColorIdMap::getInstance(); + for($i=0; $i < strlen($colorsBytes); $i++){ + $color = $dyeColorIdMap->fromInvertedId(Binary::readByte($colorsBytes[$i])); + if($color !== null){ + $colors[] = $color; + }else{ + //TODO: should throw an exception? + } + } + + return $colors; + } + + protected \Closure $colorsValidator; + + /** + * @param DyeColor[] $colors + * @param DyeColor[] $fadeColors + */ public function __construct( protected FireworkRocketType $type, - protected DyeColor $color, - protected ?DyeColor $fade, + protected array $colors, + protected array $fadeColors, protected bool $twinkle, protected bool $trail - ){} + ){ + $this->colorsValidator = function(DyeColor $_) : void{}; + + if(count($colors) === 0){ + throw new \InvalidArgumentException("Colors list cannot be empty"); + } + $this->setColors($colors); + $this->setFadeColors($fadeColors); + } public function getType() : FireworkRocketType{ return $this->type; @@ -71,20 +108,56 @@ public function setType(FireworkRocketType $type) : void{ $this->type = $type; } - public function getColor() : DyeColor{ - return $this->color; + /** + * @return DyeColor[] + */ + public function getColors() : array{ + return $this->colors; } - public function setColor(DyeColor $color) : void{ - $this->color = $color; + /** + * @param DyeColor[] $colors + */ + public function setColors(array $colors) : void{ + if(count($colors) === 0){ + throw new \InvalidArgumentException("Colors list cannot be empty"); + } + Utils::validateArrayValueType($colors, $this->colorsValidator); + $this->colors = array_values($colors); } - public function getFade() : ?DyeColor{ - return $this->fade; + /** + * Returns the main color, this defines stuff like meta. + */ + public function getMainColor() : DyeColor{ + return $this->colors[array_key_first($this->colors)]; } - public function setFade(?DyeColor $fade) : void{ - $this->fade = $fade; + /** + * Returns a the mix of all colors. + */ + public function getColorMix() : Color{ + /** @var Color[] $colors */ + $colors = []; + foreach ($this->colors as $dyeColor) { + $colors[] = $dyeColor->getRgbValue(); + } + return Color::mix(...$colors); + } + + /** + * @return DyeColor[] + */ + public function getFadeColors() : array{ + return $this->fadeColors; + } + + /** + * @param DyeColor[] $colors + */ + public function setFadeColors(array $colors) : void{ + Utils::validateArrayValueType($colors, $this->colorsValidator); + $this->fadeColors = array_values($colors); } public function willTwinkle() : bool{ @@ -108,10 +181,24 @@ public function toCompoundTag() : CompoundTag{ return CompoundTag::create() ->setByte(self::TAG_TYPE, FireworkRocketTypeIdMap::getInstance()->toId($this->type)) - ->setByteArray(self::TAG_COLOR, Binary::writeByte($dyeColorIdMap->toInvertedId($this->color))) - ->setByteArray(self::TAG_FADE, $this->fade === null ? "" : Binary::writeByte($dyeColorIdMap->toInvertedId($this->fade))) + ->setByteArray(self::TAG_COLORS, $this->encodeColors($this->colors)) + ->setByteArray(self::TAG_FADE_COLORS, $this->encodeColors($this->fadeColors)) ->setByte(self::TAG_TWINKLE, $this->twinkle ? 1 : 0) ->setByte(self::TAG_TRAIL, $this->trail ? 1 : 0) ; } + + /** + * @param DyeColor[] $colors + */ + protected function encodeColors(array $colors) : string{ + $colorsBytes = ""; + + $dyeColorIdMap = DyeColorIdMap::getInstance(); + foreach($colors as $color){ + $colorsBytes .= Binary::writeByte($dyeColorIdMap->toInvertedId($color)); + } + + return $colorsBytes; + } } diff --git a/src/item/FireworkStar.php b/src/item/FireworkStar.php index aa3148b33c7..9d6384bfb66 100644 --- a/src/item/FireworkStar.php +++ b/src/item/FireworkStar.php @@ -24,6 +24,7 @@ namespace pocketmine\item; use pocketmine\block\utils\DyeColor; +use pocketmine\color\Color; use pocketmine\data\SavedDataLoadingException; use pocketmine\nbt\tag\CompoundTag; use pocketmine\utils\Binary; @@ -31,22 +32,51 @@ class FireworkStar extends Item{ protected const TAG_EXPLOSION = "FireworksItem"; //TAG_Compound - protected const TAG_COLOR = "customColor"; //TAG_Int + protected const TAG_CUSTOM_COLOR = "customColor"; //TAG_Int protected FireworkRocketExplosion $explosion; + protected ?Color $customColor = null; + public function __construct(ItemIdentifier $identifier, string $name){ parent::__construct($identifier, $name); - $this->explosion = new FireworkRocketExplosion(FireworkRocketType::SMALL_SPHERE(), DyeColor::BLACK(), null, false, false); + $this->explosion = new FireworkRocketExplosion(FireworkRocketType::SMALL_SPHERE(), [DyeColor::BLACK()], [], false, false); } public function getExplosion() : FireworkRocketExplosion{ return $this->explosion; } - public function setExplosion(FireworkRocketExplosion $explosion) : void{ + /** @return $this */ + public function setExplosion(FireworkRocketExplosion $explosion) : self{ $this->explosion = $explosion; + return $this; + } + + /** @return $this */ + public function getColor() : Color{ + return $this->customColor ?? $this->explosion->getColorMix(); + } + + public function hasCustomColor() : bool{ + return $this->customColor !== null; + } + + public function getCustomColor() : ?Color{ + $this->customColor; + } + + /** @return $this */ + public function setCustomColor(Color $color) : self{ + $this->customColor = $color; + return $this; + } + + /** @return $this */ + public function clearCustomColor() : self{ + $this->customColor = null; + return $this; } protected function deserializeCompoundTag(CompoundTag $tag) : void{ @@ -57,12 +87,22 @@ protected function deserializeCompoundTag(CompoundTag $tag) : void{ throw new SavedDataLoadingException("Missing explosion data"); } $this->explosion = FireworkRocketExplosion::fromCompoundTag($explosionTag); + + $customColor = Color::fromARGB(Binary::unsignInt($tag->getInt(self::TAG_CUSTOM_COLOR))); + $color = $this->explosion->getColorMix(); + if($customColor->getA() !== $color->getA() || + $customColor->getR() !== $color->getR() || + $customColor->getG() !== $color->getG() || + $customColor->getB() !== $color->getB() + ){ //check that $customColor is actually custom. + $this->customColor = $customColor; + } } protected function serializeCompoundTag(CompoundTag $tag) : void{ parent::serializeCompoundTag($tag); $tag->setTag(self::TAG_EXPLOSION, $this->explosion->toCompoundTag()); - $tag->setInt(self::TAG_COLOR, Binary::signInt($this->explosion->getColor()->getRgbValue()->toARGB())); + $tag->setInt(self::TAG_CUSTOM_COLOR, Binary::signInt($this->getColor()->toARGB())); } } From fd04e9320bf32b2d15d5efd622d73f722e313d25 Mon Sep 17 00:00:00 2001 From: IvanCraft623 Date: Fri, 16 Dec 2022 23:33:48 -0500 Subject: [PATCH 06/50] Add TODO comment --- src/entity/object/FireworkRocket.php | 1 + src/item/FireworkRocketExplosion.php | 4 ++-- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/src/entity/object/FireworkRocket.php b/src/entity/object/FireworkRocket.php index 058ecaa78d5..4d7254614dd 100644 --- a/src/entity/object/FireworkRocket.php +++ b/src/entity/object/FireworkRocket.php @@ -170,6 +170,7 @@ public function canBeCollidedWith() : bool{ protected function syncNetworkData(EntityMetadataCollection $properties) : void{ parent::syncNetworkData($properties); + //TODO: Use the appropriate constant $properties->setCompoundTag(EntityMetadataProperties::MINECART_DISPLAY_BLOCK, new CacheableNbt($this->item->getNamedTag())); } } diff --git a/src/item/FireworkRocketExplosion.php b/src/item/FireworkRocketExplosion.php index 69e337cf39a..d7331accbac 100644 --- a/src/item/FireworkRocketExplosion.php +++ b/src/item/FireworkRocketExplosion.php @@ -66,7 +66,7 @@ protected static function decodeColors(string $colorsBytes) : array{ $colors = []; $dyeColorIdMap = DyeColorIdMap::getInstance(); - for($i=0; $i < strlen($colorsBytes); $i++){ + for($i = 0; $i < strlen($colorsBytes); $i++){ $color = $dyeColorIdMap->fromInvertedId(Binary::readByte($colorsBytes[$i])); if($color !== null){ $colors[] = $color; @@ -195,7 +195,7 @@ protected function encodeColors(array $colors) : string{ $colorsBytes = ""; $dyeColorIdMap = DyeColorIdMap::getInstance(); - foreach($colors as $color){ + foreach($colors as $color){ $colorsBytes .= Binary::writeByte($dyeColorIdMap->toInvertedId($color)); } From 15b12817b4944c40ff553736311e2000a6560208 Mon Sep 17 00:00:00 2001 From: IvanCraft623 Date: Sat, 17 Dec 2022 00:01:20 -0500 Subject: [PATCH 07/50] Some API improvements --- src/entity/object/FireworkRocket.php | 11 ++++++++--- src/item/FireworkRocketExplosion.php | 23 ++++++++++++++++++----- src/item/FireworkStar.php | 3 +-- 3 files changed, 27 insertions(+), 10 deletions(-) diff --git a/src/entity/object/FireworkRocket.php b/src/entity/object/FireworkRocket.php index 4d7254614dd..485a2b7b82a 100644 --- a/src/entity/object/FireworkRocket.php +++ b/src/entity/object/FireworkRocket.php @@ -76,20 +76,25 @@ public function getLifeTicks() : int{ /** * Sets maximum number of ticks this will live for. + * + * @return $this */ - public function setLifeTicks(int $lifeTicks) : void{ + public function setLifeTicks(int $lifeTicks) : self{ if ($lifeTicks < 0) { throw new \InvalidArgumentException("Life ticks cannot be negative"); } $this->lifeTicks = $lifeTicks; + return $this; } public function getItem() : FireworkItem{ return clone $this->item; } - public function setItem(FireworkItem $item) : void{ - $this->item = $item; + /** @return $this */ + public function setItem(FireworkItem $item) : self{ + $this->item = clone $item; + return $this; } /** diff --git a/src/item/FireworkRocketExplosion.php b/src/item/FireworkRocketExplosion.php index d7331accbac..1129210a070 100644 --- a/src/item/FireworkRocketExplosion.php +++ b/src/item/FireworkRocketExplosion.php @@ -104,8 +104,10 @@ public function getType() : FireworkRocketType{ return $this->type; } - public function setType(FireworkRocketType $type) : void{ + /** @return $this */ + public function setType(FireworkRocketType $type) : self{ $this->type = $type; + return $this; } /** @@ -117,13 +119,17 @@ public function getColors() : array{ /** * @param DyeColor[] $colors + * + * @return $this */ - public function setColors(array $colors) : void{ + public function setColors(array $colors) : self{ if(count($colors) === 0){ throw new \InvalidArgumentException("Colors list cannot be empty"); } Utils::validateArrayValueType($colors, $this->colorsValidator); $this->colors = array_values($colors); + + return $this; } /** @@ -154,26 +160,33 @@ public function getFadeColors() : array{ /** * @param DyeColor[] $colors + * + * @return $this */ - public function setFadeColors(array $colors) : void{ + public function setFadeColors(array $colors) : self{ Utils::validateArrayValueType($colors, $this->colorsValidator); $this->fadeColors = array_values($colors); + return $this; } public function willTwinkle() : bool{ return $this->twinkle; } - public function setTwinkle(bool $twinkle) : void{ + /** @return $this */ + public function setTwinkle(bool $twinkle) : self{ $this->twinkle = $twinkle; + return $this; } public function getTrail() : bool{ return $this->trail; } - public function setTrail(bool $trail) : void{ + /** @return $this */ + public function setTrail(bool $trail) : self{ $this->trail = $trail; + return $this; } public function toCompoundTag() : CompoundTag{ diff --git a/src/item/FireworkStar.php b/src/item/FireworkStar.php index 9d6384bfb66..3bd6b1f29d7 100644 --- a/src/item/FireworkStar.php +++ b/src/item/FireworkStar.php @@ -54,7 +54,6 @@ public function setExplosion(FireworkRocketExplosion $explosion) : self{ return $this; } - /** @return $this */ public function getColor() : Color{ return $this->customColor ?? $this->explosion->getColorMix(); } @@ -64,7 +63,7 @@ public function hasCustomColor() : bool{ } public function getCustomColor() : ?Color{ - $this->customColor; + return $this->customColor; } /** @return $this */ From a0a4acee01217e5b8e655d527049f57e4f316646 Mon Sep 17 00:00:00 2001 From: IvanCraft623 Date: Sat, 17 Dec 2022 00:14:10 -0500 Subject: [PATCH 08/50] Make PHPStan happy --- src/item/FireworkRocketExplosion.php | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/item/FireworkRocketExplosion.php b/src/item/FireworkRocketExplosion.php index 1129210a070..416aae22757 100644 --- a/src/item/FireworkRocketExplosion.php +++ b/src/item/FireworkRocketExplosion.php @@ -78,8 +78,11 @@ protected static function decodeColors(string $colorsBytes) : array{ return $colors; } + /** + * @var \Closure(DyeColor) : void + */ protected \Closure $colorsValidator; - + /** * @param DyeColor[] $colors * @param DyeColor[] $fadeColors From 21f0edf98fe82e9dd473085c4bd187e1dc560eee Mon Sep 17 00:00:00 2001 From: IvanCraft623 Date: Sat, 17 Dec 2022 00:22:02 -0500 Subject: [PATCH 09/50] shut up! --- src/item/FireworkRocketExplosion.php | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/item/FireworkRocketExplosion.php b/src/item/FireworkRocketExplosion.php index 416aae22757..02a5c2c39cc 100644 --- a/src/item/FireworkRocketExplosion.php +++ b/src/item/FireworkRocketExplosion.php @@ -78,9 +78,7 @@ protected static function decodeColors(string $colorsBytes) : array{ return $colors; } - /** - * @var \Closure(DyeColor) : void - */ + /** @var \Closure(DyeColor) : void */ protected \Closure $colorsValidator; /** From ce28e49045bf0ce88ad95da72f3520f819cff26d Mon Sep 17 00:00:00 2001 From: IvanCraft623 Date: Mon, 19 Dec 2022 01:16:05 -0500 Subject: [PATCH 10/50] Simplification --- src/entity/object/FireworkRocket.php | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/src/entity/object/FireworkRocket.php b/src/entity/object/FireworkRocket.php index 485a2b7b82a..8417ace1322 100644 --- a/src/entity/object/FireworkRocket.php +++ b/src/entity/object/FireworkRocket.php @@ -149,16 +149,13 @@ public function explode() : void{ } $world = $this->getWorld(); - $obstructed = false; + + //check for obstructing blocks foreach(VoxelRayTrace::betweenPoints($this->location, $position) as $pos){ if($world->getBlockAt((int) $pos->x, (int) $pos->y, (int) $pos->z)->isSolid()){ - $obstructed = true; - break; + continue 2; } } - if($obstructed){ - continue; - } $ev = new EntityDamageByEntityEvent($this, $entity, EntityDamageEvent::CAUSE_ENTITY_EXPLOSION, $force * sqrt((5 - $distance) / 5)); $entity->attack($ev); From d4e869237204e660d95c38174a200aaf45eafbe1 Mon Sep 17 00:00:00 2001 From: IvanCraft623 Date: Mon, 19 Dec 2022 14:47:10 -0500 Subject: [PATCH 11/50] Firework types name parity with vanilla --- src/data/bedrock/FireworkRocketTypeIdMap.php | 4 ++-- src/item/FireworkRocketType.php | 8 ++++---- src/item/FireworkStar.php | 2 +- ...ExplosionSound.php => FireworkLargeExplosionSound.php} | 2 +- 4 files changed, 8 insertions(+), 8 deletions(-) rename src/world/sound/{FireworkBigExplosionSound.php => FireworkLargeExplosionSound.php} (95%) diff --git a/src/data/bedrock/FireworkRocketTypeIdMap.php b/src/data/bedrock/FireworkRocketTypeIdMap.php index 70dc033d1dc..0f58176fe19 100644 --- a/src/data/bedrock/FireworkRocketTypeIdMap.php +++ b/src/data/bedrock/FireworkRocketTypeIdMap.php @@ -42,8 +42,8 @@ final class FireworkRocketTypeIdMap{ private array $enumToId; private function __construct(){ - $this->register(FireworkRocketTypeIds::SMALL_SPHERE, FireworkRocketType::SMALL_SPHERE()); - $this->register(FireworkRocketTypeIds::BIG_SPHERE, FireworkRocketType::BIG_SPHERE()); + $this->register(FireworkRocketTypeIds::SMALL_BALL, FireworkRocketType::SMALL_BALL()); + $this->register(FireworkRocketTypeIds::LARGE_BALL, FireworkRocketType::LARGE_BALL()); $this->register(FireworkRocketTypeIds::STAR, FireworkRocketType::STAR()); $this->register(FireworkRocketTypeIds::CREEPER, FireworkRocketType::CREEPER()); $this->register(FireworkRocketTypeIds::BURST, FireworkRocketType::BURST()); diff --git a/src/item/FireworkRocketType.php b/src/item/FireworkRocketType.php index ea37244ad00..9e648d4f3c4 100644 --- a/src/item/FireworkRocketType.php +++ b/src/item/FireworkRocketType.php @@ -34,10 +34,10 @@ * @see build/generate-registry-annotations.php * @generate-registry-docblock * - * @method static FireworkRocketType BIG_SPHERE() * @method static FireworkRocketType BURST() * @method static FireworkRocketType CREEPER() - * @method static FireworkRocketType SMALL_SPHERE() + * @method static FireworkRocketType LARGE_BALL() + * @method static FireworkRocketType SMALL_BALL() * @method static FireworkRocketType STAR() */ final class FireworkRocketType{ @@ -47,8 +47,8 @@ final class FireworkRocketType{ protected static function setup() : void{ self::registerAll( - new self("small_sphere", fn() => new FireworkExplosionSound()), - new self("big_sphere", fn() => new FireworkBigExplosionSound()), + new self("small_ball", fn() => new FireworkExplosionSound()), + new self("large_ball", fn() => new FireworkLargeExplosionSound()), new self("star", fn() => new FireworkExplosionSound()), new self("creeper", fn() => new FireworkExplosionSound()), new self("burst", fn() => new FireworkExplosionSound()), diff --git a/src/item/FireworkStar.php b/src/item/FireworkStar.php index 3bd6b1f29d7..5c2bcc80e1b 100644 --- a/src/item/FireworkStar.php +++ b/src/item/FireworkStar.php @@ -41,7 +41,7 @@ class FireworkStar extends Item{ public function __construct(ItemIdentifier $identifier, string $name){ parent::__construct($identifier, $name); - $this->explosion = new FireworkRocketExplosion(FireworkRocketType::SMALL_SPHERE(), [DyeColor::BLACK()], [], false, false); + $this->explosion = new FireworkRocketExplosion(FireworkRocketType::SMALL_BALL(), [DyeColor::BLACK()], [], false, false); } public function getExplosion() : FireworkRocketExplosion{ diff --git a/src/world/sound/FireworkBigExplosionSound.php b/src/world/sound/FireworkLargeExplosionSound.php similarity index 95% rename from src/world/sound/FireworkBigExplosionSound.php rename to src/world/sound/FireworkLargeExplosionSound.php index 462b7ded2b2..2b25019d404 100644 --- a/src/world/sound/FireworkBigExplosionSound.php +++ b/src/world/sound/FireworkLargeExplosionSound.php @@ -27,7 +27,7 @@ use pocketmine\network\mcpe\protocol\LevelSoundEventPacket; use pocketmine\network\mcpe\protocol\types\LevelSoundEvent; -class FireworkBigExplosionSound implements Sound{ +class FireworkLargeExplosionSound implements Sound{ public function encode(Vector3 $pos) : array{ return [LevelSoundEventPacket::nonActorSound(LevelSoundEvent::LARGE_BLAST, $pos, false)]; From d20f6857cc196c134844df8d179833e139c0c73b Mon Sep 17 00:00:00 2001 From: IvanCraft623 Date: Mon, 19 Dec 2022 14:48:09 -0500 Subject: [PATCH 12/50] FireworkRocketTypeIdMap: fixed uninitialized fields --- src/data/bedrock/FireworkRocketTypeIdMap.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/data/bedrock/FireworkRocketTypeIdMap.php b/src/data/bedrock/FireworkRocketTypeIdMap.php index 0f58176fe19..1ecfaa90b64 100644 --- a/src/data/bedrock/FireworkRocketTypeIdMap.php +++ b/src/data/bedrock/FireworkRocketTypeIdMap.php @@ -33,13 +33,13 @@ final class FireworkRocketTypeIdMap{ * @var FireworkRocketType[] * @phpstan-var array */ - private array $idToEnum; + private array $idToEnum = []; /** * @var int[] * @phpstan-var array */ - private array $enumToId; + private array $enumToId = []; private function __construct(){ $this->register(FireworkRocketTypeIds::SMALL_BALL, FireworkRocketType::SMALL_BALL()); From 80557d70ce38127334c1bd9da5916753a895b5e3 Mon Sep 17 00:00:00 2001 From: IvanCraft623 Date: Mon, 19 Dec 2022 14:53:54 -0500 Subject: [PATCH 13/50] oops --- src/data/bedrock/FireworkRocketTypeIds.php | 4 ++-- src/item/FireworkRocketType.php | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/data/bedrock/FireworkRocketTypeIds.php b/src/data/bedrock/FireworkRocketTypeIds.php index ae49aa594d7..7ddf0e6b9a9 100644 --- a/src/data/bedrock/FireworkRocketTypeIds.php +++ b/src/data/bedrock/FireworkRocketTypeIds.php @@ -24,8 +24,8 @@ namespace pocketmine\data\bedrock; final class FireworkRocketTypeIds{ - public const SMALL_SPHERE = 0; - public const BIG_SPHERE = 1; + public const SMALL_BALL = 0; + public const LARGE_BALL = 1; public const STAR = 2; public const CREEPER = 3; public const BURST = 4; diff --git a/src/item/FireworkRocketType.php b/src/item/FireworkRocketType.php index 9e648d4f3c4..89f078184c4 100644 --- a/src/item/FireworkRocketType.php +++ b/src/item/FireworkRocketType.php @@ -24,8 +24,8 @@ namespace pocketmine\item; use pocketmine\utils\EnumTrait; -use pocketmine\world\sound\FireworkBigExplosionSound; use pocketmine\world\sound\FireworkExplosionSound; +use pocketmine\world\sound\FireworkLargeExplosionSound; use pocketmine\world\sound\Sound; /** From 98291ecff7220c68df99cf6208540b7fc7ef9365 Mon Sep 17 00:00:00 2001 From: IvanCraft623 Date: Fri, 23 Dec 2022 17:09:29 -0500 Subject: [PATCH 14/50] Remove unused var --- src/item/FireworkRocketExplosion.php | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/item/FireworkRocketExplosion.php b/src/item/FireworkRocketExplosion.php index 02a5c2c39cc..2c3049e0e56 100644 --- a/src/item/FireworkRocketExplosion.php +++ b/src/item/FireworkRocketExplosion.php @@ -191,8 +191,6 @@ public function setTrail(bool $trail) : self{ } public function toCompoundTag() : CompoundTag{ - $dyeColorIdMap = DyeColorIdMap::getInstance(); - return CompoundTag::create() ->setByte(self::TAG_TYPE, FireworkRocketTypeIdMap::getInstance()->toId($this->type)) ->setByteArray(self::TAG_COLORS, $this->encodeColors($this->colors)) From 6e22547e9e9ab3dfc7d78b4e5351aa04e2ff15a3 Mon Sep 17 00:00:00 2001 From: IvanCraft623 Date: Fri, 23 Dec 2022 17:14:34 -0500 Subject: [PATCH 15/50] Call parent::onFirstUpdate() --- src/entity/object/FireworkRocket.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/entity/object/FireworkRocket.php b/src/entity/object/FireworkRocket.php index 8417ace1322..fd8e4419e86 100644 --- a/src/entity/object/FireworkRocket.php +++ b/src/entity/object/FireworkRocket.php @@ -106,6 +106,8 @@ public function canSaveWithChunk() : bool{ } protected function onFirstUpdate(int $currentTick) : void{ + parent::onFirstUpdate($currentTick); + $this->broadcastSound(new FireworkLaunchSound()); } From 0ce16d877bcca9843e56d5824983bd14e376b152 Mon Sep 17 00:00:00 2001 From: IvanCraft623 Date: Tue, 27 Dec 2022 21:44:52 -0500 Subject: [PATCH 16/50] Implement firework death message --- src/event/player/PlayerDeathEvent.php | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/event/player/PlayerDeathEvent.php b/src/event/player/PlayerDeathEvent.php index dd7c21eb298..b221067396e 100644 --- a/src/event/player/PlayerDeathEvent.php +++ b/src/event/player/PlayerDeathEvent.php @@ -25,6 +25,7 @@ use pocketmine\block\BlockTypeIds; use pocketmine\entity\Living; +use pocketmine\entity\object\FireworkRocket; use pocketmine\event\entity\EntityDamageByBlockEvent; use pocketmine\event\entity\EntityDamageByEntityEvent; use pocketmine\event\entity\EntityDamageEvent; @@ -146,7 +147,9 @@ public static function deriveMessage(string $name, ?EntityDamageEvent $deathCaus case EntityDamageEvent::CAUSE_ENTITY_EXPLOSION: if($deathCause instanceof EntityDamageByEntityEvent){ $e = $deathCause->getDamager(); - if($e instanceof Living){ + if($e instanceof FireworkRocket){ + return KnownTranslationFactory::death_attack_fireworks($name); + }elseif($e instanceof Living){ return KnownTranslationFactory::death_attack_explosion_player($name, $e->getDisplayName()); } } From a4e412eb158d57bbc18ce6a5bdce01468252a8e5 Mon Sep 17 00:00:00 2001 From: IvanCraft623 Date: Wed, 4 Jan 2023 12:15:44 -0500 Subject: [PATCH 17/50] Implement Explosive interface --- src/entity/object/FireworkRocket.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/entity/object/FireworkRocket.php b/src/entity/object/FireworkRocket.php index fd8e4419e86..f0480efe99a 100644 --- a/src/entity/object/FireworkRocket.php +++ b/src/entity/object/FireworkRocket.php @@ -26,6 +26,7 @@ use pocketmine\entity\animation\FireworkParticlesAnimation; use pocketmine\entity\Entity; use pocketmine\entity\EntitySizeInfo; +use pocketmine\entity\Explosive; use pocketmine\entity\Living; use pocketmine\entity\Location; use pocketmine\event\entity\EntityDamageByEntityEvent; @@ -42,7 +43,7 @@ use function count; use function sqrt; -class FireworkRocket extends Entity{ +class FireworkRocket extends Entity implements Explosive{ public static function getNetworkTypeId() : string{ return EntityIds::FIREWORKS_ROCKET; } From bb7ca1eeff6cd7cacf16c332b3e4a8c5e274b12a Mon Sep 17 00:00:00 2001 From: IvanCraft623 Date: Mon, 8 May 2023 21:30:18 -0500 Subject: [PATCH 18/50] Use `addMotion` instead of mutating the vector directly --- src/entity/object/FireworkRocket.php | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/entity/object/FireworkRocket.php b/src/entity/object/FireworkRocket.php index f0480efe99a..9477a60e635 100644 --- a/src/entity/object/FireworkRocket.php +++ b/src/entity/object/FireworkRocket.php @@ -116,9 +116,7 @@ protected function entityBaseTick(int $tickDiff = 1) : bool{ $hasUpdate = parent::entityBaseTick($tickDiff); if(!$this->isFlaggedForDespawn()){ - $this->motion->x *= 1.15; - $this->motion->y += 0.04; - $this->motion->z *= 1.15; + $this->addMotion($this->motion->x * 0.15, 0.04, $this->motion->z * 0.15); if($this->ticksLived >= $this->lifeTicks){ $this->explode(); From ff080d785da4d372057fd1e1b289793537f74b1f Mon Sep 17 00:00:00 2001 From: IvanCraft623 Date: Mon, 8 May 2023 21:32:52 -0500 Subject: [PATCH 19/50] Use appropriate constant for firework item metadata --- src/entity/object/FireworkRocket.php | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/entity/object/FireworkRocket.php b/src/entity/object/FireworkRocket.php index 9477a60e635..d2ea708d071 100644 --- a/src/entity/object/FireworkRocket.php +++ b/src/entity/object/FireworkRocket.php @@ -173,7 +173,6 @@ public function canBeCollidedWith() : bool{ protected function syncNetworkData(EntityMetadataCollection $properties) : void{ parent::syncNetworkData($properties); - //TODO: Use the appropriate constant - $properties->setCompoundTag(EntityMetadataProperties::MINECART_DISPLAY_BLOCK, new CacheableNbt($this->item->getNamedTag())); + $properties->setCompoundTag(EntityMetadataProperties::FIREWORK_ITEM, new CacheableNbt($this->item->getNamedTag())); } } From c850a7e359ae0aa2f2213c23f03874dd5b6751f2 Mon Sep 17 00:00:00 2001 From: IvanCraft623 Date: Mon, 8 May 2023 21:44:25 -0500 Subject: [PATCH 20/50] Throw `SavedDataLoadingException` on finding an unknown color --- src/item/FireworkRocketExplosion.php | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/item/FireworkRocketExplosion.php b/src/item/FireworkRocketExplosion.php index 2c3049e0e56..0056acb29a8 100644 --- a/src/item/FireworkRocketExplosion.php +++ b/src/item/FireworkRocketExplosion.php @@ -67,11 +67,12 @@ protected static function decodeColors(string $colorsBytes) : array{ $dyeColorIdMap = DyeColorIdMap::getInstance(); for($i = 0; $i < strlen($colorsBytes); $i++){ - $color = $dyeColorIdMap->fromInvertedId(Binary::readByte($colorsBytes[$i])); + $colorByte = Binary::readByte($colorsBytes[$i]); + $color = $dyeColorIdMap->fromInvertedId($colorByte); if($color !== null){ $colors[] = $color; }else{ - //TODO: should throw an exception? + throw new SavedDataLoadingException("Unknown color $colorByte"); } } From 15b4c9515838115d1df9b797f76470fa35cae226 Mon Sep 17 00:00:00 2001 From: IvanCraft623 Date: Mon, 8 May 2023 21:47:14 -0500 Subject: [PATCH 21/50] Make `encodeColors` static and move it near to `decodeColors` --- src/item/FireworkRocketExplosion.php | 32 ++++++++++++++-------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/src/item/FireworkRocketExplosion.php b/src/item/FireworkRocketExplosion.php index 0056acb29a8..0de7770095d 100644 --- a/src/item/FireworkRocketExplosion.php +++ b/src/item/FireworkRocketExplosion.php @@ -79,6 +79,20 @@ protected static function decodeColors(string $colorsBytes) : array{ return $colors; } + /** + * @param DyeColor[] $colors + */ + protected static function encodeColors(array $colors) : string{ + $colorsBytes = ""; + + $dyeColorIdMap = DyeColorIdMap::getInstance(); + foreach($colors as $color){ + $colorsBytes .= Binary::writeByte($dyeColorIdMap->toInvertedId($color)); + } + + return $colorsBytes; + } + /** @var \Closure(DyeColor) : void */ protected \Closure $colorsValidator; @@ -194,24 +208,10 @@ public function setTrail(bool $trail) : self{ public function toCompoundTag() : CompoundTag{ return CompoundTag::create() ->setByte(self::TAG_TYPE, FireworkRocketTypeIdMap::getInstance()->toId($this->type)) - ->setByteArray(self::TAG_COLORS, $this->encodeColors($this->colors)) - ->setByteArray(self::TAG_FADE_COLORS, $this->encodeColors($this->fadeColors)) + ->setByteArray(self::TAG_COLORS, self::encodeColors($this->colors)) + ->setByteArray(self::TAG_FADE_COLORS, self::encodeColors($this->fadeColors)) ->setByte(self::TAG_TWINKLE, $this->twinkle ? 1 : 0) ->setByte(self::TAG_TRAIL, $this->trail ? 1 : 0) ; } - - /** - * @param DyeColor[] $colors - */ - protected function encodeColors(array $colors) : string{ - $colorsBytes = ""; - - $dyeColorIdMap = DyeColorIdMap::getInstance(); - foreach($colors as $color){ - $colorsBytes .= Binary::writeByte($dyeColorIdMap->toInvertedId($color)); - } - - return $colorsBytes; - } } From 252cfd6fe778314d32825ad3cc59a337e2cdbd75 Mon Sep 17 00:00:00 2001 From: IvanCraft623 <57236932+IvanCraft623@users.noreply.github.com> Date: Mon, 8 May 2023 21:49:13 -0500 Subject: [PATCH 22/50] Fix typo on `getColorMix` doc Co-authored-by: Dylan T. --- src/item/FireworkRocketExplosion.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/item/FireworkRocketExplosion.php b/src/item/FireworkRocketExplosion.php index 0de7770095d..6d6b6d510f2 100644 --- a/src/item/FireworkRocketExplosion.php +++ b/src/item/FireworkRocketExplosion.php @@ -156,7 +156,7 @@ public function getMainColor() : DyeColor{ } /** - * Returns a the mix of all colors. + * Returns the mix of all colors. */ public function getColorMix() : Color{ /** @var Color[] $colors */ From e2fbb8eb3f020ee9e73fb5c1d2810111b4ab1ba6 Mon Sep 17 00:00:00 2001 From: IvanCraft623 Date: Mon, 8 May 2023 21:57:41 -0500 Subject: [PATCH 23/50] Remove useless closures for sound getter --- src/item/FireworkRocketType.php | 17 +++++++---------- 1 file changed, 7 insertions(+), 10 deletions(-) diff --git a/src/item/FireworkRocketType.php b/src/item/FireworkRocketType.php index 89f078184c4..abef63cd70f 100644 --- a/src/item/FireworkRocketType.php +++ b/src/item/FireworkRocketType.php @@ -47,25 +47,22 @@ final class FireworkRocketType{ protected static function setup() : void{ self::registerAll( - new self("small_ball", fn() => new FireworkExplosionSound()), - new self("large_ball", fn() => new FireworkLargeExplosionSound()), - new self("star", fn() => new FireworkExplosionSound()), - new self("creeper", fn() => new FireworkExplosionSound()), - new self("burst", fn() => new FireworkExplosionSound()), + new self("small_ball", new FireworkExplosionSound()), + new self("large_ball", new FireworkLargeExplosionSound()), + new self("star", new FireworkExplosionSound()), + new self("creeper", new FireworkExplosionSound()), + new self("burst", new FireworkExplosionSound()), ); } - /** - * @phpstan-param \Closure() : Sound $soundGetter - */ private function __construct( string $enumName, - private \Closure $soundGetter + private Sound $sound ){ $this->Enum___construct($enumName); } public function getSound() : Sound{ - return ($this->soundGetter)(); + return $this->sound; } } From e90f3ad62464842935911c706d5062a25c4280d5 Mon Sep 17 00:00:00 2001 From: IvanCraft623 Date: Mon, 8 May 2023 22:05:37 -0500 Subject: [PATCH 24/50] Better use the new `Color::equals()` method :P --- src/item/FireworkStar.php | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/src/item/FireworkStar.php b/src/item/FireworkStar.php index 5c2bcc80e1b..9bbfb3c4fe8 100644 --- a/src/item/FireworkStar.php +++ b/src/item/FireworkStar.php @@ -89,11 +89,7 @@ protected function deserializeCompoundTag(CompoundTag $tag) : void{ $customColor = Color::fromARGB(Binary::unsignInt($tag->getInt(self::TAG_CUSTOM_COLOR))); $color = $this->explosion->getColorMix(); - if($customColor->getA() !== $color->getA() || - $customColor->getR() !== $color->getR() || - $customColor->getG() !== $color->getG() || - $customColor->getB() !== $color->getB() - ){ //check that $customColor is actually custom. + if(!$customColor->equals($color)){ //check that $customColor is actually custom. $this->customColor = $customColor; } } From 5a5052516119b41b83cf61d6bc8f986d32f17b95 Mon Sep 17 00:00:00 2001 From: IvanCraft623 Date: Mon, 8 May 2023 22:07:13 -0500 Subject: [PATCH 25/50] Remove `clearCustomColor()` in favour of passing `null` to `setCustomColor()` --- src/item/FireworkStar.php | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/src/item/FireworkStar.php b/src/item/FireworkStar.php index 9bbfb3c4fe8..8a9e98bd003 100644 --- a/src/item/FireworkStar.php +++ b/src/item/FireworkStar.php @@ -67,17 +67,11 @@ public function getCustomColor() : ?Color{ } /** @return $this */ - public function setCustomColor(Color $color) : self{ + public function setCustomColor(?Color $color) : self{ $this->customColor = $color; return $this; } - /** @return $this */ - public function clearCustomColor() : self{ - $this->customColor = null; - return $this; - } - protected function deserializeCompoundTag(CompoundTag $tag) : void{ parent::deserializeCompoundTag($tag); From 1122009cab687ecfc7a42f117d3573d192cacfff Mon Sep 17 00:00:00 2001 From: IvanCraft623 <57236932+IvanCraft623@users.noreply.github.com> Date: Mon, 8 May 2023 22:10:27 -0500 Subject: [PATCH 26/50] Fix little cs Co-authored-by: Dylan T. --- src/item/FireworkStar.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/item/FireworkStar.php b/src/item/FireworkStar.php index 8a9e98bd003..1c361b37f49 100644 --- a/src/item/FireworkStar.php +++ b/src/item/FireworkStar.php @@ -76,7 +76,7 @@ protected function deserializeCompoundTag(CompoundTag $tag) : void{ parent::deserializeCompoundTag($tag); $explosionTag = $tag->getTag(self::TAG_EXPLOSION); - if (!$explosionTag instanceof CompoundTag) { + if(!$explosionTag instanceof CompoundTag){ throw new SavedDataLoadingException("Missing explosion data"); } $this->explosion = FireworkRocketExplosion::fromCompoundTag($explosionTag); From 291c086b2d10bbcb835b484f47bd56b47801d75f Mon Sep 17 00:00:00 2001 From: IvanCraft623 <57236932+IvanCraft623@users.noreply.github.com> Date: Mon, 8 May 2023 23:00:18 -0500 Subject: [PATCH 27/50] Apply dylan's CS suggestion Co-authored-by: Dylan T. --- src/entity/animation/FireworkParticlesAnimation.php | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/entity/animation/FireworkParticlesAnimation.php b/src/entity/animation/FireworkParticlesAnimation.php index cd9d56c8509..cdeb44f03bb 100644 --- a/src/entity/animation/FireworkParticlesAnimation.php +++ b/src/entity/animation/FireworkParticlesAnimation.php @@ -29,7 +29,9 @@ final class FireworkParticlesAnimation implements Animation{ - public function __construct(private FireworkRocket $entity){} + public function __construct( + private FireworkRocket $entity + ){} public function encode() : array{ return [ From 0b710a2a32ade4125ff2f24246ec4109db4fd520 Mon Sep 17 00:00:00 2001 From: IvanCraft623 Date: Tue, 9 May 2023 11:47:47 -0500 Subject: [PATCH 28/50] Fix flight duaration range to wrap into a signed byte range --- src/item/FireworkRocket.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/item/FireworkRocket.php b/src/item/FireworkRocket.php index 4a86936f870..e233e75c7b8 100644 --- a/src/item/FireworkRocket.php +++ b/src/item/FireworkRocket.php @@ -53,8 +53,8 @@ public function getFlightDuration() : int{ } public function setFlightDuration(int $duration) : void{ - if($duration < 1 || $duration > 255){ - throw new \InvalidArgumentException("Flight duration must be in range 1-255"); + if($duration < 1 || $duration > 127){ + throw new \InvalidArgumentException("Flight duration must be in range 1-127"); } $this->flightDuration = $duration; } From 69501b2bfb3096586de602326502543dcdb6bff2 Mon Sep 17 00:00:00 2001 From: IvanCraft623 Date: Tue, 9 May 2023 11:55:50 -0500 Subject: [PATCH 29/50] Document flight duration --- src/item/FireworkRocket.php | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/item/FireworkRocket.php b/src/item/FireworkRocket.php index e233e75c7b8..81954011381 100644 --- a/src/item/FireworkRocket.php +++ b/src/item/FireworkRocket.php @@ -48,10 +48,17 @@ class FireworkRocket extends Item{ /** @var FireworkRocketExplosion[] */ protected array $explosions = []; + /** + * Returns the flight duration of the firework (equals the amount of gunpowder used in crafting the rocket). + */ public function getFlightDuration() : int{ return $this->flightDuration; } + /** + * Sets the flight duration of the firework. + * This value will be used to get a random value for the lifetime of the entity. + */ public function setFlightDuration(int $duration) : void{ if($duration < 1 || $duration > 127){ throw new \InvalidArgumentException("Flight duration must be in range 1-127"); From 87504e4cc4829fdf19095ff25c24ebebbd13439f Mon Sep 17 00:00:00 2001 From: IvanCraft623 Date: Tue, 9 May 2023 12:04:00 -0500 Subject: [PATCH 30/50] Make FireworkRocket setters fluent --- src/item/FireworkRocket.php | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/src/item/FireworkRocket.php b/src/item/FireworkRocket.php index 81954011381..6ba4c4bc96a 100644 --- a/src/item/FireworkRocket.php +++ b/src/item/FireworkRocket.php @@ -58,12 +58,16 @@ public function getFlightDuration() : int{ /** * Sets the flight duration of the firework. * This value will be used to get a random value for the lifetime of the entity. + * + * @return $this */ - public function setFlightDuration(int $duration) : void{ + public function setFlightDuration(int $duration) : self{ if($duration < 1 || $duration > 127){ throw new \InvalidArgumentException("Flight duration must be in range 1-127"); } $this->flightDuration = $duration; + + return $this; } /** @@ -75,10 +79,14 @@ public function getExplosions() : array{ /** * @param FireworkRocketExplosion[] $explosions + * + * @return $this */ - public function setExplosions(array $explosions) : void{ + public function setExplosions(array $explosions) : self{ Utils::validateArrayValueType($explosions, function(FireworkRocketExplosion $_) : void{}); $this->explosions = $explosions; + + return $this; } public function onInteractBlock(Player $player, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, array &$returnedItems) : ItemUseResult{ From d093d22bf9fd87273cf8eec366657da2a4351c4a Mon Sep 17 00:00:00 2001 From: IvanCraft623 Date: Tue, 9 May 2023 12:06:40 -0500 Subject: [PATCH 31/50] Make FireworkRocketExplosion immutable --- src/item/FireworkRocketExplosion.php | 56 +++------------------------- 1 file changed, 5 insertions(+), 51 deletions(-) diff --git a/src/item/FireworkRocketExplosion.php b/src/item/FireworkRocketExplosion.php index 6d6b6d510f2..dc156f40c89 100644 --- a/src/item/FireworkRocketExplosion.php +++ b/src/item/FireworkRocketExplosion.php @@ -93,9 +93,6 @@ protected static function encodeColors(array $colors) : string{ return $colorsBytes; } - /** @var \Closure(DyeColor) : void */ - protected \Closure $colorsValidator; - /** * @param DyeColor[] $colors * @param DyeColor[] $fadeColors @@ -107,25 +104,20 @@ public function __construct( protected bool $twinkle, protected bool $trail ){ - $this->colorsValidator = function(DyeColor $_) : void{}; - if(count($colors) === 0){ throw new \InvalidArgumentException("Colors list cannot be empty"); } - $this->setColors($colors); - $this->setFadeColors($fadeColors); + + $colorsValidator = function(DyeColor $_) : void{}; + + Utils::validateArrayValueType($colors, $colorsValidator); + Utils::validateArrayValueType($fadeColors, $colorsValidator); } public function getType() : FireworkRocketType{ return $this->type; } - /** @return $this */ - public function setType(FireworkRocketType $type) : self{ - $this->type = $type; - return $this; - } - /** * @return DyeColor[] */ @@ -133,21 +125,6 @@ public function getColors() : array{ return $this->colors; } - /** - * @param DyeColor[] $colors - * - * @return $this - */ - public function setColors(array $colors) : self{ - if(count($colors) === 0){ - throw new \InvalidArgumentException("Colors list cannot be empty"); - } - Utils::validateArrayValueType($colors, $this->colorsValidator); - $this->colors = array_values($colors); - - return $this; - } - /** * Returns the main color, this defines stuff like meta. */ @@ -174,37 +151,14 @@ public function getFadeColors() : array{ return $this->fadeColors; } - /** - * @param DyeColor[] $colors - * - * @return $this - */ - public function setFadeColors(array $colors) : self{ - Utils::validateArrayValueType($colors, $this->colorsValidator); - $this->fadeColors = array_values($colors); - return $this; - } - public function willTwinkle() : bool{ return $this->twinkle; } - /** @return $this */ - public function setTwinkle(bool $twinkle) : self{ - $this->twinkle = $twinkle; - return $this; - } - public function getTrail() : bool{ return $this->trail; } - /** @return $this */ - public function setTrail(bool $trail) : self{ - $this->trail = $trail; - return $this; - } - public function toCompoundTag() : CompoundTag{ return CompoundTag::create() ->setByte(self::TAG_TYPE, FireworkRocketTypeIdMap::getInstance()->toId($this->type)) From 413934252ed037c8f06963c782cb90b9ec75a984 Mon Sep 17 00:00:00 2001 From: IvanCraft623 Date: Tue, 9 May 2023 12:14:02 -0500 Subject: [PATCH 32/50] Use lists instead of arrays for PHPStan --- src/item/FireworkRocketExplosion.php | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/item/FireworkRocketExplosion.php b/src/item/FireworkRocketExplosion.php index dc156f40c89..1990ddc49c4 100644 --- a/src/item/FireworkRocketExplosion.php +++ b/src/item/FireworkRocketExplosion.php @@ -61,6 +61,7 @@ public static function fromCompoundTag(CompoundTag $tag) : self{ /** * @return DyeColor[] + * @phpstan-return list */ protected static function decodeColors(string $colorsBytes) : array{ $colors = []; @@ -96,6 +97,8 @@ protected static function encodeColors(array $colors) : string{ /** * @param DyeColor[] $colors * @param DyeColor[] $fadeColors + * @phpstan-param non-empty-list $colors + * @phpstan-param list $fadeColors */ public function __construct( protected FireworkRocketType $type, @@ -120,6 +123,7 @@ public function getType() : FireworkRocketType{ /** * @return DyeColor[] + * @phpstan-return non-empty-list */ public function getColors() : array{ return $this->colors; @@ -146,6 +150,7 @@ public function getColorMix() : Color{ /** * @return DyeColor[] + * @phpstan-return list */ public function getFadeColors() : array{ return $this->fadeColors; From 12dc6b208832848601c7aaa13cdf06b24efc5fbf Mon Sep 17 00:00:00 2001 From: IvanCraft623 Date: Tue, 9 May 2023 12:34:49 -0500 Subject: [PATCH 33/50] Improve FireworkRocketExplosion documentation --- src/item/FireworkRocketExplosion.php | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/src/item/FireworkRocketExplosion.php b/src/item/FireworkRocketExplosion.php index 1990ddc49c4..b16a8286933 100644 --- a/src/item/FireworkRocketExplosion.php +++ b/src/item/FireworkRocketExplosion.php @@ -122,6 +122,8 @@ public function getType() : FireworkRocketType{ } /** + * Returns the colors of the particles. + * * @return DyeColor[] * @phpstan-return non-empty-list */ @@ -130,14 +132,14 @@ public function getColors() : array{ } /** - * Returns the main color, this defines stuff like meta. + * Returns the flash color of the explosion. */ public function getMainColor() : DyeColor{ return $this->colors[array_key_first($this->colors)]; } /** - * Returns the mix of all colors. + * Returns the mixure of colors form {@link FireworkRocketExplosion::getColors()}) */ public function getColorMix() : Color{ /** @var Color[] $colors */ @@ -149,6 +151,9 @@ public function getColorMix() : Color{ } /** + * Returns the colors to which the particles will change their color after a few seconds. + * If it is empty, there will be no color change in the particles. + * * @return DyeColor[] * @phpstan-return list */ @@ -156,10 +161,16 @@ public function getFadeColors() : array{ return $this->fadeColors; } + /** + * Returns whether the explosion has a flickering effect. + */ public function willTwinkle() : bool{ return $this->twinkle; } + /** + * Returns whether the particles has a trail effect. + */ public function getTrail() : bool{ return $this->trail; } From 1a2715d3fb0fe9e8f4f91bd6767cd4f3310725e6 Mon Sep 17 00:00:00 2001 From: IvanCraft623 Date: Tue, 9 May 2023 12:36:05 -0500 Subject: [PATCH 34/50] Rename getMainColor method --- src/item/FireworkRocketExplosion.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/item/FireworkRocketExplosion.php b/src/item/FireworkRocketExplosion.php index b16a8286933..a804e555f27 100644 --- a/src/item/FireworkRocketExplosion.php +++ b/src/item/FireworkRocketExplosion.php @@ -134,7 +134,7 @@ public function getColors() : array{ /** * Returns the flash color of the explosion. */ - public function getMainColor() : DyeColor{ + public function getFlashColor() : DyeColor{ return $this->colors[array_key_first($this->colors)]; } From 70d3d7aa90e55566a11215e644edcbf1c85d8f9b Mon Sep 17 00:00:00 2001 From: IvanCraft623 Date: Tue, 9 May 2023 12:37:30 -0500 Subject: [PATCH 35/50] Remove hasCustomColor() method --- src/item/FireworkStar.php | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/item/FireworkStar.php b/src/item/FireworkStar.php index 1c361b37f49..bfaf0e1ee4c 100644 --- a/src/item/FireworkStar.php +++ b/src/item/FireworkStar.php @@ -58,10 +58,6 @@ public function getColor() : Color{ return $this->customColor ?? $this->explosion->getColorMix(); } - public function hasCustomColor() : bool{ - return $this->customColor !== null; - } - public function getCustomColor() : ?Color{ return $this->customColor; } From 43ccb803a527a70f0627df514c700e3d38f2c190 Mon Sep 17 00:00:00 2001 From: IvanCraft623 Date: Tue, 9 May 2023 12:52:38 -0500 Subject: [PATCH 36/50] Improve FireworkStar documentation --- src/item/FireworkStar.php | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/src/item/FireworkStar.php b/src/item/FireworkStar.php index bfaf0e1ee4c..512c137a104 100644 --- a/src/item/FireworkStar.php +++ b/src/item/FireworkStar.php @@ -54,15 +54,28 @@ public function setExplosion(FireworkRocketExplosion $explosion) : self{ return $this; } + /** + * Returns the displayed color of the item. + * The mixture of explosion colors, or the custom color if it is set. + */ public function getColor() : Color{ return $this->customColor ?? $this->explosion->getColorMix(); } + /** + * Returns the displayed custom color of the item that overrides + * the mixture of explosion colors, or null is it is not set. + */ public function getCustomColor() : ?Color{ return $this->customColor; } - /** @return $this */ + /** + * Sets the displayed custom color of the item that overrides + * the mixture of explosion colors, or removes if $color is null. + * + * @return $this + */ public function setCustomColor(?Color $color) : self{ $this->customColor = $color; return $this; From 07ffb2188c1be1ed0842e82b4e79ed15ae20a29b Mon Sep 17 00:00:00 2001 From: IvanCraft623 Date: Tue, 9 May 2023 12:55:54 -0500 Subject: [PATCH 37/50] Fix typo in TAG_FLIGH_DURATION --- src/item/FireworkRocket.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/item/FireworkRocket.php b/src/item/FireworkRocket.php index 6ba4c4bc96a..e89ba62d547 100644 --- a/src/item/FireworkRocket.php +++ b/src/item/FireworkRocket.php @@ -40,7 +40,7 @@ class FireworkRocket extends Item{ protected const TAG_FIREWORK_DATA = "Fireworks"; //TAG_Compound - protected const TAG_FLIGH_DURATION = "Flight"; //TAG_Byte + protected const TAG_FLIGHT_DURATION = "Flight"; //TAG_Byte protected const TAG_EXPLOSIONS = "Explosions"; //TAG_List protected int $flightDuration = 1; @@ -120,7 +120,7 @@ protected function deserializeCompoundTag(CompoundTag $tag) : void{ throw new SavedDataLoadingException("Missing firework data"); } - $this->setFlightDuration($fireworksTag->getByte(self::TAG_FLIGH_DURATION, 1)); + $this->setFlightDuration($fireworksTag->getByte(self::TAG_FLIGHT_DURATION, 1)); if(($explosions = $fireworksTag->getListTag(self::TAG_EXPLOSIONS)) instanceof ListTag){ /** @var CompoundTag $explosion */ @@ -134,7 +134,7 @@ protected function serializeCompoundTag(CompoundTag $tag) : void{ parent::serializeCompoundTag($tag); $fireworksTag = CompoundTag::create(); - $fireworksTag->setByte(self::TAG_FLIGH_DURATION, $this->flightDuration); + $fireworksTag->setByte(self::TAG_FLIGHT_DURATION, $this->flightDuration); $explosions = new ListTag(); foreach($this->explosions as $explosion){ From 8e1b6619ad1a2e109ab9d5c2914f5c5c04175edc Mon Sep 17 00:00:00 2001 From: IvanCraft623 Date: Tue, 9 May 2023 12:59:24 -0500 Subject: [PATCH 38/50] Rename `FireworkTwinkleSound` to `FireworkCrackleSound` --- src/entity/object/FireworkRocket.php | 4 ++-- .../{FireworkTwinkleSound.php => FireworkCrackleSound.php} | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) rename src/world/sound/{FireworkTwinkleSound.php => FireworkCrackleSound.php} (95%) diff --git a/src/entity/object/FireworkRocket.php b/src/entity/object/FireworkRocket.php index d2ea708d071..9d4f7b26908 100644 --- a/src/entity/object/FireworkRocket.php +++ b/src/entity/object/FireworkRocket.php @@ -38,8 +38,8 @@ use pocketmine\network\mcpe\protocol\types\entity\EntityIds; use pocketmine\network\mcpe\protocol\types\entity\EntityMetadataCollection; use pocketmine\network\mcpe\protocol\types\entity\EntityMetadataProperties; +use pocketmine\world\sound\FireworkCrackleSound; use pocketmine\world\sound\FireworkLaunchSound; -use pocketmine\world\sound\FireworkTwinkleSound; use function count; use function sqrt; @@ -133,7 +133,7 @@ public function explode() : void{ foreach($explosions as $explosion){ $this->broadcastSound($explosion->getType()->getSound()); if($explosion->willTwinkle()){ - $this->broadcastSound(new FireworkTwinkleSound()); + $this->broadcastSound(new FireworkCrackleSound()); } } diff --git a/src/world/sound/FireworkTwinkleSound.php b/src/world/sound/FireworkCrackleSound.php similarity index 95% rename from src/world/sound/FireworkTwinkleSound.php rename to src/world/sound/FireworkCrackleSound.php index 33cae31c0da..c0e897d70b7 100644 --- a/src/world/sound/FireworkTwinkleSound.php +++ b/src/world/sound/FireworkCrackleSound.php @@ -27,7 +27,7 @@ use pocketmine\network\mcpe\protocol\LevelSoundEventPacket; use pocketmine\network\mcpe\protocol\types\LevelSoundEvent; -class FireworkTwinkleSound implements Sound{ +class FireworkCrackleSound implements Sound{ public function encode(Vector3 $pos) : array{ return [LevelSoundEventPacket::nonActorSound(LevelSoundEvent::TWINKLE, $pos, false)]; From 05e55651f8e733590e3b2d8376c139daec6f9095 Mon Sep 17 00:00:00 2001 From: IvanCraft623 Date: Tue, 9 May 2023 13:14:37 -0500 Subject: [PATCH 39/50] Fix PHPStan lints --- src/data/bedrock/item/ItemSerializerDeserializerRegistrar.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/data/bedrock/item/ItemSerializerDeserializerRegistrar.php b/src/data/bedrock/item/ItemSerializerDeserializerRegistrar.php index 16d8332af4f..76f3e940500 100644 --- a/src/data/bedrock/item/ItemSerializerDeserializerRegistrar.php +++ b/src/data/bedrock/item/ItemSerializerDeserializerRegistrar.php @@ -476,9 +476,9 @@ function(Banner $item, int $meta) : void{ Ids::FIREWORK_STAR, Items::FIREWORK_STAR(), function(FireworkStar $item, int $meta) : void{ - $item->getExplosion()->setColors([DyeColorIdMap::getInstance()->fromInvertedId($meta) ?? throw new ItemTypeDeserializeException("Unknown firework star meta $meta")]); + // Colors will be defined by CompoundTag deserialization. }, - fn(FireworkStar $item) => DyeColorIdMap::getInstance()->toInvertedId($item->getExplosion()->getMainColor()) + fn(FireworkStar $item) => DyeColorIdMap::getInstance()->toInvertedId($item->getExplosion()->getFlashColor()) ); $this->map1to1ItemWithMeta( Ids::MEDICINE, From c4ce574b129345955ab5f4f8e370a9ab6e39d2b9 Mon Sep 17 00:00:00 2001 From: IvanCraft623 Date: Tue, 9 May 2023 13:16:02 -0500 Subject: [PATCH 40/50] Remove unused import --- src/item/FireworkRocketExplosion.php | 1 - 1 file changed, 1 deletion(-) diff --git a/src/item/FireworkRocketExplosion.php b/src/item/FireworkRocketExplosion.php index a804e555f27..72b59f055bd 100644 --- a/src/item/FireworkRocketExplosion.php +++ b/src/item/FireworkRocketExplosion.php @@ -32,7 +32,6 @@ use pocketmine\utils\Binary; use pocketmine\utils\Utils; use function array_key_first; -use function array_values; use function count; use function strlen; From 7390c7fcb90f356e7811f8e9925c797812ccdde7 Mon Sep 17 00:00:00 2001 From: IvanCraft623 Date: Tue, 9 May 2023 14:01:54 -0500 Subject: [PATCH 41/50] Implement default values --- src/item/FireworkRocketExplosion.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/item/FireworkRocketExplosion.php b/src/item/FireworkRocketExplosion.php index 72b59f055bd..7cca5ed30ee 100644 --- a/src/item/FireworkRocketExplosion.php +++ b/src/item/FireworkRocketExplosion.php @@ -102,9 +102,9 @@ protected static function encodeColors(array $colors) : string{ public function __construct( protected FireworkRocketType $type, protected array $colors, - protected array $fadeColors, - protected bool $twinkle, - protected bool $trail + protected array $fadeColors = [], + protected bool $twinkle = false, + protected bool $trail = false ){ if(count($colors) === 0){ throw new \InvalidArgumentException("Colors list cannot be empty"); From 1b0d74b549cb72fde4e8ab5b74a65c6fff2ef9cf Mon Sep 17 00:00:00 2001 From: IvanCraft623 <57236932+IvanCraft623@users.noreply.github.com> Date: Tue, 9 May 2023 19:29:57 -0500 Subject: [PATCH 42/50] Fix tipo Co-authored-by: Dylan T. --- src/item/FireworkRocketExplosion.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/item/FireworkRocketExplosion.php b/src/item/FireworkRocketExplosion.php index 72b59f055bd..016f43a3bde 100644 --- a/src/item/FireworkRocketExplosion.php +++ b/src/item/FireworkRocketExplosion.php @@ -138,7 +138,7 @@ public function getFlashColor() : DyeColor{ } /** - * Returns the mixure of colors form {@link FireworkRocketExplosion::getColors()}) + * Returns the mixure of colors from {@link FireworkRocketExplosion::getColors()}) */ public function getColorMix() : Color{ /** @var Color[] $colors */ From 0f32e84c02335923972ec425ccfc00c3d19a29fa Mon Sep 17 00:00:00 2001 From: IvanCraft623 Date: Tue, 9 May 2023 21:49:31 -0500 Subject: [PATCH 43/50] Accept explosions instead of the whole item For this we have to recreate the NBT format of the item, blame mojang for complicating things. --- src/entity/object/FireworkRocket.php | 48 +++++++++++++++++++++------- src/item/FireworkRocket.php | 8 +++-- 2 files changed, 41 insertions(+), 15 deletions(-) diff --git a/src/entity/object/FireworkRocket.php b/src/entity/object/FireworkRocket.php index 9d4f7b26908..1b26e42c374 100644 --- a/src/entity/object/FireworkRocket.php +++ b/src/entity/object/FireworkRocket.php @@ -32,12 +32,15 @@ use pocketmine\event\entity\EntityDamageByEntityEvent; use pocketmine\event\entity\EntityDamageEvent; use pocketmine\item\FireworkRocket as FireworkItem; +use pocketmine\item\FireworkRocketExplosion; use pocketmine\math\VoxelRayTrace; use pocketmine\nbt\tag\CompoundTag; +use pocketmine\nbt\tag\ListTag; use pocketmine\network\mcpe\protocol\types\CacheableNbt; use pocketmine\network\mcpe\protocol\types\entity\EntityIds; use pocketmine\network\mcpe\protocol\types\entity\EntityMetadataCollection; use pocketmine\network\mcpe\protocol\types\entity\EntityMetadataProperties; +use pocketmine\utils\Utils; use pocketmine\world\sound\FireworkCrackleSound; use pocketmine\world\sound\FireworkLaunchSound; use function count; @@ -50,14 +53,18 @@ public static function getNetworkTypeId() : string{ return EntityIds::FIREWORKS_ /* Maximum number of ticks this will live for. */ protected int $lifeTicks; - protected FireworkItem $item; + /** @var FireworkRocketExplosion[] */ + protected array $explosions = []; - public function __construct(Location $location, int $lifeTicks, FireworkItem $item, ?CompoundTag $nbt = null){ + /** + * @param FireworkRocketExplosion[] $explosions + */ + public function __construct(Location $location, int $lifeTicks, array $explosions, ?CompoundTag $nbt = null){ if ($lifeTicks < 0) { throw new \InvalidArgumentException("Life ticks cannot be negative"); } $this->lifeTicks = $lifeTicks; - $this->item = $item; + $this->setExplosions($explosions); parent::__construct($location, $nbt); } @@ -88,13 +95,21 @@ public function setLifeTicks(int $lifeTicks) : self{ return $this; } - public function getItem() : FireworkItem{ - return clone $this->item; + /** + * @return FireworkRocketExplosion[] + */ + public function getExplosions() : array{ + return $this->explosions; } - /** @return $this */ - public function setItem(FireworkItem $item) : self{ - $this->item = clone $item; + /** + * @param FireworkRocketExplosion[] $explosions + * + * @return $this + */ + public function setExplosions(array $explosions) : self{ + Utils::validateArrayValueType($explosions, function(FireworkRocketExplosion $_) : void{}); + $this->explosions = $explosions; return $this; } @@ -127,10 +142,9 @@ protected function entityBaseTick(int $tickDiff = 1) : bool{ } public function explode() : void{ - $explosions = $this->item->getExplosions(); - if(($expCount = count($explosions)) !== 0){ + if(($expCount = count($this->explosions)) !== 0){ $this->broadcastAnimation(new FireworkParticlesAnimation($this)); - foreach($explosions as $explosion){ + foreach($this->explosions as $explosion){ $this->broadcastSound($explosion->getType()->getSound()); if($explosion->willTwinkle()){ $this->broadcastSound(new FireworkCrackleSound()); @@ -173,6 +187,16 @@ public function canBeCollidedWith() : bool{ protected function syncNetworkData(EntityMetadataCollection $properties) : void{ parent::syncNetworkData($properties); - $properties->setCompoundTag(EntityMetadataProperties::FIREWORK_ITEM, new CacheableNbt($this->item->getNamedTag())); + $explosions = new ListTag(); + foreach($this->explosions as $explosion){ + $explosions->push($explosion->toCompoundTag()); + } + $fireworksData = CompoundTag::create() + ->setTag(FireworkItem::TAG_FIREWORK_DATA, CompoundTag::create() + ->setTag(FireworkItem::TAG_EXPLOSIONS, $explosions) + ) + ; + + $properties->setCompoundTag(EntityMetadataProperties::FIREWORK_ITEM, new CacheableNbt($fireworksData)); } } diff --git a/src/item/FireworkRocket.php b/src/item/FireworkRocket.php index e89ba62d547..41c78c58548 100644 --- a/src/item/FireworkRocket.php +++ b/src/item/FireworkRocket.php @@ -39,9 +39,9 @@ class FireworkRocket extends Item{ - protected const TAG_FIREWORK_DATA = "Fireworks"; //TAG_Compound + public const TAG_FIREWORK_DATA = "Fireworks"; //TAG_Compound protected const TAG_FLIGHT_DURATION = "Flight"; //TAG_Byte - protected const TAG_EXPLOSIONS = "Explosions"; //TAG_List + public const TAG_EXPLOSIONS = "Explosions"; //TAG_List protected int $flightDuration = 1; @@ -104,11 +104,13 @@ public function onInteractBlock(Player $player, Block $blockReplace, Block $bloc $randomDuration = (($this->flightDuration + 1) * 10) + mt_rand(0, 12); - $entity = new FireworkEntity(Location::fromObject($position, $player->getWorld(), lcg_value() * 360, 90), $randomDuration, $this->pop()); + $entity = new FireworkEntity(Location::fromObject($position, $player->getWorld(), lcg_value() * 360, 90), $randomDuration, $this->explosions); $entity->setOwningEntity($player); $entity->setMotion(new Vector3(lcg_value() * 0.001, 0.05, lcg_value() * 0.001)); $entity->spawnToAll(); + $this->pop(); + return ItemUseResult::SUCCESS(); } From 9d08d9b017af362a73484e610cb1c03bb1674a43 Mon Sep 17 00:00:00 2001 From: IvanCraft623 Date: Wed, 10 May 2023 00:48:36 -0500 Subject: [PATCH 44/50] Update getFlightDuration and setFlightDuration --- src/item/FireworkRocket.php | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/src/item/FireworkRocket.php b/src/item/FireworkRocket.php index 41c78c58548..364d1243123 100644 --- a/src/item/FireworkRocket.php +++ b/src/item/FireworkRocket.php @@ -49,15 +49,20 @@ class FireworkRocket extends Item{ protected array $explosions = []; /** - * Returns the flight duration of the firework (equals the amount of gunpowder used in crafting the rocket). + * Returns the value that will be used to calculate a randomized flight duration + * for the firework (equals the amount of gunpowder used in crafting the rocket). + * + * The higher this value, the longer the flight duration. */ public function getFlightDuration() : int{ return $this->flightDuration; } /** - * Sets the flight duration of the firework. - * This value will be used to get a random value for the lifetime of the entity. + * Sets the value that will be used to calculate a randomized flight duration + * for the firework. + * + * The higher this value, the longer the flight duration. * * @return $this */ From eff8d855d4f4eab853f938aee1c22ff49e7490c7 Mon Sep 17 00:00:00 2001 From: IvanCraft623 Date: Wed, 10 May 2023 09:53:28 -0500 Subject: [PATCH 45/50] Rename flightDuration => flightDurationMultiplier --- src/item/FireworkRocket.php | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/item/FireworkRocket.php b/src/item/FireworkRocket.php index 364d1243123..b6e8acfefe1 100644 --- a/src/item/FireworkRocket.php +++ b/src/item/FireworkRocket.php @@ -43,7 +43,7 @@ class FireworkRocket extends Item{ protected const TAG_FLIGHT_DURATION = "Flight"; //TAG_Byte public const TAG_EXPLOSIONS = "Explosions"; //TAG_List - protected int $flightDuration = 1; + protected int $flightDurationMultiplier = 1; /** @var FireworkRocketExplosion[] */ protected array $explosions = []; @@ -54,8 +54,8 @@ class FireworkRocket extends Item{ * * The higher this value, the longer the flight duration. */ - public function getFlightDuration() : int{ - return $this->flightDuration; + public function getFlightDurationMultiplier() : int{ + return $this->flightDurationMultiplier; } /** @@ -66,11 +66,11 @@ public function getFlightDuration() : int{ * * @return $this */ - public function setFlightDuration(int $duration) : self{ + public function setFlightDurationMultiplier(int $duration) : self{ if($duration < 1 || $duration > 127){ throw new \InvalidArgumentException("Flight duration must be in range 1-127"); } - $this->flightDuration = $duration; + $this->flightDurationMultiplier = $duration; return $this; } @@ -107,7 +107,7 @@ public function onInteractBlock(Player $player, Block $blockReplace, Block $bloc default => throw new AssumptionFailedError("Invalid facing $face") }; - $randomDuration = (($this->flightDuration + 1) * 10) + mt_rand(0, 12); + $randomDuration = (($this->flightDurationMultiplier + 1) * 10) + mt_rand(0, 12); $entity = new FireworkEntity(Location::fromObject($position, $player->getWorld(), lcg_value() * 360, 90), $randomDuration, $this->explosions); $entity->setOwningEntity($player); @@ -127,7 +127,7 @@ protected function deserializeCompoundTag(CompoundTag $tag) : void{ throw new SavedDataLoadingException("Missing firework data"); } - $this->setFlightDuration($fireworksTag->getByte(self::TAG_FLIGHT_DURATION, 1)); + $this->setFlightDurationMultiplier($fireworksTag->getByte(self::TAG_FLIGHT_DURATION, 1)); if(($explosions = $fireworksTag->getListTag(self::TAG_EXPLOSIONS)) instanceof ListTag){ /** @var CompoundTag $explosion */ @@ -141,7 +141,7 @@ protected function serializeCompoundTag(CompoundTag $tag) : void{ parent::serializeCompoundTag($tag); $fireworksTag = CompoundTag::create(); - $fireworksTag->setByte(self::TAG_FLIGHT_DURATION, $this->flightDuration); + $fireworksTag->setByte(self::TAG_FLIGHT_DURATION, $this->flightDurationMultiplier); $explosions = new ListTag(); foreach($this->explosions as $explosion){ From b1e8cebf81b938e8e284a94a7daa22e636ed103c Mon Sep 17 00:00:00 2001 From: IvanCraft623 Date: Wed, 10 May 2023 09:54:08 -0500 Subject: [PATCH 46/50] Rename $fireworksTag=> $fireworkData --- src/item/FireworkRocket.php | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/item/FireworkRocket.php b/src/item/FireworkRocket.php index b6e8acfefe1..2e89ed2af5c 100644 --- a/src/item/FireworkRocket.php +++ b/src/item/FireworkRocket.php @@ -122,14 +122,14 @@ public function onInteractBlock(Player $player, Block $blockReplace, Block $bloc protected function deserializeCompoundTag(CompoundTag $tag) : void{ parent::deserializeCompoundTag($tag); - $fireworksTag = $tag->getCompoundTag(self::TAG_FIREWORK_DATA); - if($fireworksTag === null){ + $fireworkData = $tag->getCompoundTag(self::TAG_FIREWORK_DATA); + if($fireworkData === null){ throw new SavedDataLoadingException("Missing firework data"); } - $this->setFlightDurationMultiplier($fireworksTag->getByte(self::TAG_FLIGHT_DURATION, 1)); + $this->setFlightDurationMultiplier($fireworkData->getByte(self::TAG_FLIGHT_DURATION, 1)); - if(($explosions = $fireworksTag->getListTag(self::TAG_EXPLOSIONS)) instanceof ListTag){ + if(($explosions = $fireworkData->getListTag(self::TAG_EXPLOSIONS)) instanceof ListTag){ /** @var CompoundTag $explosion */ foreach($explosions as $explosion){ $this->explosions[] = FireworkRocketExplosion::fromCompoundTag($explosion); @@ -140,15 +140,15 @@ protected function deserializeCompoundTag(CompoundTag $tag) : void{ protected function serializeCompoundTag(CompoundTag $tag) : void{ parent::serializeCompoundTag($tag); - $fireworksTag = CompoundTag::create(); - $fireworksTag->setByte(self::TAG_FLIGHT_DURATION, $this->flightDurationMultiplier); + $fireworkData = CompoundTag::create(); + $fireworkData->setByte(self::TAG_FLIGHT_DURATION, $this->flightDurationMultiplier); $explosions = new ListTag(); foreach($this->explosions as $explosion){ $explosions->push($explosion->toCompoundTag()); } - $fireworksTag->setTag(self::TAG_EXPLOSIONS, $explosions); + $fireworkData->setTag(self::TAG_EXPLOSIONS, $explosions); - $tag->setTag(self::TAG_FIREWORK_DATA, $fireworksTag); + $tag->setTag(self::TAG_FIREWORK_DATA, $fireworkData); } } From fdbefd09640588d1ffd6eaf78baa06f147245e42 Mon Sep 17 00:00:00 2001 From: IvanCraft623 Date: Mon, 19 Feb 2024 18:45:12 -0500 Subject: [PATCH 47/50] Don't flagForDespawn inside explode() --- src/entity/object/FireworkRocket.php | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/entity/object/FireworkRocket.php b/src/entity/object/FireworkRocket.php index 1b26e42c374..7a40a35752c 100644 --- a/src/entity/object/FireworkRocket.php +++ b/src/entity/object/FireworkRocket.php @@ -134,6 +134,7 @@ protected function entityBaseTick(int $tickDiff = 1) : bool{ $this->addMotion($this->motion->x * 0.15, 0.04, $this->motion->z * 0.15); if($this->ticksLived >= $this->lifeTicks){ + $this->flagForDespawn(); $this->explode(); } } @@ -176,8 +177,6 @@ public function explode() : void{ $entity->attack($ev); } } - - $this->flagForDespawn(); } public function canBeCollidedWith() : bool{ From e6c52fd8161d93e1b64e2e5104645e8a93df9f1d Mon Sep 17 00:00:00 2001 From: IvanCraft623 Date: Mon, 19 Feb 2024 18:50:27 -0500 Subject: [PATCH 48/50] Use of native enum case accessor --- src/item/FireworkRocket.php | 2 +- src/item/FireworkStar.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/item/FireworkRocket.php b/src/item/FireworkRocket.php index 2e89ed2af5c..4faeb55e4e9 100644 --- a/src/item/FireworkRocket.php +++ b/src/item/FireworkRocket.php @@ -116,7 +116,7 @@ public function onInteractBlock(Player $player, Block $blockReplace, Block $bloc $this->pop(); - return ItemUseResult::SUCCESS(); + return ItemUseResult::SUCCESS; } protected function deserializeCompoundTag(CompoundTag $tag) : void{ diff --git a/src/item/FireworkStar.php b/src/item/FireworkStar.php index 512c137a104..257834f45a9 100644 --- a/src/item/FireworkStar.php +++ b/src/item/FireworkStar.php @@ -41,7 +41,7 @@ class FireworkStar extends Item{ public function __construct(ItemIdentifier $identifier, string $name){ parent::__construct($identifier, $name); - $this->explosion = new FireworkRocketExplosion(FireworkRocketType::SMALL_BALL(), [DyeColor::BLACK()], [], false, false); + $this->explosion = new FireworkRocketExplosion(FireworkRocketType::SMALL_BALL(), [DyeColor::BLACK], [], false, false); } public function getExplosion() : FireworkRocketExplosion{ From 827397878be93ed5854319e56708bf7fbbfdcdb0 Mon Sep 17 00:00:00 2001 From: IvanCraft623 Date: Sun, 18 Aug 2024 10:56:23 -0500 Subject: [PATCH 49/50] Modernize the FireworkRocketType enum --- src/data/bedrock/FireworkRocketTypeIdMap.php | 42 ++++------------ src/entity/object/FireworkRocket.php | 2 +- src/item/FireworkRocketType.php | 52 ++++++-------------- src/item/FireworkStar.php | 2 +- 4 files changed, 27 insertions(+), 71 deletions(-) diff --git a/src/data/bedrock/FireworkRocketTypeIdMap.php b/src/data/bedrock/FireworkRocketTypeIdMap.php index 1ecfaa90b64..4358c207301 100644 --- a/src/data/bedrock/FireworkRocketTypeIdMap.php +++ b/src/data/bedrock/FireworkRocketTypeIdMap.php @@ -28,40 +28,18 @@ final class FireworkRocketTypeIdMap{ use SingletonTrait; - - /** - * @var FireworkRocketType[] - * @phpstan-var array - */ - private array $idToEnum = []; - - /** - * @var int[] - * @phpstan-var array - */ - private array $enumToId = []; + /** @phpstan-use IntSaveIdMapTrait */ + use IntSaveIdMapTrait; private function __construct(){ - $this->register(FireworkRocketTypeIds::SMALL_BALL, FireworkRocketType::SMALL_BALL()); - $this->register(FireworkRocketTypeIds::LARGE_BALL, FireworkRocketType::LARGE_BALL()); - $this->register(FireworkRocketTypeIds::STAR, FireworkRocketType::STAR()); - $this->register(FireworkRocketTypeIds::CREEPER, FireworkRocketType::CREEPER()); - $this->register(FireworkRocketTypeIds::BURST, FireworkRocketType::BURST()); - } - - private function register(int $id, FireworkRocketType $type) : void{ - $this->idToEnum[$id] = $type; - $this->enumToId[$type->id()] = $id; - } - - public function fromId(int $id) : ?FireworkRocketType{ - return $this->idToEnum[$id] ?? null; - } - - public function toId(FireworkRocketType $type) : int{ - if(!isset($this->enumToId[$type->id()])){ - throw new \InvalidArgumentException("Type does not have a mapped ID"); + foreach(FireworkRocketType::cases() as $case){ + $this->register(match($case){ + FireworkRocketType::SMALL_BALL => FireworkRocketTypeIds::SMALL_BALL, + FireworkRocketType::LARGE_BALL => FireworkRocketTypeIds::LARGE_BALL, + FireworkRocketType::STAR => FireworkRocketTypeIds::STAR, + FireworkRocketType::CREEPER => FireworkRocketTypeIds::CREEPER, + FireworkRocketType::BURST => FireworkRocketTypeIds::BURST, + }, $case); } - return $this->enumToId[$type->id()]; } } diff --git a/src/entity/object/FireworkRocket.php b/src/entity/object/FireworkRocket.php index 7a40a35752c..87db02c27c7 100644 --- a/src/entity/object/FireworkRocket.php +++ b/src/entity/object/FireworkRocket.php @@ -146,7 +146,7 @@ public function explode() : void{ if(($expCount = count($this->explosions)) !== 0){ $this->broadcastAnimation(new FireworkParticlesAnimation($this)); foreach($this->explosions as $explosion){ - $this->broadcastSound($explosion->getType()->getSound()); + $this->broadcastSound($explosion->getType()->getExplosionSound()); if($explosion->willTwinkle()){ $this->broadcastSound(new FireworkCrackleSound()); } diff --git a/src/item/FireworkRocketType.php b/src/item/FireworkRocketType.php index abef63cd70f..98088664c5e 100644 --- a/src/item/FireworkRocketType.php +++ b/src/item/FireworkRocketType.php @@ -23,46 +23,24 @@ namespace pocketmine\item; -use pocketmine\utils\EnumTrait; use pocketmine\world\sound\FireworkExplosionSound; use pocketmine\world\sound\FireworkLargeExplosionSound; use pocketmine\world\sound\Sound; -/** - * This doc-block is generated automatically, do not modify it manually. - * This must be regenerated whenever registry members are added, removed or changed. - * @see build/generate-registry-annotations.php - * @generate-registry-docblock - * - * @method static FireworkRocketType BURST() - * @method static FireworkRocketType CREEPER() - * @method static FireworkRocketType LARGE_BALL() - * @method static FireworkRocketType SMALL_BALL() - * @method static FireworkRocketType STAR() - */ -final class FireworkRocketType{ - use EnumTrait { - __construct as Enum___construct; - } - - protected static function setup() : void{ - self::registerAll( - new self("small_ball", new FireworkExplosionSound()), - new self("large_ball", new FireworkLargeExplosionSound()), - new self("star", new FireworkExplosionSound()), - new self("creeper", new FireworkExplosionSound()), - new self("burst", new FireworkExplosionSound()), - ); - } - - private function __construct( - string $enumName, - private Sound $sound - ){ - $this->Enum___construct($enumName); - } - - public function getSound() : Sound{ - return $this->sound; +enum FireworkRocketType{ + case SMALL_BALL; + case LARGE_BALL; + case STAR; + case CREEPER; + case BURST; + + public function getExplosionSound() : Sound{ + return match($this){ + self::SMALL_BALL => new FireworkExplosionSound(), + self::LARGE_BALL => new FireworkLargeExplosionSound(), + self::STAR => new FireworkExplosionSound(), + self::CREEPER => new FireworkExplosionSound(), + self::BURST => new FireworkExplosionSound(), + }; } } diff --git a/src/item/FireworkStar.php b/src/item/FireworkStar.php index 257834f45a9..0eed6963bdd 100644 --- a/src/item/FireworkStar.php +++ b/src/item/FireworkStar.php @@ -41,7 +41,7 @@ class FireworkStar extends Item{ public function __construct(ItemIdentifier $identifier, string $name){ parent::__construct($identifier, $name); - $this->explosion = new FireworkRocketExplosion(FireworkRocketType::SMALL_BALL(), [DyeColor::BLACK], [], false, false); + $this->explosion = new FireworkRocketExplosion(FireworkRocketType::SMALL_BALL, [DyeColor::BLACK], [], false, false); } public function getExplosion() : FireworkRocketExplosion{ From 609c4c65f710d96f8ad65d308efa7e92fda2b00b Mon Sep 17 00:00:00 2001 From: IvanCraft623 <57236932+IvanCraft623@users.noreply.github.com> Date: Sun, 1 Sep 2024 08:14:14 -0600 Subject: [PATCH 50/50] Group some rocket types in a single case Co-authored-by: ipad54 <63200545+ipad54@users.noreply.github.com> --- src/item/FireworkRocketType.php | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/item/FireworkRocketType.php b/src/item/FireworkRocketType.php index 98088664c5e..6aa20e6d9f2 100644 --- a/src/item/FireworkRocketType.php +++ b/src/item/FireworkRocketType.php @@ -36,11 +36,11 @@ enum FireworkRocketType{ public function getExplosionSound() : Sound{ return match($this){ - self::SMALL_BALL => new FireworkExplosionSound(), - self::LARGE_BALL => new FireworkLargeExplosionSound(), - self::STAR => new FireworkExplosionSound(), - self::CREEPER => new FireworkExplosionSound(), + self::SMALL_BALL, + self::STAR, + self::CREEPER, self::BURST => new FireworkExplosionSound(), + self::LARGE_BALL => new FireworkLargeExplosionSound(), }; } }