Skip to content

Commit d5a1007

Browse files
Merge 'minor-next' into 'major-next'
Automatic merge performed by: https://github.com/pmmp/RestrictedActions/actions/runs/15288247521
2 parents dca2665 + bf33a62 commit d5a1007

31 files changed

+1029
-108
lines changed

src/block/BlockTypeIds.php

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -786,8 +786,9 @@ private function __construct(){
786786
public const RESIN_BRICKS = 10756;
787787
public const RESIN_CLUMP = 10757;
788788
public const CHISELED_RESIN_BRICKS = 10758;
789+
public const RESPAWN_ANCHOR = 10759;
789790

790-
public const FIRST_UNUSED_BLOCK_ID = 10759;
791+
public const FIRST_UNUSED_BLOCK_ID = 10760;
791792

792793
private static int $nextDynamicId = self::FIRST_UNUSED_BLOCK_ID;
793794

src/block/RespawnAnchor.php

Lines changed: 123 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,123 @@
1+
<?php
2+
3+
/*
4+
*
5+
* ____ _ _ __ __ _ __ __ ____
6+
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
7+
* | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
8+
* | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
9+
* |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
10+
*
11+
* This program is free software: you can redistribute it and/or modify
12+
* it under the terms of the GNU Lesser General Public License as published by
13+
* the Free Software Foundation, either version 3 of the License, or
14+
* (at your option) any later version.
15+
*
16+
* @author PocketMine Team
17+
* @link http://www.pocketmine.net/
18+
*
19+
*
20+
*/
21+
22+
declare(strict_types=1);
23+
24+
namespace pocketmine\block;
25+
26+
use pocketmine\data\runtime\RuntimeDataDescriber;
27+
use pocketmine\event\block\BlockPreExplodeEvent;
28+
use pocketmine\event\player\PlayerRespawnAnchorUseEvent;
29+
use pocketmine\item\Item;
30+
use pocketmine\item\ItemTypeIds;
31+
use pocketmine\lang\KnownTranslationFactory;
32+
use pocketmine\math\Vector3;
33+
use pocketmine\player\Player;
34+
use pocketmine\utils\TextFormat;
35+
use pocketmine\world\Explosion;
36+
use pocketmine\world\Position;
37+
use pocketmine\world\sound\RespawnAnchorChargeSound;
38+
use pocketmine\world\sound\RespawnAnchorSetSpawnSound;
39+
40+
final class RespawnAnchor extends Opaque{
41+
private const MIN_CHARGES = 0;
42+
private const MAX_CHARGES = 4;
43+
44+
private int $charges = self::MIN_CHARGES;
45+
46+
protected function describeBlockOnlyState(RuntimeDataDescriber $w) : void{
47+
$w->boundedIntAuto(self::MIN_CHARGES, self::MAX_CHARGES, $this->charges);
48+
}
49+
50+
public function getCharges() : int{
51+
return $this->charges;
52+
}
53+
54+
/** @return $this */
55+
public function setCharges(int $charges) : self{
56+
if($charges < self::MIN_CHARGES || $charges > self::MAX_CHARGES){
57+
throw new \InvalidArgumentException("Charges must be between " . self::MIN_CHARGES . " and " . self::MAX_CHARGES . ", given: $charges");
58+
}
59+
$this->charges = $charges;
60+
return $this;
61+
}
62+
63+
public function getLightLevel() : int{
64+
return $this->charges > 0 ? ($this->charges * 4) - 1 : 0;
65+
}
66+
67+
public function onInteract(Item $item, int $face, Vector3 $clickVector, ?Player $player = null, array &$returnedItems = []) : bool{
68+
if($item->getTypeId() === ItemTypeIds::fromBlockTypeId(BlockTypeIds::GLOWSTONE) && $this->charges < self::MAX_CHARGES){
69+
$this->position->getWorld()->setBlock($this->position, $this->setCharges($this->charges + 1));
70+
$this->position->getWorld()->addSound($this->position, new RespawnAnchorChargeSound());
71+
return true;
72+
}
73+
74+
if($this->charges > self::MIN_CHARGES){
75+
if($player === null){
76+
return false;
77+
}
78+
79+
$ev = new PlayerRespawnAnchorUseEvent($player, $this, PlayerRespawnAnchorUseEvent::ACTION_EXPLODE);
80+
$ev->call();
81+
if($ev->isCancelled()){
82+
return false;
83+
}
84+
85+
switch($ev->getAction()){
86+
case PlayerRespawnAnchorUseEvent::ACTION_EXPLODE:
87+
$this->explode($player);
88+
return false;
89+
90+
case PlayerRespawnAnchorUseEvent::ACTION_SET_SPAWN:
91+
if($player->getSpawn() !== null && $player->getSpawn()->equals($this->position)){
92+
return true;
93+
}
94+
95+
$player->setSpawn($this->position);
96+
$this->position->getWorld()->addSound($this->position, new RespawnAnchorSetSpawnSound());
97+
$player->sendMessage(KnownTranslationFactory::tile_respawn_anchor_respawnSet()->prefix(TextFormat::GRAY));
98+
return true;
99+
}
100+
}
101+
return false;
102+
}
103+
104+
private function explode(?Player $player) : void{
105+
$ev = new BlockPreExplodeEvent($this, 5, $player);
106+
$ev->setIncendiary(true);
107+
108+
$ev->call();
109+
if($ev->isCancelled()){
110+
return;
111+
}
112+
113+
$this->position->getWorld()->setBlock($this->position, VanillaBlocks::AIR());
114+
115+
$explosion = new Explosion(Position::fromObject($this->position->add(0.5, 0.5, 0.5), $this->position->getWorld()), $ev->getRadius(), $this);
116+
$explosion->setFireChance($ev->getFireChance());
117+
118+
if($ev->isBlockBreaking()){
119+
$explosion->explodeA();
120+
}
121+
$explosion->explodeB();
122+
}
123+
}

src/block/VanillaBlocks.php

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -694,6 +694,7 @@
694694
* @method static Stair RESIN_BRICK_STAIRS()
695695
* @method static Wall RESIN_BRICK_WALL()
696696
* @method static ResinClump RESIN_CLUMP()
697+
* @method static RespawnAnchor RESPAWN_ANCHOR()
697698
* @method static DoublePlant ROSE_BUSH()
698699
* @method static Sand SAND()
699700
* @method static Opaque SANDSTONE()
@@ -1647,6 +1648,8 @@ public function getLightLevel() : int{ return 10;}
16471648
self::register("warped_roots", fn(BID $id) => new NetherRoots($id, "Warped Roots", $netherRootsInfo));
16481649

16491650
self::register("chain", fn(BID $id) => new Chain($id, "Chain", new Info(BreakInfo::pickaxe(5.0, ToolTier::WOOD, 30.0))));
1651+
1652+
self::register("respawn_anchor", fn(BID $id) => new RespawnAnchor($id, "Respawn Anchor", new Info(BreakInfo::pickaxe(50.0, ToolTier::DIAMOND, 6000.0))));
16501653
}
16511654

16521655
private static function registerBlocksR17() : void{

src/data/bedrock/block/convert/BlockObjectToStateSerializer.php

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -122,6 +122,7 @@
122122
use pocketmine\block\RedstoneTorch;
123123
use pocketmine\block\RedstoneWire;
124124
use pocketmine\block\ResinClump;
125+
use pocketmine\block\RespawnAnchor;
125126
use pocketmine\block\RuntimeBlockStateRegistry;
126127
use pocketmine\block\Sapling;
127128
use pocketmine\block\SeaPickle;
@@ -1753,6 +1754,10 @@ private function registerSerializers() : void{
17531754
return Writer::create(Ids::RESIN_CLUMP)
17541755
->writeFacingFlags($block->getFaces());
17551756
});
1757+
$this->map(Blocks::RESPAWN_ANCHOR(), function(RespawnAnchor $block) : Writer{
1758+
return Writer::create(Ids::RESPAWN_ANCHOR)
1759+
->writeInt(StateNames::RESPAWN_ANCHOR_CHARGE, $block->getCharges());
1760+
});
17561761
$this->map(Blocks::ROSE_BUSH(), fn(DoublePlant $block) => Helper::encodeDoublePlant($block, Writer::create(Ids::ROSE_BUSH)));
17571762
$this->mapSlab(Blocks::SANDSTONE_SLAB(), Ids::SANDSTONE_SLAB, Ids::SANDSTONE_DOUBLE_SLAB);
17581763
$this->mapStairs(Blocks::SANDSTONE_STAIRS(), Ids::SANDSTONE_STAIRS);

src/data/bedrock/block/convert/BlockStateToObjectDeserializer.php

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1717,6 +1717,10 @@ private function registerDeserializers() : void{
17171717
$this->mapStairs(Ids::RESIN_BRICK_STAIRS, fn() => Blocks::RESIN_BRICK_STAIRS());
17181718
$this->map(Ids::RESIN_BRICK_WALL, fn(Reader $in) => Helper::decodeWall(Blocks::RESIN_BRICK_WALL(), $in));
17191719
$this->map(Ids::RESIN_CLUMP, fn(Reader $in) => Blocks::RESIN_CLUMP()->setFaces($in->readFacingFlags()));
1720+
$this->map(Ids::RESPAWN_ANCHOR, function(Reader $in) : Block{
1721+
return Blocks::RESPAWN_ANCHOR()
1722+
->setCharges($in->readBoundedInt(StateNames::RESPAWN_ANCHOR_CHARGE, 0, 4));
1723+
});
17201724
$this->mapSlab(Ids::SANDSTONE_SLAB, Ids::SANDSTONE_DOUBLE_SLAB, fn() => Blocks::SANDSTONE_SLAB());
17211725
$this->mapStairs(Ids::SANDSTONE_STAIRS, fn() => Blocks::SANDSTONE_STAIRS());
17221726
$this->map(Ids::SANDSTONE_WALL, fn(Reader $in) => Helper::decodeWall(Blocks::SANDSTONE_WALL(), $in));

src/entity/object/EndCrystal.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -129,7 +129,7 @@ public function explode() : void{
129129
$ev = new EntityPreExplodeEvent($this, 6);
130130
$ev->call();
131131
if(!$ev->isCancelled()){
132-
$explosion = new Explosion($this->getPosition(), $ev->getRadius(), $this);
132+
$explosion = new Explosion($this->getPosition(), $ev->getRadius(), $this, $ev->getFireChance());
133133
if($ev->isBlockBreaking()){
134134
$explosion->explodeA();
135135
}

src/entity/object/PrimedTNT.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -121,7 +121,7 @@ public function explode() : void{
121121
$ev->call();
122122
if(!$ev->isCancelled()){
123123
//TODO: deal with underwater TNT (underwater TNT treats water as if it has a blast resistance of 0)
124-
$explosion = new Explosion(Position::fromObject($this->location->add(0, $this->size->getHeight() / 2, 0), $this->getWorld()), $ev->getRadius(), $this);
124+
$explosion = new Explosion(Position::fromObject($this->location->add(0, $this->size->getHeight() / 2, 0), $this->getWorld()), $ev->getRadius(), $this, $ev->getFireChance());
125125
if($ev->isBlockBreaking()){
126126
$explosion->explodeA();
127127
}

src/event/block/BlockExplodeEvent.php

Lines changed: 122 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,122 @@
1+
<?php
2+
3+
/*
4+
*
5+
* ____ _ _ __ __ _ __ __ ____
6+
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
7+
* | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
8+
* | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
9+
* |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
10+
*
11+
* This program is free software: you can redistribute it and/or modify
12+
* it under the terms of the GNU Lesser General Public License as published by
13+
* the Free Software Foundation, either version 3 of the License, or
14+
* (at your option) any later version.
15+
*
16+
* @author PocketMine Team
17+
* @link http://www.pocketmine.net/
18+
*
19+
*
20+
*/
21+
22+
declare(strict_types=1);
23+
24+
namespace pocketmine\event\block;
25+
26+
use pocketmine\block\Block;
27+
use pocketmine\event\Cancellable;
28+
use pocketmine\event\CancellableTrait;
29+
use pocketmine\utils\Utils;
30+
use pocketmine\world\Position;
31+
32+
/**
33+
* Called when a block explodes, after explosion impact has been calculated.
34+
*
35+
* @see BlockPreExplodeEvent
36+
*/
37+
class BlockExplodeEvent extends BlockEvent implements Cancellable{
38+
use CancellableTrait;
39+
40+
/**
41+
* @param Block[] $blocks
42+
* @param Block[] $ignitions
43+
*/
44+
public function __construct(
45+
Block $block,
46+
private Position $position,
47+
private array $blocks,
48+
private float $yield,
49+
private array $ignitions
50+
){
51+
parent::__construct($block);
52+
53+
Utils::checkFloatNotInfOrNaN("yield", $yield);
54+
if($yield < 0.0 || $yield > 100.0){
55+
throw new \InvalidArgumentException("Yield must be in range 0.0 - 100.0");
56+
}
57+
}
58+
59+
public function getPosition() : Position{
60+
return $this->position;
61+
}
62+
63+
/**
64+
* Returns the percentage chance of drops from each block destroyed by the explosion.
65+
*
66+
* @return float 0-100
67+
*/
68+
public function getYield() : float{
69+
return $this->yield;
70+
}
71+
72+
/**
73+
* Sets the percentage chance of drops from each block destroyed by the explosion.
74+
*
75+
* @param float $yield 0-100
76+
*/
77+
public function setYield(float $yield) : void{
78+
Utils::checkFloatNotInfOrNaN("yield", $yield);
79+
if($yield < 0.0 || $yield > 100.0){
80+
throw new \InvalidArgumentException("Yield must be in range 0.0 - 100.0");
81+
}
82+
$this->yield = $yield;
83+
}
84+
85+
/**
86+
* Returns a list of blocks destroyed by the explosion.
87+
*
88+
* @return Block[]
89+
*/
90+
public function getAffectedBlocks() : array{
91+
return $this->blocks;
92+
}
93+
94+
/**
95+
* Sets the blocks destroyed by the explosion.
96+
*
97+
* @param Block[] $blocks
98+
*/
99+
public function setAffectedBlocks(array $blocks) : void{
100+
Utils::validateArrayValueType($blocks, fn(Block $block) => null);
101+
$this->blocks = $blocks;
102+
}
103+
104+
/**
105+
* Returns a list of affected blocks that will be replaced by fire.
106+
*
107+
* @return Block[]
108+
*/
109+
public function getIgnitions() : array{
110+
return $this->ignitions;
111+
}
112+
113+
/**
114+
* Set the list of blocks that will be replaced by fire.
115+
*
116+
* @param Block[] $ignitions
117+
*/
118+
public function setIgnitions(array $ignitions) : void{
119+
Utils::validateArrayValueType($ignitions, fn(Block $block) => null);
120+
$this->ignitions = $ignitions;
121+
}
122+
}

0 commit comments

Comments
 (0)