9
0
mirror of https://github.com/Xiao-MoMi/craft-engine.git synced 2025-12-25 09:59:20 +00:00

Merge branch 'Xiao-MoMi:dev' into dev

This commit is contained in:
jhqwqmc
2025-04-05 01:01:21 +08:00
committed by GitHub
19 changed files with 140 additions and 68 deletions

View File

@@ -69,12 +69,12 @@ search_recipe_admin:
- /craftengine item search-recipe
- /ce item search-recipe
totem:
totem_animation:
enable: true
permission: ce.command.admin.totem
permission: ce.command.admin.totem_animation
usage:
- /craftengine totem
- /ce totem
- /craftengine feature totem-animation
- /ce feature totem-animation
# Debug commands
debug_set_block:

View File

@@ -152,7 +152,14 @@ image:
sign: true
recipe:
# Enable the plugin's recipe system
enable: true
# Disable vanilla recipes
disable-vanilla-recipes:
# Disable all vanilla recipes
all: false
# Disable the recipes in list
list: []
gui:
browser:

View File

@@ -53,7 +53,7 @@ command.search_recipe.not_found: "<red>No recipe found for this item</red>"
command.search_usage.not_found: "<red>No usage found for this item</red>"
command.search_recipe.no_item: "<red>Please hold an item before running this command</red>"
command.search_usage.no_item: "<red>Please hold an item before running this command</red>"
command.totem.not_totem: "<red>'<arg:0>' is not type of totem_of_undying</red>"
command.totem_animation.failure.not_totem: "<red>Item '<arg:0>' is not minecraft:totem_of_undying</red>"
warning.config.image.duplicated: "<yellow>Issue found in file <arg:0> - Duplicated image '<arg:1>'.</yellow>"
warning.config.image.lack_height: "<yellow>Issue found in file <arg:0> - The image '<arg:1>' is missing the required 'height' argument.</yellow>"
warning.config.image.height_smaller_than_ascent: "<yellow>Issue found in file <arg:0> - The image '<arg:1>' violates the bitmap image rule: 'height' should be no lower than 'ascent'.</yellow>"
@@ -63,7 +63,7 @@ warning.config.image.invalid_font_name: "<yellow>Issue found in file <arg:0> - T
warning.config.image.lack_char: "<yellow>Issue found in file <arg:0> - The image '<arg:1>' is missing the required 'char' argument.</yellow>"
warning.config.image.codepoint_in_use: "<yellow>Issue found in file <arg:0> - The image '<arg:1>' is using a character[<arg:3>(<arg:4>)] in font <arg:2> that has been used by another image '<arg:5>'.</yellow>"
warning.config.image.invalid_codepoint_grid: "<yellow>Issue found in file <arg:0> - Image '<arg:1>' has an invalid 'chars' codepoint grind.</yellow>"
warning.config.image.file_not_exist: "<yellow>Issue found in file <arg:0> - PNG file <arg:2> not found for image '<arg:1>'.</yellow>"
warning.config.image.file_not_exist: "<yellow>Issue found in file <arg:0> - PNG file '<arg:2>' not found for image '<arg:1>'.</yellow>"
warning.config.recipe.duplicated: "<yellow>Issue found in file <arg:0> - Duplicated recipe '<arg:1>'.</yellow>"
warning.config.i18n.unknown_locale: "<yellow>Issue found in file <arg:0> - Unknown locale '<arg:1>'.</yellow>"
warning.config.template.duplicated: "<yellow>Issue found in file <arg:0> - Duplicated template '<arg:1>'.</yellow>"
@@ -93,8 +93,13 @@ warning.config.block.state.invalid_state: "<yellow>Issue found in file <arg:0> -
warning.config.block.state.unavailable_state: "<yellow>Issue found in file <arg:0> - The block '<arg:1>' is using an unavailable vanilla block state '<arg:2>'."
warning.config.block.state.invalid_vanilla_state_id: "<yellow>Issue found in file <arg:0> - The block '<arg:1>' is using a vanilla block state '<arg:2>' that exceeds the available slot range '0~<arg:3>'."
warning.config.block.state.conflict: "<yellow>Issue found in file <arg:0> - The block '<arg:1>' is using a vanilla block state '<arg:2>' that has been occupied by '<arg:3>'."
warning.config.block.bind_real_state: "<yellow>Issue found in file <arg:0> - The block '<arg:1>' failed to bind real block state for '<arg:2>' as the state has been occupied by '<arg:3>'.</yellow>"
warning.config.block.state.bind_real_state: "<yellow>Issue found in file <arg:0> - The block '<arg:1>' failed to bind real block state for '<arg:2>' as the state has been occupied by '<arg:3>'.</yellow>"
warning.config.block.state.invalid_property_structure: "<yellow>Issue found in file <arg:0> - The block '<arg:1>' has an invalid property structure '<arg:2>'."
warning.config.block.state.invalid_property: "<yellow>Issue found in file <arg:0> - Failed to create property '<arg:2>' for block '<arg:1>': <arg:3>."
warning.config.block.state.no_model_set: "<yellow>Issue found in file <arg:0> - The block '<arg:1>' is missing the required 'model' or 'models' argument.</yellow>"
warning.config.block.state.invalid_real_state_id: "<yellow>Issue found in file <arg:0> - The block '<arg:1>' is using a real block state '<arg:2>' that exceeds the available slot range '0~<arg:3>'. Consider adding more real states in 'additional-real-blocks.yml' if the slots are used up.</yellow>"
warning.config.block.state.invalid_real_state_id: "<yellow>Issue found in file <arg:0> - The block '<arg:1>' is using a real block state '<arg:2>' that exceeds the available slot range '0~<arg:3>'. Consider adding more real states in 'additional-real-blocks.yml' if the slots are used up.</yellow>"
warning.config.block.state.model.lack_path: "<yellow>Issue found in file <arg:0> - The block '<arg:1>' is missing the required 'path' option for 'model'.</yellow>"
warning.config.block.state.model.invalid_resource_location: "<yellow>Issue found in file <arg:0> - The block '<arg:1>' has a 'path' argument [<arg:2>] that contains legal characters. Please read https://minecraft.wiki/w/Resource_location#Legal_characters</yellow>"
warning.config.model.generation.conflict: "<yellow>Issue found in file <arg:0> - Failed to generate model for '<arg:1>' as two or more configurations attempt to generate different json models with the same path: '<arg:2>'</yellow>"
warning.config.model.generation.texture.invalid_resource_location: "<yellow>Issue found in file <arg:0> - The config '<arg:1>' has a '<arg:2>' texture argument [<arg:3>] that contains legal characters. Please read https://minecraft.wiki/w/Resource_location#Legal_characters</yellow>"
warning.config.model.generation.parent.invalid_resource_location: "<yellow>Issue found in file <arg:0> - The config '<arg:1>' has a parent argument [<arg:2>] that contains legal characters. Please read https://minecraft.wiki/w/Resource_location#Legal_characters</yellow>"

View File

@@ -53,4 +53,4 @@ command.search_recipe.not_found: "<red>No se encontró ninguna receta para este
command.search_usage.not_found: "<red>No se encontró ningún uso para este objeto</red>"
command.search_recipe.no_item: "<red>Por favor, sostén un objeto antes de ejecutar este comando</red>"
command.search_usage.no_item: "<red>Por favor, sostén un objeto antes de ejecutar este comando</red>"
command.totem.not_totem: "<red>'<arg:0>' no es del tipo totem_of_undying</red>"
command.totem_animation.failure.not_totem: "<red>'<arg:0>' no es del tipo totem_of_undying</red>"

View File

@@ -53,7 +53,7 @@ command.search_recipe.not_found: "<red>找不到此物品的配方</red>"
command.search_usage.not_found: "<red>找不到此物品的用途</red>"
command.search_recipe.no_item: "<red>请手持物品后再执行此命令</red>"
command.search_usage.no_item: "<red>请手持物品后再执行此命令</red>"
command.totem.not_totem: "<red>'<arg:0>' 不是 totem_of_undying 类型</red>"
command.totem_animation.failure.not_totem: "<red>'<arg:0>' 不是 totem_of_undying 类型</red>"
warning.config.image.duplicated: "<yellow>在文件 <arg:0> 中发现问题 - 图片 '<arg:1>' 重复定义</yellow>"
warning.config.image.lack_height: "<yellow>在文件 <arg:0> 中发现问题 - 图片 '<arg:1>' 缺少必要的 'height' 高度参数</yellow>"
warning.config.image.height_smaller_than_ascent: "<yellow>在文件 <arg:0> 中发现问题 - 图片 '<arg:1>' 违反位图规则:'height' 高度值不应小于 'ascent' 基准线高度</yellow>"
@@ -88,4 +88,18 @@ warning.config.block.state.lack_properties: "<yellow>在文件 <arg:0> 中发现
warning.config.block.state.lack_appearances: "<yellow>在文件 <arg:0> 中发现问题 - 方块 '<arg:1>' 的 'states' 配置缺少必要的 'appearances' 外观配置</yellow>"
warning.config.block.state.lack_variants: "<yellow>在文件 <arg:0> 中发现问题 - 方块 '<arg:1>' 的 'states' 配置缺少必要的 'variants' 变体配置</yellow>"
warning.config.block.state.variant.lack_appearance: "<yellow>在文件 <arg:0> 中发现问题 - 方块 '<arg:1>' 的 '<arg:2>' 变体配置缺少必要的 'appearance' 外观参数</yellow>"
warning.config.block.state.variant.invalid_appearance: "<yellow>在文件 <arg:0> 中发现问题 - 方块 '<arg:1>' 的 '<arg:2>' 变体引用了不存在的外观配置 '<arg:3>'</yellow>"
warning.config.block.state.variant.invalid_appearance: "<yellow>在文件 <arg:0> 中发现问题 - 方块 '<arg:1>' 的 '<arg:2>' 变体引用了不存在的外观配置 '<arg:3>'</yellow>"
warning.config.block.state.invalid_state: "<yellow>在文件 <arg:0> 中发现问题 - 方块 '<arg:1>' 使用了无效的原版方块状态 '<arg:2>'</yellow>"
warning.config.block.state.unavailable_state: "<yellow>在文件 <arg:0> 中发现问题 - 方块 '<arg:1>' 使用了不可用的原版方块状态 '<arg:2>'</yellow>"
warning.config.block.state.invalid_vanilla_state_id: "<yellow>在文件 <arg:0> 中发现问题 - 方块 '<arg:1>' 使用的原版方块状态 '<arg:2>' 超出可用槽位范围 '0~<arg:3>'</yellow>"
warning.config.block.state.conflict: "<yellow>在文件 <arg:0> 中发现问题 - 方块 '<arg:1>' 使用的原版方块状态 '<arg:2>' 已被 '<arg:3>' 占用</yellow>"
warning.config.block.state.bind_real_state: "<yellow>在文件 <arg:0> 中发现问题 - 方块 '<arg:1>' 未能绑定真实方块状态 '<arg:2>',该状态已被 '<arg:3>' 占用</yellow>"
warning.config.block.state.invalid_property_structure: "<yellow>在文件 <arg:0> 中发现问题 - 方块 '<arg:1>' 的属性结构 '<arg:2>' 配置无效</yellow>"
warning.config.block.state.invalid_property: "<yellow>在文件 <arg:0> 中发现问题 - 无法为方块 '<arg:1>' 创建属性 '<arg:2>'<arg:3></yellow>"
warning.config.block.state.no_model_set: "<yellow>在文件 <arg:0> 中发现问题 - 方块 '<arg:1>' 缺少必要的 'model' 或 'models' 模型参数</yellow>"
warning.config.block.state.invalid_real_state_id: "<yellow>在文件 <arg:0> 中发现问题 - 方块 '<arg:1>' 使用的真实方块状态 '<arg:2>' 超出可用槽位范围 '0~<arg:3>'。若槽位已用尽,请考虑在 additional-real-blocks.yml 中添加更多真实状态</yellow>"
warning.config.block.state.model.lack_path: "<yellow>在文件 <arg:0> 中发现问题 - 方块 '<arg:1>' 的 'model' 配置缺少必要的 'path' 路径参数</yellow>"
warning.config.block.state.model.invalid_resource_location: "<yellow>在文件 <arg:0> 中发现问题 - 方块 '<arg:1>' 的 'path' 路径参数 [<arg:2>] 包含非法字符请参考资源路径规范https://zh.minecraft.wiki/w/%E5%91%BD%E5%90%8D%E7%A9%BA%E9%97%B4ID#%E5%90%88%E6%B3%95%E5%AD%97%E7%AC%A6</yellow>"
warning.config.model.generation.conflict: "<yellow>在文件 <arg:0> 中发现问题 - 无法为 '<arg:1>' 生成模型,多个配置尝试用相同路径 '<arg:2>' 生成不同的JSON模型</yellow>"
warning.config.model.generation.texture.invalid_resource_location: "<yellow>在文件 <arg:0> 中发现问题 - 配置项 '<arg:1>' 的 '<arg:2>' 纹理参数 [<arg:3>] 包含非法字符请参考资源路径规范https://zh.minecraft.wiki/w/%E5%91%BD%E5%90%8D%E7%A9%BA%E9%97%B4ID#%E5%90%88%E6%B3%95%E5%AD%97%E7%AC%A6</yellow>"
warning.config.model.generation.parent.invalid_resource_location: "<yellow>在文件 <arg:0> 中发现问题 - 配置项 '<arg:1>' 的父模型参数 [<arg:2>] 包含非法字符请参考资源路径规范https://zh.minecraft.wiki/w/%E5%91%BD%E5%90%8D%E7%A9%BA%E9%97%B4ID#%E5%90%88%E6%B3%95%E5%AD%97%E7%AC%A6</yellow>"

View File

@@ -53,4 +53,4 @@ command.search_recipe.not_found: "<red>找不到此物品的配方</red>"
command.search_usage.not_found: "<red>找不到此物品的用途</red>"
command.search_recipe.no_item: "<red>執行此命令前請手持物品</red>"
command.search_usage.no_item: "<red>執行此命令前請手持物品</red>"
command.totem.not_totem: "<red>'<arg:0>' 不是 totem_of_undying 類型</red>"
command.totem_animation.failure.not_totem: "<red>'<arg:0>' 不是 totem_of_undying 類型</red>"

View File

@@ -21,6 +21,7 @@ import net.momirealms.craftengine.core.block.properties.Property;
import net.momirealms.craftengine.core.loot.LootTable;
import net.momirealms.craftengine.core.pack.LoadingSequence;
import net.momirealms.craftengine.core.pack.Pack;
import net.momirealms.craftengine.core.pack.ResourceLocation;
import net.momirealms.craftengine.core.pack.model.generation.ModelGeneration;
import net.momirealms.craftengine.core.plugin.CraftEngine;
import net.momirealms.craftengine.core.plugin.config.Config;
@@ -367,7 +368,7 @@ public class BukkitBlockManager extends AbstractBlockManager {
return;
}
Pair<Key, Integer> pair = parseAppearanceSection(path, id, stateSection);
Pair<Key, Integer> pair = parseAppearanceSection(pack, path, id, stateSection);
if (pair == null) return;
appearances = Map.of("default", pair.right());
@@ -407,7 +408,7 @@ public class BukkitBlockManager extends AbstractBlockManager {
Map<String, Key> tempTypeMap = new HashMap<>();
for (Map.Entry<String, Object> appearanceEntry : appearancesSection.entrySet()) {
if (appearanceEntry.getValue() instanceof Map<?, ?> appearanceSection) {
Pair<Key, Integer> pair = parseAppearanceSection(path, id, MiscUtils.castToMap(appearanceSection, false));
Pair<Key, Integer> pair = parseAppearanceSection(pack, path, id, MiscUtils.castToMap(appearanceSection, false));
if (pair == null) return;
appearances.put(appearanceEntry.getKey(), pair.right());
tempTypeMap.put(appearanceEntry.getKey(), pair.left());
@@ -463,7 +464,7 @@ public class BukkitBlockManager extends AbstractBlockManager {
for (ImmutableBlockState state : block.variantProvider().states()) {
ImmutableBlockState previous = stateId2ImmutableBlockStates[state.customBlockState().registryId() - BlockStateUtils.vanillaStateSize()];
if (previous != null && !previous.isEmpty()) {
TranslationManager.instance().log("warning.config.block.bind_real_state", path.toString(), id.toString(), state.toString(), previous.toString());
TranslationManager.instance().log("warning.config.block.state.bind_real_state", path.toString(), id.toString(), state.toString(), previous.toString());
continue;
}
stateId2ImmutableBlockStates[state.customBlockState().registryId() - BlockStateUtils.vanillaStateSize()] = state;
@@ -500,7 +501,7 @@ public class BukkitBlockManager extends AbstractBlockManager {
}
@Nullable
private Pair<Key, Integer> parseAppearanceSection(Path path, Key id, Map<String, Object> section) {
private Pair<Key, Integer> parseAppearanceSection(Pack pack, Path path, Key id, Map<String, Object> section) {
// require state non null
String vanillaStateString = (String) section.get("state");
if (vanillaStateString == null) {
@@ -538,11 +539,11 @@ public class BukkitBlockManager extends AbstractBlockManager {
List<JsonObject> variants = new ArrayList<>();
if (models instanceof Map<?, ?> singleModelSection) {
loadVariantModel(variants, MiscUtils.castToMap(singleModelSection, false));
loadVariantModel(pack, path, id, variants, MiscUtils.castToMap(singleModelSection, false));
} else if (models instanceof List<?> modelList) {
for (Object model : modelList) {
if (model instanceof Map<?,?> singleModelMap) {
loadVariantModel(variants, MiscUtils.castToMap(singleModelMap, false));
loadVariantModel(pack, path, id, variants, MiscUtils.castToMap(singleModelMap, false));
}
}
}
@@ -567,9 +568,17 @@ public class BukkitBlockManager extends AbstractBlockManager {
return Pair.of(block, vanillaStateRegistryId);
}
private void loadVariantModel(List<JsonObject> variants, Map<String, Object> singleModelMap) {
private void loadVariantModel(Pack pack, Path path, Key id, List<JsonObject> variants, Map<String, Object> singleModelMap) {
JsonObject json = new JsonObject();
String modelPath = (String) singleModelMap.get("path");
if (modelPath == null) {
TranslationManager.instance().log("warning.config.block.state.model.lack_path", path.toString(), id.toString());
return;
}
if (!ResourceLocation.isValid(modelPath)) {
TranslationManager.instance().log("warning.config.block.state.model.invalid_resource_location", path.toString(), id.toString(), modelPath);
return;
}
json.addProperty("model", modelPath);
if (singleModelMap.containsKey("x")) json.addProperty("x", MiscUtils.getAsInt(singleModelMap.get("x")));
if (singleModelMap.containsKey("y")) json.addProperty("y", MiscUtils.getAsInt(singleModelMap.get("y")));
@@ -577,7 +586,7 @@ public class BukkitBlockManager extends AbstractBlockManager {
if (singleModelMap.containsKey("weight")) json.addProperty("weight", MiscUtils.getAsInt(singleModelMap.get("weight")));
Map<String, Object> generationMap = MiscUtils.castToMap(singleModelMap.get("generation"), true);
if (generationMap != null) {
prepareModelGeneration(new ModelGeneration(Key.of(modelPath), generationMap));
prepareModelGeneration(path, id, new ModelGeneration(Key.of(modelPath), generationMap));
}
variants.add(json);
}

View File

@@ -349,7 +349,7 @@ public class BukkitItemManager extends AbstractItemManager<ItemStack> {
// Parse models
ItemModel model = ItemModels.fromMap(modelSection);
for (ModelGeneration generation : model.modelsToGenerate()) {
prepareModelGeneration(generation);
prepareModelGeneration(path, id, generation);
}
if (Config.packMaxVersion() > 21.39f) {
@@ -369,7 +369,7 @@ public class BukkitItemManager extends AbstractItemManager<ItemStack> {
// use components
ItemModel model = ItemModels.fromMap(modelSection);
for (ModelGeneration generation : model.modelsToGenerate()) {
prepareModelGeneration(generation);
prepareModelGeneration(path, id, generation);
}
if (Config.packMaxVersion() > 21.39f) {

View File

@@ -297,6 +297,7 @@ public class BukkitRecipeManager extends AbstractRecipeManager<ItemStack> {
@Override
public void unload() {
if (!Config.enableRecipeSystem()) return;
super.unload();
try {
if (VersionHelper.isVersionNewerThan1_21_2()) {
@@ -310,6 +311,7 @@ public class BukkitRecipeManager extends AbstractRecipeManager<ItemStack> {
@Override
public void delayedLoad() {
if (!Config.enableRecipeSystem()) return;
this.injectDataPackRecipes();
}
@@ -368,12 +370,23 @@ public class BukkitRecipeManager extends AbstractRecipeManager<ItemStack> {
for (Object pack : selected) {
packResources.add(Reflections.method$Pack$open.invoke(pack));
}
boolean hasDisabledAny = !Config.disabledVanillaRecipes().isEmpty();
try (AutoCloseable resourceManager = (AutoCloseable) Reflections.constructor$MultiPackResourceManager.newInstance(Reflections.instance$PackType$SERVER_DATA, packResources)) {
Map<Object, Object> scannedResources = (Map<Object, Object>) Reflections.method$FileToIdConverter$listMatchingResources.invoke(fileToIdConverter, resourceManager);
for (Map.Entry<Object, Object> entry : scannedResources.entrySet()) {
Key id = extractKeyFromResourceLocation(entry.getKey().toString());
// Maybe it's unregistered by other plugins
if (Bukkit.getRecipe(new NamespacedKey(id.namespace(), id.value())) == null) {
// now CraftEngine takes over everything
// // Maybe it's unregistered by other plugins
// if (Bukkit.getRecipe(new NamespacedKey(id.namespace(), id.value())) == null) {
// continue;
// }
if (Config.disableAllVanillaRecipes()) {
this.delayedTasksOnMainThread.add(() -> unregisterPlatformRecipe(id));
continue;
}
if (hasDisabledAny && Config.disabledVanillaRecipes().contains(id)) {
this.delayedTasksOnMainThread.add(() -> unregisterPlatformRecipe(id));
continue;
}
markAsDataPackRecipe(id);
@@ -423,6 +436,7 @@ public class BukkitRecipeManager extends AbstractRecipeManager<ItemStack> {
@Override
public void runDelayedSyncTasks() {
if (!Config.enableRecipeSystem()) return;
try {
// run delayed tasks
for (Runnable r : this.delayedTasksOnMainThread) {

View File

@@ -46,7 +46,7 @@ public class BukkitCommandManager extends AbstractCommandManager<CommandSender>
new DebugSetBlockCommand(this, plugin),
new DebugSpawnFurnitureCommand(this, plugin),
new DebugTargetBlockCommand(this, plugin),
new TotemCommand(this, plugin)
new TotemAnimationCommand(this, plugin)
));
final LegacyPaperCommandManager<CommandSender> manager = (LegacyPaperCommandManager<CommandSender>) getCommandManager();
manager.settings().set(ManagerSetting.ALLOW_UNSAFE_REGISTRATION, true);

View File

@@ -28,9 +28,9 @@ import org.incendo.cloud.suggestion.SuggestionProvider;
import java.util.concurrent.CompletableFuture;
public class TotemCommand extends BukkitCommandFeature<CommandSender> {
public class TotemAnimationCommand extends BukkitCommandFeature<CommandSender> {
public TotemCommand(CraftEngineCommandManager<CommandSender> commandManager, CraftEngine plugin) {
public TotemAnimationCommand(CraftEngineCommandManager<CommandSender> commandManager, CraftEngine plugin) {
super(commandManager, plugin);
}
@@ -49,15 +49,10 @@ public class TotemCommand extends BukkitCommandFeature<CommandSender> {
NamespacedKey namespacedKey = context.get("id");
Key key = Key.of(namespacedKey.namespace(), namespacedKey.value());
CustomItem<ItemStack> item = plugin().itemManager().getCustomItem(key).orElse(null);
if (item == null) {
handleFeedback(context, MessageConstants.COMMAND_ITEM_GET_FAILURE_NOT_EXIST, Component.text(key.toString()));
return;
}
if (MaterialUtils.getMaterial(item.material()) != Material.TOTEM_OF_UNDYING) {
if (item == null || MaterialUtils.getMaterial(item.material()) != Material.TOTEM_OF_UNDYING) {
handleFeedback(context, MessageConstants.COMMAND_TOTEM_NOT_TOTEM, Component.text(key.toString()));
return;
}
ItemStack totem = item.buildItemStack();
MultiplePlayerSelector selector = context.get("players");
for (Player player : selector.values()) {
@@ -68,6 +63,6 @@ public class TotemCommand extends BukkitCommandFeature<CommandSender> {
@Override
public String getFeatureID() {
return "totem";
return "totem_animation";
}
}

View File

@@ -3,6 +3,7 @@ package net.momirealms.craftengine.bukkit.plugin.user;
import com.google.common.collect.Lists;
import io.netty.channel.Channel;
import net.kyori.adventure.text.Component;
import net.momirealms.craftengine.bukkit.block.BukkitBlockManager;
import net.momirealms.craftengine.bukkit.item.BukkitItemManager;
import net.momirealms.craftengine.bukkit.nms.FastNMS;
import net.momirealms.craftengine.bukkit.plugin.BukkitCraftEngine;
@@ -13,6 +14,7 @@ import net.momirealms.craftengine.core.block.PackedBlockState;
import net.momirealms.craftengine.core.entity.player.InteractionHand;
import net.momirealms.craftengine.core.entity.player.Player;
import net.momirealms.craftengine.core.item.Item;
import net.momirealms.craftengine.core.item.ItemKeys;
import net.momirealms.craftengine.core.plugin.CraftEngine;
import net.momirealms.craftengine.core.plugin.network.ConnectionState;
import net.momirealms.craftengine.core.util.Direction;
@@ -437,16 +439,26 @@ public class BukkitServerPlayer extends Player {
return;
}
}
this.miningProgress = (float) Reflections.method$BlockStateBase$getDestroyProgress.invoke(this.destroyedState, serverPlayer, Reflections.method$Entity$level.invoke(serverPlayer), blockPos) + miningProgress;
float progressToAdd = (float) Reflections.method$BlockStateBase$getDestroyProgress.invoke(this.destroyedState, serverPlayer, Reflections.method$Entity$level.invoke(serverPlayer), blockPos);
int id = BlockStateUtils.blockStateToId(this.destroyedState);
ImmutableBlockState customState = BukkitBlockManager.instance().getImmutableBlockState(id);
if (customState != null && !customState.isEmpty()
&& !customState.settings().isCorrectTool(item == null ? ItemKeys.AIR : item.id())) {
progressToAdd *= customState.settings().incorrectToolSpeed();
}
this.miningProgress = progressToAdd + miningProgress;
int packetStage = (int) (this.miningProgress * 10.0F);
if (packetStage != this.lastSentState) {
this.lastSentState = packetStage;
broadcastDestroyProgress(player, hitPos, blockPos, packetStage);
}
if (this.miningProgress >= 1f) {
//Reflections.method$ServerLevel$levelEvent.invoke(Reflections.field$CraftWorld$ServerLevel.get(player.getWorld()), null, 2001, blockPos, BlockStateUtils.blockStateToId(this.destroyedState));
Reflections.method$ServerPlayerGameMode$destroyBlock.invoke(gameMode, blockPos);
Object levelEventPacket = Reflections.constructor$ClientboundLevelEventPacket.newInstance(2001, blockPos, BlockStateUtils.blockStateToId(this.destroyedState), false);
Object levelEventPacket = Reflections.constructor$ClientboundLevelEventPacket.newInstance(2001, blockPos, id, false);
sendPacket(levelEventPacket, false);
this.stopMiningBlock();
}

View File

@@ -28,6 +28,7 @@ public class BlockSettings {
@Nullable
Key itemId;
Set<Key> tags = Set.of();
float incorrectToolSpeed = 0.3f;
Set<Key> correctTools = Set.of();
String name;
@@ -81,6 +82,7 @@ public class BlockSettings {
newSettings.fluidState = settings.fluidState;
newSettings.blockLight = settings.blockLight;
newSettings.name = settings.name;
newSettings.incorrectToolSpeed = settings.incorrectToolSpeed;
return newSettings;
}
@@ -124,6 +126,10 @@ public class BlockSettings {
return canOcclude;
}
public float incorrectToolSpeed() {
return incorrectToolSpeed;
}
public String name() {
return name;
}
@@ -243,6 +249,11 @@ public class BlockSettings {
return this;
}
public BlockSettings incorrectToolSpeed(float incorrectToolSpeed) {
this.incorrectToolSpeed = incorrectToolSpeed;
return this;
}
public BlockSettings isRandomlyTicking(boolean isRandomlyTicking) {
this.isRandomlyTicking = isRandomlyTicking;
return this;
@@ -381,6 +392,10 @@ public class BlockSettings {
List<String> tools = MiscUtils.getAsStringList(value);
return settings -> settings.correctTools(tools.stream().map(Key::of).collect(Collectors.toSet()));
}));
registerFactory("incorrect-tool-dig-speed", (value -> {
float floatValue = MiscUtils.getAsFloat(value);
return settings -> settings.incorrectToolSpeed(floatValue);
}));
registerFactory("name", (value -> {
String name = value.toString();
return settings -> settings.name(name);

View File

@@ -1,8 +1,11 @@
package net.momirealms.craftengine.core.pack.model.generation;
import net.momirealms.craftengine.core.pack.ResourceLocation;
import net.momirealms.craftengine.core.plugin.CraftEngine;
import net.momirealms.craftengine.core.plugin.locale.TranslationManager;
import net.momirealms.craftengine.core.util.Key;
import java.nio.file.Path;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
@@ -25,16 +28,23 @@ public abstract class AbstractModelGenerator implements ModelGenerator {
this.modelsToGenerate.clear();
}
@Override
public void prepareModelGeneration(ModelGeneration model) {
ModelGeneration generation = this.modelsToGenerate.get(model.path());
if (generation != null) {
if (generation.equals(model)) {
public void prepareModelGeneration(Path path, Key id, ModelGeneration model) {
ModelGeneration conflict = this.modelsToGenerate.get(model.path());
if (conflict != null) {
if (conflict.equals(model)) {
return;
}
this.plugin.logger().severe("Two or more configurations attempt to generate different json models with the same path: " + model.path());
TranslationManager.instance().log("warning.config.model.generation.conflict", path.toString(), id.toString(), model.path().toString());
return;
}
if (!ResourceLocation.isValid(model.parentModelPath())) {
TranslationManager.instance().log("warning.config.model.generation.parent.invalid_resource_location", path.toString(), id.toString(), model.parentModelPath());
}
for (Map.Entry<String, String> texture : model.texturesOverride().entrySet()) {
if (!ResourceLocation.isValid(texture.getValue())) {
TranslationManager.instance().log("warning.config.model.generation.texture.invalid_resource_location", path.toString(), id.toString(), texture.getKey(), texture.getValue());
}
}
this.modelsToGenerate.put(model.path(), model);
}
}

View File

@@ -6,6 +6,4 @@ public interface ModelGenerator {
Collection<ModelGeneration> modelsToGenerate();
void clearModelsToGenerate();
void prepareModelGeneration(ModelGeneration model);
}

View File

@@ -17,6 +17,7 @@ import net.momirealms.craftengine.core.plugin.PluginProperties;
import net.momirealms.craftengine.core.plugin.locale.TranslationManager;
import net.momirealms.craftengine.core.plugin.logger.filter.DisconnectLogFilter;
import net.momirealms.craftengine.core.util.AdventureHelper;
import net.momirealms.craftengine.core.util.Key;
import net.momirealms.craftengine.core.util.MiscUtils;
import net.momirealms.craftengine.core.util.ReflectionUtils;
@@ -30,6 +31,7 @@ import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.*;
import java.util.stream.Collectors;
public class Config {
private static Config instance;
@@ -105,7 +107,10 @@ public class Config {
protected boolean furniture$hide_base_entity;
protected boolean block$sound_system$enable;
protected boolean recipe$enable;
protected boolean recipe$disable_vanilla_recipes$all;
protected Set<Key> recipe$disable_vanilla_recipes$list;
protected boolean item$non_italic_tag;
@@ -259,6 +264,8 @@ public class Config {
// recipe
recipe$enable = config.getBoolean("recipe.enable", true);
recipe$disable_vanilla_recipes$all = config.getBoolean("recipe.disable-vanilla-recipes.all", false);
recipe$disable_vanilla_recipes$list = config.getStringList("recipe.disable-vanilla-recipes.list").stream().map(Key::of).collect(Collectors.toSet());
// image
image$illegal_characters_filter$anvil = config.getBoolean("image.illegal-characters-filter.anvil", true);
@@ -350,6 +357,14 @@ public class Config {
return instance.recipe$enable;
}
public static boolean disableAllVanillaRecipes() {
return instance.recipe$disable_vanilla_recipes$all;
}
public static Set<Key> disabledVanillaRecipes() {
return instance.recipe$disable_vanilla_recipes$list;
}
public static boolean nonItalic() {
return instance.item$non_italic_tag;
}

View File

@@ -20,5 +20,5 @@ public interface MessageConstants {
TranslatableComponent.Builder COMMAND_SEARCH_RECIPE_NO_ITEM = Component.translatable().key("command.search_recipe.no_item");
TranslatableComponent.Builder COMMAND_SEARCH_USAGE_NOT_FOUND = Component.translatable().key("command.search_usage.not_found");
TranslatableComponent.Builder COMMAND_SEARCH_USAGE_NO_ITEM = Component.translatable().key("command.search_usage.no_item");
TranslatableComponent.Builder COMMAND_TOTEM_NOT_TOTEM = Component.translatable().key("command.totem.not_totem");
TranslatableComponent.Builder COMMAND_TOTEM_NOT_TOTEM = Component.translatable().key("command.totem_animation.failure.not_totem");
}

View File

@@ -1,22 +0,0 @@
package net.momirealms.craftengine.core.util;
import org.jetbrains.annotations.NotNull;
public class PreConditions {
private PreConditions() {}
public static boolean runIfTrue(boolean value, @NotNull Runnable runnable) {
if (value) {
runnable.run();
}
return value;
}
public static boolean isNull(Object value, @NotNull Runnable runnable) {
if (value == null) {
runnable.run();
}
return value == null;
}
}

View File

@@ -4,7 +4,7 @@ org.gradle.jvmargs=-Xmx1G
# Rule: [major update].[feature update].[bug fix]
project_version=0.0.43
config_version=19
lang_version=3
lang_version=4
project_group=net.momirealms
latest_minecraft_version=1.21.4