diff --git a/src/pocketmine/Player.php b/src/pocketmine/Player.php index cd5993859..73741592c 100644 --- a/src/pocketmine/Player.php +++ b/src/pocketmine/Player.php @@ -2074,6 +2074,7 @@ class Player extends Human implements CommandSender, InventoryHolder, IPlayer{ $this->setHealth(20); $this->dead = false; + $this->removeAllEffects(); $this->sendData($this); $this->sendSettings(); diff --git a/src/pocketmine/command/SimpleCommandMap.php b/src/pocketmine/command/SimpleCommandMap.php index b3e3c4cab..7abcdcb1c 100644 --- a/src/pocketmine/command/SimpleCommandMap.php +++ b/src/pocketmine/command/SimpleCommandMap.php @@ -38,6 +38,7 @@ use pocketmine\command\defaults\MeCommand; use pocketmine\command\defaults\OpCommand; use pocketmine\command\defaults\PardonCommand; use pocketmine\command\defaults\PardonIpCommand; +use pocketmine\command\defaults\ParticleCommand; use pocketmine\command\defaults\PluginsCommand; use pocketmine\command\defaults\ReloadCommand; use pocketmine\command\defaults\SaveCommand; @@ -100,6 +101,7 @@ class SimpleCommandMap implements CommandMap{ $this->register("pocketmine", new SaveCommand("save-all")); $this->register("pocketmine", new GiveCommand("give")); $this->register("pocketmine", new EffectCommand("effect")); + $this->register("pocketmine", new ParticleCommand("particle")); $this->register("pocketmine", new GamemodeCommand("gamemode")); $this->register("pocketmine", new KillCommand("kill")); $this->register("pocketmine", new SpawnpointCommand("spawnpoint")); diff --git a/src/pocketmine/command/defaults/ParticleCommand.php b/src/pocketmine/command/defaults/ParticleCommand.php new file mode 100644 index 000000000..db52bff9b --- /dev/null +++ b/src/pocketmine/command/defaults/ParticleCommand.php @@ -0,0 +1,191 @@ + [count] [data]" + ); + $this->setPermission("pocketmine.command.particle"); + } + + public function execute(CommandSender $sender, $currentAlias, array $args){ + if(!$this->testPermission($sender)){ + return true; + } + + if(count($args) < 7){ + $sender->sendMessage(TextFormat::RED . "Usage: " . $this->usageMessage); + + return true; + } + + if($sender instanceof Player){ + $level = $sender->getLevel(); + }else{ + $level = $sender->getServer()->getDefaultLevel(); + } + + $name = strtolower($args[0]); + + $pos = new Vector3((float) $args[1], (float) $args[2], (float) $args[3]); + + $xd = (float) $args[4]; + $yd = (float) $args[5]; + $zd = (float) $args[6]; + + $count = isset($args[7]) ? max(1, (int) $args[7]) : 1; + + $data = isset($args[8]) ? (int) $args[8] : null; + + $particle = $this->getParticle($name, $pos, $xd, $yd, $zd, $data); + + if($particle === null){ + $sender->sendMessage(TextFormat::RED . "Unknown particle name (" . $name . ")"); + return true; + } + + + $sender->sendMessage("Playing particle ". $name ." for ". $count ." times"); + + $random = new Random((int) (microtime(true) * 1000) + mt_rand()); + + for($i = 0; $i < $count; ++$i){ + $particle->setComponents( + $pos->x + $random->nextSignedFloat() * $xd, + $pos->y + $random->nextSignedFloat() * $yd, + $pos->z + $random->nextSignedFloat() * $zd + ); + $level->addParticle($particle); + } + + return true; + } + + /** + * @param $name + * + * @return Particle + */ + private function getParticle($name, Vector3 $pos, $xd, $yd, $zd, $data){ + switch($name){ + case "explode": + return new ExplodeParticle($pos); + case "bubble": + return new BubbleParticle($pos); + case "splash": + return new SplashParticle($pos); + case "wake": + case "water": + return new WaterParticle($pos); + case "crit": + return new CriticalParticle($pos); + case "smoke": + return new SmokeParticle($pos, $data !== null ? $data : 0); + case "spell": + return new EnchantParticle($pos); + case "dripwater": + return new WaterDripParticle($pos); + case "driplava": + return new LavaDripParticle($pos); + case "townaura": + case "spore": + return new SporeParticle($pos); + case "portal": + return new PortalParticle($pos); + case "flame": + return new FlameParticle($pos); + case "lava": + return new LavaParticle($pos); + case "reddust": + return new RedstoneParticle($pos, $data !== null ? $data : 1); + case "snowballpoof": + return new ItemBreakParticle($pos, Item::get(Item::SNOWBALL)); + case "itembreak": + if($data !== null and $data !== 0){ + return new ItemBreakParticle($pos, $data); + } + break; + case "terrain": + if($data !== null and $data !== 0){ + return new TerrainParticle($pos, $data); + } + break; + case "heart": + return new HeartParticle($pos, $data !== null ? $data : 0); + case "ink": + return new InkParticle($pos, $data !== null ? $data : 0); + + } + + if(substr($name, 0, 10) === "iconcrack_"){ + $d = explode("_", $name); + if(count($d) === 3){ + return new ItemBreakParticle($pos, Item::get((int) $d[1], (int) $d[2])); + } + }elseif(substr($name, 0, 11) === "blockcrack_"){ + $d = explode("_", $name); + if(count($d) === 2){ + return new TerrainParticle($pos, Block::get($d[1] & 0xff, $d[1] >> 12)); + } + }elseif(substr($name, 0, 10) === "blockdust_"){ + $d = explode("_", $name); + if(count($d) >= 4){ + return new DustParticle($pos, $d[1] & 0xff, $d[2] & 0xff, $d[3] & 0xff, isset($d[4]) ? $d[4] & 0xff : 255); + } + } + + return null; + } +} \ No newline at end of file diff --git a/src/pocketmine/level/particle/SporeParticle.php b/src/pocketmine/level/particle/SporeParticle.php new file mode 100644 index 000000000..92e923973 --- /dev/null +++ b/src/pocketmine/level/particle/SporeParticle.php @@ -0,0 +1,30 @@ +