Merge branch 'embeddedt:1.16' into 1.16-1
This commit is contained in:
commit
42b99d7452
2
.github/workflows/release.yml
vendored
2
.github/workflows/release.yml
vendored
|
|
@ -24,7 +24,7 @@ jobs:
|
||||||
- name: Build and publish mod to CurseForge & Modrinth
|
- name: Build and publish mod to CurseForge & Modrinth
|
||||||
run: |
|
run: |
|
||||||
chmod +x gradlew
|
chmod +x gradlew
|
||||||
./gradlew forge:publishToModSites fabric:publishToModSites forge:copyJarToBin fabric:copyJarToBin
|
./gradlew publishToModSites copyJarToBin
|
||||||
env:
|
env:
|
||||||
CURSEFORGE_TOKEN: ${{ secrets.CURSEFORGE_TOKEN }}
|
CURSEFORGE_TOKEN: ${{ secrets.CURSEFORGE_TOKEN }}
|
||||||
MODRINTH_TOKEN: ${{ secrets.MODRINTH_TOKEN }}
|
MODRINTH_TOKEN: ${{ secrets.MODRINTH_TOKEN }}
|
||||||
|
|
|
||||||
10
README.md
10
README.md
|
|
@ -6,11 +6,11 @@ Some fixes are based on prior work in various Forge PRs (check commit history an
|
||||||
is directly derived from Sodium and used under the terms of the LGPL-3.0 license.
|
is directly derived from Sodium and used under the terms of the LGPL-3.0 license.
|
||||||
|
|
||||||
## Development builds (generally stable, but may occasionally have bugs)
|
## Development builds (generally stable, but may occasionally have bugs)
|
||||||
- 1.16.5, both modloaders: https://nightly.link/embeddedt/ModernFix/workflows/gradle/1.16/Package.zip
|
- 1.16.5: https://nightly.link/embeddedt/ModernFix/workflows/gradle/1.16/Package.zip
|
||||||
- 1.18.2, both modloaders: https://nightly.link/embeddedt/ModernFix/workflows/gradle/1.18/Package.zip
|
- 1.18.2: https://nightly.link/embeddedt/ModernFix/workflows/gradle/1.18/Package.zip
|
||||||
- 1.19.2, both modloaders: https://nightly.link/embeddedt/ModernFix/workflows/gradle/1.19.2/Package.zip
|
- 1.19.2: https://nightly.link/embeddedt/ModernFix/workflows/gradle/1.19.2/Package.zip
|
||||||
- 1.19.4, both modloaders: https://nightly.link/embeddedt/ModernFix/workflows/gradle/1.19.4/Package.zip
|
- 1.20.1: https://nightly.link/embeddedt/ModernFix/workflows/gradle/1.20/Package.zip
|
||||||
- 1.20.1, both modloaders: https://nightly.link/embeddedt/ModernFix/workflows/gradle/1.20/Package.zip
|
- 1.20.2: https://nightly.link/embeddedt/ModernFix/workflows/gradle/1.20.2/Package.zip
|
||||||
|
|
||||||
------------
|
------------
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -50,8 +50,8 @@ tasks.register('generateChangelog', se.bjurr.gitchangelog.plugin.gradle.GitChang
|
||||||
|
|
||||||
fromRef = theVersionRef
|
fromRef = theVersionRef
|
||||||
|
|
||||||
file = new File("CHANGELOG.md");
|
file = new File("${rootDir}/CHANGELOG.md");
|
||||||
templateContent = new File('gradle/changelog.mustache').getText('UTF-8').replace("[[modernFixVersionRef]]", theVersionRef);
|
templateContent = new File("${rootDir}/gradle/changelog.mustache").getText('UTF-8').replace("[[modernFixVersionRef]]", theVersionRef);
|
||||||
toCommit = "HEAD";
|
toCommit = "HEAD";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -40,7 +40,7 @@ curseforge {
|
||||||
apiKey = System.getenv("CURSEFORGE_TOKEN")
|
apiKey = System.getenv("CURSEFORGE_TOKEN")
|
||||||
project {
|
project {
|
||||||
id = "790626"
|
id = "790626"
|
||||||
changelog = file('../CHANGELOG.md')
|
changelog = file("${rootDir}/CHANGELOG.md")
|
||||||
changelogType = "markdown"
|
changelogType = "markdown"
|
||||||
releaseType = isBeta ? "beta" : "release"
|
releaseType = isBeta ? "beta" : "release"
|
||||||
addGameVersion project.name.capitalize()
|
addGameVersion project.name.capitalize()
|
||||||
|
|
@ -57,7 +57,7 @@ modrinth {
|
||||||
uploadFile = remapJar
|
uploadFile = remapJar
|
||||||
gameVersions = supported_minecraft_versions.tokenize(",")
|
gameVersions = supported_minecraft_versions.tokenize(",")
|
||||||
loaders = [project.name]
|
loaders = [project.name]
|
||||||
changelog.set(provider { file("CHANGELOG.md").getText('UTF-8') })
|
changelog.set(provider { file("${rootDir}/CHANGELOG.md").getText('UTF-8') })
|
||||||
}
|
}
|
||||||
|
|
||||||
tasks.curseforge.dependsOn(rootProject.generateChangelog)
|
tasks.curseforge.dependsOn(rootProject.generateChangelog)
|
||||||
|
|
|
||||||
|
|
@ -215,7 +215,7 @@ public class ModernFixEarlyConfig {
|
||||||
disableIfModPresent("mixin.bugfix.remove_block_chunkloading", "performant");
|
disableIfModPresent("mixin.bugfix.remove_block_chunkloading", "performant");
|
||||||
disableIfModPresent("mixin.bugfix.paper_chunk_patches", "c2me");
|
disableIfModPresent("mixin.bugfix.paper_chunk_patches", "c2me");
|
||||||
disableIfModPresent("mixin.bugfix.preserve_early_window_pos", "better_loading_screen");
|
disableIfModPresent("mixin.bugfix.preserve_early_window_pos", "better_loading_screen");
|
||||||
disableIfModPresent("mixin.perf.cache_strongholds", "littletiles");
|
disableIfModPresent("mixin.perf.cache_strongholds", "littletiles", "c2me");
|
||||||
// content overlap
|
// content overlap
|
||||||
disableIfModPresent("mixin.perf.deduplicate_wall_shapes", "dashloader");
|
disableIfModPresent("mixin.perf.deduplicate_wall_shapes", "dashloader");
|
||||||
disableIfModPresent("mixin.perf.nbt_memory_usage", "c2me");
|
disableIfModPresent("mixin.perf.nbt_memory_usage", "c2me");
|
||||||
|
|
@ -229,6 +229,21 @@ public class ModernFixEarlyConfig {
|
||||||
if(isFabric) {
|
if(isFabric) {
|
||||||
disableIfModPresent("mixin.bugfix.packet_leak", "memoryleakfix");
|
disableIfModPresent("mixin.bugfix.packet_leak", "memoryleakfix");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
checkBlockstateCacheRebuilds();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void checkBlockstateCacheRebuilds() {
|
||||||
|
if(!ModernFixPlatformHooks.INSTANCE.isDevEnv())
|
||||||
|
return;
|
||||||
|
try {
|
||||||
|
if(ModernFixEarlyConfig.class.getResource("/net/minecraft/world/level/Level.class") == null) {
|
||||||
|
LOGGER.warn("We are in a non-Mojmap dev environment. Disabling blockstate cache patch");
|
||||||
|
this.options.get("mixin.perf.reduce_blockstate_cache_rebuilds").addModOverride(false, "[not mojmap]");
|
||||||
|
}
|
||||||
|
} catch(Throwable e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void disableIfModPresent(String configName, String... ids) {
|
private void disableIfModPresent(String configName, String... ids) {
|
||||||
|
|
|
||||||
|
|
@ -114,5 +114,10 @@
|
||||||
"modernfix.option.mixin.perf.twilightforest.structure_spawn_fix": "Fixes lag caused by Twilight Forest worldgen checking structures very inefficiently",
|
"modernfix.option.mixin.perf.twilightforest.structure_spawn_fix": "Fixes lag caused by Twilight Forest worldgen checking structures very inefficiently",
|
||||||
"modernfix.option.mixin.perf.fast_forge_dummies": "Speeds up Forge registry freezing during launch by using a faster code path",
|
"modernfix.option.mixin.perf.fast_forge_dummies": "Speeds up Forge registry freezing during launch by using a faster code path",
|
||||||
"modernfix.option.mixin.perf.tag_id_caching": "Speeds up uses of tag entries by caching the location object instead of recreating it every time",
|
"modernfix.option.mixin.perf.tag_id_caching": "Speeds up uses of tag entries by caching the location object instead of recreating it every time",
|
||||||
"modernfix.option.mixin.feature.disable_unihex_font": "Remove the Unicode font, saves 10MB but causes special characters to no longer render"
|
"modernfix.option.mixin.feature.disable_unihex_font": "Remove the Unicode font, saves 10MB but causes special characters to no longer render",
|
||||||
|
"modernfix.option.mixin.bugfix.world_leaks": "Reduces the memory usage of old client-side worlds that aren't needed after switching dimensions. These are normally garbage collected in vanilla, but mods sometimes retain references to them.",
|
||||||
|
"modernfix.option.mixin.perf.compact_mojang_registries": "(Fabric) Experimental option that reduces the memory usage of registries by roughly 50%. Not useful in most modpacks unless they contain millions of blocks and items.",
|
||||||
|
"modernfix.option.mixin.perf.dynamic_block_codecs": "Avoids storing a codec for every block(state) and instead generates and caches it on the fly when needed. Generally not worth enabling unless you have a million blocks/items.",
|
||||||
|
"modernfix.option.mixin.perf.faster_command_suggestions": "Mitigate lag when there are hundreds of thousands of suggestions while typing a command",
|
||||||
|
"modernfix.option.mixin.perf.mojang_registry_size": "Fixes an issue causing registration of blocks/items to slow down proportional to the number already registered. This improves startup time."
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -42,6 +42,7 @@
|
||||||
"modernfix.option.mixin.perf.deduplicate_location": "全版本共有,但由于会影响加载时间,默认禁用。对资源位置的命名空间和路径进行去重。这节省了内存,但也大大增加了新资源位置的构造成本。",
|
"modernfix.option.mixin.perf.deduplicate_location": "全版本共有,但由于会影响加载时间,默认禁用。对资源位置的命名空间和路径进行去重。这节省了内存,但也大大增加了新资源位置的构造成本。",
|
||||||
"modernfix.option.mixin.perf.dynamic_dfu": "全版本共有。修改了DFU的初始化,使其仅在第一次需要升级数据时加载。这听起来类似DFU载入优化,但实现方式截然不同,因为它能避免加载§o任何§rDFU类/数据结构,而DFU载入优化只是禁用其规则优化。本质上说,这是一个DataFixerSlayer的安全版本,因为它仍然会在需要时加载DFU。\n\n即使启用了这个选项,你也应该继续使用DFU载入优化,否则DFU规则优化依然会导致卡顿。",
|
"modernfix.option.mixin.perf.dynamic_dfu": "全版本共有。修改了DFU的初始化,使其仅在第一次需要升级数据时加载。这听起来类似DFU载入优化,但实现方式截然不同,因为它能避免加载§o任何§rDFU类/数据结构,而DFU载入优化只是禁用其规则优化。本质上说,这是一个DataFixerSlayer的安全版本,因为它仍然会在需要时加载DFU。\n\n即使启用了这个选项,你也应该继续使用DFU载入优化,否则DFU规则优化依然会导致卡顿。",
|
||||||
"modernfix.option.mixin.perf.dynamic_resources": "全版本共有。详见https://github.com/Kasualix/ModernFix/wiki/动态资源加载---常见问题解答。",
|
"modernfix.option.mixin.perf.dynamic_resources": "全版本共有。详见https://github.com/Kasualix/ModernFix/wiki/动态资源加载---常见问题解答。",
|
||||||
|
"modernfix.option.mixin.perf.dynamic_sounds": "全版本共有。允许游戏卸载声音,而不是在加载声音后无限期地保留它们。",
|
||||||
"modernfix.option.mixin.perf.dynamic_structure_manager": "全版本共有。允许游戏在结构生成结束后卸载结构文件,而非让它们永远处于已加载状态。",
|
"modernfix.option.mixin.perf.dynamic_structure_manager": "全版本共有。允许游戏在结构生成结束后卸载结构文件,而非让它们永远处于已加载状态。",
|
||||||
"modernfix.option.mixin.perf.fast_registry_validation": "全版本共有。每次验证注册时,Forge都会通过反射来查找一个方法,这完全没必要。这个补丁简单地缓存了方法的返回值,因为它每次都是一样的。",
|
"modernfix.option.mixin.perf.fast_registry_validation": "全版本共有。每次验证注册时,Forge都会通过反射来查找一个方法,这完全没必要。这个补丁简单地缓存了方法的返回值,因为它每次都是一样的。",
|
||||||
"modernfix.option.mixin.perf.faster_font_loading": "全版本共有。优化字体渲染器,以更快地加载字体,加快资源重载速度。",
|
"modernfix.option.mixin.perf.faster_font_loading": "全版本共有。优化字体渲染器,以更快地加载字体,加快资源重载速度。",
|
||||||
|
|
@ -53,7 +54,7 @@
|
||||||
"modernfix.option.mixin.perf.model_optimizations": "全版本共有。通过优化以加快模型加载过程。",
|
"modernfix.option.mixin.perf.model_optimizations": "全版本共有。通过优化以加快模型加载过程。",
|
||||||
"modernfix.option.mixin.perf.nbt_memory_usage": "全版本共有。对复合NBT标签使用一个更加高效的支持映射(backing map),从而消除重复键名,对小型复合 NBT 也使用数组映射。这减少了在内存中存储许多复合NBT标签的开销。",
|
"modernfix.option.mixin.perf.nbt_memory_usage": "全版本共有。对复合NBT标签使用一个更加高效的支持映射(backing map),从而消除重复键名,对小型复合 NBT 也使用数组映射。这减少了在内存中存储许多复合NBT标签的开销。",
|
||||||
"modernfix.option.mixin.perf.nuke_empty_chunk_sections": "仅1.16。灵感来自氢(Hydrogen)模组。将存储充满空气的区块部分标记为空(empty),避免在内存中存储它们。",
|
"modernfix.option.mixin.perf.nuke_empty_chunk_sections": "仅1.16。灵感来自氢(Hydrogen)模组。将存储充满空气的区块部分标记为空(empty),避免在内存中存储它们。",
|
||||||
"modernfix.option.mixin.perf.reduce_blockstate_cache_rebuilds": "全版本共有。§l一项关键优化。§r较新的Minecraft(1.12以上)实现了一个方块状态缓存系统,它可以缓存方块状态的常用信息,譬如其是否为固体方块,它的碰撞箱形状等等。原版中重建此缓存非常快(只要一两秒钟),但在安装了许多模组后就相当慢了,因为游戏中多了很多其它的方块状态,它们的缓存都需要被其重建。\n\n在Forge的影响下,这个问题变得更加严重,因为缓存会在很多地方重建,但这些数据在下一次重建前几乎肯定不会被用到。至于在哪儿,比如,在到达主菜单之前(在“Freezing data”阶段),以及在加载世界时(会出现很多次!)。\n\n通过让缓存重建转为惰性,现代化修复解决了这个性能瓶颈问题。每个方块状态在第一次访问数据时都会重建其缓存。无论何时,原版或Forge试图重建所有方块状态缓存的行为都会被重定向,变成简单地使每个方块状态的缓存失效。\n\n此项优化不应该对启动后的TPS产生任何影响。",
|
"modernfix.option.mixin.perf.reduce_blockstate_cache_rebuilds": "全版本共有。§l一项关键优化。§r较新的Minecraft(1.12以上)实现了一个方块状态缓存系统,它可以缓存方块状态的常用信息,譬如其是否为固体方块,它的碰撞箱形状等等。原版中重建此缓存非常快(只要一两秒钟),但在安装了许多模组后就相当慢了,因为游戏中多了很多其它的方块状态,它们的缓存都需要被其重建。\n\n在Forge的影响下,这个问题变得更加严重,因为缓存会在很多地方重建,但这些数据在下一次重建前几乎肯定不会被用到。至于在哪儿,比如,在到达主菜单之前(在“Freezing data”阶段),以及在加载世界时(会出现很多次!)。\n\n通过让缓存重建转为惰性,现代化修复解决了这个性能瓶颈问题。每个方块状态在第一次访问数据时都会重建其缓存。无论何时,原版或Forge试图重建所有方块状态缓存的行为都会被重定向,变成简单地使每个方块状态的缓存失效。\n\n此项优化应该不会对启动后的TPS产生任何影响。",
|
||||||
"modernfix.option.mixin.perf.remove_biome_temperature_cache": "全版本共有。移除生物群系温度缓存,以减少内存占用,就像新版本的锂所做的那样。",
|
"modernfix.option.mixin.perf.remove_biome_temperature_cache": "全版本共有。移除生物群系温度缓存,以减少内存占用,就像新版本的锂所做的那样。",
|
||||||
"modernfix.option.mixin.perf.resourcepacks": "全版本共有。§l一项关键优化。§r高版本的启动严重受到文件系统访问的瓶颈限制。资源包经常接受到很多请求,要列出资源或检查一项给定的资源是否存在,而每次请求都会调用一个效率极低的文件API。\n\n现代化修复通过简单地缓存模组和原版提供的所有资源的列表,完全消除了此处的大部分瓶颈。缓存在资源重载时会进行重建(除了原版资源,因为它们在游戏运行时不应改变)。\n\n高清修复不能正确加载它的连接纹理(CTM)资源,除此之外此补丁没有已知的兼容问题。不过,我不建议在任何情况下使用高清修复,因为它本身就会增加几分钟的启动时间,而且根本没有与现代化修复进行过任何测试。",
|
"modernfix.option.mixin.perf.resourcepacks": "全版本共有。§l一项关键优化。§r高版本的启动严重受到文件系统访问的瓶颈限制。资源包经常接受到很多请求,要列出资源或检查一项给定的资源是否存在,而每次请求都会调用一个效率极低的文件API。\n\n现代化修复通过简单地缓存模组和原版提供的所有资源的列表,完全消除了此处的大部分瓶颈。缓存在资源重载时会进行重建(除了原版资源,因为它们在游戏运行时不应改变)。\n\n高清修复不能正确加载它的连接纹理(CTM)资源,除此之外此补丁没有已知的兼容问题。不过,我不建议在任何情况下使用高清修复,因为它本身就会增加几分钟的启动时间,而且根本没有与现代化修复进行过任何测试。",
|
||||||
"modernfix.option.mixin.perf.reuse_datapacks": "仅1.16。试图尽可能跳过数据包重载,来加快单人世界切换/重进时的速度。可能会导致一些模组的兼容性问题,但目前默认启用。",
|
"modernfix.option.mixin.perf.reuse_datapacks": "仅1.16。试图尽可能跳过数据包重载,来加快单人世界切换/重进时的速度。可能会导致一些模组的兼容性问题,但目前默认启用。",
|
||||||
|
|
@ -114,5 +115,10 @@
|
||||||
"modernfix.option.mixin.perf.twilightforest.structure_spawn_fix": "针对暮色森林模组,修复了其世界生成检查结构效率极低导致卡顿的问题",
|
"modernfix.option.mixin.perf.twilightforest.structure_spawn_fix": "针对暮色森林模组,修复了其世界生成检查结构效率极低导致卡顿的问题",
|
||||||
"modernfix.option.mixin.perf.fast_forge_dummies": "使用更快的代码路径,加快启动时Forge注册表的冻结速度",
|
"modernfix.option.mixin.perf.fast_forge_dummies": "使用更快的代码路径,加快启动时Forge注册表的冻结速度",
|
||||||
"modernfix.option.mixin.perf.tag_id_caching": "缓存位置对象,不再每次都重新创建它,这可以加快标签条目的使用速度",
|
"modernfix.option.mixin.perf.tag_id_caching": "缓存位置对象,不再每次都重新创建它,这可以加快标签条目的使用速度",
|
||||||
"modernfix.option.mixin.feature.disable_unihex_font": "删除Unicode字体,可以节省10MB内存,但会导致特殊字符不再渲染"
|
"modernfix.option.mixin.feature.disable_unihex_font": "删除Unicode字体,可以节省10MB内存,但会导致特殊字符不再渲染",
|
||||||
|
"modernfix.option.mixin.bugfix.world_leaks": "减少切换维度后不需要的旧客户端世界的内存占用。这部分内存在原版中通常会被垃圾回收,但有时模组会保留对它们的引用。",
|
||||||
|
"modernfix.option.mixin.perf.compact_mojang_registries": "(Fabric)实验性选项,可将注册表的内存占用减少约 50%。在大多数整合包中没什么用,除非它们包含数百万个方块和物品。",
|
||||||
|
"modernfix.option.mixin.perf.dynamic_block_codecs": "不再给每个方块(状态)都存储一个编解码器,只在需要时动态生成、缓存它。通常不值得启用,除非你有一百万个方块/物品。",
|
||||||
|
"modernfix.option.mixin.perf.faster_command_suggestions": "在输入命令时,若有数十万个建议,可以缓解卡顿。",
|
||||||
|
"modernfix.option.mixin.perf.mojang_registry_size": "修复了一个问题,它会导致方块/物品的注册速度减慢,减慢的程度与已注册的数量成正比。这缩短了启动时间。"
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Binary file not shown.
|
Before Width: | Height: | Size: 17 KiB After Width: | Height: | Size: 15 KiB |
208
doc/logo.svg
Normal file
208
doc/logo.svg
Normal file
File diff suppressed because one or more lines are too long
|
After Width: | Height: | Size: 33 KiB |
209
doc/logo_transparent.svg
Normal file
209
doc/logo_transparent.svg
Normal file
File diff suppressed because one or more lines are too long
|
After Width: | Height: | Size: 33 KiB |
|
|
@ -18,9 +18,6 @@ dependencies {
|
||||||
minecraft "com.mojang:minecraft:${rootProject.minecraft_version}"
|
minecraft "com.mojang:minecraft:${rootProject.minecraft_version}"
|
||||||
mappings loom.layered() {
|
mappings loom.layered() {
|
||||||
officialMojangMappings()
|
officialMojangMappings()
|
||||||
if(rootProject.hasProperty("parchment_version")) {
|
|
||||||
parchment("org.parchmentmc.data:parchment-${minecraft_version}:${parchment_version}@zip")
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
modImplementation "net.fabricmc:fabric-loader:${rootProject.fabric_loader_version}"
|
modImplementation "net.fabricmc:fabric-loader:${rootProject.fabric_loader_version}"
|
||||||
|
|
|
||||||
|
|
@ -27,7 +27,7 @@ import java.util.*;
|
||||||
*/
|
*/
|
||||||
public class ModelBakeEventHelper {
|
public class ModelBakeEventHelper {
|
||||||
// TODO: make into config option
|
// TODO: make into config option
|
||||||
private static final Set<String> INCOMPATIBLE_MODS = ImmutableSet.of("industrialforegoing");
|
private static final Set<String> INCOMPATIBLE_MODS = ImmutableSet.of("industrialforegoing", "vampirism");
|
||||||
private final Map<ResourceLocation, BakedModel> modelRegistry;
|
private final Map<ResourceLocation, BakedModel> modelRegistry;
|
||||||
private final Set<ResourceLocation> topLevelModelLocations;
|
private final Set<ResourceLocation> topLevelModelLocations;
|
||||||
private final MutableGraph<String> dependencyGraph;
|
private final MutableGraph<String> dependencyGraph;
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,26 @@
|
||||||
|
package org.embeddedt.modernfix.forge.mixin.perf.async_locator;
|
||||||
|
|
||||||
|
import net.minecraft.network.chat.Component;
|
||||||
|
import net.minecraft.world.item.ItemStack;
|
||||||
|
import net.minecraft.world.level.storage.loot.functions.SetNameFunction;
|
||||||
|
import org.embeddedt.modernfix.forge.structure.logic.CommonLogic;
|
||||||
|
import org.embeddedt.modernfix.forge.structure.logic.ExplorationMapFunctionLogic;
|
||||||
|
import org.spongepowered.asm.mixin.Mixin;
|
||||||
|
import org.spongepowered.asm.mixin.injection.At;
|
||||||
|
import org.spongepowered.asm.mixin.injection.Redirect;
|
||||||
|
|
||||||
|
@Mixin(SetNameFunction.class)
|
||||||
|
public class SetNameFunctionMixin {
|
||||||
|
@Redirect(
|
||||||
|
method = "run",
|
||||||
|
at = @At(
|
||||||
|
value = "INVOKE",
|
||||||
|
target = "Lnet/minecraft/world/item/ItemStack;setHoverName(Lnet/minecraft/network/chat/Component;)Lnet/minecraft/world/item/ItemStack;"
|
||||||
|
)
|
||||||
|
)
|
||||||
|
public ItemStack deferSetName(ItemStack stack, Component name) {
|
||||||
|
if (CommonLogic.isEmptyPendingMap(stack))
|
||||||
|
ExplorationMapFunctionLogic.cacheName(stack, name);
|
||||||
|
return stack;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,28 @@
|
||||||
|
package org.embeddedt.modernfix.forge.mixin.perf.async_locator;
|
||||||
|
|
||||||
|
import net.minecraft.world.entity.player.Player;
|
||||||
|
import net.minecraft.world.inventory.Slot;
|
||||||
|
import net.minecraft.world.item.ItemStack;
|
||||||
|
import org.embeddedt.modernfix.forge.structure.logic.CommonLogic;
|
||||||
|
import org.spongepowered.asm.mixin.Mixin;
|
||||||
|
import org.spongepowered.asm.mixin.Shadow;
|
||||||
|
import org.spongepowered.asm.mixin.injection.At;
|
||||||
|
import org.spongepowered.asm.mixin.injection.Inject;
|
||||||
|
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
|
||||||
|
|
||||||
|
@Mixin(Slot.class)
|
||||||
|
public abstract class SlotMixin {
|
||||||
|
@Shadow
|
||||||
|
public abstract ItemStack getItem();
|
||||||
|
|
||||||
|
@Inject(
|
||||||
|
method = "mayPickup",
|
||||||
|
at = @At(value = "HEAD"),
|
||||||
|
cancellable = true
|
||||||
|
)
|
||||||
|
public void preventPickupOfPendingExplorationMap(Player player, CallbackInfoReturnable<Boolean> cir) {
|
||||||
|
if (CommonLogic.isEmptyPendingMap(getItem())) {
|
||||||
|
cir.setReturnValue(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -1,6 +1,8 @@
|
||||||
package org.embeddedt.modernfix.forge.structure.logic;
|
package org.embeddedt.modernfix.forge.structure.logic;
|
||||||
|
|
||||||
import net.minecraft.core.BlockPos;
|
import net.minecraft.core.BlockPos;
|
||||||
|
import net.minecraft.nbt.ByteTag;
|
||||||
|
import net.minecraft.network.chat.Component;
|
||||||
import net.minecraft.network.chat.TranslatableComponent;
|
import net.minecraft.network.chat.TranslatableComponent;
|
||||||
import net.minecraft.server.level.ServerLevel;
|
import net.minecraft.server.level.ServerLevel;
|
||||||
import net.minecraft.world.inventory.AbstractContainerMenu;
|
import net.minecraft.world.inventory.AbstractContainerMenu;
|
||||||
|
|
@ -15,6 +17,9 @@ import net.minecraft.world.level.saveddata.maps.MapItemSavedData;
|
||||||
import org.embeddedt.modernfix.forge.mixin.perf.async_locator.MapItemAccess;
|
import org.embeddedt.modernfix.forge.mixin.perf.async_locator.MapItemAccess;
|
||||||
|
|
||||||
public class CommonLogic {
|
public class CommonLogic {
|
||||||
|
private static final String MAP_HOVER_NAME_KEY = "menu.working";
|
||||||
|
private static final String KEY_LOCATING = "asynclocator.locating";
|
||||||
|
|
||||||
private CommonLogic() {}
|
private CommonLogic() {}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -24,10 +29,23 @@ public class CommonLogic {
|
||||||
*/
|
*/
|
||||||
public static ItemStack createEmptyMap() {
|
public static ItemStack createEmptyMap() {
|
||||||
ItemStack stack = new ItemStack(Items.FILLED_MAP);
|
ItemStack stack = new ItemStack(Items.FILLED_MAP);
|
||||||
stack.setHoverName(new TranslatableComponent("asynclocator.map.locating"));
|
stack.setHoverName(new TranslatableComponent(MAP_HOVER_NAME_KEY));
|
||||||
|
stack.addTagElement(KEY_LOCATING, ByteTag.ONE);
|
||||||
return stack;
|
return stack;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns true if the stack is an empty FILLED_MAP item with the hover tooltip name stating that it's locating a
|
||||||
|
* feature.
|
||||||
|
*
|
||||||
|
* @param stack The stack to check.
|
||||||
|
* @return True if the stack is an empty FILLED_MAP awaiting to be populated with location data.
|
||||||
|
*/
|
||||||
|
@SuppressWarnings("DataFlowIssue")
|
||||||
|
public static boolean isEmptyPendingMap(ItemStack stack) {
|
||||||
|
return stack.getItem() == Items.FILLED_MAP && stack.hasTag() && stack.getTag().contains(KEY_LOCATING);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Updates the map stack with all the given data.
|
* Updates the map stack with all the given data.
|
||||||
*
|
*
|
||||||
|
|
@ -44,7 +62,7 @@ public class CommonLogic {
|
||||||
int scale,
|
int scale,
|
||||||
MapDecoration.Type destinationType
|
MapDecoration.Type destinationType
|
||||||
) {
|
) {
|
||||||
updateMap(mapStack, level, pos, scale, destinationType, null);
|
updateMap(mapStack, level, pos, scale, destinationType, (Component)null);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -64,6 +82,27 @@ public class CommonLogic {
|
||||||
int scale,
|
int scale,
|
||||||
MapDecoration.Type destinationType,
|
MapDecoration.Type destinationType,
|
||||||
String displayName
|
String displayName
|
||||||
|
) {
|
||||||
|
updateMap(mapStack, level, pos, scale, destinationType, new TranslatableComponent(displayName));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Updates the map stack with all the given data.
|
||||||
|
*
|
||||||
|
* @param mapStack The map ItemStack to update
|
||||||
|
* @param level The ServerLevel
|
||||||
|
* @param pos The feature position
|
||||||
|
* @param scale The map scale
|
||||||
|
* @param destinationType The map feature type
|
||||||
|
* @param displayName The hover tooltip display name of the ItemStack
|
||||||
|
*/
|
||||||
|
public static void updateMap(
|
||||||
|
ItemStack mapStack,
|
||||||
|
ServerLevel level,
|
||||||
|
BlockPos pos,
|
||||||
|
int scale,
|
||||||
|
MapDecoration.Type destinationType,
|
||||||
|
Component displayName
|
||||||
) {
|
) {
|
||||||
MapItemAccess.callCreateAndStoreSavedData(
|
MapItemAccess.callCreateAndStoreSavedData(
|
||||||
mapStack, level, pos.getX(), pos.getZ(), scale, true, true, level.dimension()
|
mapStack, level, pos.getX(), pos.getZ(), scale, true, true, level.dimension()
|
||||||
|
|
@ -71,7 +110,8 @@ public class CommonLogic {
|
||||||
MapItem.renderBiomePreviewMap(level, mapStack);
|
MapItem.renderBiomePreviewMap(level, mapStack);
|
||||||
MapItemSavedData.addTargetDecoration(mapStack, pos, "+", destinationType);
|
MapItemSavedData.addTargetDecoration(mapStack, pos, "+", destinationType);
|
||||||
if (displayName != null)
|
if (displayName != null)
|
||||||
mapStack.setHoverName(new TranslatableComponent(displayName));
|
mapStack.setHoverName(displayName);
|
||||||
|
mapStack.removeTagKey(KEY_LOCATING);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,11 @@
|
||||||
package org.embeddedt.modernfix.forge.structure.logic;
|
package org.embeddedt.modernfix.forge.structure.logic;
|
||||||
|
|
||||||
|
import com.google.common.cache.Cache;
|
||||||
|
import com.google.common.cache.CacheBuilder;
|
||||||
import com.google.common.collect.ImmutableSet;
|
import com.google.common.collect.ImmutableSet;
|
||||||
import net.minecraft.core.BlockPos;
|
import net.minecraft.core.BlockPos;
|
||||||
|
import net.minecraft.network.chat.Component;
|
||||||
|
import net.minecraft.network.chat.TranslatableComponent;
|
||||||
import net.minecraft.server.level.ServerLevel;
|
import net.minecraft.server.level.ServerLevel;
|
||||||
import net.minecraft.world.item.ItemStack;
|
import net.minecraft.world.item.ItemStack;
|
||||||
import net.minecraft.world.item.Items;
|
import net.minecraft.world.item.Items;
|
||||||
|
|
@ -15,13 +19,29 @@ import net.minecraftforge.items.IItemHandlerModifiable;
|
||||||
import org.embeddedt.modernfix.ModernFix;
|
import org.embeddedt.modernfix.ModernFix;
|
||||||
import org.embeddedt.modernfix.forge.structure.AsyncLocator;
|
import org.embeddedt.modernfix.forge.structure.AsyncLocator;
|
||||||
|
|
||||||
|
import java.util.Locale;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
import java.util.function.BiConsumer;
|
import java.util.function.BiConsumer;
|
||||||
|
|
||||||
// TODO: Need to test this
|
// TODO: Need to test this
|
||||||
public class ExplorationMapFunctionLogic {
|
public class ExplorationMapFunctionLogic {
|
||||||
|
// I'd like to think that structure locating shouldn't take *this* long
|
||||||
|
private static final Cache<ItemStack, Component> MAP_NAME_CACHE =
|
||||||
|
CacheBuilder.newBuilder().expireAfterWrite(5, TimeUnit.MINUTES).build();
|
||||||
|
|
||||||
private static final int MAX_STACK_SIZE = 64;
|
private static final int MAX_STACK_SIZE = 64;
|
||||||
private ExplorationMapFunctionLogic() {}
|
private ExplorationMapFunctionLogic() {}
|
||||||
|
|
||||||
|
public static void cacheName(ItemStack stack, Component name) {
|
||||||
|
MAP_NAME_CACHE.put(stack, name);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Component getCachedName(ItemStack stack) {
|
||||||
|
Component name = MAP_NAME_CACHE.getIfPresent(stack);
|
||||||
|
MAP_NAME_CACHE.invalidate(stack);
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
public static void invalidateMap(ItemStack mapStack, ServerLevel level, BlockPos pos) {
|
public static void invalidateMap(ItemStack mapStack, ServerLevel level, BlockPos pos) {
|
||||||
handleUpdateMapInChest(mapStack, level, pos, (handler, slot) -> {
|
handleUpdateMapInChest(mapStack, level, pos, (handler, slot) -> {
|
||||||
if (handler instanceof IItemHandlerModifiable) {
|
if (handler instanceof IItemHandlerModifiable) {
|
||||||
|
|
@ -39,9 +59,10 @@ public class ExplorationMapFunctionLogic {
|
||||||
BlockPos pos,
|
BlockPos pos,
|
||||||
int scale,
|
int scale,
|
||||||
MapDecoration.Type destinationType,
|
MapDecoration.Type destinationType,
|
||||||
BlockPos invPos
|
BlockPos invPos,
|
||||||
|
Component displayName
|
||||||
) {
|
) {
|
||||||
CommonLogic.updateMap(mapStack, level, pos, scale, destinationType);
|
CommonLogic.updateMap(mapStack, level, pos, scale, destinationType, displayName);
|
||||||
// Shouldn't need to set the stack in its slot again, as we're modifying the same instance
|
// Shouldn't need to set the stack in its slot again, as we're modifying the same instance
|
||||||
handleUpdateMapInChest(mapStack, level, invPos, (handler, slot) -> {});
|
handleUpdateMapInChest(mapStack, level, invPos, (handler, slot) -> {});
|
||||||
}
|
}
|
||||||
|
|
@ -84,12 +105,17 @@ public class ExplorationMapFunctionLogic {
|
||||||
BlockPos pos,
|
BlockPos pos,
|
||||||
int scale,
|
int scale,
|
||||||
MapDecoration.Type destinationType,
|
MapDecoration.Type destinationType,
|
||||||
|
StructureFeature<?> destination,
|
||||||
BlockPos invPos
|
BlockPos invPos
|
||||||
) {
|
) {
|
||||||
if (pos == null) {
|
if (pos == null) {
|
||||||
invalidateMap(mapStack, level, invPos);
|
invalidateMap(mapStack, level, invPos);
|
||||||
} else {
|
} else {
|
||||||
updateMap(mapStack, level, pos, scale, destinationType, invPos);
|
Component displayName = getCachedName(mapStack);
|
||||||
|
if(displayName == null) {
|
||||||
|
displayName = new TranslatableComponent("filled_map." + destination.getFeatureName().toLowerCase(Locale.ROOT));
|
||||||
|
}
|
||||||
|
updateMap(mapStack, level, pos, scale, destinationType, invPos, displayName);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -104,7 +130,7 @@ public class ExplorationMapFunctionLogic {
|
||||||
) {
|
) {
|
||||||
ItemStack mapStack = CommonLogic.createEmptyMap();
|
ItemStack mapStack = CommonLogic.createEmptyMap();
|
||||||
AsyncLocator.locateLevel(level, ImmutableSet.of(destination), blockPos, searchRadius, skipKnownStructures)
|
AsyncLocator.locateLevel(level, ImmutableSet.of(destination), blockPos, searchRadius, skipKnownStructures)
|
||||||
.thenOnServerThread(pos -> handleLocationFound(mapStack, level, pos, scale, destinationType, blockPos));
|
.thenOnServerThread(pos -> handleLocationFound(mapStack, level, pos, scale, destinationType, destination, blockPos));
|
||||||
return mapStack;
|
return mapStack;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user