PocketMine-MP 5.21.2 git-a6534ecbbbcf369264567d27e5ed70f7f5be9816
Loading...
Searching...
No Matches
ChunkSelector.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\player;
25
27use const M_SQRT2;
28
29//TODO: turn this into an interface?
30final class ChunkSelector{
31
36 public function selectChunks(int $radius, int $centerX, int $centerZ) : \Generator{
37 for($subRadius = 0; $subRadius < $radius; $subRadius++){
38 $subRadiusSquared = $subRadius ** 2;
39 $nextSubRadiusSquared = ($subRadius + 1) ** 2;
40 $minX = (int) ($subRadius / M_SQRT2);
41
42 $lastZ = 0;
43
44 for($x = $subRadius; $x >= $minX; --$x){
45 for($z = $lastZ; $z <= $x; ++$z){
46 $distanceSquared = ($x ** 2 + $z ** 2);
47 if($distanceSquared < $subRadiusSquared){
48 continue;
49 }elseif($distanceSquared >= $nextSubRadiusSquared){
50 break; //skip to next X
51 }
52
53 $lastZ = $z;
54 //If the chunk is in the radius, others at the same offsets in different quadrants are also guaranteed to be.
55
56 /* Top right quadrant */
57 yield $subRadius => World::chunkHash($centerX + $x, $centerZ + $z);
58 /* Top left quadrant */
59 yield $subRadius => World::chunkHash($centerX - $x - 1, $centerZ + $z);
60 /* Bottom right quadrant */
61 yield $subRadius => World::chunkHash($centerX + $x, $centerZ - $z - 1);
62 /* Bottom left quadrant */
63 yield $subRadius => World::chunkHash($centerX - $x - 1, $centerZ - $z - 1);
64
65 if($x !== $z){
66 /* Top right quadrant mirror */
67 yield $subRadius => World::chunkHash($centerX + $z, $centerZ + $x);
68 /* Top left quadrant mirror */
69 yield $subRadius => World::chunkHash($centerX - $z - 1, $centerZ + $x);
70 /* Bottom right quadrant mirror */
71 yield $subRadius => World::chunkHash($centerX + $z, $centerZ - $x - 1);
72 /* Bottom left quadrant mirror */
73 yield $subRadius => World::chunkHash($centerX - $z - 1, $centerZ - $x - 1);
74 }
75 }
76 }
77 }
78 }
79}
selectChunks(int $radius, int $centerX, int $centerZ)