Skip to content

Commit

Permalink
Add support for BossBar colors, close #21
Browse files Browse the repository at this point in the history
Additionally return type static for phpstan
Drop PHP 7.4 support
Removed redundant PHPDocs
Might need to update DiverseBossBar's __toString()
  • Loading branch information
inxomnyaa committed Oct 26, 2022
1 parent e399002 commit 8c35364
Show file tree
Hide file tree
Showing 3 changed files with 86 additions and 78 deletions.
73 changes: 39 additions & 34 deletions src/xenialdan/apibossbar/BossBar.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
use pocketmine\entity\Entity;
use pocketmine\network\mcpe\protocol\BossEventPacket;
use pocketmine\network\mcpe\protocol\RemoveActorPacket;
use pocketmine\network\mcpe\protocol\types\BossBarColor;
use pocketmine\network\mcpe\protocol\types\entity\EntityMetadataCollection;
use pocketmine\network\mcpe\protocol\types\entity\EntityMetadataFlags;
use pocketmine\network\mcpe\protocol\types\entity\EntityMetadataProperties;
Expand All @@ -23,6 +24,7 @@ class BossBar
private array $players = [];
private string $title = "";
private string $subTitle = "";
private int $color = BossBarColor::PURPLE;
public ?int $actorId = null;
private AttributeMap $attributeMap;
protected EntityMetadataCollection $propertyManager;
Expand Down Expand Up @@ -59,20 +61,17 @@ public function getPlayers(): array

/**
* @param Player[] $players
* @return BossBar
*
* @return static
*/
public function addPlayers(array $players) : self{
public function addPlayers(array $players) : static{
foreach($players as $player){
$this->addPlayer($player);
}
return $this;
}

/**
* @param Player $player
* @return BossBar
*/
public function addPlayer(Player $player) : self{
public function addPlayer(Player $player) : static{
if(isset($this->players[$player->getId()])) return $this;
#if (!$this->getEntity() instanceof Player) $this->sendSpawnPacket([$player]);
$this->sendBossPacket([$player]);
Expand All @@ -83,10 +82,10 @@ public function addPlayer(Player $player) : self{
/**
* Removes a single player from this bar.
* Use @param Player $player
* @return BossBar
* @return static
* @see BossBar::hideFrom() when just removing temporarily to save some performance / bandwidth
*/
public function removePlayer(Player $player) : self{
public function removePlayer(Player $player) : static{
if(!isset($this->players[$player->getId()])){
GlobalLogger::get()->debug("Removed player that was not added to the boss bar (" . $this . ")");
return $this;
Expand All @@ -98,9 +97,9 @@ public function removePlayer(Player $player) : self{

/**
* @param Player[] $players
* @return BossBar
* @return static
*/
public function removePlayers(array $players) : self{
public function removePlayers(array $players) : static{
foreach($players as $player){
$this->removePlayer($player);
}
Expand All @@ -109,9 +108,9 @@ public function removePlayers(array $players) : self{

/**
* Removes all players from this bar
* @return BossBar
* @return static
*/
public function removeAllPlayers() : self{
public function removeAllPlayers() : static{
foreach($this->getPlayers() as $player) $this->removePlayer($player);
return $this;
}
Expand All @@ -128,9 +127,9 @@ public function getTitle(): string
/**
* Text above the bar. Can be empty. Should be single-line
* @param string $title
* @return BossBar
* @return static
*/
public function setTitle(string $title = "") : self{
public function setTitle(string $title = "") : static{
$this->title = $title;
$this->sendBossTextPacket($this->getPlayers());
return $this;
Expand All @@ -144,9 +143,9 @@ public function getSubTitle(): string
/**
* Optional text below the bar. Can be empty
* @param string $subTitle
* @return BossBar
* @return static
*/
public function setSubTitle(string $subTitle = "") : self{
public function setSubTitle(string $subTitle = "") : static{
$this->subTitle = $subTitle;
#$this->sendEntityDataPacket($this->getPlayers());
$this->sendBossTextPacket($this->getPlayers());
Expand All @@ -168,9 +167,9 @@ public function getFullTitle(): string

/**
* @param float $percentage 0-1
* @return BossBar
* @return static
*/
public function setPercentage(float $percentage) : self{
public function setPercentage(float $percentage) : static{
$percentage = (float) min(1.0, max(0.0, $percentage));
$this->getAttributeMap()->get(Attribute::HEALTH)->setValue($percentage * $this->getAttributeMap()->get(Attribute::HEALTH)->getMaxValue(), true, true);
#$this->sendAttributesPacket($this->getPlayers());
Expand All @@ -179,19 +178,27 @@ public function setPercentage(float $percentage) : self{
return $this;
}

public function getPercentage(): float
{
public function getPercentage() : float{
return $this->getAttributeMap()->get(Attribute::HEALTH)->getValue() / 100;
}

public function getColor() : int{
return $this->color;
}

public function setColor(int $color) : static{
$this->color = $color;
return $this;
}

/**
* TODO: Only registered players validation
* Hides the bar from the specified players without removing it.
* Useful when saving some bandwidth or when you'd like to keep the entity
*
* @param Player[] $players
*/
public function hideFrom(array $players): void
{
public function hideFrom(array $players) : void{
$pk = new BossEventPacket();
$pk->eventType = BossEventPacket::TYPE_HIDE;
foreach ($players as $player) {
Expand Down Expand Up @@ -242,10 +249,10 @@ public function getEntity(): ?Entity
/**
* STILL TODO, SHOULD NOT BE USED YET
* @param null|Entity $entity
* @return BossBar
* @return static
* TODO: use attributes and properties of the custom entity
*/
public function setEntity(?Entity $entity = null) : self{
public function setEntity(?Entity $entity = null) : static{
if($entity instanceof Entity && ($entity->isClosed() || $entity->isFlaggedForDespawn())) throw new InvalidArgumentException("Entity $entity can not be used since its not valid anymore (closed or flagged for despawn)");
if($this->getEntity() instanceof Entity && !$entity instanceof Player) $this->getEntity()->flagForDespawn();
else{
Expand All @@ -269,9 +276,9 @@ public function setEntity(?Entity $entity = null) : self{

/**
* @param bool $removeEntity Be careful with this. If set to true, the entity will be deleted.
* @return BossBar
* @return static
*/
public function resetEntity(bool $removeEntity = false) : self{
public function resetEntity(bool $removeEntity = false) : static{
if($removeEntity && $this->getEntity() instanceof Entity && !$this->getEntity() instanceof Player) $this->getEntity()->close();
return $this->setEntity();
}
Expand Down Expand Up @@ -346,19 +353,17 @@ protected function sendBossHealthPacket(array $players): void
}
}

private function addDefaults(BossEventPacket $pk): BossEventPacket
{
private function addDefaults(BossEventPacket $pk): BossEventPacket{
$pk->title = $this->getFullTitle();
$pk->healthPercent = $this->getPercentage();
$pk->unknownShort = 1;
$pk->color = 0;//Does not function anyways
$pk->overlay = 0;//Neither. Typical for Mojang: Copy-pasted from Java edition
$pk->color = $this->color;
$pk->overlay = 0;//Does not work. Typical for Mojang: Copy-pasted from Java edition
return $pk;
}

public function __toString(): string
{
return __CLASS__ . " ID: $this->actorId, Players: " . count($this->players) . ", Title: \"$this->title\", Subtitle: \"$this->subTitle\", Percentage: \"" . $this->getPercentage() . "\"";
public function __toString(): string{
return __CLASS__ . " ID: $this->actorId, Players: " . count($this->players) . ", Title: \"$this->title\", Subtitle: \"$this->subTitle\", Percentage: \"" . $this->getPercentage() . "\", Color: \"" . $this->color . "\"";
}

/**
Expand Down
87 changes: 45 additions & 42 deletions src/xenialdan/apibossbar/DiverseBossBar.php
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ class DiverseBossBar extends BossBar
private array $subTitles = [];
/** @var AttributeMap[] */
private array $attributeMaps = [];
private array $colors = [];

/**
* DiverseBossBar constructor.
Expand All @@ -34,39 +35,31 @@ public function __construct()
parent::__construct();
}

/**
* @param Player $player
* @return BossBar
*/
public function addPlayer(Player $player): BossBar
{
public function addPlayer(Player $player) : static{
$this->attributeMaps[$player->getId()] = clone parent::getAttributeMap();
return parent::addPlayer($player);
}

/**
* Removes a single player from this bar.
* Use @param Player $player
* @return BossBar
* @return static
* @see BossBar::hideFrom() when just removing temporarily to save some performance / bandwidth
*/
public function removePlayer(Player $player): BossBar
{
public function removePlayer(Player $player) : static{
unset($this->attributeMaps[$player->getId()]);
return parent::removePlayer($player);
}

public function resetFor(Player $player): DiverseBossBar
{
unset($this->attributeMaps[$player->getId()], $this->titles[$player->getId()], $this->subTitles[$player->getId()]);
public function resetFor(Player $player) : static{
unset($this->attributeMaps[$player->getId()], $this->titles[$player->getId()], $this->subTitles[$player->getId()], $this->colors[$player->getId()]);
$this->sendAttributesPacket([$player]);
$this->sendBossPacket([$player]);
return $this;
}

public function resetForAll(): DiverseBossBar
{
foreach ($this->getPlayers() as $player) {
public function resetForAll() : static{
foreach($this->getPlayers() as $player){
$this->resetFor($player);
}
return $this;
Expand All @@ -79,12 +72,12 @@ public function getTitleFor(Player $player): string

/**
* @param Player[] $players
* @param string $title
* @return DiverseBossBar
* @param string $title
*
* @return static
*/
public function setTitleFor(array $players, string $title = ""): DiverseBossBar
{
foreach ($players as $player) {
public function setTitleFor(array $players, string $title = "") : static{
foreach($players as $player){
$this->titles[$player->getId()] = $title;
$this->sendBossTextPacket([$player]);
}
Expand All @@ -98,12 +91,11 @@ public function getSubTitleFor(Player $player): string

/**
* @param Player[] $players
* @param string $subTitle
* @return DiverseBossBar
* @param string $subTitle
* @return static
*/
public function setSubTitleFor(array $players, string $subTitle = ""): DiverseBossBar
{
foreach ($players as $player) {
public function setSubTitleFor(array $players, string $subTitle = "") : static{
foreach($players as $player){
$this->subTitles[$player->getId()] = $subTitle;
$this->sendBossTextPacket([$player]);
}
Expand All @@ -127,13 +119,12 @@ public function getFullTitleFor(Player $player): string

/**
* @param Player[] $players
* @param float $percentage 0-1
* @return DiverseBossBar
* @param float $percentage 0-1
* @return static
*/
public function setPercentageFor(array $players, float $percentage): DiverseBossBar
{
$percentage = (float)min(1.0, max(0.00, $percentage));
foreach ($players as $player) {
public function setPercentageFor(array $players, float $percentage) : static{
$percentage = (float) min(1.0, max(0.00, $percentage));
foreach($players as $player){
$this->getAttributeMap($player)->get(Attribute::HEALTH)->setValue($percentage * $this->getAttributeMap($player)->get(Attribute::HEALTH)->getMaxValue(), true, true);
}
$this->sendAttributesPacket($players);
Expand All @@ -142,22 +133,35 @@ public function setPercentageFor(array $players, float $percentage): DiverseBoss
return $this;
}

public function getPercentageFor(Player $player) : float{
return $this->getAttributeMap($player)->get(Attribute::HEALTH)->getValue() / 100;
}

/**
* @param Player $player
* @return float
* @param Player[] $players
* @param int $color
*
* @return static
*/
public function getPercentageFor(Player $player): float
{
return $this->getAttributeMap($player)->get(Attribute::HEALTH)->getValue() / 100;
public function setColorFor(array $players, int $color) : static{
foreach($players as $player){
$this->colors[$player->getId()] = $color;
$this->sendBossPacket([$player]);
}
return $this;
}

public function getColorFor(Player $player) : int{
return $this->colors[$player->getId()] ?? $this->getColor();
}

/**
* TODO: Only registered players validation
* Displays the bar to the specified players
*
* @param Player[] $players
*/
public function showTo(array $players): void
{
public function showTo(array $players) : void{
$pk = new BossEventPacket();
$pk->eventType = BossEventPacket::TYPE_SHOW;
foreach ($players as $player) {
Expand Down Expand Up @@ -226,13 +230,12 @@ protected function sendBossHealthPacket(array $players): void
}
}

private function addDefaults(Player $player, BossEventPacket $pk): BossEventPacket
{
private function addDefaults(Player $player, BossEventPacket $pk): BossEventPacket{
$pk->title = $this->getFullTitleFor($player);
$pk->healthPercent = $this->getPercentageFor($player);
$pk->unknownShort = 1;
$pk->color = 0;//Does not function anyways
$pk->overlay = 0;//neither. Typical for Mojang: Copy-pasted from Java edition
$pk->color = $this->getColorFor($player);
$pk->overlay = 0;//Non-functional. Typical for Mojang: Copy-pasted from Java edition
return $pk;
}

Expand Down
4 changes: 2 additions & 2 deletions virion.yml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
name: apibossbar
version: 0.1.5
version: 0.1.6
antigen: xenialdan\apibossbar
api: [4.0.0]
php: [7.4, 8.0]
php: [ 8.0 ]
author: XenialDan

0 comments on commit 8c35364

Please sign in to comment.