Skip to content
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
120 changes: 109 additions & 11 deletions src/main/java/space/essem/image2map/Image2Map.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import com.mojang.brigadier.arguments.IntegerArgumentType;
import com.mojang.brigadier.arguments.StringArgumentType;
import com.mojang.brigadier.arguments.BoolArgumentType;
import com.mojang.brigadier.context.CommandContext;
import com.mojang.brigadier.exceptions.CommandSyntaxException;
import com.mojang.brigadier.exceptions.SimpleCommandExceptionType;
Expand All @@ -14,9 +15,12 @@
import net.fabricmc.fabric.api.command.v2.CommandRegistrationCallback;
import net.fabricmc.fabric.api.event.lifecycle.v1.ServerLifecycleEvents;
import net.minecraft.entity.Entity;
import net.minecraft.entity.data.DataTracker;
import net.minecraft.entity.ItemEntity;
import net.minecraft.entity.decoration.ItemFrameEntity;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.entity.player.PlayerInventory;
import net.minecraft.inventory.Inventory;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraft.item.Items;
import net.minecraft.nbt.NbtCompound;
Expand All @@ -32,7 +36,6 @@
import net.minecraft.util.math.MathHelper;
import net.minecraft.util.math.Vec3d;

import org.jetbrains.annotations.Nullable;
import org.slf4j.Logger;
import space.essem.image2map.config.Image2MapConfig;
import space.essem.image2map.gui.PreviewGui;
Expand Down Expand Up @@ -62,8 +65,16 @@ public void onInitialize() {
dispatcher.register(literal("image2map")
.requires(source -> source.hasPermissionLevel(CONFIG.minPermLevel))
.then(literal("create")
.then(argument("width", IntegerArgumentType.integer(1))
.then(argument("height", IntegerArgumentType.integer(1))
.then(argument("bundle", BoolArgumentType.bool())
.then(argument("width", IntegerArgumentType.integer(1))
.then(argument("height", IntegerArgumentType.integer(1))
.then(argument("mode", StringArgumentType.word()).suggests(new DitherModeSuggestionProvider())
.then(argument("path", StringArgumentType.greedyString())
.executes(this::createMap))
)
)
)
.then(argument("normalize", IntegerArgumentType.integer(1))
.then(argument("mode", StringArgumentType.word()).suggests(new DitherModeSuggestionProvider())
.then(argument("path", StringArgumentType.greedyString())
.executes(this::createMap))
Expand All @@ -89,6 +100,13 @@ public void onInitialize() {

private int openPreview(CommandContext<ServerCommandSource> context) throws CommandSyntaxException {
ServerCommandSource source = context.getSource();

PlayerEntity player = source.getPlayer();
if (!CONFIG.allowSurvivalMode && !player.getAbilities().creativeMode) {
player.sendMessage(Text.literal("You are not allowed to use this command.").formatted(Formatting.RED));
return 1;
}

String input = StringArgumentType.getString(context, "path");

source.sendFeedback(() -> Text.literal("Getting image..."), false);
Expand Down Expand Up @@ -155,10 +173,16 @@ private CompletableFuture<BufferedImage> getImage(String input) {
});
}

private int createMap(CommandContext<ServerCommandSource> context) throws CommandSyntaxException {
private int createMap(CommandContext<ServerCommandSource> context) throws CommandSyntaxException {
ServerCommandSource source = context.getSource();

PlayerEntity player = source.getPlayer();

if (!CONFIG.allowSurvivalMode && !player.getAbilities().creativeMode) {
player.sendMessage(Text.literal("You are not allowed to use this command.").formatted(Formatting.RED));
return 1;
}

DitherMode mode;
String modeStr = StringArgumentType.getString(context, "mode");
try {
Expand All @@ -184,7 +208,19 @@ private int createMap(CommandContext<ServerCommandSource> context) throws Comman
height = IntegerArgumentType.getInteger(context, "height");
} catch (Throwable e) {
width = image.getWidth();
height = image.getHeight();
height = image.getHeight();
try {
int size = IntegerArgumentType.getInteger(context, "normalize");
size = size > 8 ? 8*128 : size*128;

if (width > height) {
height = height*size / width;
width = size;
} else {
width = width*size / height;
height = size;
}
} catch (Throwable e2) {}
}

int finalHeight = height;
Expand All @@ -193,18 +229,80 @@ private int createMap(CommandContext<ServerCommandSource> context) throws Comman

CompletableFuture.supplyAsync(() -> MapRenderer.render(image, mode, finalWidth, finalHeight)).thenAcceptAsync(mapImage -> {
var items = MapRenderer.toVanillaItems(mapImage, source.getWorld(), input);
giveToPlayer(player, items, input, finalWidth, finalHeight);
source.sendFeedback(() -> Text.literal("Done!"), false);
boolean useBundle = true;
try {
useBundle = BoolArgumentType.getBool(context, "bundle");
} catch (Throwable e2) {}

giveToPlayer(player, items, input, finalWidth, finalHeight, useBundle);
source.sendFeedback(() -> Text.literal("Done!"), false);
}, source.getServer());
return null;
}, source.getServer());

return 1;
}

public static void giveToPlayer(PlayerEntity player, List<ItemStack> items, String input, int width, int height) {
private static void removeItems(Item item, int count, Inventory inventory) {
int countRemains = count;
for(int j = 0; j < inventory.size(); ++j) {
ItemStack itemStack = inventory.getStack(j);
if (itemStack.getItem().equals(item)) {
int numberToRemove = Math.min(itemStack.getCount(), countRemains);
countRemains -= numberToRemove;
itemStack.decrement(numberToRemove);

if (countRemains == 0) break;
}
}
}

private static boolean containsItem(Item item, Inventory inventory) {
return inventory.containsAny((stack) -> {
return !stack.isEmpty() && item.equals(stack.getItem());
});

}

private static void giveItemStackToPlayer(ItemStack itemStack, PlayerEntity player) {
if (player.getInventory().getEmptySlot() == -1) {
player.dropStack(itemStack);
}
else {
player.giveItemStack(itemStack);
}
}

public static void giveToPlayer(PlayerEntity player, List<ItemStack> items, String input, int width, int height, Boolean useBundle) {
if (!player.getAbilities().creativeMode) {
PlayerInventory inventory = player.getInventory();
if (inventory.count(Items.MAP) < items.size()) {
player.sendMessage(Text.literal("You need to hold "+items.size()+" empty maps.").formatted(Formatting.RED));
return;
} else {
removeItems(Items.MAP, items.size(), inventory);
}

if (useBundle) {
if (!containsItem(Items.BUNDLE, inventory)) {
player.sendMessage(Text.literal("You need to hold an empty bundle").formatted(Formatting.RED));
return;
}
else {
removeItems(Items.BUNDLE, 1, inventory);
}
}
}

if (!useBundle) {
for (ItemStack item:items) {
giveItemStackToPlayer(item, player);
}
return;
}

if (items.size() == 1) {
player.giveItemStack(items.get(0));
giveItemStackToPlayer(items.get(0), player);
} else {
var bundle = new ItemStack(Items.BUNDLE);
var list = new NbtList();
Expand All @@ -222,7 +320,7 @@ public static void giveToPlayer(PlayerEntity player, List<ItemStack> items, Stri
bundle.getOrCreateSubNbt("display").put("Lore", lore);
bundle.setCustomName(Text.literal("Maps").formatted(Formatting.GOLD));

player.giveItemStack(bundle);
giveItemStackToPlayer(bundle, player);
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ public class Image2MapConfig {

public int minPermLevel = 2;

public boolean allowSurvivalMode = true;


public static Image2MapConfig loadOrCreateConfig() {
try {
Expand Down
39 changes: 38 additions & 1 deletion src/main/java/space/essem/image2map/gui/PreviewGui.java
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ public class PreviewGui extends MapGui {
private Image2Map.DitherMode ditherMode;
private int width;
private int height;
private boolean useBundle = true;
private boolean grid = true;
private CompletableFuture<CanvasImage> imageProcessing;

Expand Down Expand Up @@ -149,6 +150,18 @@ public void setSize(int width, int height) {
this.updateImage();
}

public void setSize(int size) {
int sourceWidth = this.sourceImage.getWidth();
int sourceHeight = this.sourceImage.getHeight();
size = size > 8 ? 8*128 : size*128;

if (sourceWidth > sourceHeight) {
setSize(size, sourceHeight*size / sourceWidth);
} else {
setSize(sourceWidth*size / sourceHeight, size);
}
}

public void setDitherMode(Image2Map.DitherMode ditherMode) {
this.ditherMode = ditherMode;
this.updateImage();
Expand All @@ -159,6 +172,10 @@ public void setDrawGrid(boolean grid) {
this.draw();
}

public void setUseBundle(boolean useBundle) {
this.useBundle = useBundle;
}

@Override
public void executeCommand(String command) {
try {
Expand Down Expand Up @@ -187,7 +204,7 @@ private static <T> RequiredArgumentBuilder<PreviewGui, T> argument(String name,
x.getSource().drawLoading();
Image2Map.giveToPlayer(x.getSource().player,
MapRenderer.toVanillaItems(x.getSource().image, x.getSource().player.getServerWorld(), x.getSource().source),
x.getSource().source, x.getSource().width, x.getSource().height);
x.getSource().source, x.getSource().width, x.getSource().height, x.getSource().useBundle);

x.getSource().close();
} else {
Expand Down Expand Up @@ -230,6 +247,26 @@ private static <T> RequiredArgumentBuilder<PreviewGui, T> argument(String name,
return 0;
})
);

COMMANDS.register(literal("bundle")
.then(argument("value", BoolArgumentType.bool()).executes(x -> {
x.getSource().setUseBundle(BoolArgumentType.getBool(x, "value"));
return 0;
}))
);

COMMANDS.register(literal("normalize")
.then(argument("value", IntegerArgumentType.integer(1)).executes(x -> {
x.getSource().setSize(IntegerArgumentType.getInteger(x, "value"));
return 0;
}))
.executes(x -> {
x.getSource().player.sendMessage(Text.literal("Source: " + x.getSource().sourceImage.getWidth() + " x " + x.getSource().sourceImage.getHeight()));
x.getSource().player.sendMessage(Text.literal("MapImage: " + x.getSource().width + " x " + x.getSource().height));
return 0;
})
);

}

}