PocketMine-MP 5.37.1 git-cef37e7835c666594588f957a47b27d521c6a58e
Loading...
Searching...
No Matches
ParticleCommand.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
22declare(strict_types=1);
23
24namespace pocketmine\command\defaults;
25
69use function count;
70use function explode;
71use function max;
72use function microtime;
73use function mt_rand;
74use function strtolower;
75
77
78 public function __construct(){
79 parent::__construct(
80 "particle",
81 KnownTranslationFactory::pocketmine_command_particle_description(),
82 KnownTranslationFactory::pocketmine_command_particle_usage()
83 );
84 $this->setPermission(DefaultPermissionNames::COMMAND_PARTICLE);
85 }
86
87 public function execute(CommandSender $sender, string $commandLabel, array $args){
88 if(count($args) < 7){
90 }
91
92 if($sender instanceof Player){
93 $senderPos = $sender->getPosition();
94 $world = $senderPos->getWorld();
95 $pos = new Vector3(
96 $this->getRelativeDouble($senderPos->getX(), $sender, $args[1]),
97 $this->getRelativeDouble($senderPos->getY(), $sender, $args[2], World::Y_MIN, World::Y_MAX),
98 $this->getRelativeDouble($senderPos->getZ(), $sender, $args[3])
99 );
100 }else{
101 $world = $sender->getServer()->getWorldManager()->getDefaultWorld();
102 $pos = new Vector3((float) $args[1], (float) $args[2], (float) $args[3]);
103 }
104
105 $name = strtolower($args[0]);
106
107 $xd = (float) $args[4];
108 $yd = (float) $args[5];
109 $zd = (float) $args[6];
110
111 $count = isset($args[7]) ? max(1, (int) $args[7]) : 1;
112
113 $data = $args[8] ?? null;
114
115 $particle = $this->getParticle($name, $data);
116
117 if($particle === null){
118 $sender->sendMessage(KnownTranslationFactory::commands_particle_notFound($name)->prefix(TextFormat::RED));
119 return true;
120 }
121
122 $sender->sendMessage(KnownTranslationFactory::commands_particle_success($name, (string) $count));
123
124 $random = new Random((int) (microtime(true) * 1000) + mt_rand());
125
126 for($i = 0; $i < $count; ++$i){
127 $world->addParticle($pos->add(
128 $random->nextSignedFloat() * $xd,
129 $random->nextSignedFloat() * $yd,
130 $random->nextSignedFloat() * $zd
131 ), $particle);
132 }
133
134 return true;
135 }
136
137 private function getParticle(string $name, ?string $data = null) : ?Particle{
138 switch($name){
139 case "explode":
140 return new ExplodeParticle();
141 case "hugeexplosion":
142 return new HugeExplodeParticle();
143 case "hugeexplosionseed":
144 return new HugeExplodeSeedParticle();
145 case "bubble":
146 return new BubbleParticle();
147 case "splash":
148 return new SplashParticle();
149 case "wake":
150 case "water":
151 return new WaterParticle();
152 case "crit":
153 return new CriticalParticle();
154 case "smoke":
155 return new SmokeParticle((int) ($data ?? 0));
156 case "spell":
157 return new EnchantParticle(new Color(0, 0, 0, 255)); //TODO: colour support
158 case "instantspell":
159 return new InstantEnchantParticle(new Color(0, 0, 0, 255)); //TODO: colour support
160 case "dripwater":
161 return new WaterDripParticle();
162 case "driplava":
163 return new LavaDripParticle();
164 case "townaura":
165 case "spore":
166 return new SporeParticle();
167 case "portal":
168 return new PortalParticle();
169 case "flame":
170 return new FlameParticle();
171 case "lava":
172 return new LavaParticle();
173 case "reddust":
174 return new RedstoneParticle((int) ($data ?? 1));
175 case "snowballpoof":
176 return new ItemBreakParticle(VanillaItems::SNOWBALL());
177 case "slime":
178 return new ItemBreakParticle(VanillaItems::SLIMEBALL());
179 case "itembreak":
180 if($data !== null){
181 $item = StringToItemParser::getInstance()->parse($data);
182 if($item !== null && !$item->isNull()){
183 return new ItemBreakParticle($item);
184 }
185 }
186 break;
187 case "terrain":
188 if($data !== null){
189 $block = StringToItemParser::getInstance()->parse($data)?->getBlock();
190 if($block !== null && $block->getTypeId() !== BlockTypeIds::AIR){
191 return new TerrainParticle($block);
192 }
193 }
194 break;
195 case "heart":
196 return new HeartParticle((int) ($data ?? 0));
197 case "ink":
198 return new InkParticle((int) ($data ?? 0));
199 case "droplet":
200 return new RainSplashParticle();
201 case "enchantmenttable":
202 return new EnchantmentTableParticle();
203 case "happyvillager":
204 return new HappyVillagerParticle();
205 case "angryvillager":
206 return new AngryVillagerParticle();
207 case "forcefield":
208 return new BlockForceFieldParticle((int) ($data ?? 0));
209 case "mobflame":
210 return new EntityFlameParticle();
211 case "iconcrack":
212 if($data !== null && ($item = StringToItemParser::getInstance()->parse($data)) !== null && !$item->isNull()){
213 return new ItemBreakParticle($item);
214 }
215 break;
216 case "blockcrack":
217 if($data !== null && ($block = StringToItemParser::getInstance()->parse($data)?->getBlock()) !== null && $block->getTypeId() !== BlockTypeIds::AIR){
218 return new TerrainParticle($block);
219 }
220 break;
221 case "blockdust":
222 if($data !== null){
223 //to preserve the old unlimited explode behaviour, allow this to split into at most 5 parts
224 //this allows the 4th argument to be processed normally if given without forcing it to also consume
225 //any unexpected parts
226 //we probably ought to error in this case, but this will do for now
227 $d = explode("_", $data, limit: 5);
228 if(count($d) >= 3){
229 return new DustParticle(new Color(
230 ((int) $d[0]) & 0xff,
231 ((int) $d[1]) & 0xff,
232 ((int) $d[2]) & 0xff,
233 ((int) ($d[3] ?? 255)) & 0xff
234 ));
235 }
236 }
237 break;
238 case "sonicexplosion":
239 return new SonicExplosionParticle();
240 }
241
242 return null;
243 }
244}
execute(CommandSender $sender, string $commandLabel, array $args)