DREAMFIRE Docs ← Back to site
Loading...
Searching...
No Matches
DreamBlock.java
Go to the documentation of this file.
1/*
2 * MIT License
3 *
4 * Copyright (c) 2025 Dreamfire Studio
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a copy
7 * of this software and associated documentation files (the "Software"), to deal
8 * in the Software without restriction, including without limitation the rights
9 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 * copies of the Software, and to permit persons to whom the Software is
11 * furnished to do so, subject to the following conditions:
12 *
13 * The above copyright notice and this permission notice shall be included in all
14 * copies or substantial portions of the Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22 * SOFTWARE.
23 */
24package com.dreamfirestudios.dreamcore.DreamBlock;
25
26import org.bukkit.Location;
27import org.bukkit.Material;
28import org.bukkit.World;
29import org.bukkit.block.Block;
30
31import java.util.*;
32import java.util.concurrent.CompletableFuture;
33import java.util.function.Predicate;
34
49public class DreamBlock {
50
51 // ============================================================
52 // Synchronous Methods
53 // ============================================================
54
74 public static List<Block> filterBlocksInRadius(final Location location, final int radius, final int step,
75 final RegionShape shape, final Predicate<Block> condition) {
76 List<Block> result = new ArrayList<>();
77 final World world = location.getWorld();
78 if (world == null || step <= 0) return result;
79
80 final int cx = location.getBlockX();
81 final int cy = location.getBlockY();
82 final int cz = location.getBlockZ();
83
84 final int r2 = radius * radius;
85 for (int x = cx - radius; x < cx + radius; x += step) {
86 for (int y = cy - radius; y < cy + radius; y += step) {
87 for (int z = cz - radius; z < cz + radius; z += step) {
88 if (shape == RegionShape.SPHERE) {
89 int dx = x - cx, dy = y - cy, dz = z - cz;
90 if (dx * dx + dy * dy + dz * dz > r2) continue;
91 }
92 Block block = world.getBlockAt(x, y, z);
93 if (condition.test(block)) result.add(block);
94 }
95 }
96 }
97 return result;
98 }
99
110 public static List<Block> returnAllBlocksInRadius(final Location location, final int radius, final int step,
111 final RegionShape shape, final Material... materials) {
112 List<Block> result = new ArrayList<>();
113 final World world = location.getWorld();
114 if (world == null || step <= 0) return result;
115
116 final int cx = location.getBlockX();
117 final int cy = location.getBlockY();
118 final int cz = location.getBlockZ();
119
120 final int r2 = radius * radius;
121 final boolean filterByMaterial = materials != null && materials.length > 0;
122 final Set<Material> materialSet = filterByMaterial ? new HashSet<>(Arrays.asList(materials)) : null;
123
124 for (int x = cx - radius; x < cx + radius; x += step) {
125 for (int y = cy - radius; y < cy + radius; y += step) {
126 for (int z = cz - radius; z < cz + radius; z += step) {
127 if (shape == RegionShape.SPHERE) {
128 int dx = x - cx, dy = y - cy, dz = z - cz;
129 if (dx * dx + dy * dy + dz * dz > r2) continue;
130 }
131 Block block = world.getBlockAt(x, y, z);
132 if (!filterByMaterial || materialSet.contains(block.getType())) result.add(block);
133 }
134 }
135 }
136 return result;
137 }
138
154 public static int replaceBlocksInRadius(final Location location, final int radius, final int step,
155 final RegionShape shape, final Material[] targetMaterials,
156 final Material replacementMaterial) {
157 final World world = location.getWorld();
158 if (world == null || step <= 0) return 0;
159
160 int replaced = 0;
161 final int cx = location.getBlockX();
162 final int cy = location.getBlockY();
163 final int cz = location.getBlockZ();
164
165 final int r2 = radius * radius;
166 final Set<Material> targets = new HashSet<>(Arrays.asList(targetMaterials));
167
168 for (int x = cx - radius; x < cx + radius; x += step) {
169 for (int y = cy - radius; y < cy + radius; y += step) {
170 for (int z = cz - radius; z < cz + radius; z += step) {
171 if (shape == RegionShape.SPHERE) {
172 int dx = x - cx, dy = y - cy, dz = z - cz;
173 if (dx * dx + dy * dy + dz * dz > r2) continue;
174 }
175 Block block = world.getBlockAt(x, y, z);
176 if (targets.contains(block.getType())) {
177 block.setType(replacementMaterial, false);
178 replaced++;
179 }
180 }
181 }
182 }
183 return replaced;
184 }
185
196 public static int countBlocksInRadius(final Location location, final int radius, final int step,
197 final RegionShape shape, final Material... materials) {
198 final World world = location.getWorld();
199 if (world == null || step <= 0) return 0;
200
201 int count = 0;
202 final int cx = location.getBlockX();
203 final int cy = location.getBlockY();
204 final int cz = location.getBlockZ();
205
206 final int r2 = radius * radius;
207 final boolean filterByMaterial = materials != null && materials.length > 0;
208 final Set<Material> materialSet = filterByMaterial ? new HashSet<>(Arrays.asList(materials)) : null;
209
210 for (int x = cx - radius; x < cx + radius; x += step) {
211 for (int y = cy - radius; y < cy + radius; y += step) {
212 for (int z = cz - radius; z < cz + radius; z += step) {
213 if (shape == RegionShape.SPHERE) {
214 int dx = x - cx, dy = y - cy, dz = z - cz;
215 if (dx * dx + dy * dy + dz * dz > r2) continue;
216 }
217 Block block = world.getBlockAt(x, y, z);
218 if (!filterByMaterial || materialSet.contains(block.getType())) count++;
219 }
220 }
221 }
222 return count;
223 }
224
233 public static Block findClosestBlock(final Location location, final int radius,
234 final RegionShape shape, final Material material) {
235 final World world = location.getWorld();
236 if (world == null) return null;
237
238 Block closest = null;
239 double bestDist = Double.MAX_VALUE;
240
241 final int cx = location.getBlockX();
242 final int cy = location.getBlockY();
243 final int cz = location.getBlockZ();
244 final int r2 = radius * radius;
245
246 for (int x = cx - radius; x < cx + radius; x++) {
247 for (int y = cy - radius; y < cy + radius; y++) {
248 for (int z = cz - radius; z < cz + radius; z++) {
249 if (shape == RegionShape.SPHERE) {
250 int dx = x - cx, dy = y - cy, dz = z - cz;
251 if (dx * dx + dy * dy + dz * dz > r2) continue;
252 }
253 Block block = world.getBlockAt(x, y, z);
254 if (block.getType() == material) {
255 double dist = location.distanceSquared(block.getLocation());
256 if (dist < bestDist) {
257 bestDist = dist;
258 closest = block;
259 }
260 }
261 }
262 }
263 }
264 return closest;
265 }
266
281 public static int clearBlocksInRadius(final Location location, final int radius, final int step,
282 final RegionShape shape, final Material... materials) {
283 final World world = location.getWorld();
284 if (world == null || step <= 0) return 0;
285
286 int cleared = 0;
287 final int cx = location.getBlockX();
288 final int cy = location.getBlockY();
289 final int cz = location.getBlockZ();
290
291 final int r2 = radius * radius;
292 final boolean filterByMaterial = materials != null && materials.length > 0;
293 final Set<Material> materialSet = filterByMaterial ? new HashSet<>(Arrays.asList(materials)) : null;
294
295 for (int x = cx - radius; x < cx + radius; x += step) {
296 for (int y = cy - radius; y < cy + radius; y += step) {
297 for (int z = cz - radius; z < cz + radius; z += step) {
298 if (shape == RegionShape.SPHERE) {
299 int dx = x - cx, dy = y - cy, dz = z - cz;
300 if (dx * dx + dy * dy + dz * dz > r2) continue;
301 }
302 Block block = world.getBlockAt(x, y, z);
303 if (!filterByMaterial || materialSet.contains(block.getType())) {
304 block.setType(Material.AIR, false);
305 cleared++;
306 }
307 }
308 }
309 }
310 return cleared;
311 }
312
313 // ============================================================
314 // Asynchronous Wrappers (Read-only)
315 // ============================================================
316
326 public static CompletableFuture<List<Block>> filterBlocksInRadiusAsync(final Location location, final int radius,
327 final int step, final RegionShape shape,
328 final Predicate<Block> condition) {
329 return CompletableFuture.supplyAsync(() -> filterBlocksInRadius(location, radius, step, shape, condition));
330 }
331
341 public static CompletableFuture<List<Block>> returnAllBlocksInRadiusAsync(final Location location, final int radius,
342 final int step, final RegionShape shape,
343 final Material... materials) {
344 return CompletableFuture.supplyAsync(() -> returnAllBlocksInRadius(location, radius, step, shape, materials));
345 }
346
356 public static CompletableFuture<Integer> countBlocksInRadiusAsync(final Location location, final int radius,
357 final int step, final RegionShape shape,
358 final Material... materials) {
359 return CompletableFuture.supplyAsync(() -> countBlocksInRadius(location, radius, step, shape, materials));
360 }
361
370 public static CompletableFuture<Block> findClosestBlockAsync(final Location location, final int radius,
371 final RegionShape shape, final Material material) {
372 return CompletableFuture.supplyAsync(() -> findClosestBlock(location, radius, shape, material));
373 }
374}
Utilities for synchronous and asynchronous (read-only) block queries within a region (cube or sphere)...
static int replaceBlocksInRadius(final Location location, final int radius, final int step, final RegionShape shape, final Material[] targetMaterials, final Material replacementMaterial)
Replaces all blocks whose material is in targetMaterials within the region with replacementMaterial ...
static List< Block > returnAllBlocksInRadius(final Location location, final int radius, final int step, final RegionShape shape, final Material... materials)
Returns all blocks within a region centered at location , optionally filtered by materials .
static CompletableFuture< Block > findClosestBlockAsync(final Location location, final int radius, final RegionShape shape, final Material material)
Asynchronously finds the closest block of the specified material within a region.
static CompletableFuture< Integer > countBlocksInRadiusAsync(final Location location, final int radius, final int step, final RegionShape shape, final Material... materials)
Asynchronously counts blocks with the specified materials within a region.
static CompletableFuture< List< Block > > returnAllBlocksInRadiusAsync(final Location location, final int radius, final int step, final RegionShape shape, final Material... materials)
Asynchronously returns all blocks within a region.
static List< Block > filterBlocksInRadius(final Location location, final int radius, final int step, final RegionShape shape, final Predicate< Block > condition)
Filters blocks within a region centered at location that match condition .
static int countBlocksInRadius(final Location location, final int radius, final int step, final RegionShape shape, final Material... materials)
Counts blocks within the region.
static Block findClosestBlock(final Location location, final int radius, final RegionShape shape, final Material material)
Finds the closest block of material within the region, or null if none.
static int clearBlocksInRadius(final Location location, final int radius, final int step, final RegionShape shape, final Material... materials)
Clears (sets to Material::AIR) all blocks within the region.
static CompletableFuture< List< Block > > filterBlocksInRadiusAsync(final Location location, final int radius, final int step, final RegionShape shape, final Predicate< Block > condition)
Asynchronously filters blocks within a region.
Enumeration of geometric region shapes used in block operations.
SPHERE
A spherical region defined by all positions within a given radius from the center point,...