PocketMine-MP  1.4 - API 1.10.0
 All Classes Namespaces Functions Variables Pages
Door.php
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 namespace pocketmine\block;
23 
30 
31 
32 abstract class Door extends Transparent{
33 
34  public function canBeActivated(){
35  return true;
36  }
37 
38  public function isSolid(){
39  return false;
40  }
41 
42  private function getFullDamage(){
43  $damage = $this->getDamage();
44  $flag = ($damage & 0x08) > 0;
45 
46  if($flag){
47  $first = $this->getSide(0)->getDamage();
48  $second = $damage;
49  }else{
50  $first = $damage;
51  $second = $this->getSide(1)->getDamage();
52  }
53 
54  $flag1 = ($second & 0x01) > 0;
55 
56  return $first & 0x07 | ($flag ? 8 : 0) | ($flag1 ? 0x10 : 0);
57  }
58 
59  protected function recalculateBoundingBox(){
60 
61  $f = 0.1875;
62  $damage = $this->getFullDamage();
63 
64  $bb = new AxisAlignedBB(
65  $this->x,
66  $this->y,
67  $this->z,
68  $this->x + 1,
69  $this->y + 2,
70  $this->z + 1
71  );
72 
73  $j = $damage & 0x03;
74  $flag = (($damage & 0x04) > 0);
75  $flag1 = (($damage & 0x10) > 0);
76 
77  if($j === 0){
78  if($flag){
79  if(!$flag1){
80  $bb->setBounds(
81  $this->x,
82  $this->y,
83  $this->z,
84  $this->x + 1,
85  $this->y + 1,
86  $this->z + $f
87  );
88  }else{
89  $bb->setBounds(
90  $this->x,
91  $this->y,
92  $this->z + 1 - $f,
93  $this->x + 1,
94  $this->y + 1,
95  $this->z + 1
96  );
97  }
98  }else{
99  $bb->setBounds(
100  $this->x,
101  $this->y,
102  $this->z,
103  $this->x + $f,
104  $this->y + 1,
105  $this->z + 1
106  );
107  }
108  }elseif($j === 1){
109  if($flag){
110  if(!$flag1){
111  $bb->setBounds(
112  $this->x + 1 - $f,
113  $this->y,
114  $this->z,
115  $this->x + 1,
116  $this->y + 1,
117  $this->z + 1
118  );
119  }else{
120  $bb->setBounds(
121  $this->x,
122  $this->y,
123  $this->z,
124  $this->x + $f,
125  $this->y + 1,
126  $this->z + 1
127  );
128  }
129  }else{
130  $bb->setBounds(
131  $this->x,
132  $this->y,
133  $this->z,
134  $this->x + 1,
135  $this->y + 1,
136  $this->z + $f
137  );
138  }
139  }elseif($j === 2){
140  if($flag){
141  if(!$flag1){
142  $bb->setBounds(
143  $this->x,
144  $this->y,
145  $this->z + 1 - $f,
146  $this->x + 1,
147  $this->y + 1,
148  $this->z + 1
149  );
150  }else{
151  $bb->setBounds(
152  $this->x,
153  $this->y,
154  $this->z,
155  $this->x + 1,
156  $this->y + 1,
157  $this->z + $f
158  );
159  }
160  }else{
161  $bb->setBounds(
162  $this->x + 1 - $f,
163  $this->y,
164  $this->z,
165  $this->x + 1,
166  $this->y + 1,
167  $this->z + 1
168  );
169  }
170  }elseif($j === 3){
171  if($flag){
172  if(!$flag1){
173  $bb->setBounds(
174  $this->x,
175  $this->y,
176  $this->z,
177  $this->x + $f,
178  $this->y + 1,
179  $this->z + 1
180  );
181  }else{
182  $bb->setBounds(
183  $this->x + 1 - $f,
184  $this->y,
185  $this->z,
186  $this->x + 1,
187  $this->y + 1,
188  $this->z + 1
189  );
190  }
191  }else{
192  $bb->setBounds(
193  $this->x,
194  $this->y,
195  $this->z + 1 - $f,
196  $this->x + 1,
197  $this->y + 1,
198  $this->z + 1
199  );
200  }
201  }
202 
203  return $bb;
204  }
205 
206  public function onUpdate($type){
207  if($type === Level::BLOCK_UPDATE_NORMAL){
208  if($this->getSide(0)->getId() === self::AIR){ //Replace with common break method
209  $this->getLevel()->setBlock($this, new Air(), false);
210  if($this->getSide(1) instanceof Door){
211  $this->getLevel()->setBlock($this->getSide(1), new Air(), false);
212  }
213 
214  return Level::BLOCK_UPDATE_NORMAL;
215  }
216  }
217 
218  return false;
219  }
220 
221  public function place(Item $item, Block $block, Block $target, $face, $fx, $fy, $fz, Player $player = null){
222  if($face === 1){
223  $blockUp = $this->getSide(1);
224  $blockDown = $this->getSide(0);
225  if($blockUp->canBeReplaced() === false or $blockDown->isTransparent() === true){
226  return false;
227  }
228  $direction = $player instanceof Player ? $player->getDirection() : 0;
229  $face = [
230  0 => 3,
231  1 => 4,
232  2 => 2,
233  3 => 5,
234  ];
235  $next = $this->getSide($face[(($direction + 2) % 4)]);
236  $next2 = $this->getSide($face[$direction]);
237  $metaUp = 0x08;
238  if($next->getId() === $this->id or ($next2->isTransparent() === false and $next->isTransparent() === true)){ //Door hinge
239  $metaUp |= 0x01;
240  }
241 
242  $this->meta = $player->getDirection() & 0x03;
243  $this->getLevel()->setBlock($block, $this, true, true); //Bottom
244  $this->getLevel()->setBlock($blockUp, $b = Block::get($this->id, $metaUp), true); //Top
245  return true;
246  }
247 
248  return false;
249  }
250 
251  public function onBreak(Item $item){
252  if(($this->meta & 0x08) === 0x08){
253  $down = $this->getSide(0);
254  if($down->getId() === $this->id){
255  $this->getLevel()->setBlock($down, new Air(), true);
256  }
257  }else{
258  $up = $this->getSide(1);
259  if($up->getId() === $this->id){
260  $this->getLevel()->setBlock($up, new Air(), true);
261  }
262  }
263  $this->getLevel()->setBlock($this, new Air(), true);
264 
265  return true;
266  }
267 
268  public function onActivate(Item $item, Player $player = null){
269  if(($this->meta & 0x08) === 0x08){ //Top
270  $down = $this->getSide(0);
271  if($down->getId() === $this->id){
272  $meta = $down->getDamage() ^ 0x04;
273  $this->getLevel()->setBlock($down, Block::get($this->id, $meta), true);
274  $players = $this->getLevel()->getUsingChunk($this->x >> 4, $this->z >> 4);
275  if($player instanceof Player){
276  unset($players[$player->getId()]);
277  }
278  $pk = new LevelEventPacket();
279  $pk->x = $this->x;
280  $pk->y = $this->y;
281  $pk->z = $this->z;
282  $pk->evid = 1003;
283  $pk->data = 0;
284  Server::broadcastPacket($players, $pk);
285 
286  return true;
287  }
288 
289  return false;
290  }else{
291  $this->meta ^= 0x04;
292  $this->getLevel()->setBlock($this, $this, true);
293  $players = $this->getLevel()->getUsingChunk($this->x >> 4, $this->z >> 4);
294  if($player instanceof Player){
295  unset($players[$player->getId()]);
296  }
297  $pk = new LevelEventPacket();
298  $pk->x = $this->x;
299  $pk->y = $this->y;
300  $pk->z = $this->z;
301  $pk->evid = 1003;
302  $pk->data = 0;
303  Server::broadcastPacket($players, $pk);
304  }
305 
306  return true;
307  }
308 }
static broadcastPacket(array $players, DataPacket $packet)
Definition: Server.php:1725
getSide($side, $step=1)
Definition: Block.php:1028
static get($id, $meta=0, Position $pos=null)
Definition: Block.php:782