Mirror von
https://github.com/ViaVersion/ViaBackwards.git
synchronisiert 2024-11-20 06:50:10 +01:00
Add StructuredEnchantmentRewriter, update translation mappings
Dieser Commit ist enthalten in:
Ursprung
1507f788ec
Commit
f7dad9b5d7
@ -11,3 +11,6 @@ ij_java_names_count_to_use_import_on_demand = 999999
|
|||||||
ij_java_imports_layout = *,|,$*
|
ij_java_imports_layout = *,|,$*
|
||||||
ij_java_generate_final_locals = true
|
ij_java_generate_final_locals = true
|
||||||
ij_java_generate_final_parameters = true
|
ij_java_generate_final_parameters = true
|
||||||
|
|
||||||
|
[*.json]
|
||||||
|
indent_size = 2
|
@ -26,6 +26,7 @@ import com.viaversion.viaversion.api.data.MappingData;
|
|||||||
import com.viaversion.viaversion.api.data.MappingDataBase;
|
import com.viaversion.viaversion.api.data.MappingDataBase;
|
||||||
import com.viaversion.viaversion.api.data.Mappings;
|
import com.viaversion.viaversion.api.data.Mappings;
|
||||||
import com.viaversion.viaversion.api.protocol.Protocol;
|
import com.viaversion.viaversion.api.protocol.Protocol;
|
||||||
|
import com.viaversion.viaversion.libs.fastutil.ints.Int2ObjectArrayMap;
|
||||||
import com.viaversion.viaversion.libs.fastutil.ints.Int2ObjectMap;
|
import com.viaversion.viaversion.libs.fastutil.ints.Int2ObjectMap;
|
||||||
import com.viaversion.viaversion.libs.fastutil.ints.Int2ObjectOpenHashMap;
|
import com.viaversion.viaversion.libs.fastutil.ints.Int2ObjectOpenHashMap;
|
||||||
import com.viaversion.viaversion.libs.opennbt.tag.builtin.CompoundTag;
|
import com.viaversion.viaversion.libs.opennbt.tag.builtin.CompoundTag;
|
||||||
@ -35,6 +36,7 @@ import com.viaversion.viaversion.libs.opennbt.tag.builtin.Tag;
|
|||||||
import com.viaversion.viaversion.util.Key;
|
import com.viaversion.viaversion.util.Key;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
import java.util.logging.Level;
|
||||||
import java.util.logging.Logger;
|
import java.util.logging.Logger;
|
||||||
import org.checkerframework.checker.nullness.qual.Nullable;
|
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||||
|
|
||||||
@ -44,6 +46,7 @@ public class BackwardsMappings extends MappingDataBase {
|
|||||||
protected Int2ObjectMap<MappedItem> backwardsItemMappings;
|
protected Int2ObjectMap<MappedItem> backwardsItemMappings;
|
||||||
private Map<String, String> backwardsSoundMappings;
|
private Map<String, String> backwardsSoundMappings;
|
||||||
private Map<String, String> entityNames;
|
private Map<String, String> entityNames;
|
||||||
|
private Int2ObjectMap<String> enchantmentNames;
|
||||||
|
|
||||||
public BackwardsMappings(final String unmappedVersion, final String mappedVersion) {
|
public BackwardsMappings(final String unmappedVersion, final String mappedVersion) {
|
||||||
this(unmappedVersion, mappedVersion, null);
|
this(unmappedVersion, mappedVersion, null);
|
||||||
@ -77,23 +80,37 @@ public class BackwardsMappings extends MappingDataBase {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
final CompoundTag entityNames = data.getCompoundTag("entitynames");
|
this.entityNames = loadNameByStringMappings(data, "entitynames");
|
||||||
if (entityNames != null) {
|
this.enchantmentNames = loadNameByIdMappings(data, "enchantmentnames");
|
||||||
this.entityNames = new HashMap<>(entityNames.size());
|
this.backwardsSoundMappings = loadNameByStringMappings(data, "soundnames");
|
||||||
for (final Map.Entry<String, Tag> entry : entityNames.entrySet()) {
|
|
||||||
final StringTag mappedTag = (StringTag) entry.getValue();
|
|
||||||
this.entityNames.put(entry.getKey(), mappedTag.getValue());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
final CompoundTag soundNames = data.getCompoundTag("soundnames");
|
private @Nullable Map<String, String> loadNameByStringMappings(final CompoundTag data, final String key) {
|
||||||
if (soundNames != null) {
|
final CompoundTag nameMappings = data.getCompoundTag(key);
|
||||||
backwardsSoundMappings = new HashMap<>(soundNames.size());
|
if (nameMappings == null) {
|
||||||
for (final Map.Entry<String, Tag> entry : soundNames.entrySet()) {
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
final Map<String, String> map = new HashMap<>(nameMappings.size());
|
||||||
|
for (final Map.Entry<String, Tag> entry : nameMappings.entrySet()) {
|
||||||
final StringTag mappedTag = (StringTag) entry.getValue();
|
final StringTag mappedTag = (StringTag) entry.getValue();
|
||||||
backwardsSoundMappings.put(entry.getKey(), mappedTag.getValue());
|
map.put(entry.getKey(), mappedTag.getValue());
|
||||||
}
|
}
|
||||||
|
return map;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private @Nullable Int2ObjectMap<String> loadNameByIdMappings(final CompoundTag data, final String key) {
|
||||||
|
final CompoundTag nameMappings = data.getCompoundTag(key);
|
||||||
|
if (nameMappings == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
final Int2ObjectMap<String> map = new Int2ObjectArrayMap<>(nameMappings.size());
|
||||||
|
for (final Map.Entry<String, Tag> entry : nameMappings.entrySet()) {
|
||||||
|
final StringTag mappedTag = (StringTag) entry.getValue();
|
||||||
|
map.put(Integer.parseInt(entry.getKey()), mappedTag.getValue());
|
||||||
|
}
|
||||||
|
return map;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -142,13 +159,20 @@ public class BackwardsMappings extends MappingDataBase {
|
|||||||
|
|
||||||
public @Nullable String mappedEntityName(final String entityName) {
|
public @Nullable String mappedEntityName(final String entityName) {
|
||||||
if (entityNames == null) {
|
if (entityNames == null) {
|
||||||
ViaBackwards.getPlatform().getLogger().severe("No entity mappings found when requesting them for " + entityName);
|
ViaBackwards.getPlatform().getLogger().log(Level.SEVERE, "No entity mappings found when requesting them for " + entityName, new RuntimeException());
|
||||||
new Exception().printStackTrace();
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
return entityNames.get(entityName);
|
return entityNames.get(entityName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public @Nullable String mappedEnchantmentName(final int enchantmentId) {
|
||||||
|
if (enchantmentNames == null) {
|
||||||
|
ViaBackwards.getPlatform().getLogger().log(Level.SEVERE, "No enchantment name mappings found when requesting " + enchantmentId, new RuntimeException());
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return enchantmentNames.get(enchantmentId);
|
||||||
|
}
|
||||||
|
|
||||||
public @Nullable Int2ObjectMap<MappedItem> getBackwardsItemMappings() {
|
public @Nullable Int2ObjectMap<MappedItem> getBackwardsItemMappings() {
|
||||||
return backwardsItemMappings;
|
return backwardsItemMappings;
|
||||||
}
|
}
|
||||||
|
@ -27,6 +27,8 @@ import com.viaversion.viaversion.libs.opennbt.tag.builtin.ListTag;
|
|||||||
import com.viaversion.viaversion.libs.opennbt.tag.builtin.StringTag;
|
import com.viaversion.viaversion.libs.opennbt.tag.builtin.StringTag;
|
||||||
import com.viaversion.viaversion.libs.opennbt.tag.builtin.Tag;
|
import com.viaversion.viaversion.libs.opennbt.tag.builtin.Tag;
|
||||||
import com.viaversion.viaversion.rewriter.ItemRewriter;
|
import com.viaversion.viaversion.rewriter.ItemRewriter;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
import org.checkerframework.checker.nullness.qual.Nullable;
|
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||||
|
|
||||||
public abstract class BackwardsItemRewriterBase<C extends ClientboundPacketType, S extends ServerboundPacketType,
|
public abstract class BackwardsItemRewriterBase<C extends ClientboundPacketType, S extends ServerboundPacketType,
|
||||||
@ -52,26 +54,49 @@ public abstract class BackwardsItemRewriterBase<C extends ClientboundPacketType,
|
|||||||
return item;
|
return item;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected boolean hasBackupTag(CompoundTag displayTag, String tagName) {
|
protected boolean hasBackupTag(CompoundTag tag, String tagName) {
|
||||||
return displayTag.contains(nbtTagName("o" + tagName));
|
return tag.contains(nbtTagName(tagName));
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void saveStringTag(CompoundTag displayTag, StringTag original, String name) {
|
protected void saveStringTag(CompoundTag tag, StringTag original, String name) {
|
||||||
// Multiple places might try to backup data
|
// Multiple places might try to backup data
|
||||||
String backupName = nbtTagName("o" + name);
|
String backupName = nbtTagName(name);
|
||||||
if (!displayTag.contains(backupName)) {
|
if (!tag.contains(backupName)) {
|
||||||
displayTag.putString(backupName, original.getValue());
|
tag.putString(backupName, original.getValue());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void saveListTag(CompoundTag displayTag, ListTag<?> original, String name) {
|
protected void saveListTag(CompoundTag tag, ListTag<?> original, String name) {
|
||||||
// Multiple places might try to backup data
|
// Multiple places might try to backup data
|
||||||
String backupName = nbtTagName("o" + name);
|
String backupName = nbtTagName(name);
|
||||||
if (!displayTag.contains(backupName)) {
|
if (!tag.contains(backupName)) {
|
||||||
displayTag.put(backupName, original.copy());
|
tag.put(backupName, original.copy());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected void saveGenericTagList(CompoundTag tag, List<Tag> original, String name) {
|
||||||
|
// List tags cannot contain tags of different types, so we have to store them a bit more awkwardly as an indexed compound tag
|
||||||
|
String backupName = getNbtTagName() + "|" + name;
|
||||||
|
if (!tag.contains(backupName)) {
|
||||||
|
CompoundTag output = new CompoundTag();
|
||||||
|
for (int i = 0; i < original.size(); i++) {
|
||||||
|
output.put(Integer.toString(i), original.get(i));
|
||||||
|
}
|
||||||
|
tag.put(backupName, output);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected List<Tag> removeGenericTagList(CompoundTag tag, String name) {
|
||||||
|
String backupName = getNbtTagName() + "|" + name;
|
||||||
|
CompoundTag data = tag.getCompoundTag(backupName);
|
||||||
|
if (data == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
tag.remove(backupName);
|
||||||
|
return new ArrayList<>(data.values());
|
||||||
|
}
|
||||||
|
|
||||||
protected void restoreDisplayTag(Item item) {
|
protected void restoreDisplayTag(Item item) {
|
||||||
if (item.tag() == null) return;
|
if (item.tag() == null) return;
|
||||||
|
|
||||||
@ -90,19 +115,30 @@ public abstract class BackwardsItemRewriterBase<C extends ClientboundPacketType,
|
|||||||
}
|
}
|
||||||
|
|
||||||
protected void restoreStringTag(CompoundTag tag, String tagName) {
|
protected void restoreStringTag(CompoundTag tag, String tagName) {
|
||||||
Tag original = tag.remove(nbtTagName("o" + tagName));
|
Tag original = tag.remove(nbtTagName(tagName));
|
||||||
if (original instanceof StringTag) {
|
if (original instanceof StringTag) {
|
||||||
tag.putString(tagName, ((StringTag) original).getValue());
|
tag.putString(tagName, ((StringTag) original).getValue());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void restoreListTag(CompoundTag tag, String tagName) {
|
protected void restoreListTag(CompoundTag tag, String tagName) {
|
||||||
Tag original = tag.remove(nbtTagName("o" + tagName));
|
Tag original = tag.remove(nbtTagName(tagName));
|
||||||
if (original instanceof ListTag) {
|
if (original instanceof ListTag) {
|
||||||
tag.put(tagName, ((ListTag<?>) original).copy());
|
tag.put(tagName, ((ListTag<?>) original).copy());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public <T extends Tag> @Nullable ListTag<T> removeListTag(CompoundTag tag, String tagName, Class<T> tagType) {
|
||||||
|
String backupName = nbtTagName(tagName);
|
||||||
|
ListTag<T> data = tag.getListTag(backupName, tagType);
|
||||||
|
if (data == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
tag.remove(backupName);
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String nbtTagName() {
|
public String nbtTagName() {
|
||||||
return "VB|" + protocol.getClass().getSimpleName();
|
return "VB|" + protocol.getClass().getSimpleName();
|
||||||
|
@ -36,6 +36,8 @@ import org.checkerframework.checker.nullness.qual.Nullable;
|
|||||||
public class BackwardsStructuredItemRewriter<C extends ClientboundPacketType, S extends ServerboundPacketType,
|
public class BackwardsStructuredItemRewriter<C extends ClientboundPacketType, S extends ServerboundPacketType,
|
||||||
T extends BackwardsProtocol<C, ?, ?, S>> extends BackwardsItemRewriter<C, S, T> {
|
T extends BackwardsProtocol<C, ?, ?, S>> extends BackwardsItemRewriter<C, S, T> {
|
||||||
|
|
||||||
|
protected final StructuredEnchantmentRewriter enchantmentRewriter = new StructuredEnchantmentRewriter(this);
|
||||||
|
|
||||||
public BackwardsStructuredItemRewriter(final T protocol, final Type<Item> itemType, final Type<Item[]> itemArrayType) {
|
public BackwardsStructuredItemRewriter(final T protocol, final Type<Item> itemType, final Type<Item[]> itemArrayType) {
|
||||||
super(protocol, itemType, itemArrayType);
|
super(protocol, itemType, itemArrayType);
|
||||||
}
|
}
|
||||||
@ -53,6 +55,10 @@ public class BackwardsStructuredItemRewriter<C extends ClientboundPacketType, S
|
|||||||
final StructuredDataContainer data = item.structuredData();
|
final StructuredDataContainer data = item.structuredData();
|
||||||
data.setIdLookup(protocol, true);
|
data.setIdLookup(protocol, true);
|
||||||
|
|
||||||
|
if (protocol.getMappingData().getEnchantmentMappings() != null) {
|
||||||
|
enchantmentRewriter.handleToClient(item);
|
||||||
|
}
|
||||||
|
|
||||||
if (protocol.getTranslatableRewriter() != null) {
|
if (protocol.getTranslatableRewriter() != null) {
|
||||||
// Handle name and lore components
|
// Handle name and lore components
|
||||||
final StructuredData<Tag> customNameData = data.getNonEmpty(StructuredDataKey.CUSTOM_NAME);
|
final StructuredData<Tag> customNameData = data.getNonEmpty(StructuredDataKey.CUSTOM_NAME);
|
||||||
@ -114,6 +120,10 @@ public class BackwardsStructuredItemRewriter<C extends ClientboundPacketType, S
|
|||||||
final StructuredDataContainer data = item.structuredData();
|
final StructuredDataContainer data = item.structuredData();
|
||||||
data.setIdLookup(protocol, false);
|
data.setIdLookup(protocol, false);
|
||||||
|
|
||||||
|
if (protocol.getMappingData().getEnchantmentMappings() != null) {
|
||||||
|
enchantmentRewriter.handleToServer(item);
|
||||||
|
}
|
||||||
|
|
||||||
final CompoundTag tag = customTag(item);
|
final CompoundTag tag = customTag(item);
|
||||||
if (tag != null) {
|
if (tag != null) {
|
||||||
final Tag originalId = tag.remove(nbtTagName("id"));
|
final Tag originalId = tag.remove(nbtTagName("id"));
|
||||||
|
@ -23,6 +23,7 @@ import com.viaversion.viaversion.libs.opennbt.tag.builtin.ListTag;
|
|||||||
import com.viaversion.viaversion.libs.opennbt.tag.builtin.NumberTag;
|
import com.viaversion.viaversion.libs.opennbt.tag.builtin.NumberTag;
|
||||||
import com.viaversion.viaversion.libs.opennbt.tag.builtin.StringTag;
|
import com.viaversion.viaversion.libs.opennbt.tag.builtin.StringTag;
|
||||||
import com.viaversion.viaversion.util.ComponentUtil;
|
import com.viaversion.viaversion.util.ComponentUtil;
|
||||||
|
import com.viaversion.viaversion.util.Key;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
@ -34,8 +35,8 @@ import java.util.Map;
|
|||||||
*/
|
*/
|
||||||
public class EnchantmentRewriter {
|
public class EnchantmentRewriter {
|
||||||
|
|
||||||
private final Map<String, String> enchantmentMappings = new HashMap<>();
|
protected final Map<String, String> enchantmentMappings = new HashMap<>();
|
||||||
private final BackwardsItemRewriter<?, ?, ?> itemRewriter;
|
protected final BackwardsItemRewriter<?, ?, ?> itemRewriter;
|
||||||
private final boolean jsonFormat;
|
private final boolean jsonFormat;
|
||||||
|
|
||||||
public EnchantmentRewriter(BackwardsItemRewriter<?, ?, ?> itemRewriter, boolean jsonFormat) {
|
public EnchantmentRewriter(BackwardsItemRewriter<?, ?, ?> itemRewriter, boolean jsonFormat) {
|
||||||
@ -48,7 +49,7 @@ public class EnchantmentRewriter {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void registerEnchantment(String key, String replacementLore) {
|
public void registerEnchantment(String key, String replacementLore) {
|
||||||
enchantmentMappings.put(key, replacementLore);
|
enchantmentMappings.put(Key.stripMinecraftNamespace(key), replacementLore);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void handleToClient(Item item) {
|
public void handleToClient(Item item) {
|
||||||
@ -89,7 +90,7 @@ public class EnchantmentRewriter {
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
String enchantmentId = idTag.getValue();
|
String enchantmentId = Key.stripMinecraftNamespace(idTag.getValue());
|
||||||
String remappedName = enchantmentMappings.get(enchantmentId);
|
String remappedName = enchantmentMappings.get(enchantmentId);
|
||||||
if (remappedName != null) {
|
if (remappedName != null) {
|
||||||
if (!changed) {
|
if (!changed) {
|
||||||
|
@ -0,0 +1,189 @@
|
|||||||
|
/*
|
||||||
|
* This file is part of ViaBackwards - https://github.com/ViaVersion/ViaBackwards
|
||||||
|
* Copyright (C) 2016-2024 ViaVersion and contributors
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
package com.viaversion.viabackwards.api.rewriters;
|
||||||
|
|
||||||
|
import com.viaversion.viabackwards.api.data.BackwardsMappings;
|
||||||
|
import com.viaversion.viaversion.api.data.Mappings;
|
||||||
|
import com.viaversion.viaversion.api.minecraft.data.StructuredData;
|
||||||
|
import com.viaversion.viaversion.api.minecraft.data.StructuredDataContainer;
|
||||||
|
import com.viaversion.viaversion.api.minecraft.data.StructuredDataKey;
|
||||||
|
import com.viaversion.viaversion.api.minecraft.item.Item;
|
||||||
|
import com.viaversion.viaversion.api.minecraft.item.data.Enchantments;
|
||||||
|
import com.viaversion.viaversion.libs.fastutil.ints.Int2IntMap;
|
||||||
|
import com.viaversion.viaversion.libs.fastutil.ints.IntIntPair;
|
||||||
|
import com.viaversion.viaversion.libs.fastutil.objects.ObjectIterator;
|
||||||
|
import com.viaversion.viaversion.libs.opennbt.tag.builtin.ByteTag;
|
||||||
|
import com.viaversion.viaversion.libs.opennbt.tag.builtin.CompoundTag;
|
||||||
|
import com.viaversion.viaversion.libs.opennbt.tag.builtin.ListTag;
|
||||||
|
import com.viaversion.viaversion.libs.opennbt.tag.builtin.NumberTag;
|
||||||
|
import com.viaversion.viaversion.libs.opennbt.tag.builtin.Tag;
|
||||||
|
import com.viaversion.viaversion.util.ComponentUtil;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class StructuredEnchantmentRewriter {
|
||||||
|
|
||||||
|
protected final BackwardsItemRewriter<?, ?, ?> itemRewriter;
|
||||||
|
private boolean rewriteIds = true;
|
||||||
|
|
||||||
|
public StructuredEnchantmentRewriter(final BackwardsItemRewriter<?, ?, ?> itemRewriter) {
|
||||||
|
this.itemRewriter = itemRewriter;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void handleToClient(final Item item) {
|
||||||
|
final StructuredDataContainer data = item.structuredData();
|
||||||
|
rewriteEnchantmentsToClient(data, StructuredDataKey.ENCHANTMENTS, false);
|
||||||
|
rewriteEnchantmentsToClient(data, StructuredDataKey.STORED_ENCHANTMENTS, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void handleToServer(final Item item) {
|
||||||
|
final StructuredDataContainer data = item.structuredData();
|
||||||
|
final StructuredData<CompoundTag> customData = data.getNonEmpty(StructuredDataKey.CUSTOM_DATA);
|
||||||
|
if (customData == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
final CompoundTag tag = customData.value();
|
||||||
|
if (tag.contains(itemRewriter.getNbtTagName() + "|enchantments")) {
|
||||||
|
rewriteEnchantmentsToServer(data, tag, StructuredDataKey.ENCHANTMENTS, false);
|
||||||
|
}
|
||||||
|
if (tag.contains(itemRewriter.getNbtTagName() + "|stored_enchantments")) {
|
||||||
|
rewriteEnchantmentsToServer(data, tag, StructuredDataKey.STORED_ENCHANTMENTS, true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void rewriteEnchantmentsToClient(final StructuredDataContainer data, final StructuredDataKey<Enchantments> key, final boolean storedEnchant) {
|
||||||
|
final StructuredData<Enchantments> enchantmentsData = data.getNonEmpty(key);
|
||||||
|
if (enchantmentsData == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
final CompoundTag tag = data.computeIfAbsent(StructuredDataKey.CUSTOM_DATA, $ -> new CompoundTag()).value();
|
||||||
|
final Enchantments enchantments = enchantmentsData.value();
|
||||||
|
final List<Tag> loreToAdd = new ArrayList<>();
|
||||||
|
boolean changed = false;
|
||||||
|
|
||||||
|
final ObjectIterator<Int2IntMap.Entry> iterator = enchantments.enchantments().int2IntEntrySet().iterator();
|
||||||
|
final List<IntIntPair> updatedIds = new ArrayList<>();
|
||||||
|
while (iterator.hasNext()) {
|
||||||
|
final Int2IntMap.Entry entry = iterator.next();
|
||||||
|
final BackwardsMappings mappingData = itemRewriter.protocol().getMappingData();
|
||||||
|
final Mappings mappings = mappingData.getEnchantmentMappings();
|
||||||
|
final int mappedId = mappings.getNewId(entry.getIntKey());
|
||||||
|
if (mappedId != -1) {
|
||||||
|
if (rewriteIds) {
|
||||||
|
// Update the map after to iteration to preserve the current ids before possibly saving the original, avoid CME
|
||||||
|
updatedIds.add(IntIntPair.of(entry.getIntKey(), mappedId));
|
||||||
|
}
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
final String remappedName = mappingData.mappedEnchantmentName(entry.getIntKey());
|
||||||
|
if (remappedName != null) {
|
||||||
|
if (!changed) {
|
||||||
|
// Backup original before doing modifications
|
||||||
|
itemRewriter.saveListTag(tag, asTag(enchantments), key.identifier());
|
||||||
|
changed = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
final int level = entry.getIntValue();
|
||||||
|
loreToAdd.add(ComponentUtil.jsonStringToTag(ComponentUtil.legacyToJsonString("§7" + remappedName + " " + EnchantmentRewriter.getRomanNumber(level), true)));
|
||||||
|
iterator.remove();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (final IntIntPair pair : updatedIds) {
|
||||||
|
enchantments.add(pair.firstInt(), pair.secondInt());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (loreToAdd.isEmpty()) {
|
||||||
|
// No removed enchantments
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add glint override if there are no enchantments left
|
||||||
|
if (!storedEnchant && enchantments.size() == 0) {
|
||||||
|
final StructuredData<Boolean> glintOverride = data.getNonEmpty(StructuredDataKey.ENCHANTMENT_GLINT_OVERRIDE);
|
||||||
|
if (glintOverride != null) {
|
||||||
|
tag.putBoolean(itemRewriter.getNbtTagName() + "|glint", glintOverride.value());
|
||||||
|
} else {
|
||||||
|
tag.putBoolean(itemRewriter.getNbtTagName() + "|noglint", true);
|
||||||
|
}
|
||||||
|
data.set(StructuredDataKey.ENCHANTMENT_GLINT_OVERRIDE, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Save original lore
|
||||||
|
final StructuredData<Tag[]> loreData = data.getNonEmpty(StructuredDataKey.LORE);
|
||||||
|
if (loreData != null) {
|
||||||
|
final List<Tag> loreList = Arrays.asList(loreData.value());
|
||||||
|
itemRewriter.saveGenericTagList(tag, loreList, "lore");
|
||||||
|
loreToAdd.addAll(loreList);
|
||||||
|
} else {
|
||||||
|
tag.putBoolean(itemRewriter.getNbtTagName() + "|nolore", true);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (enchantments.showInTooltip()) {
|
||||||
|
tag.putBoolean(itemRewriter.getNbtTagName() + "|show_" + key.identifier(), true);
|
||||||
|
}
|
||||||
|
|
||||||
|
data.set(StructuredDataKey.LORE, loreToAdd.toArray(new Tag[0]));
|
||||||
|
}
|
||||||
|
|
||||||
|
private ListTag<CompoundTag> asTag(final Enchantments enchantments) {
|
||||||
|
final ListTag<CompoundTag> listTag = new ListTag<>(CompoundTag.class);
|
||||||
|
for (final Int2IntMap.Entry entry : enchantments.enchantments().int2IntEntrySet()) {
|
||||||
|
final CompoundTag enchantment = new CompoundTag();
|
||||||
|
enchantment.putInt("id", entry.getIntKey());
|
||||||
|
enchantment.putInt("lvl", entry.getIntValue());
|
||||||
|
listTag.add(enchantment);
|
||||||
|
}
|
||||||
|
return listTag;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void rewriteEnchantmentsToServer(final StructuredDataContainer data, final CompoundTag tag, final StructuredDataKey<Enchantments> key, final boolean storedEnchant) {
|
||||||
|
final ListTag<CompoundTag> enchantmentsTag = itemRewriter.removeListTag(tag, key.identifier(), CompoundTag.class);
|
||||||
|
if (enchantmentsTag == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
final Tag glintTag = tag.remove(itemRewriter.getNbtTagName() + "|glint");
|
||||||
|
if (glintTag instanceof ByteTag) {
|
||||||
|
data.set(StructuredDataKey.ENCHANTMENT_GLINT_OVERRIDE, ((NumberTag) glintTag).asBoolean());
|
||||||
|
} else if (tag.remove(itemRewriter.getNbtTagName() + "|noglint") != null) {
|
||||||
|
data.remove(StructuredDataKey.ENCHANTMENT_GLINT_OVERRIDE);
|
||||||
|
}
|
||||||
|
|
||||||
|
final List<Tag> lore = itemRewriter.removeGenericTagList(tag, "lore");
|
||||||
|
if (lore != null) {
|
||||||
|
data.set(StructuredDataKey.LORE, lore.toArray(new Tag[0]));
|
||||||
|
} else if (tag.remove(itemRewriter.getNbtTagName() + "|nolore") != null) {
|
||||||
|
data.remove(StructuredDataKey.LORE);
|
||||||
|
}
|
||||||
|
|
||||||
|
final Enchantments enchantments = new Enchantments(tag.remove(itemRewriter.getNbtTagName() + "|show_" + key.identifier()) != null);
|
||||||
|
for (final CompoundTag enchantment : enchantmentsTag) {
|
||||||
|
enchantments.add(enchantment.getInt("id"), enchantment.getInt("lvl"));
|
||||||
|
}
|
||||||
|
data.set(key, enchantments);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setRewriteIds(final boolean rewriteIds) {
|
||||||
|
this.rewriteIds = rewriteIds;
|
||||||
|
}
|
||||||
|
}
|
@ -18,6 +18,8 @@
|
|||||||
package com.viaversion.viabackwards.protocol.protocol1_20_3to1_20_5.rewriter;
|
package com.viaversion.viabackwards.protocol.protocol1_20_3to1_20_5.rewriter;
|
||||||
|
|
||||||
import com.viaversion.viabackwards.api.rewriters.BackwardsStructuredItemRewriter;
|
import com.viaversion.viabackwards.api.rewriters.BackwardsStructuredItemRewriter;
|
||||||
|
import com.viaversion.viabackwards.api.rewriters.EnchantmentRewriter;
|
||||||
|
import com.viaversion.viabackwards.api.rewriters.StructuredEnchantmentRewriter;
|
||||||
import com.viaversion.viabackwards.protocol.protocol1_20_3to1_20_5.Protocol1_20_3To1_20_5;
|
import com.viaversion.viabackwards.protocol.protocol1_20_3to1_20_5.Protocol1_20_3To1_20_5;
|
||||||
import com.viaversion.viaversion.api.Via;
|
import com.viaversion.viaversion.api.Via;
|
||||||
import com.viaversion.viaversion.api.minecraft.Particle;
|
import com.viaversion.viaversion.api.minecraft.Particle;
|
||||||
@ -42,6 +44,7 @@ public final class BlockItemPacketRewriter1_20_5 extends BackwardsStructuredItem
|
|||||||
|
|
||||||
public BlockItemPacketRewriter1_20_5(final Protocol1_20_3To1_20_5 protocol) {
|
public BlockItemPacketRewriter1_20_5(final Protocol1_20_3To1_20_5 protocol) {
|
||||||
super(protocol, Types1_20_5.ITEM, Types1_20_5.ITEM_ARRAY, Type.ITEM1_20_2, Type.ITEM1_20_2_ARRAY);
|
super(protocol, Types1_20_5.ITEM, Types1_20_5.ITEM_ARRAY, Type.ITEM1_20_2, Type.ITEM1_20_2_ARRAY);
|
||||||
|
enchantmentRewriter.setRewriteIds(false); // Let VV handle it
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
Binäre Datei nicht angezeigt.
@ -1,28 +1,189 @@
|
|||||||
{
|
{
|
||||||
"1.20.5": {
|
"1.20.5": {
|
||||||
|
"advancements.adventure.blowback.description": "Kill a Breeze with a deflected Breeze-shot Wind Charge",
|
||||||
|
"advancements.adventure.blowback.title": "Blowback",
|
||||||
|
"advancements.adventure.crafters_crafting_crafters.description": "Be near a Crafter when it crafts a Crafter",
|
||||||
|
"advancements.adventure.crafters_crafting_crafters.title": "Crafters Crafting Crafters",
|
||||||
|
"advancements.adventure.lighten_up.description": "Scrape a Copper Bulb with an Axe to make it brighter",
|
||||||
|
"advancements.adventure.lighten_up.title": "Lighten Up",
|
||||||
|
"advancements.adventure.minecraft_trials_edition.description": "Step foot in a Trial Chamber",
|
||||||
|
"advancements.adventure.minecraft_trials_edition.title": "Minecraft: Trial(s) Edition",
|
||||||
|
"advancements.adventure.overoverkill.description": "Deal 50 hearts of damage in a single hit using the Mace",
|
||||||
|
"advancements.adventure.overoverkill.title": "Over-Overkill",
|
||||||
|
"advancements.adventure.under_lock_and_key.description": "Unlock a Vault with a Trial Key",
|
||||||
|
"advancements.adventure.under_lock_and_key.title": "Under Lock and Key",
|
||||||
|
"advancements.adventure.who_needs_rockets.description": "Use a Wind Charge to launch yourself upward 8 blocks",
|
||||||
|
"advancements.adventure.who_needs_rockets.title": "Who Needs Rockets?",
|
||||||
|
"argument.resource_or_id.failed_to_parse": "Failed to parse structure: %s",
|
||||||
|
"argument.resource_or_id.invalid": "Invalid id or tag",
|
||||||
|
"arguments.item.component.expected": "Expected item component",
|
||||||
|
"arguments.item.component.malformed": "Malformed '%s' component: '%s'",
|
||||||
|
"arguments.item.component.repeated": "Item component '%s' was repeated, but only one value can be specified",
|
||||||
|
"arguments.item.component.unknown": "Unknown item component '%s'",
|
||||||
|
"arguments.item.predicate.malformed": "Malformed '%s' predicate: '%s'",
|
||||||
|
"arguments.item.predicate.unknown": "Unknown item predicate '%s''",
|
||||||
"attribute.name.generic.block_interaction_range": "Block Interaction Range",
|
"attribute.name.generic.block_interaction_range": "Block Interaction Range",
|
||||||
"attribute.name.generic.entity_interaction_range": "Entity Interaction Range",
|
"attribute.name.generic.entity_interaction_range": "Entity Interaction Range",
|
||||||
|
"attribute.name.generic.fall_damage_multiplier": "Fall Damage Multiplier",
|
||||||
|
"attribute.name.generic.gravity": "Gravity",
|
||||||
|
"attribute.name.generic.jump_strength": "Jump Strength",
|
||||||
|
"attribute.name.generic.safe_fall_distance": "Safe Fall Distance",
|
||||||
"attribute.name.generic.scale": "Scale",
|
"attribute.name.generic.scale": "Scale",
|
||||||
"attribute.name.generic.step_height": "Step Height",
|
"attribute.name.generic.step_height": "Step Height",
|
||||||
|
"attribute.name.player.block_break_speed": "Block Break Speed",
|
||||||
|
"attribute.name.player.block_interaction_range": "Block Interaction Range",
|
||||||
|
"attribute.name.player.entity_interaction_range": "Entity Interaction Range",
|
||||||
|
"block.minecraft.heavy_core": "Heavy Core",
|
||||||
|
"block.minecraft.vault": "Vault",
|
||||||
|
"chat.disabled.invalid_command_signature": "Command had unexpected or missing command argument signatures.",
|
||||||
|
"chat.disabled.invalid_signature": "Chat had an invalid signature. Please try reconnecting.",
|
||||||
|
"chat.disabled.out_of_order_chat": "Chat received out-of-order. Did your system time change?",
|
||||||
|
"chunk.toast.checkLog": "See log for more details",
|
||||||
|
"chunk.toast.loadFailure": "Failed to load chunk at %s",
|
||||||
|
"chunk.toast.lowDiskSpace": "Low disk space!",
|
||||||
|
"chunk.toast.lowDiskSpace.description": "Might not be able to save the world.",
|
||||||
|
"chunk.toast.saveFailure": "Failed to save chunk at %s",
|
||||||
|
"commands.datapack.disable.failed.feature": "Pack '%s' cannot be disabled, since it is part of an enabled flag!",
|
||||||
|
"commands.setworldspawn.failure.not_overworld": "Can only set the world spawn for overworld",
|
||||||
|
"commands.transfer.error.no_players": "Must specify at least one player to transfer",
|
||||||
|
"commands.transfer.success.multiple": "Transferring %s players to %s:%s",
|
||||||
|
"commands.transfer.success.single": "Transferring %s to %s:%s",
|
||||||
|
"connect.failed.transfer": "Connection failed while transferring to the server",
|
||||||
|
"connect.transferring": "Transferring to new server...",
|
||||||
|
"disconnect.transfer": "Transferred to another server",
|
||||||
|
"effect.minecraft.infested": "Infested",
|
||||||
|
"effect.minecraft.oozing": "Oozing",
|
||||||
|
"effect.minecraft.raid_omen": "Raid Omen",
|
||||||
|
"effect.minecraft.trial_omen": "Trial Omen",
|
||||||
|
"effect.minecraft.weaving": "Weaving",
|
||||||
|
"effect.minecraft.wind_charged": "Wind Charged",
|
||||||
|
"enchantment.minecraft.breach": "Breach",
|
||||||
|
"enchantment.minecraft.density": "Density",
|
||||||
|
"enchantment.minecraft.sweeping_edge": "Sweeping Edge",
|
||||||
|
"enchantment.minecraft.wind_burst": "Wind Burst",
|
||||||
"entity.minecraft.armadillo": "Armadillo",
|
"entity.minecraft.armadillo": "Armadillo",
|
||||||
|
"entity.minecraft.bogged": "Bogged",
|
||||||
|
"entity.minecraft.breeze_wind_charge": "Wind Charge",
|
||||||
|
"entity.minecraft.ominous_item_spawner": "Ominous Item Spawner",
|
||||||
|
"filled_map.trial_chambers": "Trial Chambers Map",
|
||||||
|
"gamerule.spawnChunkRadius": "Spawn chunk radius",
|
||||||
|
"gamerule.spawnChunkRadius.description": "Amount of chunks that stay loaded around the overworld spawn position.",
|
||||||
|
"gamerule.spawnRadius.description": "Controls the size of the area around the spawn point that players can spawn in.",
|
||||||
|
"item.canUse.unknown": "Unknown",
|
||||||
|
"item.components": "%s component(s)",
|
||||||
"item.minecraft.armadillo_scute": "Armadillo Scute",
|
"item.minecraft.armadillo_scute": "Armadillo Scute",
|
||||||
"item.minecraft.armadillo_spawn_egg": "Armadillo Spawn Egg",
|
"item.minecraft.armadillo_spawn_egg": "Armadillo Spawn Egg",
|
||||||
|
"item.minecraft.bogged_spawn_egg": "Bogged Spawn Egg",
|
||||||
|
"item.minecraft.bolt_armor_trim_smithing_template": "Smithing Template",
|
||||||
|
"item.minecraft.breeze_rod": "Breeze Rod",
|
||||||
|
"item.minecraft.flow_armor_trim_smithing_template": "Smithing Template",
|
||||||
|
"item.minecraft.flow_banner_pattern": "Banner Pattern",
|
||||||
|
"item.minecraft.flow_banner_pattern.desc": "Flow",
|
||||||
|
"item.minecraft.flow_pottery_sherd": "Flow Pottery Sherd",
|
||||||
|
"item.minecraft.guster_banner_pattern": "Banner Pattern",
|
||||||
|
"item.minecraft.guster_banner_pattern.desc": "Guster",
|
||||||
|
"item.minecraft.guster_pottery_sherd": "Guster Pottery Sherd",
|
||||||
|
"item.minecraft.lingering_potion.effect.infested": "Lingering Potion of Infestation",
|
||||||
|
"item.minecraft.lingering_potion.effect.oozing": "Lingering Potion of Oozing",
|
||||||
|
"item.minecraft.lingering_potion.effect.weaving": "Lingering Potion of Weaving",
|
||||||
|
"item.minecraft.lingering_potion.effect.wind_charged": "Lingering Potion of Wind Charging",
|
||||||
|
"item.minecraft.mace": "Mace",
|
||||||
|
"item.minecraft.ominous_bottle": "Ominous Bottle",
|
||||||
|
"item.minecraft.ominous_trial_key": "Ominous Trial Key",
|
||||||
|
"item.minecraft.potion.effect.infested": "Potion of Infestation",
|
||||||
|
"item.minecraft.potion.effect.oozing": "Potion of Oozing",
|
||||||
|
"item.minecraft.potion.effect.weaving": "Potion of Weaving",
|
||||||
|
"item.minecraft.potion.effect.wind_charged": "Potion of Wind Charging",
|
||||||
|
"item.minecraft.scrape_pottery_sherd": "Scrape Pottery Sherd",
|
||||||
|
"item.minecraft.splash_potion.effect.infested": "Splash Potion of Infestation",
|
||||||
|
"item.minecraft.splash_potion.effect.oozing": "Splash Potion of Oozing",
|
||||||
|
"item.minecraft.splash_potion.effect.weaving": "Splash Potion of Weaving",
|
||||||
|
"item.minecraft.splash_potion.effect.wind_charged": "Splash Potion of Wind Charging",
|
||||||
|
"item.minecraft.tipped_arrow.effect.infested": "Arrow of Infestation",
|
||||||
|
"item.minecraft.tipped_arrow.effect.oozing": "Arrow of Oozing",
|
||||||
|
"item.minecraft.tipped_arrow.effect.weaving": "Arrow of Weaving",
|
||||||
|
"item.minecraft.tipped_arrow.effect.wind_charged": "Arrow of Wind Charging",
|
||||||
"item.minecraft.turtle_scute": "Turtle Scute",
|
"item.minecraft.turtle_scute": "Turtle Scute",
|
||||||
|
"item.minecraft.wind_charge": "Wind Charge",
|
||||||
"item.minecraft.wolf_armor": "Wolf Armor",
|
"item.minecraft.wolf_armor": "Wolf Armor",
|
||||||
|
"item.modifiers.body": "When equipped:",
|
||||||
|
"mco.backup.narration": "Backup from %s",
|
||||||
|
"mco.client.outdated.stable.version": "Your client version (%s) is not compatible with Realms.\n\nPlease use the most recent version of Minecraft.",
|
||||||
|
"mco.client.unsupported.snapshot.version": "Your client version (%s) is not compatible with Realms.\n\nRealms is not available for this snapshot version.",
|
||||||
|
"mco.invited.player.narration": "Invited player %s",
|
||||||
|
"mco.upload.entry.commands": "%1$s, %2$s",
|
||||||
|
"multiplayer.disconnect.transfers_disabled": "Server does not accept transfers",
|
||||||
|
"optimizeWorld.stage.finished.chunks": "Finishing up upgrading chunks...",
|
||||||
|
"optimizeWorld.stage.finished.entities": "Finishing up upgrading entities...",
|
||||||
|
"optimizeWorld.stage.finished.poi": "Finishing up upgrading points of interest...",
|
||||||
|
"optimizeWorld.stage.upgrading.chunks": "Upgrading all chunks...",
|
||||||
|
"optimizeWorld.stage.upgrading.entities": "Upgrading all entities...",
|
||||||
|
"optimizeWorld.stage.upgrading.poi": "Upgrading all points of interest...",
|
||||||
|
"options.accessibility.menu_background_blurriness": "Menu Background Blur",
|
||||||
|
"options.accessibility.menu_background_blurriness.tooltip": "Changes the blurriness of menu backgrounds",
|
||||||
|
"options.font": "Font Settings...",
|
||||||
|
"options.font.title": "Font Settings",
|
||||||
|
"options.japaneseGlyphVariants": "Japanese Glyph Variants",
|
||||||
|
"options.japaneseGlyphVariants.tooltip": "Uses Japanese variants of CJK characters in the default font",
|
||||||
|
"options.telemetry.disabled": "Telemetry is disabled.",
|
||||||
|
"selectWorld.allowCommands.new": "Allow Commands",
|
||||||
|
"selectWorld.commands": "Commands",
|
||||||
|
"selectWorld.warning.lowDiskSpace.description": "There is not much space left on your device.\nRunning out of disk space while in game can lead to your world being damaged.",
|
||||||
|
"selectWorld.warning.lowDiskSpace.title": "Warning! Low disk space!",
|
||||||
|
"slot.only_single_allowed": "Only single slots allowed, got '%s'",
|
||||||
|
"subtitles.block.candle.extinguish": "Candle extinguishes",
|
||||||
|
"subtitles.block.trial_spawner.about_to_spawn_item": "Ominous item prepares",
|
||||||
|
"subtitles.block.trial_spawner.ambient_charged": "Ominous Trial Spawner crackles",
|
||||||
|
"subtitles.block.trial_spawner.charge_activate": "Omen engulfs Trial Spawner",
|
||||||
|
"subtitles.block.trial_spawner.spawn_item": "Ominous item drops",
|
||||||
|
"subtitles.block.trial_spawner.spawn_item_begin": "Ominous item appears",
|
||||||
|
"subtitles.block.vault.activate": "Vault ignites",
|
||||||
|
"subtitles.block.vault.ambient": "Vault crackles",
|
||||||
|
"subtitles.block.vault.close_shutter": "Vault closes",
|
||||||
|
"subtitles.block.vault.deactivate": "Vault extinguishes",
|
||||||
|
"subtitles.block.vault.eject_item": "Vault ejects item",
|
||||||
|
"subtitles.block.vault.insert_item": "Vault unlocks",
|
||||||
|
"subtitles.block.vault.insert_item_fail": "Vault fails unlocking",
|
||||||
|
"subtitles.block.vault.open_shutter": "Vault opens",
|
||||||
|
"subtitles.block.wet_sponge.dries": "Sponge dries",
|
||||||
"subtitles.entity.armadillo.ambient": "Armadillo grunts",
|
"subtitles.entity.armadillo.ambient": "Armadillo grunts",
|
||||||
"subtitles.entity.armadillo.brush": "Armadillo brushes",
|
"subtitles.entity.armadillo.brush": "Scute is brushed off",
|
||||||
"subtitles.entity.armadillo.death": "Armadillo dies",
|
"subtitles.entity.armadillo.death": "Armadillo dies",
|
||||||
"subtitles.entity.armadillo.eat": "Armadillo eats",
|
"subtitles.entity.armadillo.eat": "Armadillo eats",
|
||||||
"subtitles.entity.armadillo.hurt": "Armadillo hurts",
|
"subtitles.entity.armadillo.hurt": "Armadillo hurts",
|
||||||
|
"subtitles.entity.armadillo.hurt_reduced": "Armadillo shields itself",
|
||||||
"subtitles.entity.armadillo.land": "Armadillo lands",
|
"subtitles.entity.armadillo.land": "Armadillo lands",
|
||||||
|
"subtitles.entity.armadillo.peek": "Armadillo peeks",
|
||||||
"subtitles.entity.armadillo.roll": "Armadillo rolls up",
|
"subtitles.entity.armadillo.roll": "Armadillo rolls up",
|
||||||
"subtitles.entity.armadillo.scute_drop": "Scute drops",
|
"subtitles.entity.armadillo.scute_drop": "Armadillo sheds scute",
|
||||||
"subtitles.entity.armadillo.unroll": "Armadillo unrolls",
|
"subtitles.entity.armadillo.unroll_finish": "Armadillo unrolls",
|
||||||
|
"subtitles.entity.armadillo.unroll_start": "Armadillo peeks",
|
||||||
|
"subtitles.entity.bogged.ambient": "Bogged rattles",
|
||||||
|
"subtitles.entity.bogged.death": "Bogged dies",
|
||||||
|
"subtitles.entity.bogged.hurt": "Bogged hurts",
|
||||||
"subtitles.entity.breeze.charge": "Breeze charges",
|
"subtitles.entity.breeze.charge": "Breeze charges",
|
||||||
"subtitles.entity.breeze.deflect": "Breeze deflects",
|
"subtitles.entity.breeze.deflect": "Breeze deflects",
|
||||||
"subtitles.entity.breeze.whirl": "Breeze whirls",
|
"subtitles.entity.breeze.whirl": "Breeze whirls",
|
||||||
"subtitles.item.armor.equip_wolf": "Wolf armor straps",
|
"subtitles.entity.breeze.wind_burst": "Wind Charge bursts",
|
||||||
"subtitles.item.armor.unequip_wolf": "Wolf armor slips off"
|
"subtitles.entity.donkey.jump": "Donkey jumps",
|
||||||
|
"subtitles.entity.mule.jump": "Mule jumps",
|
||||||
|
"subtitles.entity.parrot.imitate.bogged": "Parrot rattles",
|
||||||
|
"subtitles.entity.wind_charge.throw": "Wind Charge flies",
|
||||||
|
"subtitles.entity.wind_charge.wind_burst": "Wind Charge bursts",
|
||||||
|
"subtitles.event.mob_effect.bad_omen": "Omen takes hold",
|
||||||
|
"subtitles.event.mob_effect.raid_omen": "Raid looms nearby",
|
||||||
|
"subtitles.event.mob_effect.trial_omen": "Ominous trial looms nearby",
|
||||||
|
"subtitles.item.armor.equip_wolf": "Wolf Armor is fastened",
|
||||||
|
"subtitles.item.armor.unequip_wolf": "Wolf Armor snips away",
|
||||||
|
"subtitles.item.mace.smash_air": "Mace smashes",
|
||||||
|
"subtitles.item.mace.smash_ground": "Mace smashes",
|
||||||
|
"subtitles.item.ominous_bottle.dispose": "Bottle breaks",
|
||||||
|
"subtitles.item.wolf_armor.break": "Wolf Armor breaks",
|
||||||
|
"subtitles.item.wolf_armor.crack": "Wolf Armor cracks",
|
||||||
|
"subtitles.item.wolf_armor.damage": "Wolf Armor takes damage",
|
||||||
|
"subtitles.item.wolf_armor.repair": "Wolf Armor is repaired",
|
||||||
|
"trim_pattern.minecraft.bolt": "Bolt Armor Trim",
|
||||||
|
"trim_pattern.minecraft.flow": "Flow Armor Trim"
|
||||||
},
|
},
|
||||||
"1.20.3": {
|
"1.20.3": {
|
||||||
"accessibility.onboarding.accessibility.button": "Accessibility Settings...",
|
"accessibility.onboarding.accessibility.button": "Accessibility Settings...",
|
||||||
|
Laden…
In neuem Issue referenzieren
Einen Benutzer sperren