Open dadodasyra opened 1 year ago
For CustomBlocks *
@dadodasyra hi, did you manage to fix it ? Or @IvanCraft623 i see you were active, do you know how to manage to fix thatt ?
@dadodasyra hi, did you manage to fix it ? Or @IvanCraft623 i see you were active, do you know how to manage to fix thatt ?
Seems like its a common problem event with the addon community
@dadodasyra someone says that we have to break the block when the animation is finish with SurvivalBlockBreakHandler:
`php final class SurvivalBlockBreakHandler{
public const DEFAULT_FX_INTERVAL_TICKS = 5;
private int $fxTicker = 0;
private float $breakSpeed;
private float $breakProgress = 0;
public function __construct(
private Player $player,
private Vector3 $blockPos,
private Block $block,
private int $targetedFace,
private int $maxPlayerDistance,
private int $fxTickInterval = self::DEFAULT_FX_INTERVAL_TICKS
){
$this->breakSpeed = $this->calculateBreakProgressPerTick();
if($this->breakSpeed > 0){
$this->player->getWorld()->broadcastPacketToViewers(
$this->blockPos,
LevelEventPacket::create(LevelEvent::BLOCK_START_BREAK, (int) (65535 * $this->breakSpeed), $this->blockPos)
);
}
}
/**
* Returns the calculated break speed as percentage progress per game tick.
*/
private function calculateBreakProgressPerTick() : float{
if(!$this->block->getBreakInfo()->isBreakable()){
return 0.0;
}
//TODO: improve this to take stuff like swimming, ladders, enchanted tools into account, fix wrong tool break time calculations for bad tools (pmmp/PocketMine-MP#211)
$breakTimePerTick = $this->block->getBreakInfo()->getBreakTime($this->player->getInventory()->getItemInHand()) * 20;
if($breakTimePerTick > 0){
return 1 / $breakTimePerTick;
}
return 1;
}
public function update() : bool{
if($this->player->getPosition()->distanceSquared($this->blockPos->add(0.5, 0.5, 0.5)) > $this->maxPlayerDistance ** 2){
return false;
}
$newBreakSpeed = $this->calculateBreakProgressPerTick();
if(abs($newBreakSpeed - $this->breakSpeed) > 0.0001){
$this->breakSpeed = $newBreakSpeed;
//TODO: sync with client
}
$this->breakProgress += $this->breakSpeed;
if(($this->fxTicker++ % $this->fxTickInterval) === 0 && $this->breakProgress < 1){
$this->player->getWorld()->addParticle($this->blockPos, new BlockPunchParticle($this->block, $this->targetedFace));
$this->player->getWorld()->addSound($this->blockPos, new BlockPunchSound($this->block));
$this->player->broadcastAnimation(new ArmSwingAnimation($this->player), $this->player->getViewers());
}
return $this->breakProgress < 1;
}
public function getBlockPos() : Vector3{
return $this->blockPos;
}
public function getTargetedFace() : int{
return $this->targetedFace;
}
public function setTargetedFace(int $face) : void{
Facing::validate($face);
$this->targetedFace = $face;
}
public function getBreakSpeed() : float{
return $this->breakSpeed;
}
public function getBreakProgress() : float{
return $this->breakProgress;
}
public function __destruct(){
if($this->player->getWorld()->isInLoadedTerrain($this->blockPos)){
$this->player->getWorld()->broadcastPacketToViewers(
$this->blockPos,
LevelEventPacket::create(LevelEvent::BLOCK_STOP_BREAK, 0, $this->blockPos)
);
}
}
} `
I think I made it to the conclusion that the default pocketmine handler is completly wrong. Normally the client destroys the block without any server confirmation but it seems that with custom items (or custom blocks i dont remember) it doesnt. Since pm implementation is probably not accurate with the client time it may create some inconstensies.
How to handle correctly breaking time ? Client side and server side are not okay with it. The animation is sometime longer, sometime shorter. The item handled is not really changing something..