diff --git a/src/entity/Living.php b/src/entity/Living.php index 852344784a6..6d62c85d257 100644 --- a/src/entity/Living.php +++ b/src/entity/Living.php @@ -38,6 +38,7 @@ use pocketmine\event\entity\EntityDamageByEntityEvent; use pocketmine\event\entity\EntityDamageEvent; use pocketmine\event\entity\EntityDeathEvent; +use pocketmine\event\entity\EntityFrostWalkerEvent; use pocketmine\inventory\ArmorInventory; use pocketmine\inventory\CallbackInventoryListener; use pocketmine\inventory\Inventory; @@ -721,19 +722,30 @@ protected function applyFrostWalker(int $level) : void{ $y = $this->location->getFloorY() - 1; $baseZ = $this->location->getFloorZ(); - $frostedIce = VanillaBlocks::FROSTED_ICE(); + $liquid = VanillaBlocks::WATER(); + $targetBlock = VanillaBlocks::FROSTED_ICE(); + if(EntityFrostWalkerEvent::hasHandlers()){ + $ev = new EntityFrostWalkerEvent($this, $radius, $liquid, $targetBlock); + $ev->call(); + if($ev->isCancelled()){ + return; + } + $radius = $ev->getRadius(); + $liquid = $ev->getLiquid(); + $targetBlock = $ev->getTargetBlock(); + } + for($x = $baseX - $radius; $x <= $baseX + $radius; $x++){ for($z = $baseZ - $radius; $z <= $baseZ + $radius; $z++){ $block = $world->getBlockAt($x, $y, $z); if( - !$block instanceof Water || - !$block->isSource() || + !$block->isSameState($liquid) || $world->getBlockAt($x, $y + 1, $z)->getTypeId() !== BlockTypeIds::AIR || count($world->getNearbyEntities(AxisAlignedBB::one()->offset($x, $y, $z))) !== 0 ){ continue; } - $world->setBlockAt($x, $y, $z, $frostedIce); + $world->setBlockAt($x, $y, $z, $targetBlock); } } } diff --git a/src/event/entity/EntityFrostWalkerEvent.php b/src/event/entity/EntityFrostWalkerEvent.php new file mode 100644 index 00000000000..15ba2826819 --- /dev/null +++ b/src/event/entity/EntityFrostWalkerEvent.php @@ -0,0 +1,84 @@ + + */ +class EntityFrostWalkerEvent extends EntityEvent implements Cancellable{ + use CancellableTrait; + + public function __construct( + Living $entity, + private int $radius, + private Liquid $liquid, + private Block $targetBlock + ){ + $this->entity = $entity; + } + + public function getRadius() : int{ + return $this->radius; + } + + public function setRadius(int $radius) : void{ + $this->radius = $radius; + } + + /** + * Returns the liquid that gets frozen + */ + public function getLiquid() : Liquid{ + return $this->liquid; + } + + /** + * Sets the liquid that gets frozen + */ + public function setLiquid(Liquid $liquid) : void{ + $this->liquid = $liquid; + } + + /** + * Returns the block that replaces the liquid + */ + public function getTargetBlock() : Block{ + return $this->targetBlock; + } + + /** + * Sets the block that replaces the liquid + */ + public function setTargetBlock(Block $targetBlock) : void{ + $this->targetBlock = $targetBlock; + } +}