Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implemented Respawn Anchor #6646

Open
wants to merge 69 commits into
base: minor-next
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
69 commits
Select commit Hold shift + click to select a range
156855b
implement respawn anchor and explosion almost like in vanilla
b1zeyofficial Mar 6, 2025
c3b4562
Cleanup
b1zeyofficial Mar 6, 2025
0b1ba8a
hmhm
b1zeyofficial Mar 6, 2025
13f27d0
first time
b1zeyofficial Mar 6, 2025
c9aaffb
phpstan, unit...
b1zeyofficial Mar 6, 2025
0ee1819
?
b1zeyofficial Mar 6, 2025
1bb3f75
code style
b1zeyofficial Mar 6, 2025
18b51ec
CS
b1zeyofficial Mar 6, 2025
3b92a4b
...
b1zeyofficial Mar 6, 2025
a776b92
b1zeyofficial Mar 6, 2025
3bc05dc
dependency
b1zeyofficial Mar 6, 2025
ca09565
test
b1zeyofficial Mar 6, 2025
34b0f3f
no comments
b1zeyofficial Mar 6, 2025
c8fe4d6
Fix CS?
b1zeyofficial Mar 6, 2025
12fdda2
CS
b1zeyofficial Mar 7, 2025
e66fdc7
Update RespawnAnchor.php
b1zeyofficial Mar 7, 2025
ad8e9e4
Update Explosion.php
b1zeyofficial Mar 9, 2025
81e6622
CS
b1zeyofficial Mar 9, 2025
71d4236
Merge branch 'minor-next' into respawn-anchor
b1zeyofficial Mar 9, 2025
003b2bf
added next() before valid()
b1zeyofficial Mar 10, 2025
b6ff485
cs
b1zeyofficial Mar 10, 2025
b82b37d
Update src/world/Explosion.php
b1zeyofficial Mar 10, 2025
30e47d2
resolved conversations?
b1zeyofficial Mar 10, 2025
99c5fb9
cs
b1zeyofficial Mar 10, 2025
ef766cf
renamed AnchorChargeSound to RespawnAnchorChargeSound
b1zeyofficial Mar 10, 2025
1af5472
Merge branch 'minor-next' into respawn-anchor
b1zeyofficial Mar 11, 2025
89ea5eb
only respawnanchor
b1zeyofficial Mar 11, 2025
86acd3e
PHPStan
b1zeyofficial Mar 11, 2025
0d7fda7
cs
b1zeyofficial Mar 11, 2025
ee21907
Update EntityExplodeEvent.php
b1zeyofficial Mar 11, 2025
cdf32fc
property must be private
b1zeyofficial Mar 11, 2025
73b2167
that should solve it
b1zeyofficial Mar 11, 2025
69cc04d
properties must be private. respawn anchor explosion optimization...
b1zeyofficial Mar 12, 2025
7efd92f
Merge branch 'minor-next' into respawn-anchor
b1zeyofficial Mar 14, 2025
9257b1d
delete unnecessary lines and update Explosion.php
b1zeyofficial Mar 16, 2025
5180e85
oops
b1zeyofficial Mar 16, 2025
d8beb89
CS
b1zeyofficial Mar 16, 2025
4a2e19c
just test
b1zeyofficial Mar 16, 2025
ab082a3
shut up cs
b1zeyofficial Mar 16, 2025
ea831cd
my bad
b1zeyofficial Mar 16, 2025
30bad75
Update Explosion.php
b1zeyofficial Mar 16, 2025
60b32b8
its all maybe
b1zeyofficial Mar 16, 2025
81e2919
PHPStan
b1zeyofficial Mar 16, 2025
b3ebad6
lol
b1zeyofficial Mar 16, 2025
410a5d7
use checkFloatNotInfOrNaN()
b1zeyofficial Mar 16, 2025
e9f2435
short message
b1zeyofficial Mar 16, 2025
c16dfae
promoteKeys
b1zeyofficial Mar 16, 2025
3dd61bf
:)
b1zeyofficial Mar 16, 2025
7b4b8ac
nan/inf check
b1zeyofficial Mar 16, 2025
001050b
Merge branch 'minor-next' into respawn-anchor
b1zeyofficial Mar 16, 2025
b158b9e
test
b1zeyofficial Mar 16, 2025
534cf87
cs
b1zeyofficial Mar 16, 2025
7842c9b
one more test
b1zeyofficial Mar 16, 2025
371cd9c
one more test
b1zeyofficial Mar 16, 2025
81a2821
forgot to change lol
b1zeyofficial Mar 16, 2025
9eb53a3
optimization?
b1zeyofficial Mar 17, 2025
70b11dd
hm
b1zeyofficial Mar 17, 2025
57f9a47
Update RespawnAnchor.php
b1zeyofficial Mar 17, 2025
8e205f2
...
b1zeyofficial Mar 17, 2025
0f83e3b
Added return $this
ipad54 Mar 17, 2025
1bb08da
Update documentation
ipad54 Mar 17, 2025
9c62f8f
Remove fire chance from BlockExplodeEvent
ipad54 Mar 17, 2025
7f622f7
Document setFireChance() in Explosion
ipad54 Mar 17, 2025
58582f6
Formatting
ipad54 Mar 17, 2025
6cfd025
Implement the ability to set fire chance in EntityPreExplodeEvent
ipad54 Mar 17, 2025
2e29694
Update BlockPreExplodeEvent.php
ipad54 Mar 17, 2025
3ad45b5
Remove unneeded docs
ipad54 Mar 17, 2025
3416214
CS
ipad54 Mar 17, 2025
73561a8
Merge branch 'minor-next' into respawn-anchor
b1zeyofficial Mar 18, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion src/block/BlockTypeIds.php
Original file line number Diff line number Diff line change
Expand Up @@ -786,8 +786,9 @@ private function __construct(){
public const RESIN_BRICKS = 10756;
public const RESIN_CLUMP = 10757;
public const CHISELED_RESIN_BRICKS = 10758;
public const RESPAWN_ANCHOR = 10759;

public const FIRST_UNUSED_BLOCK_ID = 10759;
public const FIRST_UNUSED_BLOCK_ID = 10760;

private static int $nextDynamicId = self::FIRST_UNUSED_BLOCK_ID;

Expand Down
98 changes: 98 additions & 0 deletions src/block/RespawnAnchor.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
<?php

/*
*
* ____ _ _ __ __ _ __ __ ____
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
* | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
* | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
* |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* @author PocketMine Team
* @link http://www.pocketmine.net/
*
*
*/

declare(strict_types=1);

namespace pocketmine\block;

use pocketmine\data\runtime\RuntimeDataDescriber;
use pocketmine\event\block\BlockPreExplodeEvent;
use pocketmine\item\Item;
use pocketmine\item\ItemTypeIds;
use pocketmine\math\Vector3;
use pocketmine\player\Player;
use pocketmine\world\Explosion;
use pocketmine\world\Position;
use pocketmine\world\sound\RespawnAnchorChargeSound;

final class RespawnAnchor extends Opaque{
private const MIN_CHARGES = 0;
private const MAX_CHARGES = 4;

private int $charges = self::MIN_CHARGES;

protected function describeBlockOnlyState(RuntimeDataDescriber $w) : void{
$w->boundedIntAuto(self::MIN_CHARGES, self::MAX_CHARGES, $this->charges);
}

public function getCharges() : int{
return $this->charges;
}

/** @return $this */
public function setCharges(int $charges) : self{
if($charges < self::MIN_CHARGES || $charges > self::MAX_CHARGES){
throw new \InvalidArgumentException("Charges must be between " . self::MIN_CHARGES . " and " . self::MAX_CHARGES . ", given: $charges");
}
$this->charges = $charges;
return $this;
}

public function getLightLevel() : int{
return $this->charges > 0 ? ($this->charges * 4) - 1 : 0;
}

public function onInteract(Item $item, int $face, Vector3 $clickVector, ?Player $player = null, array &$returnedItems = []) : bool{
if($item->getTypeId() === ItemTypeIds::fromBlockTypeId(BlockTypeIds::GLOWSTONE) && $this->charges < self::MAX_CHARGES){
$this->position->getWorld()->setBlock($this->position, $this->setCharges($this->charges + 1));
$this->position->getWorld()->addSound($this->position, new RespawnAnchorChargeSound());
return true;
}

if($this->charges > self::MIN_CHARGES){
//TODO: Implement the ability to set a respawn point in Nether
$this->explode($player);
return true;
}

return false;
}

private function explode(?Player $player) : void{
$ev = new BlockPreExplodeEvent($this, 5, $player);
$ev->setIncendiary(true);

$ev->call();
if($ev->isCancelled()){
return;
}

$this->position->getWorld()->setBlock($this->position, VanillaBlocks::AIR());

$explosion = new Explosion(Position::fromObject($this->position->add(0.5, 0.5, 0.5), $this->position->getWorld()), $ev->getRadius(), $this);
$explosion->setFireChance($ev->getFireChance());

if($ev->isBlockBreaking()){
$explosion->explodeA();
}
$explosion->explodeB();
}
}
3 changes: 3 additions & 0 deletions src/block/VanillaBlocks.php
Original file line number Diff line number Diff line change
Expand Up @@ -694,6 +694,7 @@
* @method static Stair RESIN_BRICK_STAIRS()
* @method static Wall RESIN_BRICK_WALL()
* @method static ResinClump RESIN_CLUMP()
* @method static RespawnAnchor RESPAWN_ANCHOR()
* @method static DoublePlant ROSE_BUSH()
* @method static Sand SAND()
* @method static Opaque SANDSTONE()
Expand Down Expand Up @@ -1642,6 +1643,8 @@ public function getLightLevel() : int{ return 10;}
self::register("warped_roots", fn(BID $id) => new NetherRoots($id, "Warped Roots", $netherRootsInfo));

self::register("chain", fn(BID $id) => new Chain($id, "Chain", new Info(BreakInfo::pickaxe(5.0, ToolTier::WOOD))));

self::register("respawn_anchor", fn(BID $id) => new RespawnAnchor($id, "Respawn Anchor", new Info(BreakInfo::pickaxe(50.0, ToolTier::DIAMOND, 1200.0))));
}

private static function registerBlocksR17() : void{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,7 @@
use pocketmine\block\RedstoneTorch;
use pocketmine\block\RedstoneWire;
use pocketmine\block\ResinClump;
use pocketmine\block\RespawnAnchor;
use pocketmine\block\RuntimeBlockStateRegistry;
use pocketmine\block\Sapling;
use pocketmine\block\SeaPickle;
Expand Down Expand Up @@ -1750,6 +1751,10 @@ private function registerSerializers() : void{
return Writer::create(Ids::RESIN_CLUMP)
->writeFacingFlags($block->getFaces());
});
$this->map(Blocks::RESPAWN_ANCHOR(), function(RespawnAnchor $block) : Writer{
return Writer::create(Ids::RESPAWN_ANCHOR)
->writeInt(StateNames::RESPAWN_ANCHOR_CHARGE, $block->getCharges());
});
$this->map(Blocks::ROSE_BUSH(), fn(DoublePlant $block) => Helper::encodeDoublePlant($block, Writer::create(Ids::ROSE_BUSH)));
$this->mapSlab(Blocks::SANDSTONE_SLAB(), Ids::SANDSTONE_SLAB, Ids::SANDSTONE_DOUBLE_SLAB);
$this->mapStairs(Blocks::SANDSTONE_STAIRS(), Ids::SANDSTONE_STAIRS);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1717,6 +1717,10 @@ private function registerDeserializers() : void{
$this->mapStairs(Ids::RESIN_BRICK_STAIRS, fn() => Blocks::RESIN_BRICK_STAIRS());
$this->map(Ids::RESIN_BRICK_WALL, fn(Reader $in) => Helper::decodeWall(Blocks::RESIN_BRICK_WALL(), $in));
$this->map(Ids::RESIN_CLUMP, fn(Reader $in) => Blocks::RESIN_CLUMP()->setFaces($in->readFacingFlags()));
$this->map(Ids::RESPAWN_ANCHOR, function(Reader $in) : Block{
return Blocks::RESPAWN_ANCHOR()
->setCharges($in->readBoundedInt(StateNames::RESPAWN_ANCHOR_CHARGE, 0, 4));
});
$this->mapSlab(Ids::SANDSTONE_SLAB, Ids::SANDSTONE_DOUBLE_SLAB, fn() => Blocks::SANDSTONE_SLAB());
$this->mapStairs(Ids::SANDSTONE_STAIRS, fn() => Blocks::SANDSTONE_STAIRS());
$this->map(Ids::SANDSTONE_WALL, fn(Reader $in) => Helper::decodeWall(Blocks::SANDSTONE_WALL(), $in));
Expand Down
2 changes: 1 addition & 1 deletion src/entity/object/EndCrystal.php
Original file line number Diff line number Diff line change
Expand Up @@ -129,7 +129,7 @@ public function explode() : void{
$ev = new EntityPreExplodeEvent($this, 6);
$ev->call();
if(!$ev->isCancelled()){
$explosion = new Explosion($this->getPosition(), $ev->getRadius(), $this);
$explosion = new Explosion($this->getPosition(), $ev->getRadius(), $this, $ev->getFireChance());
if($ev->isBlockBreaking()){
$explosion->explodeA();
}
Expand Down
2 changes: 1 addition & 1 deletion src/entity/object/PrimedTNT.php
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,7 @@ public function explode() : void{
$ev->call();
if(!$ev->isCancelled()){
//TODO: deal with underwater TNT (underwater TNT treats water as if it has a blast resistance of 0)
$explosion = new Explosion(Position::fromObject($this->location->add(0, $this->size->getHeight() / 2, 0), $this->getWorld()), $ev->getRadius(), $this);
$explosion = new Explosion(Position::fromObject($this->location->add(0, $this->size->getHeight() / 2, 0), $this->getWorld()), $ev->getRadius(), $this, $ev->getFireChance());
if($ev->isBlockBreaking()){
$explosion->explodeA();
}
Expand Down
122 changes: 122 additions & 0 deletions src/event/block/BlockExplodeEvent.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,122 @@
<?php

/*
*
* ____ _ _ __ __ _ __ __ ____
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
* | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
* | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
* |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* @author PocketMine Team
* @link http://www.pocketmine.net/
*
*
*/

declare(strict_types=1);

namespace pocketmine\event\block;

use pocketmine\block\Block;
use pocketmine\event\Cancellable;
use pocketmine\event\CancellableTrait;
use pocketmine\utils\Utils;
use pocketmine\world\Position;

/**
* Called when a block explodes, after explosion impact has been calculated.
*
* @see BlockPreExplodeEvent
*/
class BlockExplodeEvent extends BlockEvent implements Cancellable{
use CancellableTrait;

/**
* @param Block[] $blocks
* @param Block[] $ignitions
*/
public function __construct(
Block $block,
private Position $position,
private array $blocks,
private float $yield,
private array $ignitions
){
parent::__construct($block);

Utils::checkFloatNotInfOrNaN("yield", $yield);
if($yield < 0.0 || $yield > 100.0){
throw new \InvalidArgumentException("Yield must be in range 0.0 - 100.0");
}
}

public function getPosition() : Position{
return $this->position;
}

/**
* Returns the percentage chance of drops from each block destroyed by the explosion.
*
* @return float 0-100
*/
public function getYield() : float{
return $this->yield;
}

/**
* Sets the percentage chance of drops from each block destroyed by the explosion.
*
* @param float $yield 0-100
*/
public function setYield(float $yield) : void{
Utils::checkFloatNotInfOrNaN("yield", $yield);
if($yield < 0.0 || $yield > 100.0){
throw new \InvalidArgumentException("Yield must be in range 0.0 - 100.0");
}
$this->yield = $yield;
}

/**
* Returns a list of blocks destroyed by the explosion.
*
* @return Block[]
*/
public function getAffectedBlocks() : array{
return $this->blocks;
}

/**
* Sets the blocks destroyed by the explosion.
*
* @param Block[] $blocks
*/
public function setAffectedBlocks(array $blocks) : void{
Utils::validateArrayValueType($blocks, fn(Block $block) => null);
$this->blocks = $blocks;
}

/**
* Returns a list of affected blocks that will be replaced by fire.
*
* @return Block[]
*/
public function getIgnitions() : array{
return $this->ignitions;
}

/**
* Set the list of blocks that will be replaced by fire.
*
* @param Block[] $ignitions
*/
public function setIgnitions(array $ignitions) : void{
Utils::validateArrayValueType($ignitions, fn(Block $block) => null);
$this->ignitions = $ignitions;
}
}
Loading