Skip to content

Commit ff4758a

Browse files
committed
Merge 1.21.7-8 into 1.21.10: Resolve conflicts and update to MC 1.21.10
2 parents 9b831c1 + 18e4562 commit ff4758a

20 files changed

+570
-6
lines changed

CHANGELOG.md

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
# Changelog
2+
3+
## [1.2.0] - 2024-11-12
4+
5+
### Added
6+
7+
- Click-to-remove message functionality with particle effects
8+
- Configuration option to enable/disable click-to-remove feature
9+
- World event handling system for message parsing pause/resume
10+
- Automatic message parsing pause when leaving worlds
11+
- Automatic message parsing resume when joining worlds
12+
13+
### Changed
14+
15+
- Updated Minecraft version from 1.21.7 to 1.21.10
16+
- Updated Fabric API to 0.129.0+1.21.7
17+
- Fixed WorldRenderEvents imports (moved to v1.world package)
18+
- Updated rendering API calls (matrixStack() → matrices())
19+
- Fixed MinecraftClient.disconnect() mixin signature for new boolean parameter
20+
21+
### Technical
22+
23+
- MouseHandlerMixin for click detection on messages
24+
- MessageClickHandler for click processing and particle spawning
25+
- WorldEventHandler for managing message parsing state
26+
- ClientPlayNetworkHandlerMixin for world join detection
27+
- MinecraftClientMixin for world leave detection
28+
29+
## [1.1.0] - 2024-11-11
30+
31+
### Added
32+
33+
- Custom render pipeline system (CustomRenderPipeline.java, WaypointRenderer.java)
34+
- GPU resource cleanup (GameRendererMixin.java)
35+
- Rendering guide (RENDERING_GUIDE.md)
36+
37+
### Technical
38+
39+
- Support for extraction/drawing phase rendering
40+
- Example waypoint renderer with through-wall rendering
41+
- Proper GPU memory management

RENDERING_GUIDE.md

Lines changed: 155 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,155 @@
1+
# Custom Rendering Guide for Minecraft 1.21.7
2+
3+
## Quick Start
4+
5+
### Test the example waypoint
6+
7+
```bash
8+
./gradlew runClient
9+
# In game: /tp 0 100 0
10+
```
11+
12+
You should see a green cube that renders through walls.
13+
14+
## What was added
15+
16+
### New files
17+
18+
1. **CustomRenderPipeline.java** - Basic example from Fabric docs
19+
20+
- Renders a green cube at (0, 100, 0)
21+
- Renders through walls (NO_DEPTH_TEST)
22+
- Demonstrates extraction/drawing phases
23+
24+
2. **WaypointRenderer.java** - Full-featured renderer
25+
26+
- Support for multiple waypoints
27+
- Different colors and sizes
28+
- Ready to use in your project
29+
30+
3. **GameRendererMixin.java** - Resource cleanup
31+
- Prevents GPU memory leaks
32+
- Called when GameRenderer closes
33+
34+
## Usage Examples
35+
36+
### Basic - Single waypoint
37+
38+
```java
39+
import net.fabricmc.fabric.api.client.rendering.v1.WorldRenderEvents;
40+
import takeyourminestream.modid.rendering.WaypointRenderer;
41+
import takeyourminestream.modid.rendering.WaypointRenderer.Waypoint;
42+
43+
WaypointRenderer renderer = new WaypointRenderer();
44+
45+
// Add a green waypoint
46+
renderer.addWaypoint(Waypoint.green(new Vec3d(0, 100, 0)));
47+
48+
// Register rendering
49+
WorldRenderEvents.AFTER_ENTITIES.register(context -> {
50+
renderer.render(context);
51+
});
52+
```
53+
54+
### Multiple waypoints
55+
56+
```java
57+
renderer.addWaypoint(Waypoint.green(new Vec3d(0, 100, 0)));
58+
renderer.addWaypoint(Waypoint.red(new Vec3d(10, 100, 10)));
59+
renderer.addWaypoint(Waypoint.blue(new Vec3d(-10, 100, -10)));
60+
61+
// Custom waypoint
62+
renderer.addWaypoint(new Waypoint(
63+
new Vec3d(20, 100, 20), // position
64+
1f, 1f, 0f, // yellow (RGB)
65+
0.7f, // alpha
66+
2f // size in blocks
67+
));
68+
```
69+
70+
### Dynamic waypoints
71+
72+
```java
73+
WorldRenderEvents.AFTER_ENTITIES.register(context -> {
74+
renderer.clearWaypoints();
75+
76+
// Add waypoints for active messages
77+
for (Message msg : activeMessages) {
78+
renderer.addWaypoint(Waypoint.green(msg.getPosition()));
79+
}
80+
81+
renderer.render(context);
82+
});
83+
```
84+
85+
## Disable test waypoint
86+
87+
If you don't want the test waypoint, edit `fabric.mod.json`:
88+
89+
```json
90+
"client": [
91+
"takeyourminestream.modid.TakeYourMineStreamClient"
92+
// "takeyourminestream.modid.rendering.CustomRenderPipeline"
93+
]
94+
```
95+
96+
## How it works
97+
98+
### Two-phase rendering
99+
100+
1. **Extraction** - Collect data for rendering
101+
- Call `VertexRendering.drawFilledBox()`
102+
- Write vertices to BufferBuilder
103+
2. **Drawing** - Render to screen
104+
- Build the buffer
105+
- Upload to GPU
106+
- Execute draw call
107+
108+
This allows rendering the previous frame in parallel with extracting the next frame.
109+
110+
### Custom pipeline
111+
112+
```java
113+
private static final RenderPipeline MY_PIPELINE = RenderPipelines.register(
114+
RenderPipeline.builder(RenderPipelines.POSITION_COLOR_SNIPPET)
115+
.withLocation(Identifier.of("mod-id", "pipeline/my_pipeline"))
116+
.withVertexFormat(VertexFormats.POSITION_COLOR, DrawMode.TRIANGLE_STRIP)
117+
.withDepthTestFunction(DepthTestFunction.NO_DEPTH_TEST)
118+
.build()
119+
);
120+
```
121+
122+
### Resource cleanup
123+
124+
**IMPORTANT:** Always clean up resources!
125+
126+
```java
127+
public void close() {
128+
allocator.close();
129+
if (vertexBuffer != null) {
130+
vertexBuffer.close();
131+
vertexBuffer = null;
132+
}
133+
}
134+
```
135+
136+
The GameRendererMixin calls this automatically.
137+
138+
## Performance tips
139+
140+
1. Reuse BufferBuilder (don't create new each frame)
141+
2. Use MappableRingBuffer for automatic buffer management
142+
3. Group objects by pipeline
143+
4. Clear unused waypoints
144+
145+
## Compatibility
146+
147+
- ✅ Minecraft 1.21.7
148+
- ✅ Fabric Loader 0.16.14+
149+
- ✅ Fabric API 0.129.0+
150+
- ✅ Java 21
151+
152+
## Links
153+
154+
- [Fabric Rendering Documentation](https://docs.fabricmc.net/develop/rendering/world)
155+
- [Rendering Concepts](https://docs.fabricmc.net/develop/rendering/basic-concepts)

gradle.properties

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ loader_version=0.17.3
1010
loom_version=1.11-SNAPSHOT
1111

1212
# Mod Properties
13-
mod_version=1.1.0
13+
mod_version=1.2.0
1414
maven_group=takeyourminestream.modid
1515
archives_base_name=tyms
1616

src/client/java/takeyourminestream/modid/ConfigManager.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,9 @@ public void setConfigValue(String key, Object value) {
116116
case "followPlayer":
117117
configData.setFollowPlayer((Boolean) value);
118118
break;
119+
case "enableClickToRemove":
120+
configData.setEnableClickToRemove((Boolean) value);
121+
break;
119122
default:
120123
LOGGER.warning("Неизвестный ключ конфигурации: " + key);
121124
return;
@@ -143,6 +146,7 @@ private void updateConfigCache() {
143146
configCache.put("messageScale", configData.getMessageScale());
144147
configCache.put("showMessageBackground", configData.isShowMessageBackground());
145148
configCache.put("followPlayer", configData.isFollowPlayer());
149+
configCache.put("enableClickToRemove", configData.isEnableClickToRemove());
146150
}
147151

148152
public ModConfigData getConfigData() {

src/client/java/takeyourminestream/modid/ModConfig.java

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -113,4 +113,13 @@ public static boolean isFOLLOW_PLAYER() {
113113
public static void setFOLLOW_PLAYER(boolean value) {
114114
ConfigManager.getInstance().setConfigValue("followPlayer", value);
115115
}
116+
117+
public static boolean isENABLE_CLICK_TO_REMOVE() {
118+
Object value = ConfigManager.getInstance().getConfigValue("enableClickToRemove");
119+
return value != null ? (Boolean) value : true; // По умолчанию true
120+
}
121+
122+
public static void setENABLE_CLICK_TO_REMOVE(boolean value) {
123+
ConfigManager.getInstance().setConfigValue("enableClickToRemove", value);
124+
}
116125
}

src/client/java/takeyourminestream/modid/ModConfigScreen.java

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -232,6 +232,16 @@ private void createConfigEntries() {
232232
this.addDrawableChild(followPlayerButton);
233233
configEntries.add(new ConfigEntry("takeyourminestream.config.follow_player", "takeyourminestream.config.follow_player.desc", ConfigEntryType.TOGGLE, followPlayerButton, ConfigCategory.BEHAVIOR));
234234

235+
ButtonWidget clickToRemoveButton = ButtonWidget.builder(
236+
Text.translatable(ModConfig.isENABLE_CLICK_TO_REMOVE() ? "takeyourminestream.config.on" : "takeyourminestream.config.off"),
237+
btn -> {
238+
ModConfig.setENABLE_CLICK_TO_REMOVE(!ModConfig.isENABLE_CLICK_TO_REMOVE());
239+
btn.setMessage(Text.translatable(ModConfig.isENABLE_CLICK_TO_REMOVE() ? "takeyourminestream.config.on" : "takeyourminestream.config.off"));
240+
}
241+
).dimensions(0, 0, CONTROL_WIDTH, 20).build();
242+
this.addDrawableChild(clickToRemoveButton);
243+
configEntries.add(new ConfigEntry("takeyourminestream.config.click_to_remove", "takeyourminestream.config.click_to_remove.desc", ConfigEntryType.TOGGLE, clickToRemoveButton, ConfigCategory.BEHAVIOR));
244+
235245
TextFieldWidget maxFreezeDistanceField = new TextFieldWidget(textRenderer, 0, 0, CONTROL_WIDTH, 20, Text.translatable("takeyourminestream.config.max_freeze_distance"));
236246
maxFreezeDistanceField.setText(String.valueOf(ModConfig.getMAX_FREEZE_DISTANCE()));
237247
maxFreezeDistanceField.setChangedListener(s -> {

src/client/java/takeyourminestream/modid/TakeYourMineStreamClient.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,9 @@ private void initializeMod() {
5050
commandManager.registerCommands();
5151
keyBindingManager.registerKeyBindings();
5252

53+
// Регистрация обработчиков событий мира
54+
WorldEventHandler.register(messageSpawner);
55+
5356
Logger.info("Все компоненты мода инициализированы");
5457
}
5558

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
package takeyourminestream.modid;
2+
3+
import net.fabricmc.fabric.api.client.event.lifecycle.v1.ClientLifecycleEvents;
4+
import takeyourminestream.modid.messages.MessageSpawner;
5+
import takeyourminestream.modid.utils.Logger;
6+
7+
/**
8+
* Обработчик событий мира для управления паузой системы сообщений
9+
*/
10+
public class WorldEventHandler {
11+
12+
/**
13+
* Регистрирует обработчики событий входа/выхода из мира
14+
* @param messageSpawner система спавна сообщений
15+
*/
16+
public static void register(MessageSpawner messageSpawner) {
17+
// При выходе из мира - ставим на паузу
18+
ClientLifecycleEvents.CLIENT_STOPPING.register(client -> {
19+
if (messageSpawner != null) {
20+
messageSpawner.pause();
21+
Logger.info("Система сообщений поставлена на паузу (выход из игры)");
22+
}
23+
});
24+
}
25+
26+
/**
27+
* Обработчик входа в мир - снимает с паузы
28+
* Вызывается вручную при входе в мир
29+
* @param messageSpawner система спавна сообщений
30+
*/
31+
public static void onWorldJoin(MessageSpawner messageSpawner) {
32+
if (messageSpawner != null && messageSpawner.isPaused()) {
33+
messageSpawner.resume();
34+
Logger.info("Система сообщений снята с паузы (вход в мир)");
35+
}
36+
}
37+
38+
/**
39+
* Обработчик выхода из мира - ставит на паузу
40+
* Вызывается вручную при выходе из мира
41+
* @param messageSpawner система спавна сообщений
42+
*/
43+
public static void onWorldLeave(MessageSpawner messageSpawner) {
44+
if (messageSpawner != null && !messageSpawner.isPaused()) {
45+
messageSpawner.pause();
46+
Logger.info("Система сообщений поставлена на паузу (выход из мира)");
47+
}
48+
}
49+
}

src/client/java/takeyourminestream/modid/config/ModConfigData.java

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
* Модель данных конфигурации мода
55
*/
66
public class ModConfigData {
7-
private String twitchChannelName = "ijustseen_you";
7+
private String twitchChannelName = "ijustseen";
88
// Старые поля для обратной совместимости (тики)
99
private int messageLifetimeTicks = 80;
1010
private int messageFallTicks = 20;
@@ -22,6 +22,7 @@ public class ModConfigData {
2222
private MessageScale messageScale = MessageScale.NORMAL;
2323
private boolean showMessageBackground = true;
2424
private boolean followPlayer = false;
25+
private boolean enableClickToRemove = true;
2526

2627
// Геттеры
2728
public String getTwitchChannelName() { return twitchChannelName; }
@@ -40,6 +41,7 @@ public class ModConfigData {
4041
public MessageScale getMessageScale() { return messageScale; }
4142
public boolean isShowMessageBackground() { return showMessageBackground; }
4243
public boolean isFollowPlayer() { return followPlayer; }
44+
public boolean isEnableClickToRemove() { return enableClickToRemove; }
4345

4446
// Сеттеры
4547
public void setTwitchChannelName(String twitchChannelName) { this.twitchChannelName = twitchChannelName; }
@@ -58,6 +60,7 @@ public class ModConfigData {
5860
public void setMessageScale(MessageScale messageScale) { this.messageScale = messageScale; }
5961
public void setShowMessageBackground(boolean showMessageBackground) { this.showMessageBackground = showMessageBackground; }
6062
public void setFollowPlayer(boolean followPlayer) { this.followPlayer = followPlayer; }
63+
public void setEnableClickToRemove(boolean enableClickToRemove) { this.enableClickToRemove = enableClickToRemove; }
6164

6265
// Методы для обратной совместимости
6366
public boolean isMessagesInFrontOfPlayerOnly() {

0 commit comments

Comments
 (0)