diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md index 825f48c372..62c59b14cd 100644 --- a/.github/PULL_REQUEST_TEMPLATE.md +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -1,3 +1,5 @@ + + ## 简介 diff --git a/.mvn/maven-git-versioning-extension.xml b/.mvn/maven-git-versioning-extension.xml index e1702b0ad5..8334857058 100644 --- a/.mvn/maven-git-versioning-extension.xml +++ b/.mvn/maven-git-versioning-extension.xml @@ -10,7 +10,7 @@ 4.9-release-${commit.timestamp.year}.${commit.timestamp.month} - feature/(.+) + test/(.+) 4.9-${1}-${commit.short} diff --git a/CHANGELOG.md b/CHANGELOG.md index 6276538b00..d5e7bd87ac 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -43,7 +43,12 @@ * Added Spore Blossom as a fuel type for the Bio-Generator * Added a new item setting for Freezers to allow them to use a 9:1 "vanilla" ratio instead of 1:1 (1:1 by default, like before) * (API) Added `PlayerProfile#hasUnlockedEverything()` to check if a player has unlocked all researches +* (API) Added `Research#getUnlocalizedName()` * Added support for the plugin "HuskTowns" +* Added support for Minecraft 1.18.2 +* You can now pick up Slimefun blocks in creative mode using the middle mouse button +* `/sf search` no longer shows items in hidden item groups (can be overidden by a config setting) +* Fluid Pumps can now fill bottles with water #### Changes * (API) `BiomeMapParser` is now `public` @@ -61,6 +66,7 @@ * Fixed "LogBlock" integration * Fixed "Lands" integration * Fixed #3133 +* Fixed #3483 ## Release Candidate 30 (31 Dec 2021) https://thebusybiscuit.github.io/builds/TheBusyBiscuit/Slimefun4/stable/#30 diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 0000000000..40f57fcabf --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,33 @@ +# 贡献代码指南 + +在向 Slimefun 汉化版提交代码前, 你必须先阅读这个指南 + +# 提交信息规范 + +本项目强制使用 [约定式提交](https://www.conventionalcommits.org/zh-hans/v1.0.0/) 的提交信息规范 + +> 简单来说, 你的提交信息需要包含以下内容: +> +> <类型>[可选 范围]: <描述> +> +> 例如一个添加了新功能的提交应为 feat(item): add new item to Slimefun + +此外, 推荐你使用 [gitmoji](https://gitmoji.dev/) 规范, 但并不强制你使用. + +如果你提交的代码中解决或处理了 Issue 中的问题, 请你在主提交消息外显式声明 + +> 如 resolves #114514, fix #114514 等 + +如果是修复请在主提交消息上声明, 不必重复声明. + +另外的, 如果是与翻译相关的提交, 类型应为 trans + + + +# 代码规范 + +**本项目使用空格缩进!!!!!!!!!!** + +请不要过度缩减代码长度, 空格少了 Slimefun 也不会因此跑得更快. + +如果你希望你的代码被合并至官方, 请遵守 Slimefun 主仓库的 [提交规范](https://github.com/Slimefun/Slimefun4/blob/master/CONTRIBUTING.md) \ No newline at end of file diff --git a/README.md b/README.md index 74f576f1d3..2cfcf75e9f 100644 --- a/README.md +++ b/README.md @@ -33,21 +33,21 @@ Slimefun 让每个玩家可以自己决定在魔法或科技方面发展
该项目从2013年开始开发,此后一直发展.
从那时一个人开发插件到发展成一个拥有数千名参与者和一百多位贡献者的社区.
它目前添加了超过 **500 种新物品/合成配方** -([查看关于 Slimefun 的历史](https://slimefun.guizhanss.wiki/Slimefun-in-a-nutshell)). +([查看关于 Slimefun 的历史](https://slimefun-wiki.guizhanss.cn/Slimefun-in-a-nutshell)). 与此同时, Slimefun 还有种类繁多的扩展插件可供选择!
-打开 [扩展列表](https://slimefun.guizhanss.wiki/Addons), 你可能会找到你想要的扩展. +打开 [扩展列表](https://slimefun-wiki.guizhanss.cn/Addons), 你可能会找到你想要的扩展. ### 导航 * **[下载 Slimefun 4](#%e4%b8%8b%e8%bd%bd-Slimefun4)** * **[Discord 服务器](#discord)** * **[Bug 反馈](https://github.com/StarWishsama/Slimefun4/issues)** * **[官方Wiki](https://github.com/Slimefun/Slimefun4/wiki)** -* **[非官方中文 Wiki](https://slimefun.guizhanss.wiki/)** -* **[FAQ](https://slimefun.guizhanss.wiki/FAQ)** +* **[非官方中文 Wiki](https://slimefun-wiki.guizhanss.cn/)** +* **[FAQ](https://slimefun-wiki.guizhanss.cn/FAQ)** ## :floppy_disk: 下载 Slimefun4 -(可以查看: [如何安装 Slimefun](https://slimefun.guizhanss.wiki/Installing-Slimefun)) +(可以查看: [如何安装 Slimefun](https://slimefun-wiki.guizhanss.cn/Installing-Slimefun)) Slimefun 4 可以在 Releases 页面下 **免费下载**.
目前汉化版仅提供了官方开发版的选项, 但某些发布的版本会被标记为官方的 "稳定" 版.
@@ -96,18 +96,18 @@ Slimefun 4 可以在 Releases 页面下 **免费下载**.
Slimefun 有一个 (详细且经常维护的 - *咳咳*) Wiki 为新玩家准备, 你也可以考虑为 Wiki 的编写献出一份力量. 官方 Wiki: https://github.com/Slimefun/Slimefun4/wiki -非官方中文 Wiki: https://slimefun.guizhanss.wiki/ +非官方中文 Wiki: https://slimefun-wiki.guizhanss.cn/ #### :star: 有用的文章 (中文) -* [什么是 Slimefun?](https://slimefun.guizhanss.wiki/Slimefun-in-a-nutshell) -* [如何安装 Slimefun](https://slimefun.guizhanss.wiki/Installing-Slimefun) -* [Slimefun 4 扩展列表](https://slimefun.guizhanss.wiki/Addons) -* [Slimefun 4 扩展编写教程](https://slimefun.guizhanss.wiki/Developer-Guide) -* [开始使用](https://slimefun.guizhanss.wiki/Getting-Started) -* [常见问题](https://slimefun.guizhanss.wiki/FAQ) -* [使用中的常见问题](https://slimefun.guizhanss.wiki/Common-Issues) -* [帮助我们扩展 Wiki!](https://slimefun.guizhanss.wiki/Expanding-the-Wiki) -* [帮助我们翻译 Slimefun!](https://slimefun.guizhanss.wiki/Translating-Slimefun) +* [什么是 Slimefun?](https://slimefun-wiki.guizhanss.cn/Slimefun-in-a-nutshell) +* [如何安装 Slimefun](https://slimefun-wiki.guizhanss.cn/Installing-Slimefun) +* [Slimefun 4 扩展列表](https://slimefun-wiki.guizhanss.cn/Addons) +* [Slimefun 4 扩展编写教程](https://slimefun-wiki.guizhanss.cn/Developer-Guide) +* [开始使用](https://slimefun-wiki.guizhanss.cn/Getting-Started) +* [常见问题](https://slimefun-wiki.guizhanss.cn/FAQ) +* [使用中的常见问题](https://slimefun-wiki.guizhanss.cn/Common-Issues) +* [帮助我们扩展 Wiki!](https://slimefun-wiki.guizhanss.cn/Expanding-the-Wiki) +* [帮助我们翻译 Slimefun!](https://slimefun-wiki.guizhanss.cn/Translating-Slimefun) 这个 Wiki 由 @ybw0014 进行维护, 如果你发现有文章缺失, 可以咨询他补充. diff --git a/pom.xml b/pom.xml index 18af20783a..36f8a08e0f 100644 --- a/pom.xml +++ b/pom.xml @@ -110,7 +110,7 @@ org.apache.maven.plugins maven-compiler-plugin - 3.9.0 + 3.10.0 @@ -233,7 +233,7 @@ io.github.baked-libs dough-api - 1.1.2 + 1.1.3 compile @@ -267,13 +267,13 @@ org.mockito mockito-core - 4.3.1 + 4.4.0 test com.github.seeseemelk MockBukkit-v1.18 - 1.15.5 + 1.18.1 test @@ -286,7 +286,6 @@ - com.sk89q.worldedit @@ -361,7 +360,7 @@ com.github.LoneDev6 itemsadder-api - 2.5.5 + 3.0.0 provided diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/api/items/SlimefunItem.java b/src/main/java/io/github/thebusybiscuit/slimefun4/api/items/SlimefunItem.java index 175c022e13..268fe006de 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/api/items/SlimefunItem.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/api/items/SlimefunItem.java @@ -221,6 +221,11 @@ protected SlimefunItem(ItemGroup itemGroup, ItemStack item, String id, RecipeTyp return itemGroup; } + /** + * Retrieve the recipe for this {@link SlimefunItem}. + * + * @return An {@link ItemStack} array of 9 which represents the recipe for this {@link SlimefunItem} + */ public @Nonnull ItemStack[] getRecipe() { return recipe; } @@ -655,7 +660,12 @@ public void setResearch(@Nullable Research research) { this.research = research; } - public void setRecipe(ItemStack[] recipe) { + /** + * Sets the recipe for this {@link SlimefunItem}. + * + * @param recipe The recipe for this {@link ItemStack} + */ + public void setRecipe(@Nonnull ItemStack[] recipe) { if (recipe == null || recipe.length != 9) { throw new IllegalArgumentException("Recipes must be of length 9"); } @@ -663,6 +673,11 @@ public void setRecipe(ItemStack[] recipe) { this.recipe = recipe; } + /** + * Sets the {@link RecipeType} for this {@link SlimefunItem}. + * + * @param type The {@link RecipeType} for this {@link SlimefunItem} + */ public void setRecipeType(@Nonnull RecipeType type) { Validate.notNull(type, "The RecipeType is not allowed to be null!"); this.recipeType = type; @@ -862,7 +877,7 @@ public final void addOfficialWikipage(@Nonnull String page) { Validate.notNull(page, "Wiki page cannot be null."); // 转换链接 page = page.replace("#", "?id="); - wikiURL = Optional.of("https://slimefun.guizhanss.wiki/" + page); + wikiURL = Optional.of("https://slimefun-wiki.guizhanss.cn/" + page); } /** @@ -1119,10 +1134,22 @@ public final int hashCode() { return getId().hashCode(); } + /** + * Retrieve a {@link SlimefunItem} by its id. + * + * @param id The id of the {@link SlimefunItem} + * @return The {@link SlimefunItem} associated with that id. Null if non-existent + */ public static @Nullable SlimefunItem getById(@Nonnull String id) { return Slimefun.getRegistry().getSlimefunItemIds().get(id); } + /** + * Retrieve a {@link SlimefunItem} from an {@link ItemStack}. + * + * @param item The {@link ItemStack} to check + * @return The {@link SlimefunItem} associated with this {@link ItemStack} if present, otherwise null + */ public static @Nullable SlimefunItem getByItem(@Nullable ItemStack item) { if (item == null || item.getType() == Material.AIR) { return null; diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/api/researches/Research.java b/src/main/java/io/github/thebusybiscuit/slimefun4/api/researches/Research.java index 8223a2327e..72c68d3dea 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/api/researches/Research.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/api/researches/Research.java @@ -12,6 +12,7 @@ import org.apache.commons.lang.Validate; import org.bukkit.Bukkit; +import org.bukkit.ChatColor; import org.bukkit.GameMode; import org.bukkit.Keyed; import org.bukkit.NamespacedKey; @@ -120,6 +121,15 @@ public int getID() { return localized != null ? localized : name; } + /** + * Retrieve the name of this {@link Research} without any localization nor coloring. + * + * @return The unlocalized, decolorized name for this {@link Research} + */ + public @Nonnull String getUnlocalizedName() { + return ChatColor.stripColor(name); + } + /** * Gets the cost in XP levels to unlock this {@link Research}. * diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/core/SlimefunRegistry.java b/src/main/java/io/github/thebusybiscuit/slimefun4/core/SlimefunRegistry.java index e3865a4ef3..107542de50 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/core/SlimefunRegistry.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/core/SlimefunRegistry.java @@ -104,7 +104,8 @@ public void load(@Nonnull Slimefun plugin, @Nonnull Config cfg) { guideKey = new NamespacedKey(plugin, "slimefun_guide_mode"); boolean showVanillaRecipes = cfg.getBoolean("guide.show-vanilla-recipes"); - guides.put(SlimefunGuideMode.SURVIVAL_MODE, new SurvivalSlimefunGuide(showVanillaRecipes)); + boolean showHiddenItemGroupsInSearch = cfg.getBoolean("guide.show-hidden-item-groups-in-search"); + guides.put(SlimefunGuideMode.SURVIVAL_MODE, new SurvivalSlimefunGuide(showVanillaRecipes, showHiddenItemGroupsInSearch)); guides.put(SlimefunGuideMode.CHEAT_MODE, new CheatSheetSlimefunGuide()); researchRanks.addAll(cfg.getStringList("research-ranks")); diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/core/guide/options/PlayerLanguageOption.java b/src/main/java/io/github/thebusybiscuit/slimefun4/core/guide/options/PlayerLanguageOption.java index 97f18bc907..df0f72e678 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/core/guide/options/PlayerLanguageOption.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/core/guide/options/PlayerLanguageOption.java @@ -89,7 +89,7 @@ private void openLanguageSelection(Player p, ItemStack guide) { }); } else if (i == 7) { menu.addItem(7, new CustomItemStack(SlimefunUtils.getCustomHead(HeadTexture.ADD_NEW_LANGUAGE.getTexture()), Slimefun.getLocalization().getMessage(p, "guide.languages.translations.name"), "", "&7\u21E8 &e" + Slimefun.getLocalization().getMessage(p, "guide.languages.translations.lore")), (pl, slot, item, action) -> { - ChatUtils.sendURL(pl, "https://slimefun.guizhanss.wiki/Translating-Slimefun"); + ChatUtils.sendURL(pl, "https://slimefun-wiki.guizhanss.cn/Translating-Slimefun"); pl.closeInventory(); return false; }); diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/core/guide/options/SlimefunGuideSettings.java b/src/main/java/io/github/thebusybiscuit/slimefun4/core/guide/options/SlimefunGuideSettings.java index d7ce331ae3..df1c70f1f4 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/core/guide/options/SlimefunGuideSettings.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/core/guide/options/SlimefunGuideSettings.java @@ -161,7 +161,7 @@ private static void addHeader(Player p, ChestMenu menu, ItemStack guide) { menu.addMenuClickHandler(8, (pl, slot, item, action) -> { pl.closeInventory(); - ChatUtils.sendURL(pl, "https://slimefun.guizhanss.wiki/"); + ChatUtils.sendURL(pl, "https://slimefun-wiki.guizhanss.cn/"); return false; }); @@ -181,7 +181,7 @@ private static void addHeader(Player p, ChestMenu menu, ItemStack guide) { menu.addMenuClickHandler(47, (pl, slot, item, action) -> { pl.closeInventory(); - ChatUtils.sendURL(pl, "https://slimefun.guizhanss.wiki/Addons"); + ChatUtils.sendURL(pl, "https://slimefun-wiki.guizhanss.cn/Addons"); return false; }); diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/core/services/localization/Language.java b/src/main/java/io/github/thebusybiscuit/slimefun4/core/services/localization/Language.java index b112cc6080..a9f7c7f59a 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/core/services/localization/Language.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/core/services/localization/Language.java @@ -59,8 +59,7 @@ public Language(@Nonnull String id, @Nonnull String hash) { * * @return The identifier of this {@link Language} */ - @Nonnull - public String getId() { + public @Nonnull String getId() { return id; } @@ -101,8 +100,7 @@ public void setFile(@Nonnull LanguageFile file, @Nonnull FileConfiguration confi * * @return The {@link ItemStack} used to display this {@link Language} */ - @Nonnull - public ItemStack getItem() { + public @Nonnull ItemStack getItem() { return item; } @@ -114,8 +112,7 @@ public ItemStack getItem() { * The {@link Player} to localize the name for * @return The localized name of this {@link Language} */ - @Nonnull - public String getName(@Nonnull Player p) { + public @Nonnull String getName(@Nonnull Player p) { return Slimefun.getLocalization().getMessage(p, "languages." + id); } @@ -136,7 +133,11 @@ public String toString() { @Nonnull FileConfiguration[] getFiles() { - return Arrays.stream(LanguageFile.valuesCached).map(this::getFile).toArray(FileConfiguration[]::new); + // @formatter:off + return Arrays.stream(LanguageFile.valuesCached) + .map(this::getFile) + .toArray(FileConfiguration[]::new); + // @formatter:on } } \ No newline at end of file diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/core/services/localization/LanguagePreset.java b/src/main/java/io/github/thebusybiscuit/slimefun4/core/services/localization/LanguagePreset.java index c04c74a318..bc692be6e6 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/core/services/localization/LanguagePreset.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/core/services/localization/LanguagePreset.java @@ -1,78 +1,95 @@ package io.github.thebusybiscuit.slimefun4.core.services.localization; -import org.bukkit.inventory.ItemStack; - import javax.annotation.Nonnull; import javax.annotation.ParametersAreNonnullByDefault; +import org.bukkit.inventory.ItemStack; + /** * This enum holds info about a {@link Language} that is embedded in our resources folder. * Every enum constant holds the key of that {@link Language} as well as a texture hash * for the {@link ItemStack} to display. - * + * * @author TheBusyBiscuit - * + * * @see Language * */ public enum LanguagePreset { - ENGLISH("en", true, "a1701f21835a898b20759fb30a583a38b994abf60d3912ab4ce9f2311e74f72"), - GERMAN("de", true, "5e7899b4806858697e283f084d9173fe487886453774626b24bd8cfecc77b3f"), - FRENCH("fr", true, "51269a067ee37e63635ca1e723b676f139dc2dbddff96bbfef99d8b35c996bc"), - ITALIAN("it", true, "85ce89223fa42fe06ad65d8d44ca412ae899c831309d68924dfe0d142fdbeea4"), - SPANISH("es", true, "32bd4521983309e0ad76c1ee29874287957ec3d96f8d889324da8c887e485ea8"), - RUSSIAN("ru", true, "16eafef980d6117dabe8982ac4b4509887e2c4621f6a8fe5c9b735a83d775ad"), + ENGLISH("en", "a1701f21835a898b20759fb30a583a38b994abf60d3912ab4ce9f2311e74f72"), + GERMAN("de", "5e7899b4806858697e283f084d9173fe487886453774626b24bd8cfecc77b3f"), + FRENCH("fr", "51269a067ee37e63635ca1e723b676f139dc2dbddff96bbfef99d8b35c996bc"), + ITALIAN("it", "85ce89223fa42fe06ad65d8d44ca412ae899c831309d68924dfe0d142fdbeea4"), + SPANISH("es", "32bd4521983309e0ad76c1ee29874287957ec3d96f8d889324da8c887e485ea8"), + RUSSIAN("ru", "16eafef980d6117dabe8982ac4b4509887e2c4621f6a8fe5c9b735a83d775ad"), POLISH("pl", false, "921b2af8d2322282fce4a1aa4f257a52b68e27eb334f4a181fd976bae6d8eb"), - UKRAINIAN("uk", true, "28b9f52e36aa5c7caaa1e7f26ea97e28f635e8eac9aef74cec97f465f5a6b51"), + UKRAINIAN("uk", "28b9f52e36aa5c7caaa1e7f26ea97e28f635e8eac9aef74cec97f465f5a6b51"), BELARUSIAN("be", false, "8c12eaf0d83e97e2bace652d0d23e74908ee766894361271f00c22ea82d25b02"), - SWEDISH("sv", true, "e910904bff9c86f6ed47688e9429c26e8d9c5d5743bd3ebb8e6f5040be192998"), + SWEDISH("sv", "e910904bff9c86f6ed47688e9429c26e8d9c5d5743bd3ebb8e6f5040be192998"), DUTCH("nl", false, "c23cf210edea396f2f5dfbced69848434f93404eefeabf54b23c073b090adf"), DANISH("da", false, "10c23055c392606f7e531daa2676ebe2e348988810c15f15dc5b3733998232"), FINNISH("fi", false, "59f2349729a7ec8d4b1478adfe5ca8af96479e983fbad238ccbd81409b4ed"), NORWEGIAN("no", false, "e0596e165ec3f389b59cfdda93dd6e363e97d9c6456e7c2e123973fa6c5fda"), - CZECH("cs", true, "48152b7334d7ecf335e47a4f35defbd2eb6957fc7bfe94212642d62f46e61e"), + CZECH("cs", "48152b7334d7ecf335e47a4f35defbd2eb6957fc7bfe94212642d62f46e61e"), ROMANIAN("ro", false, "dceb1708d5404ef326103e7b60559c9178f3dce729007ac9a0b498bdebe46107"), - BULGARIAN("bg", false, "19039e1fd88c78d9d7adc5aad5ab16e356be13464934ed9e2b0cef2051c5b534"), + BULGARIAN("bg", "19039e1fd88c78d9d7adc5aad5ab16e356be13464934ed9e2b0cef2051c5b534"), PORTUGUESE_PORTUGAL("pt", false, "ebd51f4693af174e6fe1979233d23a40bb987398e3891665fafd2ba567b5a53a"), - PORTUGUESE_BRAZIL("pt-BR", true, "9a46475d5dcc815f6c5f2859edbb10611f3e861c0eb14f088161b3c0ccb2b0d9"), - HUNGARIAN("hu", true, "4a9c3c4b6c5031332dd2bfece5e31e999f8deff55474065cc86993d7bdcdbd0"), + PORTUGUESE_BRAZIL("pt-BR", "9a46475d5dcc815f6c5f2859edbb10611f3e861c0eb14f088161b3c0ccb2b0d9"), + HUNGARIAN("hu", "4a9c3c4b6c5031332dd2bfece5e31e999f8deff55474065cc86993d7bdcdbd0"), CROATIAN("hr", false, "b050c04ec8cabce71d7103f3e9ef4bb8819f9f365eb335a9139912bc07ed445"), LATVIAN("lv", false, "f62a4938b59447f996b5ed94101df07429d1ad34776d591ffc6fd75b79473c"), GREEK("el", false, "1514de6dd2b7682b1d3ebcd10291ae1f021e3012b5c8beffeb75b1819eb4259d"), - SLOVAK("sk", true, "6c72a8c115a1fb669a25715c4d15f22136ac4c2452784e4894b3d56bc5b0b9"), - VIETNAMESE("vi", true, "8a57b9d7dd04169478cfdb8d0b6fd0b8c82b6566bb28371ee9a7c7c1671ad0bb"), - INDONESIAN("id", true, "5db2678ccaba7934412cb97ee16d416463a392574c5906352f18dea42895ee"), - CHINESE_CHINA("zh-CN", true, "7f9bc035cdc80f1ab5e1198f29f3ad3fdd2b42d9a69aeb64de990681800b98dc"), - CHINESE_TAIWAN("zh-TW", true, "702a4afb2e1e2e3a1894a8b74272f95cfa994ce53907f9ac140bd3c932f9f"), - JAPANESE("ja", true, "d640ae466162a47d3ee33c4076df1cab96f11860f07edb1f0832c525a9e33323"), - KOREAN("ko", true, "fc1be5f12f45e413eda56f3de94e08d90ede8e339c7b1e8f32797390e9a5f"), - HEBREW("he", true, "1ba086a2cc7272cf5ba49c80248546c22e5ef1bab54120e8a8e5d9e75b6a"), - ARABIC("ar", true, "a4be759a9cf7f0a19a7e8e62f23789ad1d21cebae38af9d9541676a3db001572"), - TURKISH("tr", true, "9852b9aba3482348514c1034d0affe73545c9de679ae4647f99562b5e5f47d09"), + SLOVAK("sk", "6c72a8c115a1fb669a25715c4d15f22136ac4c2452784e4894b3d56bc5b0b9"), + VIETNAMESE("vi", "8a57b9d7dd04169478cfdb8d0b6fd0b8c82b6566bb28371ee9a7c7c1671ad0bb"), + INDONESIAN("id", "5db2678ccaba7934412cb97ee16d416463a392574c5906352f18dea42895ee"), + CHINESE_CHINA("zh-CN", "7f9bc035cdc80f1ab5e1198f29f3ad3fdd2b42d9a69aeb64de990681800b98dc"), + CHINESE_TAIWAN("zh-TW", "702a4afb2e1e2e3a1894a8b74272f95cfa994ce53907f9ac140bd3c932f9f"), + JAPANESE("ja", "d640ae466162a47d3ee33c4076df1cab96f11860f07edb1f0832c525a9e33323"), + KOREAN("ko", "fc1be5f12f45e413eda56f3de94e08d90ede8e339c7b1e8f32797390e9a5f"), + HEBREW("he", TextDirection.RIGHT_TO_LEFT, "1ba086a2cc7272cf5ba49c80248546c22e5ef1bab54120e8a8e5d9e75b6a"), + ARABIC("ar", TextDirection.RIGHT_TO_LEFT, "a4be759a9cf7f0a19a7e8e62f23789ad1d21cebae38af9d9541676a3db001572"), + TURKISH("tr", "9852b9aba3482348514c1034d0affe73545c9de679ae4647f99562b5e5f47d09"), PERSIAN("fa", false, "5cd9badf1972583b663b44b1e027255de8f275aa1e89defcf77782ba6fcc652"), - SERBIA("sr", false, "5b0483a4f0ddf4fbbc977b127b3d294d7a869f995366e3f50f6b05a70f522510"), + SERBIAN("sr", false, "5b0483a4f0ddf4fbbc977b127b3d294d7a869f995366e3f50f6b05a70f522510"), AFRIKAANS("af", false, "961a1eacc10524d1f45f23b0e487bb2fc33948d9676b418b19a3da0b109d0e3c"), MALAY("ms", false, "754b9041dea6db6db44750f1385a743adf653767b4b8802cad4c585dd3f5be46"), - THAI("th", true, "2a7916e4a852f7e6f3f3de19c7fb57686a37bce834bd54684a7dbef8d53fb"), - MACEDONIAN("mk", false, "a0e0b0b5d87a855466980a101a757bcdb5f77d9f7287889f3efa998ee0472fc0"), - TAGALOG("tl", true, "9306c0c1ce6a9c61bb42a572c49e6d0ed20e0e6b3d122cc64c339cbf78e9e937"); + THAI("th", "2a7916e4a852f7e6f3f3de19c7fb57686a37bce834bd54684a7dbef8d53fb"), + MACEDONIAN("mk", "a0e0b0b5d87a855466980a101a757bcdb5f77d9f7287889f3efa998ee0472fc0"), + TAGALOG("tl", "9306c0c1ce6a9c61bb42a572c49e6d0ed20e0e6b3d122cc64c339cbf78e9e937"); private final String id; private final boolean releaseReady; private final String textureHash; + private final TextDirection textDirection; @ParametersAreNonnullByDefault - LanguagePreset(String id, boolean releaseReady, String textureHash) { + LanguagePreset(String id, boolean releaseReady, TextDirection direction, String textureHash) { this.id = id; this.releaseReady = releaseReady; this.textureHash = textureHash; + this.textDirection = direction; + } + + @ParametersAreNonnullByDefault + LanguagePreset(String id, boolean releaseReady, String textureHash) { + this(id, releaseReady, TextDirection.LEFT_TO_RIGHT, textureHash); + } + + @ParametersAreNonnullByDefault + LanguagePreset(String id, TextDirection direction, String textureHash) { + this(id, true, direction, textureHash); + } + + @ParametersAreNonnullByDefault + LanguagePreset(String id, String textureHash) { + this(id, true, textureHash); } /** * This returns the id of this {@link Language}. - * - * @return Language ID + * + * @return The language code */ public @Nonnull String getLanguageCode() { return id; @@ -81,14 +98,32 @@ public enum LanguagePreset { /** * This returns whether this {@link LanguagePreset} is "release-ready". * A release-ready {@link Language} will be available in RC builds of Slimefun. - * + * * @return Whether this {@link Language} is "release-ready" */ boolean isReadyForRelease() { return releaseReady; } + /** + * This returns the texture hash for this language. + * This will be the flag of the corresponding country. + * (Not accurate I know, but better than having all languages + * look the same by using the same items) + * + * @return The texture hash of this language + */ public @Nonnull String getTexture() { return textureHash; } + + /** + * This returns the direction of text for + * this language. + * + * @return The direction of text for this language + */ + public @Nonnull TextDirection getTextDirection() { + return textDirection; + } } diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/core/services/localization/TextDirection.java b/src/main/java/io/github/thebusybiscuit/slimefun4/core/services/localization/TextDirection.java new file mode 100644 index 0000000000..1c1d57bb11 --- /dev/null +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/core/services/localization/TextDirection.java @@ -0,0 +1,25 @@ +package io.github.thebusybiscuit.slimefun4.core.services.localization; + +/** + * A simple enum to define the direction of text for a given {@link LanguagePreset} + * + * @author TheBusyBiscuit + * + */ +public enum TextDirection { + + /** + * The text flows from left to right. + * This is true for most western languages, + * such as English, Spanish, German, French and more. + */ + LEFT_TO_RIGHT, + + /** + * The text flows from right to left. + * Most common languages that use this direction + * of text are Hebrew and Arabic. + */ + RIGHT_TO_LEFT + +} diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/Slimefun.java b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/Slimefun.java index 9a227d30b8..17cd3470fa 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/Slimefun.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/Slimefun.java @@ -81,6 +81,7 @@ import io.github.thebusybiscuit.slimefun4.implementation.listeners.HopperListener; import io.github.thebusybiscuit.slimefun4.implementation.listeners.ItemDropListener; import io.github.thebusybiscuit.slimefun4.implementation.listeners.ItemPickupListener; +import io.github.thebusybiscuit.slimefun4.implementation.listeners.MiddleClickListener; import io.github.thebusybiscuit.slimefun4.implementation.listeners.MiningAndroidListener; import io.github.thebusybiscuit.slimefun4.implementation.listeners.MultiBlockListener; import io.github.thebusybiscuit.slimefun4.implementation.listeners.NetworkListener; @@ -259,7 +260,7 @@ private void onPluginStart() { if (PaperLib.isPaper()) { logger.log(Level.INFO, "检测到 Paper 服务端! 性能优化已应用."); } else { - PaperLib.suggestPaper(this); + LangUtil.suggestPaper(this); } // Check if CS-CoreLib is installed (it is no longer needed) @@ -390,6 +391,8 @@ public void onDisable() { return; } + SlimefunExtra.shutdown(); + // Cancel all tasks from this plugin immediately Bukkit.getScheduler().cancelTasks(this); @@ -625,6 +628,7 @@ private void registerListeners() { new SoulboundListener(this); new AutoCrafterListener(this); new SlimefunItemHitListener(this); + new MiddleClickListener(this); // Bees were added in 1.15 if (minecraftVersion.isAtLeast(MinecraftVersion.MINECRAFT_1_15)) { diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/StartupWarnings.java b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/StartupWarnings.java index 5642f10b2e..14a2fee93e 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/StartupWarnings.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/StartupWarnings.java @@ -62,13 +62,13 @@ static void oldJavaVersion(Logger logger, int recommendedJavaVersion) { int javaVersion = NumberUtils.getJavaVersion(); logger.log(Level.WARNING, BORDER); - logger.log(Level.WARNING, PREFIX + "正在使用的Java版本 (Java {0}) 已过时。", javaVersion); + logger.log(Level.WARNING, PREFIX + "正在使用的 Java 版本 (Java {0}) 已过时.", javaVersion); logger.log(Level.WARNING, PREFIX); - logger.log(Level.WARNING, PREFIX + "由于高版本MC对 Java {0} 的强制依赖,", recommendedJavaVersion); - logger.log(Level.WARNING, PREFIX + "我们推荐您尽快升级到 Java {0}。", recommendedJavaVersion); - logger.log(Level.WARNING, PREFIX + "同时,为尽快使用到新版本Java带来的特性,"); - logger.log(Level.WARNING, PREFIX + "Slimefun 也会在不久的将来依赖于 Java {0}。", recommendedJavaVersion); - logger.log(Level.WARNING, PREFIX + "为了不影响您以后的正常使用,请尽快更新!"); + logger.log(Level.WARNING, PREFIX + "由于高版本 Minecraft 对 Java {0} 的强制依赖,", recommendedJavaVersion); + logger.log(Level.WARNING, PREFIX + "我们推荐您尽快升级到 Java {0}.", recommendedJavaVersion); + logger.log(Level.WARNING, PREFIX + "同时,为尽快使用到新版本Java带来的特性,"); + logger.log(Level.WARNING, PREFIX + "Slimefun 也会在不久的将来依赖于 Java {0}.", recommendedJavaVersion); + logger.log(Level.WARNING, PREFIX + "为了不影响您以后的正常使用,请尽快更新!"); logger.log(Level.WARNING, BORDER); } diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/guide/CheatSheetSlimefunGuide.java b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/guide/CheatSheetSlimefunGuide.java index 3f70d7ebf4..5595cae668 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/guide/CheatSheetSlimefunGuide.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/guide/CheatSheetSlimefunGuide.java @@ -34,7 +34,7 @@ public class CheatSheetSlimefunGuide extends SurvivalSlimefunGuide { private final ItemStack item; public CheatSheetSlimefunGuide() { - super(false); + super(false, true); item = new SlimefunGuideItem(this, "&cSlimefun 指南 &4(作弊模式)"); } diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/guide/SurvivalSlimefunGuide.java b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/guide/SurvivalSlimefunGuide.java index b365887d8e..ed93029ba0 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/guide/SurvivalSlimefunGuide.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/guide/SurvivalSlimefunGuide.java @@ -73,10 +73,12 @@ public class SurvivalSlimefunGuide implements SlimefunGuideImplementation { private final int[] recipeSlots = { 3, 4, 5, 12, 13, 14, 21, 22, 23 }; private final ItemStack item; private final boolean showVanillaRecipes; + private final boolean showHiddenItemGroupsInSearch; - public SurvivalSlimefunGuide(boolean showVanillaRecipes) { + public SurvivalSlimefunGuide(boolean showVanillaRecipes, boolean showHiddenItemGroupsInSearch) { this.showVanillaRecipes = showVanillaRecipes; - item = new SlimefunGuideItem(this, "&aSlimefun 指南 &7(箱子界面)"); + this.showHiddenItemGroupsInSearch = showHiddenItemGroupsInSearch; + item = new SlimefunGuideItem(this, "&aSlimefun Guide &7(Chest GUI)"); } /** @@ -110,7 +112,7 @@ protected final boolean isSurvivalMode() { * The {@link Player} who opened his {@link SlimefunGuide} * @param profile * The {@link PlayerProfile} of the {@link Player} - * + * * @return a {@link List} of visible {@link ItemGroup} instances */ protected @Nonnull List getVisibleItemGroups(@Nonnull Player p, @Nonnull PlayerProfile profile) { @@ -364,7 +366,9 @@ public void openSearch(PlayerProfile profile, String input, boolean addToHistory break; } - if (!slimefunItem.isHidden() && !slimefunItem.getItemGroup().isHidden(p) && isSearchFilterApplicable(slimefunItem, searchTerm)) { + boolean isItemGroupHidden = showHiddenItemGroupsInSearch || !slimefunItem.getItemGroup().isHidden(p); + + if (!slimefunItem.isHidden() && isItemGroupHidden && isSearchFilterApplicable(slimefunItem, searchTerm)) { ItemStack itemstack = new CustomItemStack(slimefunItem.getItem(), meta -> { ItemGroup itemGroup = slimefunItem.getItemGroup(); meta.setLore(Arrays.asList("", ChatColor.DARK_GRAY + "\u21E8 " + ChatColor.WHITE + itemGroup.getDisplayName(p))); diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/androids/ProgrammableAndroid.java b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/androids/ProgrammableAndroid.java index 7be7f12c93..2f29327539 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/androids/ProgrammableAndroid.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/androids/ProgrammableAndroid.java @@ -130,7 +130,7 @@ public void newInstance(BlockMenu menu, Block b) { return false; }); - menu.replaceExistingItem(25, new CustomItemStack(Material.PLAYER_HEAD, Slimefun.getLocalization().getMessage("android.access-manager.title"), "", Slimefun.getLocalization().getMessage("android.access-manager.subtitle"))); + menu.replaceExistingItem(25, new CustomItemStack(HeadTexture.MOTOR.getAsItemStack(), Slimefun.getLocalization().getMessage("android.access-manager.title"), "", Slimefun.getLocalization().getMessage("android.access-manager.subtitle"))); menu.addMenuClickHandler(25, (p, slot, item, action) -> { BlockStorage.addBlockInfo(b, "paused", "true"); Slimefun.getLocalization().sendMessage(p, "android.stopped", true); diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/electric/machines/FluidPump.java b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/electric/machines/FluidPump.java index 87f948bcbf..7879c0bff0 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/electric/machines/FluidPump.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/electric/machines/FluidPump.java @@ -1,6 +1,7 @@ package io.github.thebusybiscuit.slimefun4.implementation.items.electric.machines; import java.util.List; +import java.util.concurrent.ThreadLocalRandom; import javax.annotation.Nonnull; import javax.annotation.Nullable; @@ -38,6 +39,9 @@ import me.mrCookieSlime.Slimefun.api.BlockStorage; import me.mrCookieSlime.Slimefun.api.inventory.BlockMenu; import me.mrCookieSlime.Slimefun.api.inventory.BlockMenuPreset; +import org.bukkit.inventory.meta.PotionMeta; +import org.bukkit.potion.PotionData; +import org.bukkit.potion.PotionType; /** * This machine collects liquids from the {@link World} and puts them @@ -57,6 +61,7 @@ public class FluidPump extends SimpleSlimefunItem implements Invent private final int[] outputBorder = { 14, 15, 16, 17, 23, 26, 32, 33, 34, 35 }; private final ItemStack emptyBucket = ItemStackWrapper.wrap(new ItemStack(Material.BUCKET)); + private final ItemStack emptyBottle = ItemStackWrapper.wrap(new ItemStack(Material.GLASS_BOTTLE)); @ParametersAreNonnullByDefault public FluidPump(ItemGroup itemGroup, SlimefunItemStack item, RecipeType recipeType, ItemStack[] recipe) { @@ -137,7 +142,9 @@ protected void tick(@Nonnull Block b) { BlockMenu menu = BlockStorage.getInventory(b); for (int slot : getInputSlots()) { - if (SlimefunUtils.isItemSimilar(menu.getItemInSlot(slot), emptyBucket, true, false)) { + ItemStack itemInSlot = menu.getItemInSlot(slot); + + if (SlimefunUtils.isItemSimilar(itemInSlot, emptyBucket, true, false)) { ItemStack bucket = getFilledBucket(fluid); if (!menu.fits(bucket, getOutputSlots())) { @@ -153,6 +160,26 @@ protected void tick(@Nonnull Block b) { nextFluid.setType(Material.AIR); } + return; + } else if (SlimefunUtils.isItemSimilar(itemInSlot, emptyBottle, true, false)) { + ItemStack bottle = getFilledBottle(fluid); + + if (!menu.fits(bottle, getOutputSlots())) { + return; + } + + Block nextFluid = findNextFluid(fluid); + + if (nextFluid != null) { + removeCharge(b.getLocation(), ENERGY_CONSUMPTION); + menu.consumeItem(slot); + menu.pushItem(bottle, getOutputSlots()); + + if (ThreadLocalRandom.current().nextInt(100) < 30) { + nextFluid.setType(Material.AIR); + } + } + return; } } @@ -185,8 +212,21 @@ private Block findNextFluid(@Nonnull Block fluid) { return null; } - @Nonnull - private ItemStack getFilledBucket(@Nonnull Block fluid) { + private @Nonnull ItemStack getFilledBottle(@Nonnull Block fluid) { + switch (fluid.getType()) { + case WATER: + case BUBBLE_COLUMN: + ItemStack waterBottle = new ItemStack(Material.POTION); + PotionMeta meta = (PotionMeta) waterBottle.getItemMeta(); + meta.setBasePotionData(new PotionData(PotionType.WATER)); + waterBottle.setItemMeta(meta); + return waterBottle; + default: + return new ItemStack(Material.GLASS_BOTTLE); + } + } + + private @Nonnull ItemStack getFilledBucket(@Nonnull Block fluid) { switch (fluid.getType()) { case LAVA: return new ItemStack(Material.LAVA_BUCKET); diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/listeners/MiddleClickListener.java b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/listeners/MiddleClickListener.java new file mode 100644 index 0000000000..343c90ab33 --- /dev/null +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/listeners/MiddleClickListener.java @@ -0,0 +1,103 @@ +package io.github.thebusybiscuit.slimefun4.implementation.listeners; + +import java.util.Optional; + +import javax.annotation.Nonnull; +import javax.annotation.ParametersAreNonnullByDefault; + +import org.bukkit.Material; +import org.bukkit.block.Block; +import org.bukkit.entity.HumanEntity; +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; +import org.bukkit.event.inventory.ClickType; +import org.bukkit.event.inventory.InventoryCreativeEvent; +import org.bukkit.event.inventory.InventoryType.SlotType; + +import io.github.thebusybiscuit.slimefun4.api.items.SlimefunItem; +import io.github.thebusybiscuit.slimefun4.implementation.Slimefun; +import me.mrCookieSlime.Slimefun.api.BlockStorage; + +/** + * The {@link MiddleClickListener} is responsible for listening to the {@link InventoryCreativeEvent}. + * + * @author svr333 + * + */ +public class MiddleClickListener implements Listener { + + public MiddleClickListener(@Nonnull Slimefun plugin) { + plugin.getServer().getPluginManager().registerEvents(this, plugin); + } + + /* + * General Discloser: this event has really really really weird behavior on middle click. + * Has been tested thoroughly to make sure it doesnt break anything else. + */ + @EventHandler + public void onInventoryCreativeEvent(InventoryCreativeEvent e) { + /* + * When clicking outside of an inventory with middle click, + * ClickType is not MIDDLE but CREATIVE (because this ClickType covers + * multiple cases, we have to filter out more later on) + */ + if (e.getClick() == ClickType.CREATIVE && e.getSlotType() == SlotType.QUICKBAR) { + HumanEntity player = e.getWhoClicked(); + // get the block the player is looking at for later + Block b = player.getTargetBlockExact(5); + + // Fixes: #3483 + if (b == null || !isActualMiddleClick(e, b)) { + return; + } + + // find the actual slimefun item the user is looking at + SlimefunItem sfItem = BlockStorage.check(b); + + // vanilla block -> ignore + if (sfItem == null) { + return; + } + + /* + * Before giving the item to the user, check if you can swap + * to the item instead (user already has item in hotbar). + * This is sometimes bypassed by the client itself (not fixable though). + */ + for (int i = 0; i < 9; i++) { + if (sfItem.isItem(player.getInventory().getItem(i))) { + player.getInventory().setHeldItemSlot(i); + // Has to be cancelled in order for it to work properly. + e.setCancelled(true); + return; + } + } + + // Give the item, doing it like this will not alter any other cases. + e.setCursor(sfItem.getItem().clone()); + } + } + + @ParametersAreNonnullByDefault + private boolean isActualMiddleClick(InventoryCreativeEvent e, Block b) { + /* + * On a middle click outside the user inventory, cursor will be set + * to the actual block that is middle clicked, while currentItem will be AIR. + * + * This check is really weird due to the weird nature of this event's behaviour. + * It checks if the block the player is looking at is of the same type as the cursor; + * after this we can make sure that it is a middle click outside of the inventory + * currentItem should also be air, otherwise it is not outside of the inventory + */ + boolean isOutsideInventoryClick = e.getCursor().getType() == b.getType() && e.getCurrentItem().getType() == Material.AIR; + + /* + * This is an edge case where the player is looking at a WALL_HEAD (eg. cargo) + * and then the boolean above wont match because WALL_HEAD != PLAYER_HEAD. + * This check makes up for that lack. + */ + boolean isPlayerWallhead = b.getType() == Material.PLAYER_WALL_HEAD && e.getCursor().getType() == Material.PLAYER_HEAD; + + return isOutsideInventoryClick || isPlayerWallhead; + } +} diff --git a/src/main/java/ren/natsuyuk1/slimefunextra/IntegrationHelper.java b/src/main/java/ren/natsuyuk1/slimefunextra/IntegrationHelper.java index af71dadfab..ade8af04ce 100644 --- a/src/main/java/ren/natsuyuk1/slimefunextra/IntegrationHelper.java +++ b/src/main/java/ren/natsuyuk1/slimefunextra/IntegrationHelper.java @@ -10,6 +10,7 @@ import io.github.bakedlibs.dough.protection.ActionType; import io.github.bakedlibs.dough.protection.Interaction; +import io.github.thebusybiscuit.slimefun4.api.events.AndroidFarmEvent; import io.github.thebusybiscuit.slimefun4.api.events.AndroidMineEvent; import io.github.thebusybiscuit.slimefun4.implementation.Slimefun; import io.github.thebusybiscuit.slimefun4.utils.JsonUtils; @@ -19,8 +20,10 @@ import org.bukkit.OfflinePlayer; import org.bukkit.block.Block; import org.bukkit.entity.Player; +import org.bukkit.event.Cancellable; import org.bukkit.event.EventHandler; import org.bukkit.event.Listener; +import org.bukkit.plugin.Plugin; import org.maxgamer.quickshop.api.QuickShopAPI; import javax.annotation.Nonnull; @@ -72,29 +75,50 @@ public static void register(@Nonnull Slimefun plugin) { plugin.getServer().getPluginManager().registerEvents(instance, plugin); } + public static void shutdown() { + qsMethod = null; + shopAPI = null; + logger = null; + } + + @EventHandler + public void onAndroidFarm(AndroidFarmEvent e) { + handleAndroidBreak(e.getAndroid().getBlock(), e); + } + @EventHandler public void onAndroidMine(AndroidMineEvent e) { - if (e != null) { - Player p = Bukkit.getPlayer(getOwnerFromJson(BlockStorage.getBlockInfoAsJson(e.getAndroid().getBlock()))); - Location androidLoc = e.getAndroid().getBlock().getLocation(); - String location = androidLoc.getWorld().getName() + " [" + androidLoc.getBlockX() + "," + androidLoc.getBlockY() + "," + androidLoc.getBlockZ() + "]"; - - if (p == null) { - logger.log(Level.WARNING, "检测到在 " + location + " 有机器人尝试挖矿, 但无法获取其主人"); - e.setCancelled(true); - return; - } + handleAndroidBreak(e.getAndroid().getBlock(), e); + } - if (!checkPermission(p, e.getBlock(), Interaction.BREAK_BLOCK)) { - e.setCancelled(true); - Slimefun.getLocalization().sendMessage(p, "android.no-permission"); + /** + * 处理机器人破坏方块 + * + * @param android 机器人方块实例 + * @param event 机器人破坏事件 + */ + private void handleAndroidBreak(@Nonnull Block android, @Nonnull Cancellable event) { + try { + OfflinePlayer p = Bukkit.getOfflinePlayer(getOwnerFromJson(BlockStorage.getBlockInfoAsJson(android))); + + if (!checkPermission(p, android, Interaction.BREAK_BLOCK)) { + event.setCancelled(true); + if (p.isOnline() && p.getPlayer() != null) { + Slimefun.getLocalization().sendMessage(p.getPlayer(), "android.no-permission"); + } } + } catch (Exception x) { + Slimefun.logger().log(Level.WARNING, "在处理机器人破坏方块时遇到了意外", x); } } /** * 检查是否可以在领地内破坏/交互方块 * + * 领地已支持 Slimefun + * + * 详见: https://github.com/Zrips/Residence/blob/master/src/com/bekvon/bukkit/residence/slimeFun/SlimeFunResidenceModule.java + * * @param p 玩家 * @param block 被破坏的方块 * @param action 交互类型 @@ -112,28 +136,33 @@ public static boolean checkPermission(OfflinePlayer p, Block block, Interaction return true; } + Player onlinePlayer = p.getPlayer(); + + if (onlinePlayer == null) { + return false; + } + + if (onlinePlayer.hasPermission("residence.admin")) { + return true; + } + ResidencePermissions perms = res.getPermissions(); if (perms != null) { - Player online = p.getPlayer(); - - if (action.getType() == ActionType.BLOCK && perms.playerHas(online, Flags.admin, FlagPermissions.FlagCombo.OnlyTrue)) { + if (action.getType() == ActionType.BLOCK && perms.playerHas(onlinePlayer, Flags.admin, FlagPermissions.FlagCombo.OnlyTrue)) { return true; } switch (action) { case BREAK_BLOCK: - return perms.playerHas(online, Flags.destroy, FlagPermissions.FlagCombo.OnlyTrue); + return perms.playerHas(onlinePlayer, Flags.destroy, FlagPermissions.FlagCombo.OnlyTrue); case INTERACT_BLOCK: - // 领地已支持 Slimefun - // 详见 - // https://github.com/Zrips/Residence/blob/master/src/com/bekvon/bukkit/residence/slimeFun/SlimeFunResidenceModule.java - return perms.playerHas(online, Flags.container, FlagPermissions.FlagCombo.OnlyTrue); + return perms.playerHas(onlinePlayer, Flags.container, FlagPermissions.FlagCombo.OnlyTrue); case PLACE_BLOCK: // move 是为了机器人而检查的, 防止机器人跑进别人领地然后还出不来 - return perms.playerHas(online, Flags.place, FlagPermissions.FlagCombo.OnlyTrue) - || perms.playerHas(online, Flags.build, FlagPermissions.FlagCombo.OnlyTrue) - && perms.playerHas(online, Flags.move, FlagPermissions.FlagCombo.TrueOrNone); + return perms.playerHas(onlinePlayer, Flags.place, FlagPermissions.FlagCombo.OnlyTrue) + || perms.playerHas(onlinePlayer, Flags.build, FlagPermissions.FlagCombo.OnlyTrue) + && perms.playerHas(onlinePlayer, Flags.move, FlagPermissions.FlagCombo.TrueOrNone); } } } @@ -175,9 +204,14 @@ public static boolean checkForQuickShop(@Nonnull Location l) { } } - QuickShopAPI qs = (QuickShopAPI) Bukkit.getPluginManager().getPlugin("QuickShop"); + Plugin qsPlugin = Bukkit.getPluginManager().getPlugin("QuickShop"); + + if (qsPlugin instanceof QuickShopAPI) { + return ((QuickShopAPI) qsPlugin).getShopManager().getShop(l) != null; + } - return qs.getShopManager().getShop(l) != null; + logger.log(Level.WARNING, "与QuickShop的兼容出现问题,请避免使用热重载更换插件版本。如频繁出现该问题请反馈至粘液科技汉化版。"); + return false; } private static void registerQuickShop(@Nonnull Slimefun plugin) { diff --git a/src/main/java/ren/natsuyuk1/slimefunextra/SlimefunExtra.java b/src/main/java/ren/natsuyuk1/slimefunextra/SlimefunExtra.java index 832060a1da..6a29de1db7 100644 --- a/src/main/java/ren/natsuyuk1/slimefunextra/SlimefunExtra.java +++ b/src/main/java/ren/natsuyuk1/slimefunextra/SlimefunExtra.java @@ -10,4 +10,9 @@ public static void register(@Nonnull Slimefun sf) { VaultHelper.register(sf); UpdateChecker.checkUpdate(); } + + public static void shutdown() { + IntegrationHelper.shutdown(); + VaultHelper.shutdown(); + } } diff --git a/src/main/java/ren/natsuyuk1/slimefunextra/VaultHelper.java b/src/main/java/ren/natsuyuk1/slimefunextra/VaultHelper.java index ec8459c0c0..f54176d502 100644 --- a/src/main/java/ren/natsuyuk1/slimefunextra/VaultHelper.java +++ b/src/main/java/ren/natsuyuk1/slimefunextra/VaultHelper.java @@ -27,6 +27,10 @@ public static void register(@Nonnull Slimefun plugin) { } } + public static void shutdown() { + econ = null; + } + public static Economy getEcon() { return econ; } diff --git a/src/main/resources/config.yml b/src/main/resources/config.yml index c0d1674b47..bc6cd88325 100644 --- a/src/main/resources/config.yml +++ b/src/main/resources/config.yml @@ -34,6 +34,7 @@ guide: show-vanilla-recipes: true # 是否在玩家第一次进入服务器时自动赠送粘液科技指南 receive-on-first-join: true + show-hidden-item-groups-in-search: false researches: # 是否允许创造模式玩家免费解锁研究 diff --git a/src/main/resources/languages/bg/messages.yml b/src/main/resources/languages/bg/messages.yml index 3ae2625ed6..51ead13d4a 100644 --- a/src/main/resources/languages/bg/messages.yml +++ b/src/main/resources/languages/bg/messages.yml @@ -150,7 +150,9 @@ messages: mode-change: '&b%device% режим на устройството променен на: &9%mode%' not-shears: '&cMulti Tool не може да бъде използван, като ножици!' auto-crafting: + select-a-recipe: '&eПромъкни се и натисни десен бутон върху &7този блок с предмета, който искате да изработите.' recipe-set: '&aУспешно сложихте рецепта на тази машина.' + recipe-removed: '&eВие успешно премахнахте рецептата от тази машина. Можете да поставите нова рецепта по всяко време!' no-recipes: '&cНе можем да намерим никакви валидни рецепти за предмета, който държите.' missing-chest: '&cЛипсващ сандък! Auto-Crafters трябва да бъдат сложени върху сандък.' select: 'Изберете тази рецепта' @@ -163,13 +165,13 @@ messages: enabled: - '&aВ момента тази рецепта е включена' - '' - - '&eLeft Click &7to temporarily disable the recipe' - - '&eRight Click &7to remove this recipe' + - '&eДесен бутон, &7за да деактивирате временно тази рецепта' + - '&eДесен бутон, &7за да премахнете тази рецепта' disabled: - '&cВ момента тази рецепта е изключена' - '' - - '&eLeft Click &7to re-enable this recipe' - - '&eRight Click &7to remove this recipe' + - '&eЛяв бутон, &7за да активирате повторно тази рецепта' + - '&eДесен бутон, &7за да премахнете тази рецепта' talisman: anvil: '&a&oВашия Талисман спаси инструмента Ви от счупването му' miner: '&a&oВашия Талисман удвой предметите, които ще получавате от копаене' diff --git a/src/main/resources/languages/bg/recipes.yml b/src/main/resources/languages/bg/recipes.yml index 1fa0e11303..d40f0f48cf 100644 --- a/src/main/resources/languages/bg/recipes.yml +++ b/src/main/resources/languages/bg/recipes.yml @@ -1,168 +1,168 @@ --- slimefun: multiblock: - name: Multiblock + name: 'Мултиблок' lore: - - Постройте показаната структура - - както е показана. Не се craft-ва. + - 'Постройте показаната структура' + - 'както е показана. Не се craft-ва.' enhanced_crafting_table: - name: Enhanced Crafting Table + name: 'Подобрена работна маса' lore: - - Направете този Предмет, както е показано - - в Enhanced Crafting Table. - - Нормален Crafting Table(Работна Маса) няма да е достатъчен! + - 'Направете този Предмет, както е показано' + - 'в Enhanced Crafting Table.' + - 'Нормален Crafting Table(Работна Маса) няма да е достатъчен!' armor_forge: - name: Armor Forge + name: 'Ковач на брони' lore: - - Направете този Предмет, както е показано - - използвайки Armor Forge + - 'Направете този Предмет, както е показано' + - 'използвайки Armor Forge' grind_stone: - name: Grind Stone + name: 'Раздробител' lore: - - Направете този Предмет, както е показано - - използвайки Grind Stone + - 'Направете този Предмет, както е показано' + - 'използвайки Grind Stone' smeltery: - name: Smeltery + name: 'Разтопител' lore: - - Направете този Предмет, както е показано - - използвайки Smeltery + - 'Направете този Предмет, както е показано' + - 'използвайки Smeltery' ore_crusher: - name: Ore Crusher + name: 'Трошач на руди' lore: - - Направете този Предмет, както е показано - - използвайки Ore Crusher + - 'Направете този Предмет, както е показано' + - 'използвайки Ore Crusher' mob_drop: - name: Mob Drop + name: 'Част от съществото' lore: - - Убийте този Mob, за да - - получите този предмет + - 'Убийте този Mob, за да' + - 'получите този предмет' gold_pan: - name: Gold Pan + name: 'Златна тава' lore: - - Използвайте Gold Pan, за да - - получите този предмет + - 'Използвайте Gold Pan, за да' + - 'получите този предмет' compressor: - name: Compressor + name: 'Компресор' lore: - - Направете този Предмет, както е показано - - използвайки Compressor + - 'Направете този Предмет, както е показано' + - 'използвайки Compressor' pressure_chamber: - name: Pressure Chamber + name: 'Камера под налягане' lore: - - Направете този Предмет, както е показано - - използвайки Pressure Chamber + - 'Направете този Предмет, както е показано' + - 'използвайки Pressure Chamber' ore_washer: - name: Ore Washer + name: 'Мияч на руди' lore: - - Направете този Предмет, както е показано - - използвайки Ore Washer + - 'Направете този Предмет, както е показано' + - 'използвайки Ore Washer' juicer: - name: Juicer + name: 'Сокоизтисквачка' lore: - - Направете този Предмет, както е показано - - използвайки Juicer + - 'Направете този Предмет, както е показано' + - 'използвайки Juicer' magic_workbench: - name: Magic Workbench + name: 'Магическа работна маса' lore: - - Направете този Предмет, както е показано - - използвайки Magic Workbench + - 'Направете този Предмет, както е показано' + - 'използвайки Magic Workbench' ancient_altar: - name: Ancient Altar + name: 'Древен олтар' lore: - - Направете този Предмет, както е показано - - използвайки Ancient Altar. - - Вижте Ancient Altar за повече информация + - 'Направете този Предмет, както е показано' + - 'използвайки Ancient Altar.' + - 'Вижте Ancient Altar за повече информация' heated_pressure_chamber: - name: Heated Pressure Chamber + name: 'Нагрята камера под налягане' lore: - - Направете този Предмет, както е показано - - използвайки Heated Pressure Chamber + - 'Направете този Предмет, както е показано' + - 'използвайки Heated Pressure Chamber' food_fabricator: - name: Food Fabricator + name: 'Производител на храна' lore: - - Направете този Предмет, както е показано - - използвайки Food Fabricator + - 'Направете този Предмет, както е показано' + - 'използвайки Food Fabricator' food_composter: - name: Food Composter + name: 'Компостьор за храна' lore: - - Направете този Предмет, както е показано - - използвайки Food Composter + - 'Направете този Предмет, както е показано' + - 'използвайки Food Composter' freezer: - name: Freezer + name: 'Фризер' lore: - - Направете този Предмет, както е показано - - използвайки Freezer + - 'Направете този Предмет, както е показано' + - 'използвайки Freezer' geo_miner: - name: GEO Miner + name: 'ГЕО копач' lore: - - Този Предмет може да бъде събран - - като използвате GEO Miner + - 'Този Предмет може да бъде събран' + - 'като използвате GEO Miner' nuclear_reactor: - name: Nuclear Reactor + name: 'Ядрен реактор' lore: - - Този Предмет е вторичен-продукт - - направен от Nuclear Reactor + - 'Този Предмет е вторичен-продукт' + - 'направен от Nuclear Reactor' oil_pump: - name: Oil Pump + name: 'Нефтена помпа' lore: - - Този Предмет може да бъде събран - - като използвате Oil Pump + - 'Този Предмет може да бъде събран' + - 'като използвате Oil Pump' pickaxe_of_containment: - name: Pickaxe of Containment + name: 'Кирка на ограничаването' lore: - - Този Блок може да бъде получен - - като изкопаете Spawner(Спаунер) с - - предмета Pickaxe of Containment + - 'Този Блок може да бъде получен' + - 'като изкопаете Spawner(Спаунер) с' + - 'предмета Pickaxe of Containment' refinery: - name: Refinery + name: 'Рафинерия' lore: - - Направете този Предмет, както е показано - - използвайки Refinery + - 'Направете този Предмет, както е показано' + - 'използвайки Refinery' barter_drop: - name: Piglin Bartering Drop + name: 'Артикул за търговия с пиглина' lore: - - Търгувайте с Piglins(Пиглини), като използвате - - Gold Ingots(Златни Кюлчета), за да получите този Предмет + - 'Търгувайте с Piglins(Пиглини), като използвате' + - 'Gold Ingots(Златни Кюлчета), за да получите този Предмет' minecraft: shaped: - name: Shaped Crafting Recipe + name: 'Оформена рецепта за изработка' lore: - - Направете този Предмет, както е показано - - в нормалния Crafting Table(Работна Маса). - - Формата е много важна. + - 'Направете този Предмет, както е показано' + - 'в нормалния Crafting Table(Работна Маса).' + - 'Формата е много важна.' shapeless: - name: Shapeless Crafting Recipe + name: 'Безформена рецепта за изработка' lore: - - Направете този Предмет, както е показано - - в нормалния Crafting Table(Работна Маса). - - Тази Рецепта е безформена. + - 'Направете този Предмет, както е показано' + - 'в нормалния Crafting Table(Работна Маса).' + - 'Тази Рецепта е безформена.' furnace: - name: Furnace Recipe + name: 'Рецепта за пещ' lore: - - Изпечете този предмет в Furnace(Печка) - - за да си направите желания предмет + - 'Изпечете този предмет в Furnace(Печка)' + - 'за да си направите желания предмет' blasting: - name: Blast Furnace Recipe + name: 'Рецепта за доменна пещ' lore: - - Изпечете този предмет в Blast Furnace(Бласт Печка) - - за да си направите желания предмет + - 'Изпечете този предмет в Blast Furnace(Бласт Печка)' + - 'за да си направите желания предмет' smoking: - name: Smoker Recipe + name: 'Рецепта за пушечна фурна' lore: - - Изпечете този предмет в Smoker(Упошвател) - - за да си направите желания предмет + - 'Изпечете този предмет в Smoker(Упошвател)' + - 'за да си направите желания предмет' campfire: - name: Campfire Recipe + name: 'Рецепта за лагерен огън' lore: - - Изпечете този предмет върху Campfire(Огън) - - за да си направите желания предмет + - 'Изпечете този предмет върху Campfire(Огън)' + - 'за да си направите желания предмет' stonecutting: - name: Stonecutter Recipe + name: 'Рецепта за каменоделски циркуляр' lore: - - Направете този Предмет, както е показано - - използвайки Stonecutter + - 'Направете този Предмет, както е показано' + - 'използвайки Stonecutter' smithing: - name: Smithing Table Recipe + name: 'Рецепта за коваческа маса' lore: - - Направете този Предмет, както е показано - - използвайки Smithing Table + - 'Направете този Предмет, както е показано' + - 'използвайки Smithing Table' diff --git a/src/main/resources/languages/bg/researches.yml b/src/main/resources/languages/bg/researches.yml index 079bcafdf5..20a4c3cc62 100644 --- a/src/main/resources/languages/bg/researches.yml +++ b/src/main/resources/languages/bg/researches.yml @@ -1,6 +1,7 @@ --- slimefun: walking_sticks: Бастуни + portable_crafter: Преносима работна маса fortune_cookie: Бисквитка с Късмет portable_dustbin: Преносимо Кошче meat_jerky: Пастърма @@ -21,6 +22,7 @@ slimefun: misc_power_items: Важни предмети, свързани със захранването battery: Твоята първа батерия steel_plate: Стоманено покритие + steel_thruster: Стоманен ускорител parachute: Парашут grappling_hook: Абордажна кука jetpacks: Джетпак @@ -109,6 +111,7 @@ slimefun: jetboots: Джет ботуши armored_jetboots: Бронирани джет ботуши seismic_axe: Земетръсна брадва + pickaxe_of_vein_mining: Кирка на венозното копаене bound_weapons: Обвързани с душата оръжия bound_tools: Обвързани с душата инструменти bound_armor: Обвързана с душата броня @@ -214,11 +217,13 @@ slimefun: advanced_electric_smeltery: Модерен електрически разтопител advanced_farmer_android: Модерни андроиди - Фермер lava_generator: Генератор с лава + nether_ice: Охлаждане от лед от Недъра nether_star_reactor: Реактор с Недър звезда blistering_ingots: Блистерна радиоактивност automatic_ignition_chamber: Автоматична запалваща камера output_chest: Изходен сандък за основни машини copper_wire: Разредена проводимост + radiant_backpack: Пътническа раница auto_drier: Сух ден diet_cookie: Диетична бисквитка storm_staff: Гръмотевична тояга @@ -236,6 +241,7 @@ slimefun: industrial_miner: Промишлен добив advanced_industrial_miner: По-добро копаене magical_zombie_pills: Де-зомбифициране + auto_brewer: Индустриална пивоварна climbing_pick: Алпинист shulker_shell: Синтетични шулкъри enchantment_rune: Древно омагьосване diff --git a/src/main/resources/languages/cs/messages.yml b/src/main/resources/languages/cs/messages.yml index ca62f32dc2..792a357bd7 100644 --- a/src/main/resources/languages/cs/messages.yml +++ b/src/main/resources/languages/cs/messages.yml @@ -23,6 +23,11 @@ commands: description: Nabije předmět, který držíš charge-success: Předmět byl nabit! not-rechargeable: Tento předmět nelze nabít! + timings: + description: Timings pro Slimefun a jeho doplňky + please-wait: '&ePočkej, prosím, vteřinu… Výsledky přicházejí!' + verbose-player: '&4Tato vlajka nemůže být použita hráčem!' + unknown-flag: '&4Neplatná vlajka: &c%flag%' debug: description: 'Spustit ladění pro vývojáře' current: '&7Aktuální testovací případ: &6%test_case%' @@ -76,16 +81,37 @@ guide: translations: name: '&aChybí zde něco?' lore: 'Klikni pro přidání vlastního překladu' + options: + learning-animation: + enabled: + text: + - '&bAnimace Výzkumu: &aAno' + - '' + - '&7Nyní můžete přepnout, zda-li' + - '&7uvidíte informace o průběhu vašeho hloubání' + - '&7když budete zkoumat předmět.' + click: '&eKliknutím vypnete animace výzkumu' + disabled: + text: + - '&bAnimace Výzkumu: &4Ne' + - '' + - '&7Nyní můžete přepnout, zda-li' + - '&7uvidíte informace o průběhu vašeho hloubání' + - '&7když budete zkoumat předmět.' + click: '&eKliknutím zapnete animace výzkumu' title: main: 'Slimefun příručka' settings: 'Nastavení a informace' languages: 'Zvol svůj preferovaný jazyk' credits: 'Slimefun4 pomocníci' + wiki: 'Slimefun4 Wiki' addons: 'Doplňky pro Slimefun4' bugs: 'Nahlášení chyb' source: 'Zdrojový kód' versions: 'Nainstalovaná verze' credits: + commit: 'Commit' + commits: 'Commity' profile-link: 'Klikni pro navštívení jeho profilu na GitHubu' open: 'Klikni pro zobrazení našich pomocníků' description: @@ -99,6 +125,7 @@ guide: resourcepack: '&cTvůrce modifikačního balíčku' translator: '&9Překladatel' messages: + not-researched: '&4Nemáš dostatek znalostí, abys tohle pochopil. &cMusíš odemknout &f"%item%&f"' not-enough-xp: '&4Nemáš dostatek XP úrovní na to, abys vyzkoumal tuhle věc' unlocked: '&bMáš vyzkoumáno &7„%research%”' only-players: '&4Tenhle příkaz je jenom pro hráče' @@ -123,26 +150,32 @@ messages: mode-change: '&b%device% mód změněn na: &9%mode%' not-shears: '&cMulti Tool nemůže být použit jako nůžky!' auto-crafting: + select-a-recipe: '&eSkrč se a klikni pravým tlačítkem &7na tento blok s předmětem, který chceš vyrobit.' recipe-set: '&aÚspěšně jsi nastavil recept pro tento stroj.' recipe-removed: '&eÚspěšně jsi odstranil recept z tohoto stroje. Kdykoliv můžeš nastavit nový recept!' + no-recipes: '&cNemohu najít žádné platné recepty pro předmět, který držíš.' missing-chest: '&cChybějící truhla! Automatický pracovní stůl musí být položen nad truhlou.' select: 'Vybrat tento recept' temporarily-disabled: '&eTento Automatický pracovní stůl byl dočasně vypnut. Můžete ho kdykoliv znovu zapnout!' re-enabled: '&eTento Automatický pracovní stůl byl znovu aktivován!' + recipe-unavailable: | + &cTento předmět je buďto zakázán na vašem serveru, nebo jste ho ještě neodemkli. + &7Zkuste tento předmět vyrobit, pokud jste to ještě neudělali, abyste odemkli příslušný recept. tooltips: enabled: - '&aTento recept je aktuálně povolen' - '' - - '&eLeft Click &7to temporarily disable the recipe' - - '&eRight Click &7to remove this recipe' + - '&eKlikni levým tlačítkem &7pro dočasné vypnutí receptu' + - '&eKlikni pravým tlačítkem &7pro odstranění tohoto receptu' disabled: - '&cTento recept je momentálně zakázán' - '' - - '&eLeft Click &7to re-enable this recipe' - - '&eRight Click &7to remove this recipe' + - '&eKlikni levým tlačítkem &7pro opětovné povolení tohoto receptu' + - '&eKlikni pravým tlačítkem &7pro odstranění tohoto receptu' talisman: anvil: '&a&oTvůj talisman zachránil tvůj nástroj od rozbití' miner: '&a&oTvůj talisman zdvojnásobil tvou kořist' + farmer: '&a&oVáš talisman právě zdvojnásobil vaš zisk' hunter: '&a&oTvůj talisman zdvojnásobil tvou kořist' lava: '&a&oTvůj talisman tě zachránil před uhořením' water: '&a&oTvůj talisman tě zachránil před utopením' @@ -198,6 +231,9 @@ messages: - '&7Vždy se podívej na světlou stránku života!' - '&7Tohle byl vlastně Biscuit, a ne Cookie' - '&7Neonové cedule jsou LIT!' + above-limit-level: '&cNelze o(d)enchantovat enchant level vyšší než %level%!' + pickaxe-of-the-seeker: + no-ores: '&cNemohu najít žádné rudy v okolí!' machines: pattern-not-found: '&eBohužel se nepodařilo rozpoznat tento recept. Dej do dávkovače předměty tak, aby odpovídaly receptu.' unknown-material: '&eBohužel se nepodařilo rozpoznat tento předmět v dávkovači. Dej tam něco správného.' @@ -205,6 +241,7 @@ machines: full-inventory: '&eBohužel, můj inventář je plný.' in-use: '&cInventář tohoto bloku je právě otevřen jiným hráčem.' ignition-chamber-no-flint: '&cIgnition Chamberu chybí křesadlo.' + inventory-empty: '&6Úspěšně jsi vytvořili tento Multiblock. Pokračuj umístěním předmětů do dávkovače a kliknutím na něj znovu vyrobíš předmět, který chceš!' ANCIENT_ALTAR: not-enough-pedestals: '&4Altar nemá dostatek Pedestal &c(%pedestals% / 8)' unknown-catalyst: '&4Neznámý katalyst. &cPoužij správný recept!' @@ -252,6 +289,8 @@ brewing_stand: not-working: '&4Nemůžeš používat Slimefun předměty ve varném stojanu!' cartography_table: not-working: '&4Nemůžeš použít Slimefun předměty v kartografickém stole!' +smithing_table: + not-working: '&4Nemůžeš použít Slimefun předmět jako kovářský materiál!' villagers: no-trading: '&4Nemůžeš vyměňovat Slimefun předměty s vesničany!' backpack: diff --git a/src/main/resources/languages/cs/recipes.yml b/src/main/resources/languages/cs/recipes.yml index 48fac2597a..a9abf3e6af 100644 --- a/src/main/resources/languages/cs/recipes.yml +++ b/src/main/resources/languages/cs/recipes.yml @@ -1,168 +1,168 @@ --- slimefun: multiblock: - name: Multiblock + name: 'Multiblock' lore: - '0': Postav ukázanou konstrukci, - '1': jak je ukázáno. Nevyrábí se. + - 'Postav ukázanou konstrukci,' + - 'jak je ukázáno. Nevyrábí se.' enhanced_crafting_table: - name: Enhanced Crafting Table + name: 'Vylepšený pracovní stůl' lore: - '0': Vyrob tento předmět, jak je ukázáno, - '1': za pomocí Enhanced Crafting Table - '2': Normální pracovní stůl nebude stačit! + - 'Vyrob tento předmět, jak je ukázáno,' + - 'za pomocí Enhanced Crafting Table' + - 'Normální pracovní stůl nebude stačit!' armor_forge: - name: Armor Forge + name: 'Výheň pro zbroj' lore: - '0': Vyrob tento předmět, jak je ukázáno, - '1': za použití Armor Forge + - 'Vyrob tento předmět, jak je ukázáno,' + - 'za použití Armor Forge' grind_stone: - name: Brusný kámen + name: 'Brusný kámen' lore: - '0': Vyrob tento předmět, jak je ukázáno, - '1': za použití brusného kamene + - 'Vyrob tento předmět, jak je ukázáno,' + - 'za použití brusného kamene' smeltery: - name: Smeltery + name: 'Tavírna' lore: - '0': Vyrob tento předmět, jak je ukázáno, - '1': za použití Smeltery + - 'Vyrob tento předmět, jak je ukázáno,' + - 'za použití Smeltery' ore_crusher: - name: Ore Crusher + name: 'Drtič rud' lore: - '0': Vyrob tento předmět, jak je ukázáno, - '1': za použití Ore Crusher + - 'Vyrob tento předmět, jak je ukázáno,' + - 'za použití Ore Crusher' mob_drop: + name: 'Kořist z monstra' lore: - '0': Zabij tohle stvoření - '1': k získání tohoto předmětu - name: Mob Drop + - 'Zabij tohle stvoření' + - 'k získání tohoto předmětu' gold_pan: - name: Gold Pan + name: 'Rýžovací pánev' lore: - '0': Použij Gold Pan k - '1': získání tohoto předmětu + - 'Použij Gold Pan k' + - 'získání tohoto předmětu' compressor: - name: Compressor + name: 'Kompresor' lore: - '0': Vyrob tento předmět, jak je ukázáno, - '1': za použití Compressor + - 'Vyrob tento předmět, jak je ukázáno,' + - 'za použití Compressor' pressure_chamber: - name: Pressure Chamber + name: 'Tlaková komora' lore: - '0': Vyrob tento předmět, jak je ukázáno, - '1': za použití Pressure Chamber + - 'Vyrob tento předmět, jak je ukázáno,' + - 'za použití Pressure Chamber' ore_washer: - name: Ore Washer + name: 'Čištič rud' lore: - '0': Vyrob tento předmět, jak je ukázáno, - '1': za použití Ore Washer + - 'Vyrob tento předmět, jak je ukázáno,' + - 'za použití Ore Washer' juicer: - name: Juicer + name: 'Odšťavňovač' lore: - '0': Vyrob tento džus, jak je je ukázáno, - '1': za použití Juicer + - 'Vyrob tento džus, jak je je ukázáno,' + - 'za použití Juicer' magic_workbench: - name: Magic Workbench + name: 'Magický pracovní stůl' lore: - '0': Vyrob tento předmět, jak je ukázáno, - '1': za použití Magic Workbench + - 'Vyrob tento předmět, jak je ukázáno,' + - 'za použití Magic Workbench' ancient_altar: - name: Ancient Altar + name: 'Starověký oltář' lore: - '0': Vyrob tento předmět, jak je ukázáno, - '1': za použití Ancient Altar. - '2': Podívej se na Ancient Altar pro více informací + - 'Vyrob tento předmět, jak je ukázáno,' + - 'za použití Ancient Altar.' + - 'Podívej se na Ancient Altar pro více informací' heated_pressure_chamber: - name: Heated Pressure Chamber + name: 'Zahřívaná tlaková komora' lore: - '0': Vyrob tento předmět, jak je ukázáno, - '1': za použití Heated Pressure Chamber + - 'Vyrob tento předmět, jak je ukázáno,' + - 'za použití Heated Pressure Chamber' food_fabricator: - name: Food Fabricator + name: 'Fabrikátor jídla' lore: - '0': Vyrob tento předmět, jak je ukázáno, - '1': za použití Food Fabricator + - 'Vyrob tento předmět, jak je ukázáno,' + - 'za použití Food Fabricator' food_composter: - name: Food Composter + name: 'Komposter na jídlo' lore: - '0': Vyrob tento předmět, jak je ukázáno, - '1': za použití Food Composter + - 'Vyrob tento předmět, jak je ukázáno,' + - 'za použití Food Composter' freezer: - name: Freezer + name: 'Mrazák' lore: - '0': Vyrob tento předmět, jak je ukázáno, - '1': za použití Freezer + - 'Vyrob tento předmět, jak je ukázáno,' + - 'za použití Freezer' geo_miner: - name: GEO Miner + name: 'GEO horník' lore: - '0': Tento předmět lze shromažďovat - '1': pomocí GEO Miner + - 'Tento předmět lze shromažďovat' + - 'pomocí GEO Miner' nuclear_reactor: - name: Nuclear Reactor + name: 'Jaderný reaktor' lore: - '1': při provozování v Nuclear Reactor - '0': Tento předmět je vedlejší produkt + - 'Tento předmět je vedlejší produkt' + - 'při provozování v Nuclear Reactor' oil_pump: - name: Oil Pump + name: 'Ropná pumpa' lore: - '0': Tento předmět lze shromažďovat - '1': pomocí Oil Pump + - 'Tento předmět lze shromažďovat' + - 'pomocí Oil Pump' pickaxe_of_containment: - name: Pickaxe of Containment + name: 'Krumpáč zadržení' lore: - '1': těžbou líhně pomocí - '2': Pickaxe of Containment - '0': Tento blok lze získat + - 'Tento blok lze získat' + - 'těžbou líhně pomocí' + - 'Pickaxe of Containment' refinery: - name: Refinery + name: 'Rafinérie' lore: - '0': Vyrob tento předmět, jak je ukázáno, - '1': za použití Rafinery + - 'Vyrob tento předmět, jak je ukázáno,' + - 'za použití Rafinery' barter_drop: - name: Piglin Bartering Drop + name: 'Odměna z obchodování s pigliny' lore: - '0': Vyměňuj s pigliny zlaté - '1': ingoty k získání tohoto předmětu + - 'Vyměňuj s pigliny zlaté' + - 'ingoty k získání tohoto předmětu' minecraft: shaped: - name: Recept na výrobu ve tvaru + name: 'Recept na výrobu ve tvaru' lore: - '0': Vyrob tento předmět, jak je ukázáno, - '1': v normálním pracovním stole - '2': Tvar je důležitý. + - 'Vyrob tento předmět, jak je ukázáno,' + - 'v normálním pracovním stole' + - 'Tvar je důležitý.' shapeless: - name: U receptu nezáleží na tvaru + name: 'U receptu nezáleží na tvaru' lore: - '0': Vyrob tento předmět, jak je ukázáno, - '1': v normálním pracovním stole - '2': Tento recept je beztvarý. + - 'Vyrob tento předmět, jak je ukázáno,' + - 'v normálním pracovním stole' + - 'Tento recept je beztvarý.' furnace: + name: 'Recept na pec' lore: - '0': Roztav tento předmět v peci - '1': k vyrobení vysněného předmětu - name: Recept na pec + - 'Roztav tento předmět v peci' + - 'k vyrobení vysněného předmětu' blasting: - name: Recept na tavicí pec + name: 'Recept na tavicí pec' lore: - '0': Roztav tento předmět v tavící peci - '1': k vyrobení vysněného předmětu + - 'Roztav tento předmět v tavící peci' + - 'k vyrobení vysněného předmětu' smoking: - name: Recept na troubu + name: 'Recept na troubu' lore: - '0': Upeč tenhle předmět v troubě - '1': k vyrobení vysněného předmětu + - 'Upeč tenhle předmět v troubě' + - 'k vyrobení vysněného předmětu' campfire: + name: 'Recept na táborák' lore: - '0': Upeč tenhle předmět v táboráku - '1': k vyrobení vysněného předmětu - name: Recept na táborák + - 'Upeč tenhle předmět v táboráku' + - 'k vyrobení vysněného předmětu' stonecutting: - name: Recept na řezačku kamene + name: 'Recept na řezačku kamene' lore: - '0': Vyrob tento předmět, jak je ukázáno, - '1': za použití řezačky kamene + - 'Vyrob tento předmět, jak je ukázáno,' + - 'za použití řezačky kamene' smithing: name: 'Recept na kovářský stůl ' lore: - '0': Vyrob tento předmět, jak je ukázáno, - '1': za použití kovářského stolu + - 'Vyrob tento předmět, jak je ukázáno,' + - 'za použití kovářského stolu' diff --git a/src/main/resources/languages/cs/researches.yml b/src/main/resources/languages/cs/researches.yml index 3ab80b9962..facaa79c4b 100644 --- a/src/main/resources/languages/cs/researches.yml +++ b/src/main/resources/languages/cs/researches.yml @@ -62,6 +62,8 @@ slimefun: water_talisman: Talisman dýchání pod vodou angel_talisman: Talisman anděla fire_talisman: Talisman hasiče + caveman_talisman: Talisman jeskynního člověka + wise_talisman: Talisman moudrosti lava_crystal: Ohnivá situace magician_talisman: Talisman kouzelníka traveller_talisman: Talisman cestovatele @@ -145,6 +147,7 @@ slimefun: hologram_projector: Hologramy capacitors: Kondenzátory 1. stupně high_tier_capacitors: Kondenzátory 2. stupně + even_higher_tier_capacitors: Kondenzátory 3. stupně solar_generators: Solární elektrárna electric_furnaces: Elektrická pec electric_ore_grinding: Drcení a broušení @@ -168,6 +171,7 @@ slimefun: energized_solar_generator: Nezastavitelná solární energie energized_gps_transmitter: Nejlepší vysílač energy_regulator: Energické sítě 101 + energy_connectors: Drátové připojení butcher_androids: Řeznické androidy organic_food: Organické jídlo auto_breeder: Automatické krmení @@ -185,6 +189,7 @@ slimefun: cargo_basics: Základy nákladu cargo_nodes: Nastavení nákladu electric_ingot_machines: Elektrická výroba ingotů + medium_tier_electric_ingot_machines: Rychlá výroba ingotů high_tier_electric_ingot_machines: Super rychlá výroba ingotů automated_crafting_chamber: Automatická výroba better_food_fabricator: Vylepšená výroba jídla @@ -206,6 +211,7 @@ slimefun: better_heated_pressure_chamber: Vylepšená vytápěná tlaková komora elytra: Krovky special_elytras: Speciální krovky + trident: Trojzubec electric_crucible: Elektrický kotel better_electric_crucibles: Horké kotle advanced_electric_smeltery: Vylepšená elektrická tavírna @@ -230,23 +236,26 @@ slimefun: electric_press: Elektrický lis magnesium_generator: Energie z magnézia kelp_cookie: Chutná řasa + makeshift_smeltery: Vylepšená tavírna + tree_growth_accelerator: Rychlejší stromy + industrial_miner: Průmyslové těžení advanced_industrial_miner: Lepší těžení magical_zombie_pills: Dezombifikace - enchantment_rune: Antická očarování + auto_brewer: Průmyslový pivovar climbing_pick: Blokace nájezdníků - caveman_talisman: Talisman jeskynního člověka - even_higher_tier_capacitors: Kondenzátory 3. stupně - elytra_cap: Popraskané brnění - energy_connectors: Drátové připojení - bee_armor: Včelí zbroj - wise_talisman: Talisman moudrosti - book_binder: Vázání knihy očarování - makeshift_smeltery: Vylepšená tavírna - tree_growth_accelerator: Rychlejší stromy + shulker_shell: Syntetičtí shulkeři + enchantment_rune: Antická očarování lead_clothing: Olověné oblečení tape_measure: Svinovací metr iron_golem_assembler: Automatická farma na železné golemy - shulker_shell: Syntetičtí shulkeři villager_rune: Obnova vesnických obchodů - industrial_miner: Průmyslové těžení - auto_brewer: Průmyslový pivovar + elytra_cap: Popraskané brnění + bee_armor: Včelí zbroj + book_binder: Vázání knihy očarování + auto_crafting: Automatická výroba + produce_collector: Automatické dojení + improved_generators: Vylepšené generátory + ingredients_and_cheese: Slimefun kuchyně + medium_tier_auto_enchanting: Rychlé automatické Očarování a Odčarování + portable_teleporter: Teleportace odkudkoli + farmer_talisman: Talisman farmáře diff --git a/src/main/resources/languages/es/messages.yml b/src/main/resources/languages/es/messages.yml index 1b97091978..f88a777744 100644 --- a/src/main/resources/languages/es/messages.yml +++ b/src/main/resources/languages/es/messages.yml @@ -29,7 +29,11 @@ commands: verbose-player: '&4La flag verbose no puede ser usada por un jugador!' unknown-flag: '&4flag desconocida: &c%flag%' debug: + description: 'Ejecutar registro de depuración para los desarolladores' + current: '&7Caso de prueba actual: &6%test_case%' + none-running: '&7Actualmente no se está ejecutando ningún caso de prueba!' running: '&7Ejecutando el modo de depuración con prueba: &6%test%' + disabled: '&7Desactivar Modo de Depuración.' placeholderapi: profile-loading: 'Cargando...' guide: @@ -81,12 +85,20 @@ guide: learning-animation: enabled: text: - - '&bLearning Animation: &aYes' + - '&bAnimación de Aprendizaje: &aSí' - '' - '&7Ahora puedes seleccionar si' - - '&7will see information about your pondering in chat' - - '&7upon researching an item.' + - '&7podrás ver el avance de tu meditación en el chat' + - '&7al investigar un objeto.' click: '&eCliquea para desactivar la animación de aprendizaje' + disabled: + text: + - '&bAnimación de Aprendizaje: &4No' + - '' + - '&7Ahora puedes seleccionar si' + - '&7podrás ver el avance de tu meditación en el chat' + - '&7al investigar un objeto.' + click: '&eHaz clic para activar la animación de aprendizaje' title: main: 'Guía de Slimefun.' settings: 'Configuración e Información.' @@ -113,6 +125,7 @@ guide: resourcepack: '&cArtista de Resourcepack' translator: '&9Traductor' messages: + not-researched: '&4No tienes el conocimiento suficiente para entender esto. &cNecesitas desbloquear: &f"%item%&f"' not-enough-xp: '&4No tienes suficiente XP para desbloquear esto.' unlocked: '&bHas desbloqueado &7"%research%"' only-players: '&4Este comando es solo para jugadores.' @@ -138,16 +151,31 @@ messages: not-shears: '&c¡Una Multi Tool no puede ser usada como tijeras!' auto-crafting: select-a-recipe: '&eAgáchate y haz Clic Derecho &7a este bloque con el objeto que quieres crear.' + recipe-set: '&aHas configurado con éxito la receta para esta máquina.' + recipe-removed: '&eHas eliminado con éxito la receta de esta máquina. ¡Puedes establecer una receta en cualquier momento!' no-recipes: '&cNo se han encontrado recetas validas para el objeto que estás sosteniendo.' + missing-chest: '&c¡Cofre no encontrado! Los crafteos automaticos tienen que estar colocados encima de un cofre.' + select: 'Selecciona esta receta' + temporarily-disabled: '&e¡Este Auto-Crafter ha sido temporalmente desactivado. Puedes re-activarlo de nuevo en cualquier momento!' + re-enabled: '&e¡Este Auto-Crafter ha sido re-activado!' + recipe-unavailable: | + &cEste objeto esta deshabilitado en el servidor, o aun no lo has desbloqueado. + &7Intenta fabricar el objeto si no lo has hecho antes para desbloquear la receta. tooltips: enabled: - - '&aThis recipe is currently enabled' + - '&aEsta receta esta actualmente activada' - '' - '&eClic izquierdo &7para desactivar temporalmente la receta' - - '&eRight Click &7to remove this recipe' + - '&eClick derecho &7para eliminar esta receta' + disabled: + - '&cEsta receta está actualmente desactivada' + - '' + - '&eClick izquierdo &7para re-activar esta receta' + - '&eClick Derecho &7para eliminar esta receta' talisman: anvil: '&a&oEl talismán salvó tu herramienta de ser destruida.' miner: '&a&oTu talismán ha duplicado los minerales.' + farmer: '&a&oTu Talismán acaba de duplicar tus objetos' hunter: '&a&oTu talismán ha duplicado el botín' lava: '&a&oTu talismán ha evitado que te quemes en lava.' water: '&a&oTu talismán ha evitado que mueras ahogado.' @@ -203,6 +231,9 @@ messages: - '&7¡Siempre mira el lado bueno de la vida!' - '&7Esta era un bizcocho y no una galleta' - '&7¡Los signos de neón son lo MEJOR!' + above-limit-level: '&c¡No puedes (des)encantar un nivel de encantamiento superior a %level%!' + pickaxe-of-the-seeker: + no-ores: '&c¡No se encuentra ningún mineral cerca!' machines: pattern-not-found: '&eLo siento, no puedo reconocer esta receta. Por favor coloca el objeto en el patrón correcto dentro del dispensador.' unknown-material: '&eLo siento, no puedo reconocer el objeto en mi dispensador. Por favor coloca algo que si conozca.' @@ -258,6 +289,8 @@ brewing_stand: not-working: '&4¡No puedes usar objetos de Slimefun en un soporte para pociones!' cartography_table: not-working: '&4No puedes usar items de Slimefun en una Mesa de Cartografía!' +smithing_table: + not-working: '&4! No puedes usar este objeto de Slimefun, como un material de herrería!' villagers: no-trading: '&4¡No puedes comerciar objetos de Slimefun con los aldeanos!' backpack: @@ -359,6 +392,7 @@ languages: ja: 'Japonés' fa: 'Persa' th: 'Tailandés' + tl: 'Tagalog' ro: 'Rumano' bg: 'Búlgaro' ko: 'Coreano' diff --git a/src/main/resources/languages/es/recipes.yml b/src/main/resources/languages/es/recipes.yml index 868b785365..7e65308b0a 100644 --- a/src/main/resources/languages/es/recipes.yml +++ b/src/main/resources/languages/es/recipes.yml @@ -1,168 +1,168 @@ --- slimefun: multiblock: - name: Multiblock + name: 'Multibloque' lore: - - Construye la estructura tal como se muestra - - como se muestra. No es una receta. + - 'Construye la estructura tal como se muestra' + - 'como se muestra. No es una receta.' enhanced_crafting_table: - name: Enhanced Crafting Table + name: 'Mesa de crafteo mejorada' lore: - - Haz este objeto tal como se muestra - - en una Enhanced Crafting Table. - - "¡Una Tabla de Crafteo normal no servirá!" + - 'Haz este objeto tal como se muestra' + - 'en una Enhanced Crafting Table.' + - '¡Una Tabla de Crafteo normal no servirá!' armor_forge: - name: Armor Forge + name: 'Forja de armaduras' lore: - - Haz este objeto tal como se muestra - - usando una Armor Forge + - 'Haz este objeto tal como se muestra' + - 'usando una Armor Forge' grind_stone: - name: Grind Stone + name: 'Piedra de Moler' lore: - - Haz este objeto tal como se muestra - - usando una Grind Stone + - 'Haz este objeto tal como se muestra' + - 'usando una Grind Stone' smeltery: - name: Smeltery + name: 'Fundición' lore: - - Haz este objeto tal como se muestra - - usando un Smeltery + - 'Haz este objeto tal como se muestra' + - 'usando un Smeltery' ore_crusher: - name: Ore Crusher + name: 'Trituradora de mineral' lore: - - Haz este objeto tal como se muestra - - usando un Ore Crusher + - 'Haz este objeto tal como se muestra' + - 'usando un Ore Crusher' mob_drop: - name: Botín de Mob + name: 'Botín de Mob' lore: - - Mata ese Mob para - - obtener este objeto. + - 'Mata ese Mob para' + - 'obtener este objeto.' gold_pan: - name: Gold Pan + name: 'Colador' lore: - - Usa un Gold Pan para - - obtener este objeto. + - 'Usa un Gold Pan para' + - 'obtener este objeto.' compressor: - name: Compressor + name: 'Compresor' lore: - - Haz este objeto tal como se muestra - - usando un Compressor + - 'Haz este objeto tal como se muestra' + - 'usando un Compressor' pressure_chamber: - name: Pressure Chamber + name: 'Cámara de Presión' lore: - - Haz este objeto tal como se muestra - - usando un Pressure Chamber + - 'Haz este objeto tal como se muestra' + - 'usando un Pressure Chamber' ore_washer: - name: Ore Washer + name: 'Lavador de Minerales' lore: - - Haz este objeto tal como se muestra - - usando un Ore Washer + - 'Haz este objeto tal como se muestra' + - 'usando un Ore Washer' juicer: - name: Juicer + name: 'Exprimidor' lore: - - Haz este jugo tal como se muestra - - usando un Juicer + - 'Haz este jugo tal como se muestra' + - 'usando un Juicer' magic_workbench: - name: Magic Workbench + name: 'Mesa de Trabajo Mágica' lore: - - Haz este objeto tal como se muestra - - Usando una Magic Workbench + - 'Haz este objeto tal como se muestra' + - 'Usando una Magic Workbench' ancient_altar: - name: Ancient Altar + name: 'Altar Antiguo' lore: - - Haz este objeto tal como se muestra - - usando un Ancient Altar. - - Busca Ancient Altar para mas info. + - 'Haz este objeto tal como se muestra' + - 'usando un Ancient Altar.' + - 'Busca Ancient Altar para mas info.' heated_pressure_chamber: - name: Heated Pressure Chamber + name: 'Cámara de Presión Caliente' lore: - - Haz este objeto tal como se muestra - - usando una Heated Pressure Chamber + - 'Haz este objeto tal como se muestra' + - 'usando una Heated Pressure Chamber' food_fabricator: - name: Food Fabricator + name: 'Fabricador de alimentos' lore: - - Haz este objeto tal como se muestra - - usando un Food Fabricator + - 'Haz este objeto tal como se muestra' + - 'usando un Food Fabricator' food_composter: - name: Food Composter + name: 'Compostador de Comida' lore: - - Haz este objeto tal como se muestra - - usando un Food Composter + - 'Haz este objeto tal como se muestra' + - 'usando un Food Composter' freezer: - name: Freezer + name: 'Congelador' lore: - - Congela este objeto tal como se muestra - - usando un Freezer + - 'Congela este objeto tal como se muestra' + - 'usando un Freezer' geo_miner: - name: GEO Miner + name: 'GEO-Minador' lore: - - Este objeto se puede obtener - - usando un GEO Miner + - 'Este objeto se puede obtener' + - 'usando un GEO Miner' nuclear_reactor: - name: Nuclear Reactor + name: 'Reactor nuclear' lore: - - Este objeto es un suproducto generado - - al correr un Nuclear Reactor + - 'Este objeto es un suproducto generado' + - 'al correr un Nuclear Reactor' oil_pump: - name: Oil Pump + name: 'Bomba Petrolera' lore: - - Este objeto puede ser recogido - - usando una Oil Pump + - 'Este objeto puede ser recogido' + - 'usando una Oil Pump' pickaxe_of_containment: - name: Pickaxe of Containment + name: 'Pica-Spawners' lore: - - Este bloque puede ser obtenido - - al minar un Generador con - - el Pickaxe of Containment + - 'Este bloque puede ser obtenido' + - 'al minar un Generador con' + - 'el Pickaxe of Containment' refinery: - name: Refinery + name: 'Refinería' lore: - - Haz este objeto tal como se muestra - - usando una Refinery + - 'Haz este objeto tal como se muestra' + - 'usando una Refinery' barter_drop: - name: Piglin Bartering Drop + name: 'Trueque de Piglin' lore: - - Tradea con Piglins usando - - Lingotes de Oro para obtener este objeto + - 'Tradea con Piglins usando' + - 'Lingotes de Oro para obtener este objeto' minecraft: shaped: - name: Receta de Crafteo con forma + name: 'Receta de Crafteo con forma' lore: - - Haz este objeto tal como se muestra - - en una Tabla de Crafteo normal, - - la forma es importante. + - 'Haz este objeto tal como se muestra' + - 'en una Tabla de Crafteo normal,' + - 'la forma es importante.' shapeless: - name: Receta de Crafteo sin forma + name: 'Receta de Crafteo sin forma' lore: - - Haz este objeto tal como se muestra - - en una Tabla de Crafteo normal - - Esta receta no tiene forma. + - 'Haz este objeto tal como se muestra' + - 'en una Tabla de Crafteo normal' + - 'Esta receta no tiene forma.' furnace: - name: Receta de Horno + name: 'Receta de Horno' lore: - - Funde este objeto en un Horno - - para obtener el objeto que buscas. + - 'Funde este objeto en un Horno' + - 'para obtener el objeto que buscas.' blasting: - name: Receta de Alto Horno + name: 'Receta de Alto Horno' lore: - - Funde este objeto en un Alto Horno - - para obtener el objeto que buscas. + - 'Funde este objeto en un Alto Horno' + - 'para obtener el objeto que buscas.' smoking: - name: Receta de Ahumador + name: 'Receta de Ahumador' lore: - - Funde este objeto en un Ahumador - - para obtener el objeto que buscas. + - 'Funde este objeto en un Ahumador' + - 'para obtener el objeto que buscas.' campfire: - name: Receta de Hoguera + name: 'Receta de Hoguera' lore: - - Funde este objeto sobre una Hoguera - - para obtener el objeto que buscas. + - 'Funde este objeto sobre una Hoguera' + - 'para obtener el objeto que buscas.' stonecutting: - name: Receta de Cortapiedras + name: 'Receta de Cortapiedras' lore: - - Haz este objeto tal como se muestra - - usando un Cortapiedras + - 'Haz este objeto tal como se muestra' + - 'usando un Cortapiedras' smithing: - name: Smithing Table Recipe + name: 'Receta de Mesa de Herrerías' lore: - - Haz este objeto como se muestra - - usando una Smithing Table + - 'Haz este objeto como se muestra' + - 'usando una Smithing Table' diff --git a/src/main/resources/languages/es/researches.yml b/src/main/resources/languages/es/researches.yml index f816c31b27..1cbba4cfa4 100644 --- a/src/main/resources/languages/es/researches.yml +++ b/src/main/resources/languages/es/researches.yml @@ -25,7 +25,7 @@ slimefun: steel_thruster: Propulsor de Acero parachute: Paracaídas grappling_hook: Gancho - jetpacks: Jetpacks + jetpacks: Jetpack multitools: Multi Herramientas solar_panel_and_helmet: Energía solar elemental_staff: Bastónes Elementales @@ -62,6 +62,8 @@ slimefun: water_talisman: Talismán del Pez angel_talisman: Talismán del Ángel fire_talisman: Talismán del Bombero + caveman_talisman: Talismán del Cavernícola + wise_talisman: Talismán del Sabio lava_crystal: Situación Ardiente magician_talisman: Talismán del Mago traveller_talisman: Talismán del Explorador @@ -97,7 +99,7 @@ slimefun: backpacks: Mochilas woven_backpack: Mochila Tejida crucible: Crisol - gilded_backpack: 'Mochila Reforzada ' + gilded_backpack: Mochila Reforzada armored_jetpack: Jetpack Blindado ender_talismans: Talismán de Ender nickel_and_cobalt: Aún más Minerales @@ -145,6 +147,7 @@ slimefun: hologram_projector: Hologramas capacitors: Capacitador LVL I high_tier_capacitors: Capacitador LVL II + even_higher_tier_capacitors: Capacitores Tier 3 solar_generators: Generador Solar electric_furnaces: Horno Eléctrico electric_ore_grinding: Triturar y Moler @@ -168,6 +171,7 @@ slimefun: energized_solar_generator: Energía Solar a Tiempo Completo energized_gps_transmitter: Transmisor de Punta energy_regulator: Redes Energéticas 101 + energy_connectors: Conexiones Instaladas butcher_androids: Androides Carniceros organic_food: Comida Organica auto_breeder: Auto-Alimentacion @@ -185,6 +189,7 @@ slimefun: cargo_basics: Fundamentos de Cargas cargo_nodes: Configuración de Carga electric_ingot_machines: Fabricación Eléctrica de Lingotes + medium_tier_electric_ingot_machines: Fabricación Eléctrica de Lingotes high_tier_electric_ingot_machines: Lingotes Super Rápidos automated_crafting_chamber: Crafteo Automatizado better_food_fabricator: Fabricación de Alimentos Mejorado @@ -204,8 +209,9 @@ slimefun: high_tier_carbon_press: Carbón Prensado Definitivo wither_assembler: Mata Withers Automatizado better_heated_pressure_chamber: Maquina de Presión Caliente Mejorada - elytra: Elytras + elytra: Élitros special_elytras: Elytras Especiales + trident: Tridente electric_crucible: Crisól Electrificado better_electric_crucibles: Crisoles Calientes advanced_electric_smeltery: Fundición Eléctrica Avanzada @@ -236,16 +242,20 @@ slimefun: advanced_industrial_miner: Minería Mejorada magical_zombie_pills: De-Zombificación auto_brewer: Alquimia Industrial + climbing_pick: Incursor de Bloques + shulker_shell: Shulkers Sintéticos enchantment_rune: Encantamiento Antiguo lead_clothing: Ropa de Plomo tape_measure: Cinta Métrica iron_golem_assembler: Iron Golems Automáticos - climbing_pick: Block Raider - shulker_shell: Shulkers Sintéticos villager_rune: Restablece los Intercambios de los Aldeanos - caveman_talisman: Talisman of the Caveman - even_higher_tier_capacitors: Capacitores Tier 3 elytra_cap: Equipo de choque - energy_connectors: Conexiones Instaladas bee_armor: Armadura de Abeja - wise_talisman: Talismán del Sabio + book_binder: Atadura de Libros de Encantamiento + auto_crafting: Crafteo Automatizado + produce_collector: Ordeño Automático + improved_generators: Generadores Improvisados + ingredients_and_cheese: Cocina de Slimefun + medium_tier_auto_enchanting: Mejorar Encantar y Desencantar Automático + portable_teleporter: Teletransporte en tu bolsillo + farmer_talisman: Talisman del Granjero diff --git a/src/main/resources/languages/he/messages.yml b/src/main/resources/languages/he/messages.yml index d8eb04c772..abe377b16e 100644 --- a/src/main/resources/languages/he/messages.yml +++ b/src/main/resources/languages/he/messages.yml @@ -82,16 +82,17 @@ guide: - '&aאנימציית למידה: &aכן' - '' - '&7עכשיו אתה יכול לעבור בין אם אתה' - - '&7will see information about your pondering in chat' + - '&7יראה מידע על התלבטויותיך בתיבת הדיבור' - '&7 עם חקר פריט.' click: '&e לחץ על מנת לבטל את אנימציית הלמידה שלך' disabled: text: - - '&bLearning Animation: &4No' + - '&bאנימציית למידה: &aלא' - '' - '&7עכשיו אתה יכול לעבור בין אם אתה' - - '&7will see information about your pondering in chat' - - '7& עם חקר פריט.' + - '&7יראה מידע על התלבטויותיך בתיבת הדיבור' + - '&7 עם חקר פריט.' + click: '&e לחץ על מנת לאפשר את אנימציית הלמידה שלך' title: main: 'סליים פאן מדריך' settings: 'הגדרות & מידע ' @@ -140,6 +141,21 @@ messages: multi-tool: mode-change: '&b%device% &9: המצב השתנה ל: %mode%' not-shears: '&c מולטי טול לא יכול לשמש כמזמרה!' + auto-crafting: + select: 'בחר מתכון זה' + temporarily-disabled: '&eיוצר אוטומטי זה מושבת זמנית אתה יכול להפעילו שוב בכל זמן!' + re-enabled: '&aיוצר אוטומטי זה הופעל שוב!' + tooltips: + enabled: + - '&aמתכון זה כרגע פעיל' + - '' + - '&e לחץ על מקש שמאלי &7 על מנת להשבית מתכון זה זמנית' + - '&eהקש על מקש ימני &7 על מנת למחוק מתכון זה' + disabled: + - '&cמתכון זה כרגע מושבת' + - '' + - '&eלחץ על מקש שמאלי &7 על מנת לאפשר שוב מתכון זה' + - '&eלחץ על מקש ימני &7 על מנת למחוק מתכון זה' talisman: anvil: '&a&o הקמע שלך הציל את הכלי שלך מלהישבר' miner: '&a&o הקמע שלך בכפיל את הפריטים הנופלים' @@ -198,6 +214,9 @@ messages: - '&7תמיד תסתכל על הצד הטוב שבחיים' - '&7זה היה למעשה ביסקוויט ולא עוגיה' - '&7שלטי הניאון דולקים' + above-limit-level: '&c לא מצליח לכשף/להוריד כישוף עם רמה גבוהה יותר מהרמה (%level%)!' + pickaxe-of-the-seeker: + no-ores: '&c לא מצליח למצוא עופרות בקרבת מקום!' machines: pattern-not-found: "&e סליחה לא יכולתי \n .לזהות את המתכון \nאנא הכנס את \nהפריטים בדפוס הנכון לתוך המתקן " unknown-material: '&e סליחה, לא יכולתי לזהות את הפריט במתקן שלי. אנא הכנס משהו שאני יודע.' @@ -205,6 +224,7 @@ machines: full-inventory: '&e סליחה המלאי שלי יותר מדיי מלא!' in-use: '&c המלאי של בלוק זה נפתח כרגע על ידי שחקן אחר.' ignition-chamber-no-flint: '&c תא הצתה חסר צור ופלדה.' + inventory-empty: '&6 הקמת בהצלחה את ה מולטיבלוק הזה. המשך על ידי הנחת פריטים בתוך המתקן ולחץ עלי שוב כדי ליצור את הפריט הרצוי!' ANCIENT_ALTAR: not-enough-pedestals: "&4 המזבח אני מוקף בכמות המתאימה של כינים &c(%pedestals% /\n8( " unknown-catalyst: '&4 זרז לא ידוע! &c השתמש במתכון הנכון במקום זאת!' diff --git a/src/main/resources/languages/he/recipes.yml b/src/main/resources/languages/he/recipes.yml index ed97d539c0..074bd89a84 100644 --- a/src/main/resources/languages/he/recipes.yml +++ b/src/main/resources/languages/he/recipes.yml @@ -1 +1,91 @@ --- +slimefun: + multiblock: + name: 'מולטיבלוק' + lore: + - 'בנה את הסרטוט המוצג' + - 'כמו שנראה, זה לא נוצר.' + enhanced_crafting_table: + name: 'שולחן יצירה מכושף' + lore: + - 'צור פריט זה, כמו בסרטוט' + - 'בתוך שולחן יצירה מכושף.' + - 'שולחן יצירה רגיל לא יספיק!' + armor_forge: + lore: + - 'צור פריט זה, כמו בסרטוט' + - 'using an Armor Forge' + grind_stone: + name: 'אבן השחזה' + smeltery: + name: 'תנור התכה' + ore_crusher: + lore: + - 'צור פריט זה, כמו בסרטוט' + - 'using an Ore Crusher' + juicer: + name: 'מסחטה' + magic_workbench: + name: 'שולחן מלאכה קסום' + lore: + - 'Craft this Item as shown' + - 'משתמש בשולחן מלאכה קסום' + ancient_altar: + name: 'מזבח עתיק' + lore: + - 'Craft this Item as shown' + - 'משתמש במזבח עתיק.' + - 'חקור את המזבח העתיק בשביל עוד מידע' + heated_pressure_chamber: + name: 'תא לחץ מחומם' + lore: + - 'צור פריט זה, כמו בסרטוט' + - 'using a Heated Pressure Chamber' + food_fabricator: + name: 'מעבד מזון' + lore: + - 'Craft this Item as shown' + - 'משתמש במעבד מזון' + barter_drop: + name: 'טיפת חליפין של חזיר' + lore: + - 'סחר חליפין עם חזירים באמצעות' + - 'Gold Ingots to obtain this Item' +minecraft: + shaped: + name: 'מתכון יצירה מעוצב' + lore: + - 'צור פריט זה, כמו בסרטוט' + - 'בתוך שולחן יצירה רגיל.' + - 'הצורה חשובה.' + shapeless: + name: 'מתכון יצירה ללא צורה' + lore: + - 'צור פריט זה, כמו בסרטוט' + - 'בתוך שולחן יצירה רגיל.' + - 'פריט זה הוא חסר צורה.' + furnace: + lore: + - 'התך פריט זה בתוך תנור' + - 'ליצור את הפריט הרצוי' + blasting: + name: 'מתכון של תנור מתכות' + lore: + - 'התך פריט זה בתוך תנור מתכות' + - 'ליצור את הפריט הרצוי' + smoking: + lore: + - 'התך פריט זה בתוך מעשנה' + - 'ליצור את הפריט הרצוי' + campfire: + lore: + - 'התך פריט זה מעל מדורה' + - 'ליצור את הפריט הרצוי' + stonecutting: + lore: + - 'צור פריט זה, כמו בסרטוט' + - 'using a Stonecutter' + smithing: + lore: + - 'צור פריט זה, כמו בסרטוט' + - 'using a Smithing Table' diff --git a/src/main/resources/languages/it/messages.yml b/src/main/resources/languages/it/messages.yml index c45c1855ac..28241dbd65 100644 --- a/src/main/resources/languages/it/messages.yml +++ b/src/main/resources/languages/it/messages.yml @@ -121,7 +121,7 @@ messages: give-research: '&bHai dato a %player% la ricerca &7 "%research% &7"' hungry: '&cSei troppo affamato per farlo!' disabled-in-world: '&4&lQuesto oggetto è stato disattivato in questo mondo!' - disabled-item: '&4& lQuesto oggetto è stato disabilitato! Come l''hai ottenuto?' + disabled-item: '&4&lQuesto oggetto è stato disabilitato! Come l''hai ottenuto?' no-tome-yourself: '&cNon puoi utilizzare il &4Tomo della conoscienza &c su te stesso ...' multimeter: '&bEnergia salvata: &3%stored% &b/&3%capacity%' piglin-barter: '&4Non puoi barattare con i Piglins usando gli oggetti di Slimefun' diff --git a/src/main/resources/languages/tr/messages.yml b/src/main/resources/languages/tr/messages.yml index 2ee7612cd8..ac4c9af471 100644 --- a/src/main/resources/languages/tr/messages.yml +++ b/src/main/resources/languages/tr/messages.yml @@ -24,7 +24,12 @@ commands: charge-success: Eşyanız şarz edildi! not-rechargeable: Bu eşya şarz edilemez! timings: + description: Slimefun ve Eklentileri için zamanlamalar please-wait: '&eLütfen bir saniye bekleyin... Sonuçlar geliyor!' + verbose-player: '&4Ayrıntılı bayrak bir oyuncu tarafından kullanılamaz!' + debug: + description: 'Developerlar için hata ayıklamayı başlat' + disabled: '&7Hata ayıklama kapalı.' placeholderapi: profile-loading: 'Yükleniyor...' guide: @@ -119,6 +124,14 @@ messages: multi-tool: mode-change: '&b%device% modül değiştirildi: &9%mode%' not-shears: '&cBir Multi Tool makas olarak kullanılamaz!' + auto-crafting: + select: 'Bu tarifi seçin' + tooltips: + enabled: + - '&aBu tarif şu anda etkin' + - '' + - '&eLeft Click &7to temporarily disable the recipe' + - '&eRight Click &7to remove this recipe' talisman: anvil: '&a&oTılsım aletinizi kırılmadan kurtardı' miner: '&a&oTılsımın madenini ikiye katladı' @@ -176,6 +189,8 @@ messages: - '&7Daima hayatın parlak tarafından bak!' - '&7Bu aslında bir Bisküvi idi, Kurabiye değil.' - '&7Neon levhalar ışık yayar!' + pickaxe-of-the-seeker: + no-ores: '&cYakındaki cevherleri bulamıyorum!' machines: pattern-not-found: '&eÜzgünüm, bu tarifi tanıyamadım. Lütfen Eşyaları Dağıtıcıya doğru şekilde yerleştirin.' unknown-material: '&eÜzgünüm, fırlatıcıdaki Eşyayı tanıyamadım. Lütfen bildiğim bir şey koy.' @@ -257,6 +272,7 @@ android: scripts: already-uploaded: '&4Bu senaryo zaten yüklendi.' editor: 'Senaryo Editörü' + too-long: '&cSenaryo düzenlemek için çok uzun!' instructions: START: '&2Senaryoyu başlat' REPEAT: '&9Senaryoyu Tekrar Et' diff --git a/src/test/java/io/github/thebusybiscuit/slimefun4/core/services/localization/AbstractLocaleRegexChecker.java b/src/test/java/io/github/thebusybiscuit/slimefun4/core/services/localization/AbstractLocaleRegexChecker.java new file mode 100644 index 0000000000..63eef282b4 --- /dev/null +++ b/src/test/java/io/github/thebusybiscuit/slimefun4/core/services/localization/AbstractLocaleRegexChecker.java @@ -0,0 +1,103 @@ +package io.github.thebusybiscuit.slimefun4.core.services.localization; + +import java.io.BufferedReader; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.nio.charset.StandardCharsets; +import java.util.Arrays; +import java.util.List; +import java.util.Map; +import java.util.regex.Matcher; +import java.util.regex.Pattern; +import java.util.stream.Stream; + +import javax.annotation.Nonnull; +import javax.annotation.Nullable; +import javax.annotation.ParametersAreNonnullByDefault; + +import org.apache.commons.lang.Validate; +import org.bukkit.configuration.file.FileConfiguration; +import org.junit.jupiter.api.AfterAll; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.params.provider.Arguments; + +import be.seeseemelk.mockbukkit.MockBukkit; + +class AbstractLocaleRegexChecker { + + private final Pattern pattern; + + AbstractLocaleRegexChecker(@Nonnull Pattern pattern) { + Validate.notNull(pattern, "The pattern cannot be null."); + + this.pattern = pattern; + } + + @BeforeAll + public static void load() { + MockBukkit.mock(); + } + + @AfterAll + public static void unload() { + MockBukkit.unmock(); + } + + public @Nonnull Pattern getPattern() { + return this.pattern; + } + + @ParametersAreNonnullByDefault + @Nullable + BufferedReader readLanguageFile(LanguagePreset lang, LanguageFile file) { + String path = file.getFilePath(lang.getLanguageCode()); + InputStream inputStream = getClass().getResourceAsStream(path); + + if (inputStream == null) { + // This file does not exist, we consider it "passed". + return null; + } + + return new BufferedReader(new InputStreamReader(inputStream, StandardCharsets.UTF_8)); + } + + @ParametersAreNonnullByDefault + void assertNoRegexMatchesForAllEntries(LanguagePreset lang, LanguageFile file, FileConfiguration config) { + for (Map.Entry entry : config.getValues(true).entrySet()) { + String key = entry.getKey(); + Object value = entry.getValue(); + + if (value instanceof String) { + String location = lang.getLanguageCode() + '/' + file.name() + ": " + key; + assertNoRegexMatch(location, (String) value); + } else if (value instanceof List) { + int index = 0; + for (Object element : (List) value) { + if (element instanceof String) { + String location = lang.getLanguageCode() + '/' + file.name() + ": " + key + "[" + index + "]"; + assertNoRegexMatch(location, (String) element); + } + + index++; + } + } + } + } + + @ParametersAreNonnullByDefault + void assertNoRegexMatch(String location, String value) { + Matcher matcher = getPattern().matcher(value); + boolean hasMatch = matcher.find(); + + if (hasMatch) { + Assertions.fail("Mistake found @ \"" + location + "\" - \"" + matcher.group() + "\"!"); + } + } + + static @Nonnull Stream getAllLanguageFiles() { + Stream stream = Arrays.stream(LanguagePreset.values()); + return stream.flatMap(a -> Arrays.stream(LanguageFile.values()).map(b -> Arguments.of(a, b))); + } + +} diff --git a/src/test/java/io/github/thebusybiscuit/slimefun4/core/services/localization/TestColorCodes.java b/src/test/java/io/github/thebusybiscuit/slimefun4/core/services/localization/TestColorCodes.java new file mode 100644 index 0000000000..9be3d2710b --- /dev/null +++ b/src/test/java/io/github/thebusybiscuit/slimefun4/core/services/localization/TestColorCodes.java @@ -0,0 +1,52 @@ +package io.github.thebusybiscuit.slimefun4.core.services.localization; + +import java.io.BufferedReader; +import java.io.IOException; +import java.util.regex.Pattern; + +import javax.annotation.ParametersAreNonnullByDefault; + +import org.bukkit.configuration.file.FileConfiguration; +import org.bukkit.configuration.file.YamlConfiguration; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.MethodSource; + +/** + * We need to make sure that color codes are still working properly. + *

+ * Sometimes, the color code can be accidentally removed as people see + * it as part of the word on first look. This test is designed to catch + * these cases. It is not perfect but it does catch a few instances. + *

+ * The test checks for color chars (ampersands) that have no follow-up + * chatcolor key but rather a preceeding one. + *

+ * The test will catch occurences like "a& ", "b&Hello" or "7&", "5& a". + * The test will however ignore valid color codes such as "a&a". + * + * @author TheBusyBiscuit + * + */ +class TestColorCodes extends AbstractLocaleRegexChecker { + + TestColorCodes() { + super(Pattern.compile("[a-f0-9klmno]&[^a-f0-9klmno]")); + } + + @ParameterizedTest + @ParametersAreNonnullByDefault + @MethodSource("getAllLanguageFiles") + @DisplayName("Test for mistakes in color codes for Slimefun locale files") + void testSpelling(LanguagePreset lang, LanguageFile file) throws IOException { + try (BufferedReader reader = readLanguageFile(lang, file)) { + if (reader == null) { + return; + } + + FileConfiguration config = YamlConfiguration.loadConfiguration(reader); + assertNoRegexMatchesForAllEntries(lang, file, config); + } + } + +} diff --git a/src/test/java/io/github/thebusybiscuit/slimefun4/implementation/items/TestSlimefunItem.java b/src/test/java/io/github/thebusybiscuit/slimefun4/implementation/items/TestSlimefunItem.java index 63fc9669a1..c3e02edf47 100644 --- a/src/test/java/io/github/thebusybiscuit/slimefun4/implementation/items/TestSlimefunItem.java +++ b/src/test/java/io/github/thebusybiscuit/slimefun4/implementation/items/TestSlimefunItem.java @@ -53,7 +53,7 @@ void testWikiPages() { Optional wiki = item.getWikipage(); Assertions.assertTrue(wiki.isPresent()); - Assertions.assertEquals("https://slimefun.guizhanss.wiki/Test", wiki.get()); + Assertions.assertEquals("https://slimefun-wiki.guizhanss.cn/Test", wiki.get()); } @Test