Skip to content

Commit

Permalink
initial work
Browse files Browse the repository at this point in the history
  • Loading branch information
ix0rai committed Jun 6, 2024
1 parent 79b3726 commit 1a40700
Show file tree
Hide file tree
Showing 9 changed files with 210 additions and 74 deletions.
8 changes: 4 additions & 4 deletions src/main/java/io/ix0rai/rainglow/Rainglow.java
Original file line number Diff line number Diff line change
Expand Up @@ -57,13 +57,13 @@ public static Identifier id(String id) {
return new Identifier(MOD_ID, id);
}

public static String generateRandomColourId(World world, RandomGenerator random) {
var colours = MODE_CONFIG.getMode(world).getColours();
public static String generateRandomColourId(World world, RandomGenerator random, RainglowEntity entity) {
var colours = MODE_CONFIG.getMode(world, entity).getColours();
return colours.get(random.nextInt(colours.size())).getId();
}

public static boolean colourUnloaded(World world, RainglowEntity entityType, String colour) {
var colours = MODE_CONFIG.getMode(world).getColours();
var colours = MODE_CONFIG.getMode(world, entityType).getColours();
return !colours.contains(RainglowColour.get(colour)) && !colour.equals(entityType.getDefaultColour().getId());
}

Expand All @@ -85,7 +85,7 @@ public static RainglowColour getColour(World world, RainglowEntity entityType, D
String colour = tracker.get(entityType.getTrackedData());
if (colourUnloaded(world, entityType, colour)) {
// Use last generated colour if not null else generate a new colour
tracker.set(entityType.getTrackedData(), generateRandomColourId(world, random));
tracker.set(entityType.getTrackedData(), generateRandomColourId(world, random, entityType));
colour = tracker.get(entityType.getTrackedData());
}

Expand Down
120 changes: 102 additions & 18 deletions src/main/java/io/ix0rai/rainglow/config/PerWorldConfig.java
Original file line number Diff line number Diff line change
Expand Up @@ -8,41 +8,91 @@
import folk.sisby.kaleido.lib.quiltconfig.api.values.TrackedValue;
import folk.sisby.kaleido.lib.quiltconfig.api.values.ValueMap;
import io.ix0rai.rainglow.Rainglow;
import io.ix0rai.rainglow.data.RainglowEntity;
import io.ix0rai.rainglow.data.RainglowMode;
import io.ix0rai.rainglow.mixin.MinecraftServerAccessor;
import net.minecraft.client.MinecraftClient;
import net.minecraft.server.MinecraftServer;
import net.minecraft.server.dedicated.DedicatedServer;
import net.minecraft.world.World;
import org.jetbrains.annotations.Nullable;

import java.nio.file.Files;
import java.nio.file.Path;
import java.util.HashMap;
import java.util.Map;
import java.util.function.Consumer;

@SerializedNameConvention(NamingSchemes.SNAKE_CASE)
public class PerWorldConfig extends ReflectiveConfig {
@Comment("The mode used for each non-local world.")
@Comment("Note that for singleplayer worlds, the mode is saved in the world folder in the file \"config/rainglow.json\".")
public final TrackedValue<ValueMap<String>> modesByWorld = this.map("").build();
public final TrackedValue<ValueMap<ValueMap<String>>> modesByWorld = this.map(ValueMap.builder("").build()).build();

public RainglowMode getMode(World world) {
// todo hot garbage
public Map<RainglowEntity, RainglowMode> getModes(World world) {
var saveName = getSaveName(world);
Either<Map<String, String>, ValueMap<String>> modes = null;

if (saveName.right().isPresent()) {
modes = Either.right(modesByWorld.value().get(saveName.right().get()));
} else if (saveName.left().isPresent()) {
Path path = getJsonPath(saveName.left().get());
if (Files.exists(path)) {
try {
var data = readJson(path);
modes = Either.left(data.entities);
} catch (Exception e) {
Rainglow.LOGGER.error("Failed to load Rainglow config for world " + saveName.left().get(), e);
}
} else {
save(saveName.left().get(), RainglowMode.get(Rainglow.CONFIG.defaultMode.value()), null);
}
}

if (modes == null) {
var map = new HashMap<RainglowEntity, RainglowMode>();
for (RainglowEntity entity : RainglowEntity.values()) {
map.put(entity, RainglowMode.get(Rainglow.CONFIG.defaultMode.value()));
}

return map;
} else {
if (modes.left().isPresent()) {
var map = new HashMap<RainglowEntity, RainglowMode>();
for (RainglowEntity entity : RainglowEntity.values()) {
map.put(entity, RainglowMode.get(modes.left().get().get(entity.getId())));
}

return map;
} else {
var map = new HashMap<RainglowEntity, RainglowMode>();
for (RainglowEntity entity : RainglowEntity.values()) {
map.put(entity, RainglowMode.get(modes.right().get().get(entity.getId())));
}

return map;
}
}
}

public RainglowMode getMode(World world, RainglowEntity entity) {
var saveName = getSaveName(world);
String mode = null;

if (saveName.right().isPresent()) {
mode = modesByWorld.value().get(saveName.right().get());
mode = modesByWorld.value().get(entity.getId()).get(saveName.right().get());
} else if (saveName.left().isPresent()) {
Path path = getJsonPath(saveName.left().get());
if (Files.exists(path)) {
try {
var data = Rainglow.GSON.fromJson(Files.readString(path), RainglowJson.class);
if (data != null) {
mode = data.mode;
}
var data = readJson(path);
mode = data.entities.get(entity.getId());
} catch (Exception e) {
Rainglow.LOGGER.error("Failed to load Rainglow config for world " + saveName.left().get(), e);
}
} else {
save(saveName.left().get(), RainglowMode.get(Rainglow.CONFIG.defaultMode.value()));
save(saveName.left().get(), RainglowMode.get(Rainglow.CONFIG.defaultMode.value()), entity);
}
}

Expand All @@ -53,18 +103,47 @@ public RainglowMode getMode(World world) {
}
}

public void setMode(World world, RainglowMode mode) {
var saveName = getSaveName(world);
if (saveName.right().isPresent()) {
modesByWorld.value().put(saveName.right().get(), mode.getId());
} else if (saveName.left().isPresent()) {
save(saveName.left().get(), mode);
private static RainglowJson readJson(Path path) {
if (Files.exists(path)) {
try {
return Rainglow.GSON.fromJson(Files.readString(path), RainglowJson.class);
} catch (Exception e) {
Rainglow.LOGGER.error("Failed to load Rainglow config for world " + path, e);
}
}

return new RainglowJson(RainglowMode.get(Rainglow.CONFIG.defaultMode.value()));
}

public void setMode(World world, RainglowMode mode, @Nullable RainglowEntity entity) {
Consumer<String> setter = (id) -> {
var saveName = getSaveName(world);
if (saveName.right().isPresent()) {
modesByWorld.value().get(id).put(saveName.right().get(), mode.getId());
} else if (saveName.left().isPresent()) {
save(saveName.left().get(), mode, entity);
}
};

if (entity != null) {
setter.accept(entity.getId());
} else {
for (RainglowEntity e : RainglowEntity.values()) {
setter.accept(e.getId());
}
}
}

private static void save(Path worldPath, RainglowMode mode) {
private static void save(Path worldPath, RainglowMode mode, @Nullable RainglowEntity entity) {
Path path = getJsonPath(worldPath);
var data = new RainglowJson(mode.getId());
RainglowJson data;

if (Files.exists(path) && entity != null) {
data = readJson(path);
data.entities.put(entity.getId(), mode.getId());
} else {
data = new RainglowJson(mode);
}

try {
Path configPath = getConfigFolderPath(worldPath);
Expand Down Expand Up @@ -108,7 +187,12 @@ private static Path getWorldPath(MinecraftServer server) {
return ((MinecraftServerAccessor) server).getSession().method_54543().path();
}

private record RainglowJson(String mode) {

private record RainglowJson(Map<String, String> entities) {
public RainglowJson(RainglowMode mode) {
this(new HashMap<>());
for (RainglowEntity entity : RainglowEntity.values()) {
this.entities.put(entity.getId(), mode.getId());
}
}
}
}
76 changes: 54 additions & 22 deletions src/main/java/io/ix0rai/rainglow/config/RainglowConfigScreen.java
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
import net.minecraft.client.MinecraftClient;
import net.minecraft.client.gui.screen.Screen;
import net.minecraft.client.gui.tooltip.Tooltip;
import net.minecraft.client.gui.widget.ClickableWidget;
import net.minecraft.client.gui.widget.button.ButtonWidget;
import net.minecraft.client.gui.widget.button.CyclingButtonWidget;
import net.minecraft.client.gui.widget.layout.GridWidget;
Expand All @@ -16,6 +17,7 @@
import net.minecraft.client.gui.widget.text.TextWidget;
import net.minecraft.client.option.Option;
import net.minecraft.text.CommonTexts;
import net.minecraft.text.MutableText;
import net.minecraft.text.Style;
import net.minecraft.text.Text;
import net.minecraft.util.Language;
Expand All @@ -42,7 +44,14 @@ public class RainglowConfigScreen extends Screen implements ScreenWithUnsavedWar
public RainglowConfigScreen(@Nullable Screen parent) {
super(TITLE);
this.parent = parent;
this.mode = getMode();
if (MinecraftClient.getInstance().world != null) {
var modes = Rainglow.MODE_CONFIG.getModes(MinecraftClient.getInstance().world);
// if all modes are the same, set the mode to that mode, otherwise set it to null
this.mode = modes.entrySet().stream().allMatch(entry -> entry.getValue().equals(modes.get(RainglowEntity.GLOW_SQUID))) ? modes.get(RainglowEntity.GLOW_SQUID) : null;
} else {
this.mode = RainglowMode.get(Rainglow.CONFIG.defaultMode.getRealValue());
}

this.saveButton = ButtonWidget.builder(Rainglow.translatableText("config.save"), button -> this.save()).build();
this.saveButton.active = false;
}
Expand All @@ -51,15 +60,15 @@ private void setMode(RainglowMode mode) {
if (MinecraftClient.getInstance().world == null) {
Rainglow.CONFIG.defaultMode.setValue(mode.getId());
} else {
Rainglow.MODE_CONFIG.setMode(MinecraftClient.getInstance().world, mode);
Rainglow.MODE_CONFIG.setMode(MinecraftClient.getInstance().world, mode, null);
}
}

private RainglowMode getMode() {
private RainglowMode getMode(RainglowEntity entity) {
if (MinecraftClient.getInstance().world == null) {
return RainglowMode.get(Rainglow.CONFIG.defaultMode.getRealValue());
} else {
return Rainglow.MODE_CONFIG.getMode(MinecraftClient.getInstance().world);
return Rainglow.MODE_CONFIG.getMode(MinecraftClient.getInstance().world, entity);
}
}

Expand All @@ -81,8 +90,14 @@ public void init() {
if (!this.isConfirming) {
// header
headerLayout.add(new TextWidget(TITLE, this.textRenderer), settings -> settings.alignHorizontallyCenter().alignVerticallyTop().setPadding(12));
headerLayout.add(createModeButton(), LayoutSettings::alignVerticallyBottom);
headerLayout.add(getInfoText(), LayoutSettings::alignHorizontallyCenter);
LinearLayoutWidget modeLayout = headerLayout.add(LinearLayoutWidget.createHorizontal().setSpacing(8), LayoutSettings::alignVerticallyBottom);
modeLayout.add(createModeButton(), LayoutSettings::alignVerticallyBottom);
// todo link to page with per-entity mode editing
modeLayout.add(ButtonWidget.builder(Text.literal("grind"), button -> {
//this.mode = RainglowMode.get("grind");
// this.saveButton.active = true;
}).width(100).build(), LayoutSettings::alignVerticallyBottom);
headerLayout.add(getInfoText(), settings -> settings.alignHorizontallyCenter().alignVerticallyBottom().setBottomPadding(1));

// contents
LinearLayoutWidget contentLayout = LinearLayoutWidget.createVertical();
Expand Down Expand Up @@ -138,22 +153,39 @@ private DeferredSaveOption<Integer> createColourRaritySlider(RainglowEntity enti
));
}

public CyclingButtonWidget<RainglowMode> createModeButton() {
return CyclingButtonWidget.builder(RainglowMode::getText)
.values(RainglowMode.values())
.initially(this.mode)
.tooltip(this::createColourListLabel)
.build(
0,
0,
308,
20,
Rainglow.translatableText("config.mode"),
(cyclingButtonWidget, mode) -> {
this.saveButton.active = true;
RainglowConfigScreen.this.mode = mode;
}
);
public ClickableWidget createModeButton() {
if (mode != null) {
return CyclingButtonWidget.builder(RainglowMode::getText)
.values(RainglowMode.values())
.initially(this.mode)
.tooltip(this::createColourListLabel)
.build(
0,
0,
200,
20,
Rainglow.translatableText("config.mode"),
(cyclingButtonWidget, mode) -> {
this.saveButton.active = true;
this.mode = mode;
}
);
} else {
return ButtonWidget.builder(Text.literal("Mode: Mixed"), button -> {
this.mode = RainglowMode.get(Rainglow.CONFIG.defaultMode.getRealValue());
this.saveButton.active = true;
this.clearAndInit();
}).tooltip(createTooltip()).width(200).build();
}
}

private Tooltip createTooltip() {
MutableText text = Text.empty().append("Modes:");
for (RainglowEntity entity : RainglowEntity.values()) {
text.append("\n").append(Text.translatable("entity.minecraft." + entity.getId())).append(": ").append(this.getMode(entity).getText());
}

return Tooltip.create(text);
}

private void save() {
Expand Down
42 changes: 24 additions & 18 deletions src/main/java/io/ix0rai/rainglow/data/RainglowColour.java
Original file line number Diff line number Diff line change
Expand Up @@ -12,38 +12,40 @@
import java.util.Map;

public enum RainglowColour {
BLACK("black", new RGB(0.0F, 0.0F, 0.0F), new RGB(0.0F, 0.0F, 0.0F), new RGB(0, 0, 0), Items.BLACK_DYE),
BLUE("blue", new RGB(0.6F, 1.0F, 0.8F), new RGB(0.08F, 0.4F, 0.4F), new RGB(204, 31, 102), Items.BLUE_DYE),
BROWN("brown", new RGB(1.0F, 0.5F, 0.0F), new RGB(1.0F, 0.4F, 0.4F), new RGB(149, 59, 35), Items.BROWN_DYE),
CYAN("cyan", new RGB(0.6F, 1.0F, 0.8F), new RGB(0.08F, 0.4F, 0.4F), new RGB(204, 31, 102), Items.CYAN_DYE),
GRAY("gray", new RGB(0.6F, 0.6F, 0.6F), new RGB(0.4F, 0.4F, 0.4F), new RGB(100, 100, 100), Items.GRAY_DYE),
GREEN("green", new RGB(0.6F, 1.0F, 0.8F), new RGB(0.08F, 1.0F, 0.4F), new RGB(0, 200, 0), Items.GREEN_DYE),
INDIGO("indigo", new RGB(0.6F, 1.0F, 0.8F), new RGB(0.08F, 0.4F, 1.0F), new RGB(0, 0, 200), Items.AMETHYST_SHARD),
LIGHT_BLUE("light_blue", new RGB(0.6F, 1.0F, 0.8F), new RGB(0.08F, 0.4F, 0.4F), new RGB(204, 31, 102), Items.LIGHT_BLUE_DYE),
LIGHT_GRAY("light_gray", new RGB(0.6F, 0.6F, 0.6F), new RGB(0.4F, 0.4F, 0.4F), new RGB(100, 100, 100), Items.LIGHT_GRAY_DYE),
LIME("lime", new RGB(0.6F, 1.0F, 0.8F), new RGB(0.08F, 1.0F, 0.4F), new RGB(0, 200, 0), Items.LIME_DYE),
MAGENTA("magenta", new RGB(0.3F, 0F, 0.25F), new RGB(0.5F, 0.05F, 0.5F), new RGB(200, 0, 100), Items.MAGENTA_DYE),
ORANGE("orange", new RGB(1.0F, 0.5F, 0.0F), new RGB(1.0F, 0.4F, 0.4F), new RGB(200, 0, 0), Items.ORANGE_DYE),
PINK("pink", new RGB(0.6F, 0F, 0.5F), new RGB(1.0F, 0.1F, 1.0F), new RGB(200, 0, 0), Items.PINK_DYE),
PURPLE("purple", new RGB(0.3F, 0F, 0.25F), new RGB(0.5F, 0.05F, 0.5F), new RGB(200, 0, 100), Items.PURPLE_DYE),
RED("red", new RGB(1.0F, 1.0F, 0.8F), new RGB(1.0F, 0.4F, 0.4F), new RGB(200, 0, 0), Items.RED_DYE),
WHITE("white", new RGB(1.0F, 1.0F, 1.0F), new RGB(1.0F, 1.0F, 1.0F), new RGB(200, 200, 200), Items.WHITE_DYE),
YELLOW("yellow", new RGB(1.0F, 1.0F, 0.8F), new RGB(1.0F, 1.0F, 0.4F), new RGB(200, 0, 0), Items.YELLOW_DYE);
BLACK("black", 0x000000, new RGB(0.0F, 0.0F, 0.0F), new RGB(0.0F, 0.0F, 0.0F), new RGB(0, 0, 0), Items.BLACK_DYE),
BLUE("blue", 0x0000FF, new RGB(0.6F, 1.0F, 0.8F), new RGB(0.08F, 0.4F, 0.4F), new RGB(204, 31, 102), Items.BLUE_DYE),
BROWN("brown", 0x964B00, new RGB(1.0F, 0.5F, 0.0F), new RGB(1.0F, 0.4F, 0.4F), new RGB(149, 59, 35), Items.BROWN_DYE),
CYAN("cyan", 0x00FFFF, new RGB(0.6F, 1.0F, 0.8F), new RGB(0.08F, 0.4F, 0.4F), new RGB(204, 31, 102), Items.CYAN_DYE),
GRAY("gray", 0x808080, new RGB(0.6F, 0.6F, 0.6F), new RGB(0.4F, 0.4F, 0.4F), new RGB(100, 100, 100), Items.GRAY_DYE),
GREEN("green", 0x0A5C36, new RGB(0.6F, 1.0F, 0.8F), new RGB(0.08F, 1.0F, 0.4F), new RGB(0, 200, 0), Items.GREEN_DYE),
INDIGO("indigo", 0x4B0082, new RGB(0.6F, 1.0F, 0.8F), new RGB(0.08F, 0.4F, 1.0F), new RGB(0, 0, 200), Items.AMETHYST_SHARD),
LIGHT_BLUE("light_blue", 0xADD8E6, new RGB(0.6F, 1.0F, 0.8F), new RGB(0.08F, 0.4F, 0.4F), new RGB(204, 31, 102), Items.LIGHT_BLUE_DYE),
LIGHT_GRAY("light_gray", 0xd3d3d3, new RGB(0.6F, 0.6F, 0.6F), new RGB(0.4F, 0.4F, 0.4F), new RGB(100, 100, 100), Items.LIGHT_GRAY_DYE),
LIME("lime", 0x32CD32, new RGB(0.6F, 1.0F, 0.8F), new RGB(0.08F, 1.0F, 0.4F), new RGB(0, 200, 0), Items.LIME_DYE),
MAGENTA("magenta", 0xFF00FF, new RGB(0.3F, 0F, 0.25F), new RGB(0.5F, 0.05F, 0.5F), new RGB(200, 0, 100), Items.MAGENTA_DYE),
ORANGE("orange", 0xFFA500, new RGB(1.0F, 0.5F, 0.0F), new RGB(1.0F, 0.4F, 0.4F), new RGB(200, 0, 0), Items.ORANGE_DYE),
PINK("pink", 0xFFC0CB, new RGB(0.6F, 0F, 0.5F), new RGB(1.0F, 0.1F, 1.0F), new RGB(200, 0, 0), Items.PINK_DYE),
PURPLE("purple", 0x800080, new RGB(0.3F, 0F, 0.25F), new RGB(0.5F, 0.05F, 0.5F), new RGB(200, 0, 100), Items.PURPLE_DYE),
RED("red", 0xFF0000, new RGB(1.0F, 1.0F, 0.8F), new RGB(1.0F, 0.4F, 0.4F), new RGB(200, 0, 0), Items.RED_DYE),
WHITE("white", 0xFFFFFF, new RGB(1.0F, 1.0F, 1.0F), new RGB(1.0F, 1.0F, 1.0F), new RGB(200, 200, 200), Items.WHITE_DYE),
YELLOW("yellow", 0xFFFF00, new RGB(1.0F, 1.0F, 0.8F), new RGB(1.0F, 1.0F, 0.4F), new RGB(200, 0, 0), Items.YELLOW_DYE);

private static final HashMap<String, RainglowColour> BY_ID = new HashMap<>();
static {
Arrays.stream(values()).forEach(mode -> BY_ID.put(mode.getId(), mode));
}

private final String id;
private final int hex;
private final Map<RainglowEntity, Identifier> textures;
private final RGB passiveParticleRgb;
private final RGB altPassiveParticleRgb;
private final RGB inkRgb;
private final Item item;

RainglowColour(String id, RGB passiveParticleRgb, RGB altPassiveParticleRgb, RGB inkRgb, Item item) {
RainglowColour(String id, int hex, RGB passiveParticleRgb, RGB altPassiveParticleRgb, RGB inkRgb, Item item) {
this.id = id;
this.hex = hex;
this.textures = new HashMap<>();
this.passiveParticleRgb = passiveParticleRgb;
this.altPassiveParticleRgb = altPassiveParticleRgb;
Expand Down Expand Up @@ -79,6 +81,10 @@ public String getId() {
return this.id;
}

public int getHex() {
return this.hex;
}

public RGB getPassiveParticleRgb() {
return this.passiveParticleRgb;
}
Expand Down
2 changes: 1 addition & 1 deletion src/main/java/io/ix0rai/rainglow/data/RainglowEntity.java
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ public RainglowColour readNbt(World world, NbtCompound nbt, RandomGenerator rand
String colour = nbt.getString(Rainglow.CUSTOM_NBT_KEY);

if (Rainglow.colourUnloaded(world, this, colour)) {
colour = Rainglow.generateRandomColourId(world, random);
colour = Rainglow.generateRandomColourId(world, random, this);
}

return RainglowColour.get(colour);
Expand Down
Loading

0 comments on commit 1a40700

Please sign in to comment.