Skip to content

Commit

Permalink
修复tip渲染的一些问题
Browse files Browse the repository at this point in the history
  • Loading branch information
goumo committed Dec 16, 2024
1 parent 8e87c4c commit 7c17994
Show file tree
Hide file tree
Showing 11 changed files with 169 additions and 122 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@
import net.minecraft.world.item.ArmorItem.Type;
import net.minecraft.world.item.*;
import net.minecraft.world.item.Item.Properties;
import net.minecraft.world.item.Items;
import net.minecraftforge.common.ForgeSpawnEggItem;
import net.minecraftforge.registries.DeferredRegister;
import net.minecraftforge.registries.ForgeRegistries;
Expand Down
9 changes: 4 additions & 5 deletions src/main/java/com/teammoeg/frostedheart/content/tips/Tip.java
Original file line number Diff line number Diff line change
Expand Up @@ -318,16 +318,16 @@ public Builder fromJson(JsonObject json) {
if (json.has("id")) {
this.id = json.get("id").getAsString();
} else {
error(ErrorType.OTHER, Lang.str("This tip has no id"));
error(ErrorType.LOAD, Lang.str("This tip cannot be loaded because there is no id in its file"));
id = "exception";
return this;
}
if (json.has("image")) {
Optional.ofNullable(ResourceLocation.tryParse(json.get("image").getAsString())).ifPresentOrElse(this::image, () -> error(ErrorType.OTHER, Lang.str("Invalid ResourceLocation")));
ResourceLocation image = ResourceLocation.tryParse(json.get("image").getAsString());
if (image != null) {
this.image = image;
} else {
error(ErrorType.OTHER, Lang.str("Invalid ResourceLocation"));
error(ErrorType.LOAD, Lang.str("The image ResourceLocation is invalid"));
return this;
}
}
Expand All @@ -350,7 +350,7 @@ private int tryGetColorOrElse(JsonObject json, String name, int defColor) {
try {
return Integer.parseUnsignedInt(json.get(name).getAsString(), 16);
} catch (NumberFormatException e) {
error(ErrorType.OTHER, e);
error(ErrorType.LOAD, e, Lang.str("'" + name + "' is not a valid hexadecimal number"));
return defColor;
}
}
Expand Down Expand Up @@ -385,7 +385,6 @@ public enum ErrorType {
SAVE("save"),
EMPTY("empty"),
INVALID("invalid"),
INVALID_IMAGE("invalid_image"),
NOT_EXISTS("not_exists");

final String key;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,7 @@ public void general(Tip tip) {
if (tip.isOnceOnly() && manager.state.isUnlocked(tip)) return;

// 渲染队列已有此 tip 时返回
for (Tip queue : TipRenderer.renderQueue) {
for (Tip queue : TipRenderer.TIP_QUEUE) {
if (queue.getId().equals(tip.getId())) return;
}

Expand All @@ -148,9 +148,9 @@ public void general(Tip tip) {

if (tip.isPin()) {
TipRenderer.removeCurrent();
TipRenderer.renderQueue.add(0, tip);
TipRenderer.TIP_QUEUE.add(0, tip);
} else {
TipRenderer.renderQueue.add(tip);
TipRenderer.TIP_QUEUE.add(tip);
}
}

Expand All @@ -167,23 +167,23 @@ public void force(String id) {
public void force(Tip tip) {
if (tip.isPin()) {
TipRenderer.removeCurrent();
TipRenderer.renderQueue.add(0, tip);
TipRenderer.TIP_QUEUE.add(0, tip);
} else {
TipRenderer.renderQueue.add(tip);
TipRenderer.TIP_QUEUE.add(tip);
}
}

/**
* 使 tip 永久显示,即 {@code alwaysVisible = true}
*/
public void alwaysVisible(Tip tip) {
var list = TipRenderer.renderQueue;
var list = TipRenderer.TIP_QUEUE;
if (list.size() <= 1 || list.get(0) == tip) return;
for (int i = 0; i < list.size(); i++) {
Tip t = list.get(i);
if (t == tip) {
Tip clone = Tip.builder("").copy(t).alwaysVisible(true).build();
TipRenderer.renderQueue.set(i, clone);
TipRenderer.TIP_QUEUE.set(i, clone);
return;
}
}
Expand All @@ -193,7 +193,7 @@ public void alwaysVisible(Tip tip) {
* 置顶 tip
*/
public void pin(String id) {
var list = TipRenderer.renderQueue;
var list = TipRenderer.TIP_QUEUE;
if (list.size() <= 1 || list.get(0).getId().equals(id)) return;
Iterator<Tip> iterator = list.iterator();
while (iterator.hasNext()) {
Expand All @@ -217,7 +217,7 @@ public void removeCurrent() {
* 清除 tip 队列
*/
public void clearRenderQueue() {
TipRenderer.renderQueue.clear();
TipRenderer.TIP_QUEUE.clear();
TipRenderer.removeCurrent();
}
}
Expand All @@ -244,7 +244,7 @@ protected void loadFromFile() {
// 文件存在但是无法正确读取
if (TIP_STATE_FILE.exists()) {
String message = "The file '" + TIP_STATE_FILE + "' already exists but cannot be read correctly, it may be corrupted";
manager.displayException(Tip.ErrorType.OTHER, new Exception(message));
manager.displayException(Tip.ErrorType.LOAD, new Exception(message));
LOGGER.warn(message);
}
return;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,11 @@
import com.teammoeg.frostedheart.content.tips.client.gui.widget.TipWidget;
import com.teammoeg.frostedheart.infrastructure.config.FHConfig;
import com.teammoeg.frostedheart.util.client.ClientUtils;
import com.teammoeg.frostedheart.util.client.FHColorHelper;
import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.components.EditBox;
import net.minecraft.client.gui.components.events.GuiEventListener;
import net.minecraft.client.gui.screens.ChatScreen;
import net.minecraft.client.gui.screens.Screen;
import net.minecraft.client.gui.screens.inventory.CommandBlockEditScreen;
import net.minecraftforge.api.distmarker.Dist;
Expand All @@ -18,47 +22,69 @@

@Mod.EventBusSubscriber(modid = FHMain.MODID, bus = Mod.EventBusSubscriber.Bus.FORGE, value = Dist.CLIENT)
public class TipRenderer {
public static final List<Tip> renderQueue = new ArrayList<>();

/**
* TipWidget实例
*/
public static final TipWidget TIP_WIDGET = new TipWidget();
// 不在GUI中渲染
public static final List<Class<? extends Screen>> GUI_BLACKLIST = new ArrayList<>();
/**
* tip渲染队列
*/
public static final List<Tip> TIP_QUEUE = new ArrayList<>();
/**
* screen黑名单
*/
public static final List<Class<? extends Screen>> SCREEN_BLACKLIST = new ArrayList<>();
static {
GUI_BLACKLIST.add(CommandBlockEditScreen.class);
SCREEN_BLACKLIST.add(CommandBlockEditScreen.class);
}

/**
* @return 是否正在渲染tip
*/
public static boolean isTipRendering() {
return TIP_WIDGET.getState() != TipWidget.State.IDLE;
}

/**
* 移除当前显示的tip
*/
public static void removeCurrent() {
if (!renderQueue.isEmpty()) renderQueue.remove(0);
TIP_WIDGET.removeTip();
if (!TIP_QUEUE.isEmpty()) TIP_QUEUE.remove(0);
TIP_WIDGET.setState(TipWidget.State.FADING_OUT);
}

@SubscribeEvent
public static void onGuiInit(ScreenEvent.Init.Pre event) {
public static void onGuiInit(ScreenEvent.Init event) {
if (!FHConfig.CLIENT.renderTips.get())
return;
if (GUI_BLACKLIST.contains(event.getScreen().getClass()))
if (SCREEN_BLACKLIST.contains(event.getScreen().getClass()))
return;

// TODO 兼容JEI
// 将TipWidget添加到当前screen中
if (!event.getListenersList().contains(TIP_WIDGET)) {
event.addListener(TIP_WIDGET.closeButton);
event.addListener(TIP_WIDGET.pinButton);
event.addListener(TIP_WIDGET);
// 按钮由TipWidget渲染

// 原版的物品和tooltip顺序可能在screen渲染之后,
// 而我为了确保tip始终渲染在所有layout的最上层将
// z轴偏移了+800,这导致了tip的半透明背景会因为渲
// 染顺序而剔除这些元素
//
// 将tipWidget和按钮从screen的渲染列表中移除
event.getScreen().renderables.remove(TIP_WIDGET.closeButton);
event.getScreen().renderables.remove(TIP_WIDGET.pinButton);
event.getScreen().renderables.remove(TIP_WIDGET);
}
}

@SubscribeEvent
public static void renderOnHUD(RenderGuiEvent.Post event) {
if (!FHConfig.CLIENT.renderTips.get() || renderQueue.isEmpty())
public static void onHudRender(RenderGuiEvent.Post event) {
if (!FHConfig.CLIENT.renderTips.get() || TIP_QUEUE.isEmpty())
return;
Minecraft MC = ClientUtils.mc();
if (MC.screen != null && !GUI_BLACKLIST.contains(MC.screen.getClass()))
if (MC.screen != null && !SCREEN_BLACKLIST.contains(MC.screen.getClass()))
return;

// if (WIDGET_INSTANCE.getState() != TipWidget.State.IDLE) {
Expand All @@ -79,20 +105,32 @@ public static void renderOnHUD(RenderGuiEvent.Post event) {
}

@SubscribeEvent
public static void onGuiRender(ScreenEvent.Render event) {
if (!FHConfig.CLIENT.renderTips.get() || renderQueue.isEmpty() || !event.getScreen().children().contains(TIP_WIDGET))
public static void onGuiRender(ScreenEvent.Render.Post event) {
if (!FHConfig.CLIENT.renderTips.get() || TIP_QUEUE.isEmpty())
return;
if (!event.getScreen().children().contains(TIP_WIDGET))
return;

// 避免点击tip后聊天栏无法编辑
if (event.getScreen() instanceof ChatScreen) {
for (GuiEventListener child : event.getScreen().children()) {
if (child instanceof EditBox e) {
event.getScreen().setFocused(e);
}
}
}

TIP_WIDGET.renderWidget(event.getGuiGraphics(), event.getMouseX(), event.getMouseY(), event.getPartialTick());
update();
}

private static void update() {
if (TIP_WIDGET.getState() == TipWidget.State.IDLE) {
// 删除当前
renderQueue.remove(TIP_WIDGET.getTip());
TIP_WIDGET.removeTip();
TIP_QUEUE.remove(TIP_WIDGET.lastTip);
TIP_WIDGET.lastTip = null;
// 切换下一个
if (!renderQueue.isEmpty()) {
TIP_WIDGET.setTip(renderQueue.get(0));
if (!TIP_QUEUE.isEmpty()) {
TIP_WIDGET.setTip(TIP_QUEUE.get(0));
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,8 @@ protected TipEditorScreen() {
@Override
protected void init() {
addRenderableWidget(new IconButton(50, 50, IconButton.Icon.CHECK, FHColorHelper.CYAN, Component.translatable("gui.yes"), (b) -> {
if (!TipRenderer.renderQueue.isEmpty()) {
TipRenderer.renderQueue.get(0).saveAsFile();
if (!TipRenderer.TIP_QUEUE.isEmpty()) {
TipRenderer.TIP_QUEUE.get(0).saveAsFile();
}
}));
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,21 +1,8 @@
package com.teammoeg.frostedheart.content.tips.client.gui;

import com.teammoeg.frostedheart.FHMain;
import com.teammoeg.frostedheart.content.tips.Tip;
import com.teammoeg.frostedheart.content.tips.TipManager;
import com.teammoeg.frostedheart.content.tips.client.gui.widget.IconButton;
import com.teammoeg.frostedheart.util.client.AnimationUtil;
import com.teammoeg.frostedheart.util.client.ClientUtils;
import com.teammoeg.frostedheart.util.client.FHColorHelper;
import com.teammoeg.frostedheart.util.client.FHGuiHelper;
import com.teammoeg.frostedheart.util.client.RawMouseHelper;
import com.teammoeg.frostedheart.util.lang.Lang;
import net.minecraft.client.gui.GuiGraphics;
import net.minecraft.client.gui.screens.Screen;
import net.minecraft.client.resources.language.I18n;
import net.minecraft.network.chat.Component;
import net.minecraft.util.Mth;
import org.lwjgl.glfw.GLFW;

import java.util.HashMap;
import java.util.List;
Expand Down
Loading

0 comments on commit 7c17994

Please sign in to comment.