Mob spawner rewrite

Closes #849
This commit is contained in:
Tatsuyuki Ishi 2016-04-24 14:02:35 +09:00
commit f90844fb46

View file

@ -37,11 +37,26 @@ use pocketmine\Player;
class MobSpawner extends Spawnable{
public function __construct(FullChunk $chunk, CompoundTag $nbt){
parent::__construct($chunk, $nbt);
if(!isset($nbt->EntityId)){
$nbt->EntityId = new IntTag("EntityId", 0);
}
parent::__construct($chunk, $nbt);
$this->lastUpdate = $this->getLevel()->getServer()->getTick();
if(!isset($nbt->SpawnCount)){
$nbt->SpawnCount = new IntTag("SpawnCount", 4);
}
if(!isset($nbt->SpawnRange)){
$nbt->SpawnRange = new IntTag("SpawnRange", 4);
}
if(!isset($nbt->MinSpawnDelay)){
$nbt->MinSpawnDelay = new IntTag("MinSpawnDelay", 200);
}
if(!isset($nbt->MaxSpawnDelay)){
$nbt->MaxSpawnDelay = new IntTag("MaxSpawnDelay", 799);
}
if(!isset($nbt->Delay)){
$nbt->Delay = new IntTag("Delay", mt_rand($nbt->MinSpawnDelay->getValue(), $nbt->MaxSpawnDelay->getValue()));
}
if($this->getEntityId() > 0) $this->scheduleUpdate();
}
@ -50,7 +65,7 @@ class MobSpawner extends Spawnable{
}
public function setEntityId($id){
$this->namedtag->EntityId = new IntTag("EntityId", $id);
$this->namedtag->EntityId->setValue($id);
$this->spawnToAll();
if($this->chunk instanceof FullChunk){
$this->chunk->setChanged();
@ -59,6 +74,46 @@ class MobSpawner extends Spawnable{
$this->scheduleUpdate();
}
public function getSpawnCount(){
return $this->namedtag["SpawnCount"];
}
public function setSpawnCount($value){
$this->namedtag->SpawnCount->setValue($value);
}
public function getSpawnRange(){
return $this->namedtag["SpawnRange"];
}
public function setSpawnRange($value){
$this->namedtag->SpawnRange->setValue($value);
}
public function getMinSpawnDelay(){
return $this->namedtag["MinSpawnDelay"];
}
public function setMinSpawnDelay($value){
$this->namedtag->MinSpawnDelay->setValue($value);
}
public function getMaxSpawnDelay(){
return $this->namedtag["MaxSpawnDelay"];
}
public function setMaxSpawnDelay($value){
$this->namedtag->MaxSpawnDelay->setValue($value);
}
public function getDelay(){
return $this->namedtag["Delay"];
}
public function setDelay($value){
$this->namedtag->Delay->setValue($value);
}
public function getName() : string{
return "Monster Spawner";
}
@ -86,35 +141,42 @@ class MobSpawner extends Spawnable{
if(!($this->chunk instanceof FullChunk)) return false;
if($this->canUpdate()){
$currentTick = $this->getLevel()->getServer()->getTick();
$baseTick = $this->getLevel()->getServer()->getTicksPerSecondAverage();
if(($currentTick - $this->lastUpdate) > $baseTick * 10){//Spawn per 10 seconds
$this->lastUpdate = $currentTick;
$up = $this->getLevel()->getBlock($this->getSide(Vector3::SIDE_UP));
if($up->getId() == Item::AIR){
$this->getLevel()->getServer()->getPluginManager()->callEvent($ev = new EntityGenerateEvent($this->add(0, 1, 0), $this->getEntityId(), EntityGenerateEvent::CAUSE_MOB_SPAWNER));
if(!$ev->isCancelled()){
$pos = $ev->getPosition();
$nbt = new CompoundTag("", [
"Pos" => new ListTag("Pos", [
new DoubleTag("", $pos->x),
new DoubleTag("", $pos->y),
new DoubleTag("", $pos->z)
]),
"Motion" => new ListTag("Motion", [
new DoubleTag("", 0),
new DoubleTag("", 0),
new DoubleTag("", 0)
]),
"Rotation" => new ListTag("Rotation", [
new FloatTag("", 0),
new FloatTag("", 0)
]),
]);
$entity = Entity::createEntity($this->getEntityId(), $this->chunk, $nbt);
$entity->spawnToAll();
if($this->getDelay() == 0){
$success = 0;
for($i = 0; $i < $this->getSpawnCount(); $i++)
{
$pos = $this->add(mt_rand() / mt_getrandmax() * $this->getSpawnRange(), mt_rand(-1, 1), mt_rand() / mt_getrandmax() * $this->getSpawnRange());
$target = $this->getLevel()->getBlock($pos);
$ground = $target->getSide(Vector3::SIDE_DOWN);
if($target->getId() == Item::AIR && $ground->isSolid()){
$success++;
$this->getLevel()->getServer()->getPluginManager()->callEvent($ev = new EntityGenerateEvent($pos, $this->getEntityId(), EntityGenerateEvent::CAUSE_MOB_SPAWNER));
if(!$ev->isCancelled()){
$nbt = new CompoundTag("", [
"Pos" => new ListTag("Pos", [
new DoubleTag("", $pos->x),
new DoubleTag("", $pos->y),
new DoubleTag("", $pos->z)
]),
"Motion" => new ListTag("Motion", [
new DoubleTag("", 0),
new DoubleTag("", 0),
new DoubleTag("", 0)
]),
"Rotation" => new ListTag("Rotation", [
new FloatTag("", mt_rand() / mt_getrandmax() * 360),
new FloatTag("", 0)
]),
]);
$entity = Entity::createEntity($this->getEntityId(), $this->chunk, $nbt);
$entity->spawnToAll();
}
}
}
if($success > 0) $this->setDelay(mt_rand($this->getMinSpawnDelay(), $this->getMaxSpawnDelay()));
}
else{
$this->setDelay($this->getDelay() - 1);
}
}