42    public const MAX_AGE = 15;
 
   44    protected function getFireDamage() : 
int{
 
   48    private function canBeSupportedBy(
Block $block) : 
bool{
 
   53        $world = $this->position->getWorld();
 
   54        $down = $this->
getSide(Facing::DOWN);
 
   55        if(SoulFire::canBeSupportedBy($down)){
 
   56            $world->setBlock($this->position, VanillaBlocks::SOUL_FIRE());
 
   57        }elseif(!$this->canBeSupportedBy($this->
getSide(Facing::DOWN)) && !$this->hasAdjacentFlammableBlocks()){
 
   58            $world->setBlock($this->position, VanillaBlocks::AIR());
 
   60            $world->scheduleDelayedBlockUpdate($this->position, mt_rand(30, 40));
 
 
   69        $down = $this->getSide(
Facing::DOWN);
 
   72        if($this->age < self::MAX_AGE && mt_rand(0, 2) === 0){
 
   78        if(!$down->burnsForever()){
 
   80            if($this->age === self::MAX_AGE){
 
   81                if(!$down->isFlammable() && mt_rand(0, 3) === 3){ 
 
   83                    $result = VanillaBlocks::AIR();
 
   85            }elseif(!$this->hasAdjacentFlammableBlocks()){
 
   87                if($down->isTransparent() || $this->age > 3){
 
   88                    $result = VanillaBlocks::AIR();
 
   93        $world = $this->position->getWorld();
 
   95            $world->setBlock($this->position, $result);
 
   98        $world->scheduleDelayedBlockUpdate($this->position, mt_rand(30, 40));
 
  101            $this->burnBlocksAround();
 
 
  107        $this->onRandomTick();
 
 
  110    private function hasAdjacentFlammableBlocks() : bool{
 
  111        foreach(
Facing::ALL as $face){
 
  112            if($this->getSide($face)->isFlammable()){
 
  120    private function burnBlocksAround() : void{
 
  123        foreach($this->getHorizontalSides() as $side){
 
  124            $this->burnBlock($side, 300);
 
  128        $this->burnBlock($this->getSide(Facing::UP), 350);
 
  129        $this->burnBlock($this->getSide(Facing::DOWN), 350);
 
  132    private function burnBlock(Block $block, 
int $chanceBound) : void{
 
  133        if(mt_rand(0, $chanceBound) < $block->getFlammability()){
 
  135            if(BlockBurnEvent::hasHandlers()){
 
  136                $ev = 
new BlockBurnEvent($block, $this);
 
  138                $cancelled = $ev->isCancelled();
 
  141                $block->onIncinerate();
 
  143                $world = $this->position->getWorld();
 
  144                if($world->getBlock($block->position)->isSameState($block)){
 
  145                    $spreadedFire = 
false;
 
  146                    if(mt_rand(0, $this->age + 9) < 5){ 
 
  148                        $fire->age = min(self::MAX_AGE, $fire->age + (mt_rand(0, 4) >> 2));
 
  149                        $spreadedFire = $this->spreadBlock($block, $fire);
 
  152                        $world->setBlock($block->position, VanillaBlocks::AIR());
 
  159    private function spreadFire() : void{
 
  160        $world = $this->position->getWorld();
 
  161        $difficultyChanceIncrease = $world->getDifficulty() * 7;
 
  162        $ageDivisor = $this->age + 30;
 
  164        for($y = -1; $y <= 4; ++$y){
 
  165            $targetY = $y + (int) $this->position->y;
 
  166            if($targetY < World::Y_MIN || $targetY >= World::Y_MAX){
 
  170            $randomBound = 100 + ($y > 1 ? ($y - 1) * 100 : 0);
 
  172            for($z = -1; $z <= 1; ++$z){
 
  173                $targetZ = $z + (int) $this->position->z;
 
  174                for($x = -1; $x <= 1; ++$x){
 
  175                    if($x === 0 && $y === 0 && $z === 0){
 
  178                    $targetX = $x + (int) $this->position->x;
 
  179                    if(!$world->isInWorld($targetX, $targetY, $targetZ)){
 
  183                    if(!$world->isChunkLoaded($targetX >> Chunk::COORD_BIT_SIZE, $targetZ >> Chunk::COORD_BIT_SIZE)){
 
  186                    $block = $world->getBlockAt($targetX, $targetY, $targetZ);
 
  187                    if($block->getTypeId() !== BlockTypeIds::AIR){
 
  194                    foreach($block->position->sides() as $vector3){
 
  195                        if($world->isInWorld($vector3->x, $vector3->y, $vector3->z)){
 
  196                            $encouragement = max($encouragement, $world->getBlockAt($vector3->x, $vector3->y, $vector3->z)->getFlameEncouragement());
 
  200                    if($encouragement <= 0){
 
  204                    $maxChance = intdiv($encouragement + 40 + $difficultyChanceIncrease, $ageDivisor);
 
  207                    if($maxChance > 0 && mt_rand(0, $randomBound - 1) <= $maxChance){
 
  209                        $new->age = min(self::MAX_AGE, $this->age + (mt_rand(0, 4) >> 2));
 
  210                        $this->spreadBlock($block, $new);
 
  217    private function spreadBlock(Block $block, Block $newState) : bool{
 
  218        return BlockEventHelper::spread($block, $newState, $this);