CustomiesDevs / Customies

A PocketMine-MP plugin that implements support for custom blocks, items and entities.
MIT License
112 stars 54 forks source link

Breaking time #100

Open dadodasyra opened 1 year ago

dadodasyra commented 1 year ago

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..

dadodasyra commented 1 year ago

For CustomBlocks *

AzOxStOz commented 1 year ago

@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 commented 1 year ago

@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

AzOxStOz commented 1 year ago

@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)
        );
    }
}

} `

dadodasyra commented 1 year ago

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.