Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

concentric squares #3

Open
wants to merge 8 commits into
base: master
Choose a base branch
from
Open
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
7 changes: 4 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,12 @@

Fabric Chunk Pregenerator is a fabric mod that allows you to pregenerate chunks for your server or for singleplayer while running fabric. Requires Fabric API!



# Commands

`/pregen start <radius>` - Pregenerates in a square that is <radius> chunks long and wide. Only one pregeneration can run at a time.
`/pregen start <radius> <first>` - Pregenerates in a square that is <radius> chunks away from player in each direction starting from <first> chunks away.
- Only one pregeneration can run at a time.

`/pregen stop` - Stops pregeneration and displays the amount completed.

Expand All @@ -19,4 +20,4 @@ Fabric Chunk Pregenerator is a fabric mod that allows you to pregenerate chunks

## Discord Server

https://discord.gg/BuBGds9
https://discord.gg/BuBGds9
2 changes: 1 addition & 1 deletion gradle.properties
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,6 @@ loader_version=0.8.7+build.201
fabric_version=0.12.1+build.361-1.16

# Mod Properties
mod_version = 0.2.2
mod_version = 0.2.3
maven_group = supercoder79.chunkpregen
archives_base_name = fabric-chunkpregen
47 changes: 35 additions & 12 deletions src/main/java/supercoder79/chunkpregen/Commands.java
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@
import net.minecraft.util.math.ChunkPos;

import java.text.DecimalFormat;
import java.util.HashSet;
import java.util.Set;
import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
Expand All @@ -21,6 +23,7 @@ public class Commands {
private static int threadsDone = 0;
private static ConcurrentLinkedQueue<ChunkPos> queue = new ConcurrentLinkedQueue<>();
private static int total = 1;
private static int skipped_total = 0;
private static boolean shouldGenerate = false;
private static ExecutorService executor;

Expand All @@ -32,13 +35,15 @@ public static void init() {

lab.then(CommandManager.literal("start")
.then(CommandManager.argument("radius", IntegerArgumentType.integer(0))
.then(CommandManager.argument("first", IntegerArgumentType.integer(0))
.executes(cmd -> {
if (!shouldGenerate) {
shouldGenerate = true;

ServerCommandSource source = cmd.getSource();

int radius = IntegerArgumentType.getInteger(cmd, "radius");
int first = IntegerArgumentType.getInteger(cmd, "first");

ChunkPos pos;
if (source.getEntity() == null) {
Expand All @@ -50,28 +55,41 @@ public static void init() {
queue.clear();

total = 0;

for (int x = pos.x - radius; x < pos.x + radius; x++) {
for (int z = pos.z - radius; z < pos.z + radius; z++) {
queue.add(new ChunkPos(x, z));
total++;
skipped_total=(first==0)?0:(int)(1+(Math.pow(first-1,2)+first-1)*4); // get number of chunks skipped due to start location skipping. helps with ring determination later
// concentric squares. start in the middle or at "first" ring
Set<ChunkPos> chunks = new HashSet<>(); // helps remove duplicates rather than ifing. lazy man's ifs ;)
for (int ring = first; ring <= radius; ring++) {
for (int v = -ring; v <= ring; v++) {
chunks.add(new ChunkPos(pos.x + ring, pos.z + v));
chunks.add(new ChunkPos(pos.x - ring, pos.z + v));
chunks.add(new ChunkPos(pos.x+v,pos.z+ring));
chunks.add(new ChunkPos(pos.x+v,pos.z-ring));
}
}

execute(source);
queue.addAll(chunks);
total += queue.size(); // why count as they add when you can just count it all at the end

if (getLastRing(total+skipped_total)==radius) // sanity check
execute(source);
else {
shouldGenerate=false;
throw(new IllegalArgumentException("Failed to math"));
}

source.sendFeedback(new LiteralText("Pregenerating " + total + " chunks..."), true);
} else {
cmd.getSource().sendFeedback(new LiteralText("Pregen already running. Please execute '/pregen stop' to start another pregeneration."), true);
}
return 1;
})));
}))));

lab.then(CommandManager.literal("stop")
.executes(cmd -> {
if (shouldGenerate) {
int amount = total-queue.size();
int ring = getLastRing(skipped_total+amount);
cmd.getSource().sendFeedback(new LiteralText("Pregen stopped! " + (amount) + " out of " + total + " generated. (" + (((double)(amount) / (double)(total))) * 100 + "%)"), true);
cmd.getSource().sendFeedback(new LiteralText("Last completed radius: " + (ring)), true);
}
shouldGenerate = false;
return 1;
Expand All @@ -81,9 +99,11 @@ public static void init() {
.executes(cmd -> {
if (shouldGenerate) {
int amount = total-queue.size();
int ring = getLastRing(skipped_total+amount);
cmd.getSource().sendFeedback(new LiteralText("Pregen status: " + (amount) + " out of " + total + " generated. (" + (((double)(amount) / (double)(total))) * 100 + "%)"), true);
cmd.getSource().sendFeedback(new LiteralText("Last completed radius: " + (ring)), true);
} else {
cmd.getSource().sendFeedback(new LiteralText("No pregeneration currently running. Run /pregen start <radius> to start."), false);
cmd.getSource().sendFeedback(new LiteralText("No pregeneration currently running. Run /pregen start <radius> <first> to start."), false);
}
return 1;
}));
Expand All @@ -92,7 +112,7 @@ public static void init() {
executes(cmd -> {
ServerCommandSource source = cmd.getSource();

source.sendFeedback(new LiteralText("/pregen start <radius> - Pregenerate a square centered on the player that is <radius> chunks long and wide."), false);
source.sendFeedback(new LiteralText("/pregen start <radius> <first> - Pregenerate a square centered on the player that is <radius> chunks from the player in each direction and starts at <first> chunks away."), false);
source.sendFeedback(new LiteralText("/pregen stop - Stop pregeneration and displays the amount completed."), false);
source.sendFeedback(new LiteralText("/pregen status - Display the amount of chunks pregenerated."), false);
source.sendFeedback(new LiteralText("/pregen help - Display this message."), false);
Expand All @@ -102,13 +122,16 @@ public static void init() {
dispatcher.register(lab);
});
}

private static int getLastRing(int value) {
return (int)(Math.floor(-1+Math.sqrt(value))/2);
}
private static void incrementAmount(ServerCommandSource source) {
int amount = total - queue.size();

if (amount % 100 == 0) {
System.gc();
source.sendFeedback(new LiteralText("Pregenerated " + (format.format(((double)(amount) / (double)(total)) * 100)) + "%"), true);
int ring = getLastRing(skipped_total+amount);
source.sendFeedback(new LiteralText("Pregenerated " + ring + " rings, " + (format.format(((double)(amount) / (double)(total)) * 100)) + "% total"), true);
}
}

Expand Down