Skip to content

Commit 582c165

Browse files
committed
Implemented Explosion and PrimedTNT, closes #2139
1 parent 5fb2054 commit 582c165

File tree

11 files changed

+237
-52
lines changed

11 files changed

+237
-52
lines changed

src/pocketmine/Server.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1584,7 +1584,7 @@ public function __construct(\ClassLoader $autoloader, \ThreadedLogger $logger, $
15841584
Generator::addGenerator(Normal::class, "default");
15851585

15861586
//Temporal workaround, pthreads static property nullification test
1587-
if(PluginManager::$pluginParentTimer === null){
1587+
if(PluginManager::$pluginParentTimer === null or Timings::$serverTickTimer === null){
15881588
$this->getLogger()->emergency("You are using an invalid pthreads version. Please update your binaries.");
15891589
kill(getmypid());
15901590
return;

src/pocketmine/block/Block.php

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -687,7 +687,10 @@ public static function get($id, $meta = 0, Position $pos = null){
687687
}
688688

689689
if($pos instanceof Position){
690-
$block->position($pos);
690+
$block->x = $pos->x;
691+
$block->y = $pos->y;
692+
$block->z = $pos->z;
693+
$block->level = $pos->level;
691694
}
692695

693696
return $block;

src/pocketmine/block/Fallable.php

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,6 @@ public function onUpdate($type){
5151
new Double("", $this->y + 0.5),
5252
new Double("", $this->z + 0.5)
5353
]),
54-
//TODO: add random motion with physics
5554
"Motion" => new Enum("Motion", [
5655
new Double("", 0),
5756
new Double("", 0),

src/pocketmine/block/TNT.php

Lines changed: 31 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,16 @@
2121

2222
namespace pocketmine\block;
2323

24+
use pocketmine\entity\PrimedTNT;
2425
use pocketmine\item\Item;
26+
use pocketmine\level\Explosion;
27+
use pocketmine\nbt\tag\Byte;
28+
use pocketmine\nbt\tag\Compound;
29+
use pocketmine\nbt\tag\Double;
30+
use pocketmine\nbt\tag\Enum;
31+
use pocketmine\nbt\tag\Float;
2532
use pocketmine\Player;
33+
use pocketmine\utils\Random;
2634

2735
class TNT extends Solid{
2836
public function __construct(){
@@ -33,9 +41,8 @@ public function __construct(){
3341

3442
public function onActivate(Item $item, Player $player = null){
3543
if($item->getID() === Item::FLINT_STEEL){
36-
if(($player->gamemode & 0x01) === 0){
37-
$item->useOn($this);
38-
}
44+
$item->useOn($this);
45+
3946
$data = [
4047
"x" => $this->x + 0.5,
4148
"y" => $this->y + 0.5,
@@ -44,9 +51,27 @@ public function onActivate(Item $item, Player $player = null){
4451
"fuse" => 20 * 4, //4 seconds
4552
];
4653
$this->getLevel()->setBlock($this, new Air(), false, false, true);
47-
//TODO
48-
//$e = Server::getInstance()->api->entity->add($this->level, ENTITY_OBJECT, OBJECT_PRIMEDTNT, $data);
49-
//$e->spawnToAll();
54+
55+
$mot = (new Random())->nextSignedFloat() * M_PI * 2;
56+
$tnt = new PrimedTNT($this->getLevel()->getChunk($this->x >> 4, $this->z >> 4), new Compound("", [
57+
"Pos" => new Enum("Pos", [
58+
new Double("", $this->x + 0.5),
59+
new Double("", $this->y + 0.5),
60+
new Double("", $this->z + 0.5)
61+
]),
62+
"Motion" => new Enum("Motion", [
63+
new Double("", -sin($mot) * 0.02),
64+
new Double("", 0.2),
65+
new Double("", -cos($mot) * 0.02)
66+
]),
67+
"Rotation" => new Enum("Rotation", [
68+
new Float("", 0),
69+
new Float("", 0)
70+
]),
71+
"Fuse" => new Byte("Fuse", 80)
72+
]));
73+
74+
$tnt->spawnToAll();
5075

5176
return true;
5277
}

src/pocketmine/entity/DroppedItem.php

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,8 @@ public function onUpdate(){
9797
$this->motionY *= 1 - $this->drag;
9898
$this->motionZ *= $friction;
9999

100+
$this->updateMovement();
101+
100102
if($this->onGround){
101103
$this->motionY *= -0.5;
102104
}
@@ -105,7 +107,6 @@ public function onUpdate(){
105107
$this->kill();
106108
}
107109

108-
$this->updateMovement();
109110
}
110111

111112
$this->timings->stopTiming();

src/pocketmine/entity/Entity.php

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -281,10 +281,10 @@ public function sendMetadata($player){
281281
foreach($player as $p){
282282
if($p === $this){
283283
/** @var Player $p */
284-
$pk = new SetEntityDataPacket();
285-
$pk->eid = 0;
286-
$pk->metadata = $this->getData();
287-
$p->dataPacket($pk);
284+
$pk2 = new SetEntityDataPacket();
285+
$pk2->eid = 0;
286+
$pk2->metadata = $this->getData();
287+
$p->dataPacket($pk2);
288288
}else{
289289
$p->dataPacket($pk);
290290
}

src/pocketmine/entity/Explosive.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,4 +24,5 @@
2424

2525
interface Explosive{
2626

27+
public function explode();
2728
}

src/pocketmine/entity/PrimedTNT.php

Lines changed: 114 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,10 +22,124 @@
2222
namespace pocketmine\entity;
2323

2424

25+
use pocketmine\event\entity\EntityDamageEvent;
26+
use pocketmine\level\Explosion;
27+
use pocketmine\nbt\tag\Byte;
2528
use pocketmine\nbt\tag\String;
29+
use pocketmine\network\protocol\AddEntityPacket;
30+
use pocketmine\network\protocol\SetEntityMotionPacket;
31+
use pocketmine\Player;
2632

2733
class PrimedTNT extends Entity implements Explosive{
34+
const NETWORK_ID = 65;
35+
36+
public $width = 0.98;
37+
public $length = 0.98;
38+
public $height = 0.98;
39+
40+
protected $gravity = 0.04;
41+
protected $drag = 0.02;
42+
43+
protected $fuse;
44+
45+
public $canCollide = false;
46+
2847
protected function initEntity(){
2948
$this->namedtag->id = new String("id", "PrimedTNT");
49+
if(isset($this->namedtag->Fuse)){
50+
$this->fuse = $this->namedtag["Fuse"];
51+
}else{
52+
$this->fuse = 80;
53+
}
54+
}
55+
56+
57+
public function canCollideWith(Entity $entity){
58+
return false;
59+
}
60+
61+
public function getData(){
62+
return [
63+
16 => ["type" => 0, "value" => $this->fuse],
64+
];
65+
}
66+
67+
public function saveNBT(){
68+
parent::saveNBT();
69+
$this->namedtag->Fuse = new Byte("Fuse", $this->fuse);
70+
}
71+
72+
public function onUpdate(){
73+
74+
if($this->closed){
75+
return false;
76+
}
77+
78+
$this->timings->startTiming();
79+
80+
$this->entityBaseTick();
81+
82+
if(!$this->dead){
83+
84+
$this->motionY -= $this->gravity;
85+
86+
$this->move($this->motionX, $this->motionY, $this->motionZ);
87+
88+
$friction = 1 - $this->drag;
89+
90+
$this->motionX *= $friction;
91+
$this->motionY *= $friction;
92+
$this->motionZ *= $friction;
93+
94+
$this->updateMovement();
95+
96+
if($this->onGround){
97+
$this->motionY *= -0.5;
98+
$this->motionX *= 0.7;
99+
$this->motionZ *= 0.7;
100+
}
101+
102+
if($this->fuse-- <= 0){
103+
$this->kill();
104+
$this->explode();
105+
}else{
106+
$this->sendMetadata($this->getViewers());
107+
}
108+
109+
}
110+
111+
112+
return !$this->onGround or ($this->motionX == 0 and $this->motionY == 0 and $this->motionZ == 0);
113+
}
114+
115+
public function attack($damage, $source = EntityDamageEvent::CAUSE_MAGIC){
116+
117+
}
118+
119+
public function heal($amount){
120+
121+
}
122+
123+
public function explode(){
124+
(new Explosion($this, 4, $this))->explode();
125+
}
126+
127+
public function spawnTo(Player $player){
128+
$pk = new AddEntityPacket();
129+
$pk->type = PrimedTNT::NETWORK_ID;
130+
$pk->eid = $this->getID();
131+
$pk->x = $this->x;
132+
$pk->y = $this->y;
133+
$pk->z = $this->z;
134+
$pk->did = 0;
135+
$player->dataPacket($pk);
136+
137+
$pk = new SetEntityMotionPacket();
138+
$pk->entities = [
139+
[$this->getID(), $this->motionX, $this->motionY, $this->motionZ]
140+
];
141+
$player->dataPacket($pk);
142+
143+
parent::spawnTo($player);
30144
}
31145
}

0 commit comments

Comments
 (0)