Skip to content

Commit

Permalink
fix: some reworking of the reward table editor screen
Browse files Browse the repository at this point in the history
  • Loading branch information
desht committed Oct 15, 2024
1 parent 3ca185a commit 34ff28c
Show file tree
Hide file tree
Showing 14 changed files with 162 additions and 62 deletions.
7 changes: 7 additions & 0 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,13 @@ subprojects {

loom {
silentMojangMappingsLicense()

runs {
client {
vmArgs "-Xmx4G"
programArgs "--width", "1920", "--height", "1080"
}
}
}

dependencies {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,7 @@ protected ItemStack _insertItem(int slot, ItemStack stack, boolean simulate) {
return stack;
}

LootCrate crate = LootCrateItem.getCrate(stack);
LootCrate crate = LootCrateItem.getCrate(stack, false);
if (crate == null) {
return stack;
}
Expand Down Expand Up @@ -160,7 +160,7 @@ protected ItemStack _insertItem(int slot, ItemStack stack, boolean simulate) {
}

protected boolean _isItemValid(int slot, ItemStack stack) {
return slot == 0 && LootCrateItem.getCrate(stack) != null;
return slot == 0 && LootCrateItem.getCrate(stack, level.isClientSide) != null;
}

protected ItemStack _extractItem(int slot, int amount, boolean simulate) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,7 @@ public static BlockEntityRendererProvider<TaskScreenBlockEntity> taskScreenRende

private void registerItemColors(Minecraft minecraft) {
ColorHandlerRegistry.registerItemColors((stack, tintIndex) -> {
LootCrate crate = LootCrateItem.getCrate(stack);
LootCrate crate = LootCrateItem.getCrate(stack, true);
return crate == null ? 0xFFFFFFFF : (0xFF000000 | crate.getColor().rgb());
}, ModItems.LOOTCRATE.get());
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package dev.ftb.mods.ftbquests.client.gui;

import com.mojang.blaze3d.platform.InputConstants;
import dev.ftb.mods.ftblibrary.config.ConfigGroup;
import dev.ftb.mods.ftblibrary.config.DoubleConfig;
import dev.ftb.mods.ftblibrary.config.ui.EditConfigScreen;
Expand Down Expand Up @@ -100,6 +101,17 @@ protected void doAccept() {
parentScreen.run();
}

public boolean keyPressed(Key key) {
if (super.keyPressed(key)) {
return true;
} else if ((key.is(InputConstants.KEY_RETURN) || key.is(InputConstants.KEY_NUMPADENTER)) && key.modifiers.shift()) {
this.doAccept();
return true;
} else {
return false;
}
}

private class CustomTopPanel extends TopPanel {
private final RewardTableSettingsButton settingsButton;
private final AddWeightedRewardButton addButton;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
import dev.ftb.mods.ftblibrary.ui.input.MouseButton;
import dev.ftb.mods.ftblibrary.ui.misc.AbstractButtonListScreen;
import dev.ftb.mods.ftblibrary.util.TooltipList;
import dev.ftb.mods.ftbquests.FTBQuests;
import dev.ftb.mods.ftbquests.client.ClientQuestFile;
import dev.ftb.mods.ftbquests.client.gui.quests.QuestScreen;
import dev.ftb.mods.ftbquests.net.CreateObjectMessage;
Expand All @@ -25,24 +26,31 @@
import dev.ftb.mods.ftbquests.quest.reward.RandomReward;
import dev.ftb.mods.ftbquests.quest.translation.TranslationKey;
import dev.ftb.mods.ftbquests.registry.ModItems;
import it.unimi.dsi.fastutil.ints.IntOpenHashSet;
import it.unimi.dsi.fastutil.ints.IntSet;
import net.minecraft.ChatFormatting;
import net.minecraft.Util;
import net.minecraft.client.gui.GuiGraphics;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.network.chat.Component;
import net.minecraft.network.protocol.common.custom.CustomPacketPayload;
import net.minecraft.world.item.Items;
import org.apache.commons.lang3.mutable.MutableInt;
import org.jetbrains.annotations.NotNull;

import java.util.*;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.function.Function;
import java.util.stream.Collectors;

public class RewardTablesScreen extends AbstractButtonListScreen {
private final QuestScreen questScreen;
private final SimpleTextButton addButton;
private final List<RewardTable> rewardTablesCopy; // deep local copy of reward tables
private final IntSet editedIndexes = new IntOpenHashSet();
private final IntSet pendingDeleteIndexes = new IntOpenHashSet();
private boolean changed = false;
private final Set<RewardTable> editedTables = new HashSet<>();

public RewardTablesScreen(QuestScreen questScreen) {
super();
Expand Down Expand Up @@ -79,8 +87,12 @@ public void onClicked(MouseButton button) {

@Override
public void addButtons(Panel panel) {
rewardTablesCopy.stream().sorted()
.forEach(table -> panel.add(new RewardTableButton(panel, table)));
List<RewardTableButton> buttons = new ArrayList<>();
for (int i = 0; i < rewardTablesCopy.size(); i++) {
RewardTable table = rewardTablesCopy.get(i);
buttons.add(new RewardTableButton(panel, table, i));
}
panel.addAll(buttons.stream().sorted(Comparator.comparing(btn -> btn.table)).toList());
}

@Override
Expand Down Expand Up @@ -127,27 +139,46 @@ protected void doCancel() {

@Override
protected void doAccept() {
ClientQuestFile file = ClientQuestFile.INSTANCE;
Set<Long> toRemove = file.getRewardTables().stream().map(t -> t.id).collect(Collectors.toSet());

rewardTablesCopy.forEach(table -> {
if (table.getId() == 0L) {
// newly-created
CompoundTag extra = Util.make(new CompoundTag(), tag -> file.getTranslationManager().addInitialTranslation(
tag, file.getLocale(), TranslationKey.TITLE, table.getRawTitle())
);
NetworkManager.sendToServer(CreateObjectMessage.create(table, extra));
IntSet toCreate = new IntOpenHashSet();
for (int idx = 0; idx < rewardTablesCopy.size(); idx++) {
if (rewardTablesCopy.get(idx).getId() == 0L && !pendingDeleteIndexes.contains(idx)) {
toCreate.add(idx);
}
toRemove.remove(table.getId());
});
}
editedIndexes.removeAll(pendingDeleteIndexes);

toRemove.forEach(id -> NetworkManager.sendToServer(new DeleteObjectMessage(id)));
int nAdded = sendToServer(toCreate, RewardTablesScreen::makeCreationPacket, true);
int nEdited = sendToServer(editedIndexes, EditObjectMessage::forQuestObject, false);
int nDeleted = sendToServer(pendingDeleteIndexes, DeleteObjectMessage::forQuestObject, false);

editedTables.forEach(table -> NetworkManager.sendToServer(EditObjectMessage.forQuestObject(table)));
FTBQuests.LOGGER.debug("Sent {} new, {} edited, {} deleted reward tables to server", nAdded, nEdited, nDeleted);

questScreen.run();
}

private static CreateObjectMessage makeCreationPacket(RewardTable table) {
ClientQuestFile file = ClientQuestFile.INSTANCE;
CompoundTag extra = Util.make(new CompoundTag(), tag -> file.getTranslationManager().addInitialTranslation(
tag, file.getLocale(), TranslationKey.TITLE, table.getRawTitle())
);
return CreateObjectMessage.create(table, extra);
}

private <T extends CustomPacketPayload> int sendToServer(IntSet indexes, Function<RewardTable, T> func, boolean addNew) {
int sent = 0;
for (int idx : indexes) {
if (idx >= 0 && idx < rewardTablesCopy.size()) {
RewardTable table = rewardTablesCopy.get(idx);
if (addNew && table.id == 0 || !addNew && table.id != 0) {
// id == 0 means table is only locally added, no need to sync an edit/delete for it
NetworkManager.sendToServer(func.apply(table));
sent++;
}
}
}
return sent;
}

private class CustomTopPanel extends TopPanel {
@Override
public void addWidgets() {
Expand All @@ -169,11 +200,13 @@ public void draw(GuiGraphics graphics, Theme theme, int x, int y, int w, int h)

private class RewardTableButton extends SimpleTextButton {
private final RewardTable table;
private final int idx;

public RewardTableButton(Panel panel, RewardTable table) {
public RewardTableButton(Panel panel, RewardTable table, int idx) {
super(panel, table.getTitle(), table.getIcon());

this.table = table;
this.idx = idx;
setHeight(16);

if (this.table.getLootCrate() != null) {
Expand All @@ -199,7 +232,7 @@ public void onClicked(MouseButton button) {
List<ContextMenuItem> menu = List.of(
new ContextMenuItem(Component.translatable("ftbquests.gui.edit"), ItemIcon.getItemIcon(Items.FEATHER),
b -> editRewardTable()),
new ContextMenuItem(Component.translatable("gui.remove"), Icons.BIN,
new ContextMenuItem(Component.translatable(pendingDeleteIndexes.contains(idx) ? "ftbquests.gui.restore" : "gui.remove"), Icons.BIN,
b -> deleteRewardTable()),
new ContextMenuItem(getLootCrateText(), ItemIcon.getItemIcon(ModItems.LOOTCRATE.get()),
b -> toggleLootCrate())
Expand All @@ -214,25 +247,43 @@ public void drawBackground(GuiGraphics graphics, Theme theme, int x, int y, int
ItemIcon.getItemIcon(ModItems.LOOTCRATE.get()).draw(graphics, x + w - 26, y + 2, 12, 12);
Icons.BIN.draw(graphics, x + w - 13, y + 2, 12, 12);
}
if (pendingDeleteIndexes.contains(idx)) {
Color4I.RED.withAlpha(64).draw(graphics, x, y, w, h);
} else if (rewardTablesCopy.get(idx).getId() == 0) {
Color4I.GREEN.withAlpha(64).draw(graphics, x, y, w, h);
}
Color4I.GRAY.withAlpha(40).draw(graphics, x, y + h, w, 1);
}

@Override
public void draw(GuiGraphics graphics, Theme theme, int x, int y, int w, int h) {
super.draw(graphics, theme, x, y, w, h);

if (pendingDeleteIndexes.contains(idx)) {
Color4I.GRAY.draw(graphics, x + 20, y + h / 2, theme.getStringWidth(title), 1);
} else if (rewardTablesCopy.get(idx).getId() == 0) {
Icons.ADD.draw(graphics, x + 24 + theme.getStringWidth(title), y + 2, 12, 12);
}
}

private void editRewardTable() {
new EditRewardTableScreen(RewardTablesScreen.this, table, editedReward -> {
rewardTablesCopy.replaceAll(t -> t.getId() == editedReward.id ? editedReward : t);
rewardTablesCopy.set(idx, editedReward);
changed = true;
editedTables.add(editedReward);
editedIndexes.add(idx);
editedReward.clearCachedData();
refreshWidgets();
}).openGui();
}

private void deleteRewardTable() {
openYesNo(Component.translatable("delete_item", table.getTitle()), Component.empty(), () -> {
rewardTablesCopy.removeIf(t -> t == table);
changed = true;
refreshWidgets();
});
if (pendingDeleteIndexes.contains(idx)) {
pendingDeleteIndexes.remove(idx);
} else {
pendingDeleteIndexes.add(idx);
}
changed = true;
refreshWidgets();
}

private void toggleLootCrate() {
Expand All @@ -245,6 +296,7 @@ private void toggleLootCrate() {
}

changed = true;
editedIndexes.add(idx);
refreshWidgets();
}

Expand All @@ -253,7 +305,7 @@ public void addMouseOverText(TooltipList list) {
super.addMouseOverText(list);

if (getMouseX() > getX() + width - 13) {
list.add(Component.translatable("gui.remove"));
list.add(Component.translatable(pendingDeleteIndexes.contains(idx) ? "ftbquests.gui.restore" : "gui.remove"));
} else if (getMouseX() > getX() + width - 26) {
list.add(getLootCrateText());
} else {
Expand All @@ -269,7 +321,7 @@ public void addMouseOverText(TooltipList list) {

@NotNull
private Component getLootCrateText() {
return Component.translatable("ftbquests.reward_table." +
return Component.translatable("ftbquests.reward_table." +
(table.getLootCrate() != null ? "disable_loot_crate" : "enable_loot_crate"));
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
import dev.ftb.mods.ftbquests.quest.task.StructureTask;
import dev.ftb.mods.ftbquests.quest.theme.ThemeLoader;
import dev.ftb.mods.ftbquests.quest.theme.property.ThemeProperties;
import net.minecraft.ChatFormatting;
import net.minecraft.client.Minecraft;
import net.minecraft.network.chat.ClickEvent;
import net.minecraft.network.chat.Component;
Expand Down Expand Up @@ -118,8 +119,8 @@ public void onClicked(MouseButton button) {
b -> ChangeProgressMessage.sendToServer(questScreen.file.selfTeamData, questScreen.file, progressChange -> progressChange.setReset(false)))
.setYesNoText(Component.translatable("ftbquests.gui.complete_instantly_q")));

contextMenu.add(new ContextMenuItem(Component.translatable("ftbquests.reward_tables"), ThemeProperties.REWARD_TABLE_ICON.get(),
b -> new RewardTablesScreen(questScreen).openGui()));
contextMenu.add(new TooltipContextMenuItem(Component.translatable("ftbquests.reward_tables"), ThemeProperties.REWARD_TABLE_ICON.get(),
b -> new RewardTablesScreen(questScreen).openGui(), Component.literal("[Ctrl + T]").withStyle(ChatFormatting.DARK_GRAY)));
contextMenu.add(new ContextMenuItem(Component.translatable("ftbquests.gui.save_on_server"), ThemeProperties.SAVE_ICON.get(),
b -> NetworkManager.sendToServer(ForceSaveMessage.INSTANCE)));
contextMenu.add(new ContextMenuItem(Component.translatable("ftbquests.gui.save_as_file"), ThemeProperties.DOWNLOAD_ICON.get(),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
import dev.ftb.mods.ftbquests.client.FTBQuestsClient;
import dev.ftb.mods.ftbquests.client.gui.CustomToast;
import dev.ftb.mods.ftbquests.client.gui.FTBQuestsTheme;
import dev.ftb.mods.ftbquests.client.gui.RewardTablesScreen;
import dev.ftb.mods.ftbquests.client.gui.SelectQuestObjectScreen;
import dev.ftb.mods.ftbquests.net.*;
import dev.ftb.mods.ftbquests.quest.*;
Expand Down Expand Up @@ -266,11 +267,11 @@ public void addObjectMenuItems(List<ContextMenuItem> contextMenu, Runnable gui,
};
if (selectedChapter != null) {
if (selectedChapter.isAutofocus(object.id)) {
contextMenu.add(new ContextMenuItem(Component.translatable("ftbquest.gui.clear_autofocused"),
contextMenu.add(new ContextMenuItem(Component.translatable("ftbquests.gui.clear_autofocused"),
Icons.MARKER,
b -> setAutofocusedId(0L)));
} else if (object instanceof Quest || object instanceof QuestLink) {
contextMenu.add(new ContextMenuItem(Component.translatable("ftbquest.gui.set_autofocused"),
contextMenu.add(new ContextMenuItem(Component.translatable("ftbquests.gui.set_autofocused"),
Icons.MARKER,
b -> setAutofocusedId(object.id)));
}
Expand Down Expand Up @@ -538,6 +539,12 @@ public boolean keyPressed(Key key) {
return pasteSelectedQuest(!key.modifiers.shift());
}
}
case GLFW.GLFW_KEY_T -> {
if (key.modifiers.control()) {
new RewardTablesScreen(this).openGui();
return true;
}
}
}
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package dev.ftb.mods.ftbquests.item;

import dev.architectury.platform.Platform;
import dev.ftb.mods.ftbquests.FTBQuests;
import dev.ftb.mods.ftbquests.client.ClientQuestFile;
import dev.ftb.mods.ftbquests.client.gui.RewardNotificationsScreen;
Expand Down Expand Up @@ -42,16 +43,21 @@ public LootCrateItem() {
}

@Nullable
public static LootCrate getCrate(ItemStack stack) {
public static LootCrate getCrate(ItemStack stack, boolean isClientSide) {
return FTBQuests.getComponent(stack, ModDataComponents.LOOT_CRATE)
.map(type -> LootCrate.LOOT_CRATES.get(type))
.map(type -> LootCrate.getLootCrates(isClientSide).get(type))
.orElse(null);
}

@Nullable
public static LootCrate getCrate(ItemStack stack) {
return getCrate(stack, Platform.getEnv() == EnvType.CLIENT);
}

@Override
public InteractionResultHolder<ItemStack> use(Level world, Player player, InteractionHand hand) {
ItemStack stack = player.getItemInHand(hand);
LootCrate crate = getCrate(stack);
LootCrate crate = getCrate(stack, player.level().isClientSide);

if (crate == null) {
return new InteractionResultHolder<>(InteractionResult.FAIL, stack);
Expand Down Expand Up @@ -87,7 +93,7 @@ public InteractionResultHolder<ItemStack> use(Level world, Player player, Intera

@Override
public boolean isFoil(ItemStack stack) {
LootCrate crate = getCrate(stack);
LootCrate crate = getCrate(stack, true);
return crate != null && crate.isGlow();
}

Expand All @@ -104,7 +110,7 @@ public void appendHoverText(ItemStack stack, TooltipContext context, List<Compon
return;
}

LootCrate crate = getCrate(stack);
LootCrate crate = getCrate(stack, true);
if (crate != null) {
if (crate.getItemName().isEmpty()) {
// if crate doesn't have an item name, show the reward table's name in the tooltip
Expand Down
Loading

0 comments on commit 34ff28c

Please sign in to comment.