38 public const DEFAULT_FX_INTERVAL_TICKS = 5;
40 private int $fxTicker = 0;
41 private float $breakSpeed;
42 private float $breakProgress = 0;
44 public function __construct(
48 private int $targetedFace,
49 private int $maxPlayerDistance,
50 private int $fxTickInterval = self::DEFAULT_FX_INTERVAL_TICKS
52 $this->breakSpeed = $this->calculateBreakProgressPerTick();
53 if($this->breakSpeed > 0){
54 $this->player->getWorld()->broadcastPacketToViewers(
64 private function calculateBreakProgressPerTick() :
float{
65 if(!$this->block->getBreakInfo()->isBreakable()){
69 $breakTimePerTick = $this->block->getBreakInfo()->getBreakTime($this->player->getInventory()->getItemInHand()) * 20;
71 if($breakTimePerTick > 0){
72 return 1 / $breakTimePerTick;
77 public function update() :
bool{
78 if($this->player->getPosition()->distanceSquared($this->blockPos->add(0.5, 0.5, 0.5)) > $this->maxPlayerDistance ** 2){
82 $newBreakSpeed = $this->calculateBreakProgressPerTick();
83 if(abs($newBreakSpeed - $this->breakSpeed) > 0.0001){
84 $this->breakSpeed = $newBreakSpeed;
88 $this->breakProgress += $this->breakSpeed;
90 if(($this->fxTicker++ % $this->fxTickInterval) === 0 && $this->breakProgress < 1){
91 $this->player->getWorld()->addParticle($this->blockPos,
new BlockPunchParticle($this->block, $this->targetedFace));
92 $this->player->getWorld()->addSound($this->blockPos,
new BlockPunchSound($this->block));
93 $this->player->broadcastAnimation(
new ArmSwingAnimation($this->player), $this->player->getViewers());
96 return $this->breakProgress < 1;
99 public function getBlockPos() :
Vector3{
100 return $this->blockPos;
103 public function getTargetedFace() :
int{
104 return $this->targetedFace;
107 public function setTargetedFace(
int $face) :
void{
108 Facing::validate($face);
109 $this->targetedFace = $face;
112 public function getBreakSpeed() :
float{
113 return $this->breakSpeed;
116 public function getBreakProgress() :
float{
117 return $this->breakProgress;
120 public function __destruct(){
121 if($this->player->getWorld()->isInLoadedTerrain($this->blockPos)){
122 $this->player->getWorld()->broadcastPacketToViewers(