41 protected const TAG_TYPE =
"FireworkType";
42 protected const TAG_COLORS =
"FireworkColor";
43 protected const TAG_FADE_COLORS =
"FireworkFade";
44 protected const TAG_TWINKLE =
"FireworkFlicker";
45 protected const TAG_TRAIL =
"FireworkTrail";
51 $colors = self::
decodeColors($tag->getByteArray(self::TAG_COLORS));
52 if(count($colors) === 0){
57 FireworkRocketTypeIdMap::getInstance()->fromId($tag->getByte(self::TAG_TYPE)) ??
throw new SavedDataLoadingException(
"Invalid firework type"),
60 $tag->getByte(self::TAG_TWINKLE, 0) !== 0,
61 $tag->getByte(self::TAG_TRAIL, 0) !== 0
70 protected static function decodeColors(
string $colorsBytes) : array{
73 $dyeColorIdMap = DyeColorIdMap::getInstance();
74 for($i = 0, $len = strlen($colorsBytes); $i < $len; $i++){
75 $colorByte = ord($colorsBytes[$i]);
76 $color = $dyeColorIdMap->fromInvertedId($colorByte);
93 $dyeColorIdMap = DyeColorIdMap::getInstance();
94 foreach($colors as $color){
95 $colorsBytes .= chr($dyeColorIdMap->toInvertedId($color));
108 protected FireworkRocketType $type,
109 protected array $colors,
110 protected array $fadeColors = [],
111 protected bool $twinkle =
false,
112 protected bool $trail =
false
114 if(count($colors) === 0){
115 throw new \InvalidArgumentException(
"Colors list cannot be empty");
118 $colorsValidator =
function(DyeColor $_) :
void{};
120 Utils::validateArrayValueType($colors, $colorsValidator);
121 Utils::validateArrayValueType($fadeColors, $colorsValidator);
124 public function getType() : FireworkRocketType{
135 return $this->colors;
142 return $this->colors[array_key_first($this->colors)];
151 foreach($this->colors as $dyeColor){
152 $colors[] = $dyeColor->getRgbValue();
154 return Color::mix(...$colors);
165 return $this->fadeColors;
172 return $this->twinkle;
185 ->setByteArray(self::TAG_COLORS, self::encodeColors($this->colors))
186 ->setByteArray(self::TAG_FADE_COLORS, self::encodeColors($this->fadeColors))
187 ->setByte(self::TAG_TWINKLE, $this->twinkle ? 1 : 0)
188 ->setByte(self::TAG_TRAIL, $this->trail ? 1 : 0);