Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion java plugin/addons/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ Plugins that extend MCConnect through MCDataLink (3.22+). Background and securit
| BetterJoinMessages | MCConnect's join/leave messages (reward levels, `/profil`), first-join message, greeting, fixed lines per player, silent players, no message on quick reconnects | `/joinmessage` |
| EasyHeadDrop | player heads (date, killer, weapon) with chance, looting bonus and anti-farming cooldown; optional mob heads and chat announcement | – |
| EasyNewCraftingRecipes | own shaped, shapeless and furnace recipes, applied without a restart, problems shown on the website | – |
| SpawnElytra | double jump near the spawn or in rectangles with their own boost starts a glide without an elytra, no fall damage | `/spawnelytra` |
| SpawnElytra | double jump in rectangles and circles, each with its own boost, starts a glide without an elytra, no fall damage | `/spawnelytra` |
| SpawnProtect | protected regions (box or circle around the spawn) with 13 protections, bypass, greeting | `/spawnprotect` (`/sprot`) |

Build: `mvn package` in `java plugin/` (builds MCDataLink and all addons). The Dockerfile copies the addon jars to
Expand Down
2 changes: 1 addition & 1 deletion java plugin/addons/SpawnElytra/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,6 @@
</parent>

<artifactId>SpawnElytra</artifactId>
<version>2.2</version>
<version>2.3</version>
<packaging>jar</packaging>
</project>
Original file line number Diff line number Diff line change
Expand Up @@ -4,17 +4,25 @@
import org.bukkit.World;
import org.tobias.mcdatalink.api.AddonConfig;

/** One rectangle from the settings: between two corners (in any order), with its own boost. */
/** One area from the settings, with its own boost: a box between two corners (in any order) or a circle. */
final class Area {
final String name;
/** empty: the main world */
final String world;
final boolean circle, aroundSpawn;
final int minX, minY, minZ, maxX, maxY, maxZ;
final int centerX, centerY, centerZ;
final int radius;
/** circle: blocks above the center that still count, 0 = no limit */
final int height;
final double boost;

private Area(AddonConfig row) {
name = row.getString("name", "bereich");
world = row.getString("world", "").trim();
String shape = row.getString("shape", "rectangle");
aroundSpawn = "spawn".equals(shape);
circle = aroundSpawn || "circle".equals(shape);
int[] a = row.getPosition("pos1");
int[] b = row.getPosition("pos2");
if (a == null) a = new int[]{0, 0, 0};
Expand All @@ -25,6 +33,13 @@ private Area(AddonConfig row) {
maxX = Math.max(a[0], b[0]);
maxY = Math.max(a[1], b[1]);
maxZ = Math.max(a[2], b[2]);
int[] center = row.getPosition("center");
if (center == null) center = new int[]{0, 0, 0};
centerX = center[0];
centerY = center[1];
centerZ = center[2];
radius = Math.max(1, row.getInt("radius", 20));
height = row.getInt("height", 0);
boost = row.getDouble("boost", 1.0);
}

Expand All @@ -33,19 +48,32 @@ static Area of(AddonConfig row) {
return row.getBoolean("enabled", true) ? new Area(row) : null;
}

boolean contains(Location location, World main, int height) {
boolean contains(Location location, World main) {
World candidate = location.getWorld();
if (candidate == null) return false;
if (!(world.isEmpty() ? candidate.equals(main) : candidate.getName().equalsIgnoreCase(world))) return false;
return covers(location.getBlockX(), location.getBlockY(), location.getBlockZ(), height);
if (!circle) return inBox(location.getBlockX(), location.getBlockY(), location.getBlockZ());
if (aroundSpawn) {
Location spawn = candidate.getSpawnLocation();
return inCircle(location.getX() - spawn.getX(), location.getZ() - spawn.getZ(), location.getBlockY(), spawn.getBlockY());
}
return inCircle(location.getX() - (centerX + 0.5), location.getZ() - (centerZ + 0.5), location.getBlockY(), centerY);
}

/** Both corners included; in the height from the lower corner up to height blocks above the higher one (0 = no limit). */
boolean covers(int x, int y, int z, int height) {
return x >= minX && x <= maxX && z >= minZ && z <= maxZ && (height <= 0 || (y >= minY && y <= maxY + height));
/** Both corners included. */
boolean inBox(int x, int y, int z) {
return x >= minX && x <= maxX && y >= minY && y <= maxY && z >= minZ && z <= maxZ;
}

/** dx, dz: horizontal distance to the center; in the height from its level up to height blocks above, both included. */
boolean inCircle(double dx, double dz, int y, int levelOfCenter) {
if (height > 0 && (y < levelOfCenter || y > levelOfCenter + height)) return false;
return dx * dx + dz * dz <= (double) radius * radius;
}

String size() {
return (maxX - minX + 1) + " × " + (maxZ - minZ + 1) + " Blöcke, Schub " + boost;
if (!circle) return "Rechteck " + (maxX - minX + 1) + " × " + (maxZ - minZ + 1) + ", Y " + minY + " bis " + maxY + ", Schub " + boost;
return "Kreis mit Radius " + radius + " um " + (aroundSpawn ? "den Weltspawn" : centerX + " " + centerY + " " + centerZ)
+ (height > 0 ? ", " + height + " Blöcke hoch" : "") + ", Schub " + boost;
}
}
Loading
Loading