GenisysPro  for Minecraft PE/Windows 10 v1.1.x
Feature-rich server software for Minecraft PE and Windows 10 Edition
Explosion Class Reference

Public Member Functions

 __construct (Position $center, $size, $what=null, bool $dropItem=true)
 
 explodeA ()
 
 explodeB ()
 

Data Fields

 $level
 
 $source
 
 $size
 
 $affectedBlocks = []
 
 $stepLen = 0.3
 

Constructor & Destructor Documentation

◆ __construct()

__construct ( Position  $center,
  $size,
  $what = null,
bool  $dropItem = true 
)

Explosion constructor.

Parameters
Position$center
$size
null$what
bool$dropItem
68  {
69  $this->level = $center->getLevel();
70  $this->source = $center;
71  $this->size = max($size, 0);
72  $this->what = $what;
73  $this->dropItem = $dropItem;
74  }

Member Function Documentation

◆ explodeA()

explodeA ( )
Returns
bool
79  : bool{
80  if($this->size < 0.1){
81  return false;
82  }
83 
84  $vector = new Vector3(0, 0, 0);
85  $vBlock = new Vector3(0, 0, 0);
86 
87  $mRays = intval($this->rays - 1);
88  for($i = 0; $i < $this->rays; ++$i){
89  for($j = 0; $j < $this->rays; ++$j){
90  for($k = 0; $k < $this->rays; ++$k){
91  if($i === 0 or $i === $mRays or $j === 0 or $j === $mRays or $k === 0 or $k === $mRays){
92  $vector->setComponents($i / $mRays * 2 - 1, $j / $mRays * 2 - 1, $k / $mRays * 2 - 1);
93  $vector->setComponents(($vector->x / ($len = $vector->length())) * $this->stepLen, ($vector->y / $len) * $this->stepLen, ($vector->z / $len) * $this->stepLen);
94  $pointerX = $this->source->x;
95  $pointerY = $this->source->y;
96  $pointerZ = $this->source->z;
97 
98  for($blastForce = $this->size * (mt_rand(700, 1300) / 1000); $blastForce > 0; $blastForce -= $this->stepLen * 0.75){
99  $x = (int) $pointerX;
100  $y = (int) $pointerY;
101  $z = (int) $pointerZ;
102  $vBlock->x = $pointerX >= $x ? $x : $x - 1;
103  $vBlock->y = $pointerY >= $y ? $y : $y - 1;
104  $vBlock->z = $pointerZ >= $z ? $z : $z - 1;
105  if($vBlock->y < 0 or $vBlock->y >= Level::Y_MAX){
106  break;
107  }
108  $block = $this->level->getBlock($vBlock);
109 
110  if($block->getId() !== 0){
111  $blastForce -= ($block->getResistance() / 5 + 0.3) * $this->stepLen;
112  if($blastForce > 0){
113  if(!isset($this->affectedBlocks[$index = Level::blockHash($block->x, $block->y, $block->z)])){
114  $this->affectedBlocks[$index] = $block;
115  }
116  }
117  }
118  $pointerX += $vector->x;
119  $pointerY += $vector->y;
120  $pointerZ += $vector->z;
121  }
122  }
123  }
124  }
125  }
126 
127  return true;
128  }

◆ explodeB()

explodeB ( )
Returns
bool
133  : bool{
134  $send = [];
135  $updateBlocks = [];
136 
137  $source = (new Vector3($this->source->x, $this->source->y, $this->source->z))->floor();
138  $yield = (1 / $this->size) * 100;
139 
140  if($this->what instanceof Entity){
141  $this->level->getServer()->getPluginManager()->callEvent($ev = new EntityExplodeEvent($this->what, $this->source, $this->affectedBlocks, $yield));
142  if($ev->isCancelled()){
143  return false;
144  }else{
145  $yield = $ev->getYield();
146  $this->affectedBlocks = $ev->getBlockList();
147  }
148  }
149 
150  $explosionSize = $this->size * 2;
151  $minX = Math::floorFloat($this->source->x - $explosionSize - 1);
152  $maxX = Math::ceilFloat($this->source->x + $explosionSize + 1);
153  $minY = Math::floorFloat($this->source->y - $explosionSize - 1);
154  $maxY = Math::ceilFloat($this->source->y + $explosionSize + 1);
155  $minZ = Math::floorFloat($this->source->z - $explosionSize - 1);
156  $maxZ = Math::ceilFloat($this->source->z + $explosionSize + 1);
157 
158  $explosionBB = new AxisAlignedBB($minX, $minY, $minZ, $maxX, $maxY, $maxZ);
159 
160  $list = $this->level->getNearbyEntities($explosionBB, $this->what instanceof Entity ? $this->what : null);
161  foreach($list as $entity){
162  $distance = $entity->distance($this->source) / $explosionSize;
163 
164  if($distance <= 1){
165  $motion = $entity->subtract($this->source)->normalize();
166 
167  $impact = (1 - $distance) * ($exposure = 1);
168 
169  $damage = (int) ((($impact * $impact + $impact) / 2) * 8 * $explosionSize + 1);
170 
171  if($this->what instanceof Entity){
172  $ev = new EntityDamageByEntityEvent($this->what, $entity, EntityDamageEvent::CAUSE_ENTITY_EXPLOSION, $damage);
173  }elseif($this->what instanceof Block){
174  $ev = new EntityDamageByBlockEvent($this->what, $entity, EntityDamageEvent::CAUSE_BLOCK_EXPLOSION, $damage);
175  }else{
176  $ev = new EntityDamageEvent($entity, EntityDamageEvent::CAUSE_BLOCK_EXPLOSION, $damage);
177  }
178 
179  if($entity->attack($ev->getFinalDamage(), $ev) === true){
180  $ev->useArmors();
181  }
182  $entity->setMotion($motion->multiply($impact));
183  }
184  }
185 
186 
187  $air = Item::get(Item::AIR);
188 
189  foreach($this->affectedBlocks as $block){
190  if($block->getId() === Block::TNT){
191  $mot = (new Random())->nextSignedFloat() * M_PI * 2;
192  $tnt = Entity::createEntity("PrimedTNT", $this->level, new CompoundTag("", [
193  "Pos" => new ListTag("Pos", [
194  new DoubleTag("", $block->x + 0.5),
195  new DoubleTag("", $block->y),
196  new DoubleTag("", $block->z + 0.5)
197  ]),
198  "Motion" => new ListTag("Motion", [
199  new DoubleTag("", -sin($mot) * 0.02),
200  new DoubleTag("", 0.2),
201  new DoubleTag("", -cos($mot) * 0.02)
202  ]),
203  "Rotation" => new ListTag("Rotation", [
204  new FloatTag("", 0),
205  new FloatTag("", 0)
206  ]),
207  "Fuse" => new ByteTag("Fuse", mt_rand(10, 30))
208  ]));
209  $tnt->spawnToAll();
210  }elseif($this->dropItem and mt_rand(0, 100) < $yield){
211  foreach($block->getDrops($air) as $drop){
212  $this->level->dropItem($block->add(0.5, 0.5, 0.5), Item::get(...$drop));
213  }
214  }
215 
216  $this->level->setBlockIdAt($block->x, $block->y, $block->z, 0);
217 
218  $pos = new Vector3($block->x, $block->y, $block->z);
219 
220  for($side = 0; $side < 5; $side++){
221  $sideBlock = $pos->getSide($side);
222  if(!isset($this->affectedBlocks[$index = Level::blockHash($sideBlock->x, $sideBlock->y, $sideBlock->z)]) and !isset($updateBlocks[$index])){
223  $this->level->getServer()->getPluginManager()->callEvent($ev = new BlockUpdateEvent($this->level->getBlock($sideBlock)));
224  if(!$ev->isCancelled()){
225  $ev->getBlock()->onUpdate(Level::BLOCK_UPDATE_NORMAL);
226  }
227  $updateBlocks[$index] = true;
228  }
229  }
230  $send[] = new Vector3($block->x - $source->x, $block->y - $source->y, $block->z - $source->z);
231  }
232 
233  $pk = new ExplodePacket();
234  $pk->x = $this->source->x;
235  $pk->y = $this->source->y;
236  $pk->z = $this->source->z;
237  $pk->radius = $this->size;
238  $pk->records = $send;
239  $this->level->addChunkPacket($source->x >> 4, $source->z >> 4, $pk);
240 
241  $this->level->addParticle(new HugeExplodeSeedParticle($source));
242  $this->level->broadcastLevelSoundEvent($source, LevelSoundEventPacket::SOUND_EXPLODE);
243 
244  return true;
245  }

Field Documentation

◆ $affectedBlocks

$affectedBlocks = []

◆ $level

$level

◆ $size

$size

◆ $source

$source

◆ $stepLen

$stepLen = 0.3

The documentation for this class was generated from the following file: