Vanilla-alike Explosions

This commit is contained in:
Shoghi Cervantes 2013-09-07 01:28:15 +02:00
parent 24211764ce
commit 0ddc48ca80
2 changed files with 42 additions and 34 deletions

View File

@ -31,7 +31,7 @@ class TNTBlock extends SolidBlock{
if(($player->gamemode & 0x01) === 0){ if(($player->gamemode & 0x01) === 0){
$item->useOn($this); $item->useOn($this);
} }
$explosion = new Explosion($this->level, $this, 3); $explosion = new Explosion(new Position($this->x + 0.5, $this->y, $this->z + 0.5, $this->level), 4);
$explosion->explode(); $explosion->explode();
return true; return true;
} }

View File

@ -20,14 +20,14 @@
*/ */
class Explosion{ class Explosion{
private $i = 8; //Rays private $i = 12; //Rays
public $level; public $level;
public $source; public $source;
public $size; public $size;
public $affectedBlocks = array(); public $affectedBlocks = array();
public function __construct(Level $level, Vector3 $center, $size){ public function __construct(Position $center, $size){
$this->level = $level; $this->level = $center->level;
$this->source = $center; $this->source = $center;
$this->size = max($size, 0); $this->size = max($size, 0);
} }
@ -41,7 +41,7 @@ class Explosion{
))){ ))){
return false; return false;
} }
$airblock = new AirBlock();
$drops = array(); $drops = array();
for($i = 0; $i < $this->i; ++$i){ for($i = 0; $i < $this->i; ++$i){
for($j = 0; $j < $this->i; ++$j){ for($j = 0; $j < $this->i; ++$j){
@ -55,50 +55,58 @@ class Explosion{
$d4 /= $d6; $d4 /= $d6;
$d5 /= $d6; $d5 /= $d6;
$f1 = $this->size * (0.7 + (mt_rand(0, 1000000) / 1000000) * 0.6); $blastForce = $this->size * (mt_rand(700, 1300) / 1000);
$d0 = $this->source->x; $X = $this->source->x;
$d1 = $this->source->y; $Y = $this->source->y;
$d2 = $this->source->z; $Z = $this->source->z;
for($f2 = 0.3; $f1 > 0; $f1 -= $f2 * 0.75){ for($stepLen = 0.3; $blastForce > 0; $blastForce -= $stepLen * 0.75){
$l = (int) $d0; $x = (int) $X;
$i1 = (int) $d1; $y = (int) $Y;
$j1 = (int) $d2; $z = (int) $Z;
$k1 = $this->level->getBlock(new Vector3($l, $i1, $j1)); $block = $this->level->getBlock(new Vector3($x, $y, $z));
$f1 -= ($k1->getHardness() / 5 + 0.3) * $f2; if(!($block instanceof AirBlock) and $y < 128 and $y >= 0){
$blastForce -= ($block->getHardness() / 5 + 0.3) * $stepLen;
if(!($k1 instanceof AirBlock) and $f1 > 0 and $i1 < 128 and $i1 >= 0){ if($blastForce > 0){
$this->level->setBlockRaw(new Vector3($l, $i1, $j1), $airblock, false, false); //Do not send record $this->affectedBlocks[$x.":".$y.":".$z] = $block;
$this->affectedBlocks[$l.$i1.$j1] = new Vector3($l - $this->source->x, $i1 - $this->source->y, $j1 - $this->source->z);
if(mt_rand(0, 100) < 30){
$drops[] = array(new Position($l, $i1, $j1, $this->level), BlockAPI::getItem($k1->getID(), $k1->getMetadata()));
} }
} }
$d0 += $d3 * $f2; $X += $d3 * $stepLen;
$d1 += $d4 * $f2; $Y += $d4 * $stepLen;
$d2 += $d5 * $f2; $Z += $d5 * $stepLen;
} }
} }
} }
} }
} }
$server->api->player->broadcastPacket($server->api->player->getAll($this->level), MC_EXPLOSION, array( $send = array();
"x" => $this->source->x, $airblock = new AirBlock();
"y" => $this->source->y, $source = $this->source->floor();
"z" => $this->source->z,
"radius" => $this->size,
"records" => $this->affectedBlocks,
));
foreach($server->api->entity->getRadius($this->source, 10) as $entity){ foreach($server->api->entity->getRadius($this->source, 10) as $entity){
$impact = (1 - $this->source->distance($entity) / 10); $impact = (1 - $this->source->distance($entity) / 10);
$damage = (int) (($impact * $impact + $impact) * 4 * $this->size + 1); $damage = (int) (($impact * $impact + $impact) * 4 * $this->size + 1);
$entity->harm($damage, "explosion"); $entity->harm($damage, "explosion");
} }
foreach($drops as $drop){
$server->api->entity->drop($drop[0], $drop[1]); foreach($this->affectedBlocks as $block){
$this->level->setBlockRaw($block, $airblock, false, false); //Do not send record
$send[] = new Vector3($block->x - $source->x, $block->y - $source->y, $block->z - $source->z);
if(mt_rand(0, 100) < 30){
$server->api->entity->drop(new Position($block->x + 0.5, $block->y, $block->z + 0.5, $this->level), BlockAPI::getItem($block->getID(), $block->getMetadata()));
}
} }
$server->api->player->broadcastPacket($server->api->player->getAll($this->level), MC_EXPLOSION, array(
"x" => $this->source->x,
"y" => $this->source->y,
"z" => $this->source->z,
"radius" => $this->size,
"records" => $send,
));
} }
} }