mirror of
https://github.com/GeyserMC/Geyser.git
synced 2024-08-14 23:57:35 +00:00
Refactor TagCache to be extensible
Previously, for any new tag, we would have to add a field, add the line to load it, add the line to clear it, and make a method for that tag. Now, you just add an enum.
This commit is contained in:
parent
c48428daf0
commit
b81408820b
14 changed files with 177 additions and 161 deletions
|
@ -31,6 +31,7 @@ import org.cloudburstmc.math.vector.Vector3f;
|
|||
import org.geysermc.geyser.entity.EntityDefinition;
|
||||
import org.geysermc.geyser.inventory.GeyserItemStack;
|
||||
import org.geysermc.geyser.session.GeyserSession;
|
||||
import org.geysermc.geyser.session.cache.tags.ItemTag;
|
||||
import org.geysermc.geyser.util.InteractionResult;
|
||||
import org.geysermc.geyser.util.InteractiveTag;
|
||||
|
||||
|
@ -49,7 +50,7 @@ public class DolphinEntity extends WaterEntity {
|
|||
@NonNull
|
||||
@Override
|
||||
protected InteractiveTag testMobInteraction(@NonNull Hand hand, @NonNull GeyserItemStack itemInHand) {
|
||||
if (!itemInHand.isEmpty() && session.getTagCache().isFish(itemInHand)) {
|
||||
if (!itemInHand.isEmpty() && session.getTagCache().is(ItemTag.FISHES, itemInHand)) {
|
||||
return InteractiveTag.FEED;
|
||||
}
|
||||
return super.testMobInteraction(hand, itemInHand);
|
||||
|
@ -58,7 +59,7 @@ public class DolphinEntity extends WaterEntity {
|
|||
@NonNull
|
||||
@Override
|
||||
protected InteractionResult mobInteract(@NonNull Hand hand, @NonNull GeyserItemStack itemInHand) {
|
||||
if (!itemInHand.isEmpty() && session.getTagCache().isFish(itemInHand)) {
|
||||
if (!itemInHand.isEmpty() && session.getTagCache().is(ItemTag.FISHES, itemInHand)) {
|
||||
// Feed
|
||||
return InteractionResult.SUCCESS;
|
||||
}
|
||||
|
|
|
@ -36,6 +36,7 @@ import org.geysermc.geyser.entity.EntityDefinition;
|
|||
import org.geysermc.geyser.inventory.GeyserItemStack;
|
||||
import org.geysermc.geyser.item.type.Item;
|
||||
import org.geysermc.geyser.session.GeyserSession;
|
||||
import org.geysermc.geyser.session.cache.tags.ItemTag;
|
||||
import org.geysermc.geyser.util.EntityUtils;
|
||||
import org.geysermc.geyser.util.InteractionResult;
|
||||
|
||||
|
@ -61,7 +62,7 @@ public class AxolotlEntity extends AnimalEntity {
|
|||
|
||||
@Override
|
||||
public boolean canEat(Item item) {
|
||||
return session.getTagCache().isAxolotlFood(item);
|
||||
return session.getTagCache().is(ItemTag.AXOLOTL_FOOD, item);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -35,6 +35,7 @@ import org.cloudburstmc.protocol.bedrock.packet.EntityEventPacket;
|
|||
import org.geysermc.geyser.entity.EntityDefinition;
|
||||
import org.geysermc.geyser.item.type.Item;
|
||||
import org.geysermc.geyser.session.GeyserSession;
|
||||
import org.geysermc.geyser.session.cache.tags.ItemTag;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
|
@ -67,6 +68,6 @@ public class BeeEntity extends AnimalEntity {
|
|||
|
||||
@Override
|
||||
public boolean canEat(Item item) {
|
||||
return session.getTagCache().isFlower(item);
|
||||
return session.getTagCache().is(ItemTag.FLOWERS, item);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -33,6 +33,7 @@ import org.cloudburstmc.protocol.bedrock.data.entity.EntityFlag;
|
|||
import org.geysermc.geyser.entity.EntityDefinition;
|
||||
import org.geysermc.geyser.item.type.Item;
|
||||
import org.geysermc.geyser.session.GeyserSession;
|
||||
import org.geysermc.geyser.session.cache.tags.ItemTag;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
|
@ -56,6 +57,6 @@ public class FoxEntity extends AnimalEntity {
|
|||
|
||||
@Override
|
||||
public boolean canEat(Item item) {
|
||||
return session.getTagCache().isFoxFood(item);
|
||||
return session.getTagCache().is(ItemTag.FOX_FOOD, item);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -33,8 +33,8 @@ import org.cloudburstmc.protocol.bedrock.data.entity.EntityDataTypes;
|
|||
import org.geysermc.geyser.entity.EntityDefinition;
|
||||
import org.geysermc.geyser.inventory.GeyserItemStack;
|
||||
import org.geysermc.geyser.item.Items;
|
||||
import org.geysermc.geyser.item.type.FlowerItem;
|
||||
import org.geysermc.geyser.session.GeyserSession;
|
||||
import org.geysermc.geyser.session.cache.tags.ItemTag;
|
||||
import org.geysermc.geyser.util.InteractionResult;
|
||||
import org.geysermc.geyser.util.InteractiveTag;
|
||||
|
||||
|
@ -77,7 +77,7 @@ public class MooshroomEntity extends AnimalEntity {
|
|||
} else if (!isBaby && isAlive() && itemInHand.asItem() == Items.SHEARS) {
|
||||
// Shear items
|
||||
return InteractionResult.SUCCESS;
|
||||
} else if (isBrown && session.getTagCache().isSmallFlower(itemInHand) && itemInHand.asItem() instanceof FlowerItem) {
|
||||
} else if (isBrown && session.getTagCache().is(ItemTag.SMALL_FLOWERS, itemInHand)) {
|
||||
// ?
|
||||
return InteractionResult.SUCCESS;
|
||||
}
|
||||
|
|
|
@ -39,6 +39,7 @@ import org.geysermc.geyser.entity.EntityDefinitions;
|
|||
import org.geysermc.geyser.entity.type.Tickable;
|
||||
import org.geysermc.geyser.item.type.Item;
|
||||
import org.geysermc.geyser.session.GeyserSession;
|
||||
import org.geysermc.geyser.session.cache.tags.ItemTag;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
|
@ -72,7 +73,7 @@ public class SnifferEntity extends AnimalEntity implements Tickable {
|
|||
|
||||
@Override
|
||||
public boolean canEat(Item item) {
|
||||
return session.getTagCache().isSnifferFood(item);
|
||||
return session.getTagCache().is(ItemTag.SNIFFER_FOOD, item);
|
||||
}
|
||||
|
||||
public void setSnifferState(ObjectEntityMetadata<SnifferState> entityMetadata) {
|
||||
|
|
|
@ -35,6 +35,7 @@ import org.cloudburstmc.protocol.bedrock.data.entity.EntityFlag;
|
|||
import org.geysermc.geyser.entity.EntityDefinition;
|
||||
import org.geysermc.geyser.inventory.GeyserItemStack;
|
||||
import org.geysermc.geyser.session.GeyserSession;
|
||||
import org.geysermc.geyser.session.cache.tags.ItemTag;
|
||||
import org.geysermc.geyser.util.InteractionResult;
|
||||
import org.geysermc.geyser.util.InteractiveTag;
|
||||
|
||||
|
@ -65,7 +66,7 @@ public class CreeperEntity extends MonsterEntity {
|
|||
@NonNull
|
||||
@Override
|
||||
protected InteractiveTag testMobInteraction(@NonNull Hand hand, @NonNull GeyserItemStack itemInHand) {
|
||||
if (session.getTagCache().isCreeperIgniter(itemInHand.asItem())) {
|
||||
if (session.getTagCache().is(ItemTag.CREEPER_IGNITERS, itemInHand)) {
|
||||
return InteractiveTag.IGNITE_CREEPER;
|
||||
} else {
|
||||
return super.testMobInteraction(hand, itemInHand);
|
||||
|
@ -75,7 +76,7 @@ public class CreeperEntity extends MonsterEntity {
|
|||
@NonNull
|
||||
@Override
|
||||
protected InteractionResult mobInteract(@NonNull Hand hand, @NonNull GeyserItemStack itemInHand) {
|
||||
if (session.getTagCache().isCreeperIgniter(itemInHand.asItem())) {
|
||||
if (session.getTagCache().is(ItemTag.CREEPER_IGNITERS, itemInHand)) {
|
||||
// Ignite creeper - as of 1.19.3
|
||||
session.playSoundEvent(SoundEvent.IGNITE, position);
|
||||
return InteractionResult.SUCCESS;
|
||||
|
|
|
@ -35,6 +35,7 @@ import org.geysermc.geyser.entity.EntityDefinition;
|
|||
import org.geysermc.geyser.inventory.GeyserItemStack;
|
||||
import org.geysermc.geyser.item.Items;
|
||||
import org.geysermc.geyser.session.GeyserSession;
|
||||
import org.geysermc.geyser.session.cache.tags.ItemTag;
|
||||
import org.geysermc.geyser.util.InteractionResult;
|
||||
import org.geysermc.geyser.util.InteractiveTag;
|
||||
|
||||
|
@ -65,7 +66,7 @@ public class PiglinEntity extends BasePiglinEntity {
|
|||
@Override
|
||||
public void updateOffHand(GeyserSession session) {
|
||||
// Check if the Piglin is holding Gold and set the ADMIRING flag accordingly so its pose updates
|
||||
setFlag(EntityFlag.ADMIRING, session.getTagCache().shouldPiglinAdmire(session.getItemMappings().getMapping(this.offHand).getJavaItem()));
|
||||
setFlag(EntityFlag.ADMIRING, session.getTagCache().is(ItemTag.PIGLIN_LOVED, session.getItemMappings().getMapping(this.offHand).getJavaItem()));
|
||||
super.updateBedrockMetadata();
|
||||
|
||||
super.updateOffHand(session);
|
||||
|
|
|
@ -57,7 +57,7 @@ import java.util.function.ToIntFunction;
|
|||
* Stores any information sent via Java registries. May not contain all data in a given registry - we'll strip what's
|
||||
* unneeded.
|
||||
*
|
||||
* Crafted as of 1.20.5 for easy "add new registry" in the future.
|
||||
* Crafted as of 1.20.5 for easy "add new registry" functionality in the future.
|
||||
*/
|
||||
@Accessors(fluent = true)
|
||||
@Getter
|
||||
|
@ -118,6 +118,7 @@ public final class RegistryCache {
|
|||
REGISTRIES.put("minecraft:" + registry, (registryCache, entries) -> {
|
||||
Int2ObjectMap<T> localCache = localCacheFunction.apply(registryCache);
|
||||
// Clear each local cache every time a new registry entry is given to us
|
||||
// (e.g. proxy server switches)
|
||||
localCache.clear();
|
||||
for (int i = 0; i < entries.size(); i++) {
|
||||
RegistryEntry entry = entries.get(i);
|
||||
|
|
|
@ -27,64 +27,45 @@ package org.geysermc.geyser.session.cache;
|
|||
|
||||
import com.github.steveice10.mc.protocol.packet.common.clientbound.ClientboundUpdateTagsPacket;
|
||||
import it.unimi.dsi.fastutil.ints.IntList;
|
||||
import it.unimi.dsi.fastutil.ints.IntLists;
|
||||
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||
import org.geysermc.geyser.GeyserLogger;
|
||||
import org.geysermc.geyser.inventory.GeyserItemStack;
|
||||
import org.geysermc.geyser.item.type.Item;
|
||||
import org.geysermc.geyser.registry.type.BlockMapping;
|
||||
import org.geysermc.geyser.session.GeyserSession;
|
||||
import org.geysermc.geyser.session.cache.tags.BlockTag;
|
||||
import org.geysermc.geyser.session.cache.tags.ItemTag;
|
||||
|
||||
import javax.annotation.ParametersAreNonnullByDefault;
|
||||
import java.util.EnumMap;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Manages information sent from the {@link ClientboundUpdateTagsPacket}. If that packet is not sent, all lists here
|
||||
* will remain empty, matching Java Edition behavior.
|
||||
*
|
||||
* This system is designed for easy extensibility - just add an enum to {@link BlockTag} or {@link ItemTag}.
|
||||
*/
|
||||
@ParametersAreNonnullByDefault
|
||||
public class TagCache {
|
||||
/* Blocks */
|
||||
private IntList leaves;
|
||||
private IntList wool;
|
||||
public final class TagCache {
|
||||
// Put these here so the enums can load without a static map
|
||||
public static final Map<String, BlockTag> ALL_BLOCK_TAGS = new HashMap<>();
|
||||
public static final Map<String, ItemTag> ALL_ITEM_TAGS = new HashMap<>();
|
||||
|
||||
private IntList axeEffective;
|
||||
private IntList hoeEffective;
|
||||
private IntList pickaxeEffective;
|
||||
private IntList shovelEffective;
|
||||
|
||||
private IntList requiresStoneTool;
|
||||
private IntList requiresIronTool;
|
||||
private IntList requiresDiamondTool;
|
||||
|
||||
/* Items */
|
||||
private IntList axolotlFood;
|
||||
private IntList creeperIgniters;
|
||||
private IntList fishes;
|
||||
private IntList flowers;
|
||||
private IntList foxFood;
|
||||
private IntList piglinLoved;
|
||||
private IntList smallFlowers;
|
||||
private IntList snifferFood;
|
||||
|
||||
public TagCache() {
|
||||
// Ensure all lists are non-null
|
||||
clear();
|
||||
}
|
||||
private final Map<BlockTag, IntList> blocks = new EnumMap<>(BlockTag.class);
|
||||
private final Map<ItemTag, IntList> items = new EnumMap<>(ItemTag.class);
|
||||
|
||||
public void loadPacket(GeyserSession session, ClientboundUpdateTagsPacket packet) {
|
||||
Map<String, int[]> blockTags = packet.getTags().get("minecraft:block");
|
||||
this.leaves = IntList.of(blockTags.get("minecraft:leaves"));
|
||||
this.wool = IntList.of(blockTags.get("minecraft:wool"));
|
||||
|
||||
this.axeEffective = IntList.of(blockTags.get("minecraft:mineable/axe"));
|
||||
this.hoeEffective = IntList.of(blockTags.get("minecraft:mineable/hoe"));
|
||||
this.pickaxeEffective = IntList.of(blockTags.get("minecraft:mineable/pickaxe"));
|
||||
this.shovelEffective = IntList.of(blockTags.get("minecraft:mineable/shovel"));
|
||||
|
||||
this.requiresStoneTool = IntList.of(blockTags.get("minecraft:needs_stone_tool"));
|
||||
this.requiresIronTool = IntList.of(blockTags.get("minecraft:needs_iron_tool"));
|
||||
this.requiresDiamondTool = IntList.of(blockTags.get("minecraft:needs_diamond_tool"));
|
||||
this.blocks.clear();
|
||||
ALL_BLOCK_TAGS.forEach((location, tag) -> {
|
||||
int[] values = blockTags.get(location);
|
||||
if (values != null) {
|
||||
this.blocks.put(tag, IntList.of(values));
|
||||
} else {
|
||||
session.getGeyser().getLogger().debug("Block tag not found from server: " + location);
|
||||
}
|
||||
});
|
||||
|
||||
// Hack btw
|
||||
GeyserLogger logger = session.getGeyser().getLogger();
|
||||
|
@ -96,14 +77,15 @@ public class TagCache {
|
|||
}
|
||||
|
||||
Map<String, int[]> itemTags = packet.getTags().get("minecraft:item");
|
||||
this.axolotlFood = IntList.of(itemTags.get("minecraft:axolotl_food"));
|
||||
this.creeperIgniters = load(itemTags.get("minecraft:creeper_igniters"));
|
||||
this.fishes = IntList.of(itemTags.get("minecraft:fishes"));
|
||||
this.flowers = IntList.of(itemTags.get("minecraft:flowers"));
|
||||
this.foxFood = IntList.of(itemTags.get("minecraft:fox_food"));
|
||||
this.piglinLoved = IntList.of(itemTags.get("minecraft:piglin_loved"));
|
||||
this.smallFlowers = IntList.of(itemTags.get("minecraft:small_flowers"));
|
||||
this.snifferFood = load(itemTags.get("minecraft:sniffer_food"));
|
||||
this.items.clear();
|
||||
ALL_ITEM_TAGS.forEach((location, tag) -> {
|
||||
int[] values = itemTags.get(location);
|
||||
if (values != null) {
|
||||
this.items.put(tag, IntList.of(values));
|
||||
} else {
|
||||
session.getGeyser().getLogger().debug("Item tag not found from server: " + location);
|
||||
}
|
||||
});
|
||||
|
||||
// Hack btw
|
||||
boolean emulatePost1_13Logic = itemTags.get("minecraft:signs").length > 1;
|
||||
|
@ -113,98 +95,32 @@ public class TagCache {
|
|||
}
|
||||
}
|
||||
|
||||
private IntList load(int @Nullable[] tags) {
|
||||
if (tags == null) {
|
||||
return IntLists.EMPTY_LIST;
|
||||
/**
|
||||
* @return true if the block tag is present and contains this block mapping's Java ID.
|
||||
*/
|
||||
public boolean is(BlockTag tag, BlockMapping mapping) {
|
||||
IntList values = this.blocks.get(tag);
|
||||
if (values != null) {
|
||||
return values.contains(mapping.getJavaBlockId());
|
||||
}
|
||||
return IntList.of(tags);
|
||||
return false;
|
||||
}
|
||||
|
||||
public void clear() {
|
||||
this.leaves = IntLists.emptyList();
|
||||
this.wool = IntLists.emptyList();
|
||||
|
||||
this.axeEffective = IntLists.emptyList();
|
||||
this.hoeEffective = IntLists.emptyList();
|
||||
this.pickaxeEffective = IntLists.emptyList();
|
||||
this.shovelEffective = IntLists.emptyList();
|
||||
|
||||
this.requiresStoneTool = IntLists.emptyList();
|
||||
this.requiresIronTool = IntLists.emptyList();
|
||||
this.requiresDiamondTool = IntLists.emptyList();
|
||||
|
||||
this.axolotlFood = IntLists.emptyList();
|
||||
this.creeperIgniters = IntLists.emptyList();
|
||||
this.fishes = IntLists.emptyList();
|
||||
this.flowers = IntLists.emptyList();
|
||||
this.foxFood = IntLists.emptyList();
|
||||
this.piglinLoved = IntLists.emptyList();
|
||||
this.smallFlowers = IntLists.emptyList();
|
||||
this.snifferFood = IntLists.emptyList();
|
||||
/**
|
||||
* @return true if the item tag is present and contains this item stack's Java ID.
|
||||
*/
|
||||
public boolean is(ItemTag tag, GeyserItemStack itemStack) {
|
||||
return is(tag, itemStack.asItem());
|
||||
}
|
||||
|
||||
public boolean isAxolotlFood(Item item) {
|
||||
return axolotlFood.contains(item.javaId());
|
||||
}
|
||||
|
||||
public boolean isCreeperIgniter(Item item) {
|
||||
return creeperIgniters.contains(item.javaId());
|
||||
}
|
||||
|
||||
public boolean isFish(GeyserItemStack itemStack) {
|
||||
return fishes.contains(itemStack.getJavaId());
|
||||
}
|
||||
|
||||
public boolean isFlower(Item item) {
|
||||
return flowers.contains(item.javaId());
|
||||
}
|
||||
|
||||
public boolean isFoxFood(Item item) {
|
||||
return foxFood.contains(item.javaId());
|
||||
}
|
||||
|
||||
public boolean shouldPiglinAdmire(Item item) {
|
||||
return piglinLoved.contains(item.javaId());
|
||||
}
|
||||
|
||||
public boolean isSmallFlower(GeyserItemStack itemStack) {
|
||||
return smallFlowers.contains(itemStack.getJavaId());
|
||||
}
|
||||
|
||||
public boolean isSnifferFood(Item item) {
|
||||
return snifferFood.contains(item.javaId());
|
||||
}
|
||||
|
||||
public boolean isAxeEffective(BlockMapping blockMapping) {
|
||||
return axeEffective.contains(blockMapping.getJavaBlockId());
|
||||
}
|
||||
|
||||
public boolean isHoeEffective(BlockMapping blockMapping) {
|
||||
return hoeEffective.contains(blockMapping.getJavaBlockId());
|
||||
}
|
||||
|
||||
public boolean isPickaxeEffective(BlockMapping blockMapping) {
|
||||
return pickaxeEffective.contains(blockMapping.getJavaBlockId());
|
||||
}
|
||||
|
||||
public boolean isShovelEffective(BlockMapping blockMapping) {
|
||||
return shovelEffective.contains(blockMapping.getJavaBlockId());
|
||||
}
|
||||
|
||||
public boolean isShearsEffective(BlockMapping blockMapping) {
|
||||
int javaBlockId = blockMapping.getJavaBlockId();
|
||||
return leaves.contains(javaBlockId) || wool.contains(javaBlockId);
|
||||
}
|
||||
|
||||
public boolean requiresStoneTool(BlockMapping blockMapping) {
|
||||
return requiresStoneTool.contains(blockMapping.getJavaBlockId());
|
||||
}
|
||||
|
||||
public boolean requiresIronTool(BlockMapping blockMapping) {
|
||||
return requiresIronTool.contains(blockMapping.getJavaBlockId());
|
||||
}
|
||||
|
||||
public boolean requiresDiamondTool(BlockMapping blockMapping) {
|
||||
return requiresDiamondTool.contains(blockMapping.getJavaBlockId());
|
||||
/**
|
||||
* @return true if the item tag is present and contains this item's Java ID.
|
||||
*/
|
||||
public boolean is(ItemTag tag, Item item) {
|
||||
IntList values = this.items.get(tag);
|
||||
if (values != null) {
|
||||
return values.contains(item.javaId());
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
|
48
core/src/main/java/org/geysermc/geyser/session/cache/tags/BlockTag.java
vendored
Normal file
48
core/src/main/java/org/geysermc/geyser/session/cache/tags/BlockTag.java
vendored
Normal file
|
@ -0,0 +1,48 @@
|
|||
/*
|
||||
* Copyright (c) 2019-2024 GeyserMC. http://geysermc.org
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*
|
||||
* @author GeyserMC
|
||||
* @link https://github.com/GeyserMC/Geyser
|
||||
*/
|
||||
|
||||
package org.geysermc.geyser.session.cache.tags;
|
||||
|
||||
import org.geysermc.geyser.session.cache.TagCache;
|
||||
|
||||
public enum BlockTag {
|
||||
LEAVES("leaves"),
|
||||
WOOL("wool"),
|
||||
AXE_EFFECTIVE("mineable/axe"),
|
||||
HOE_EFFECTIVE("mineable/hoe"),
|
||||
PICKAXE_EFFECTIVE("mineable/pickaxe"),
|
||||
SHOVEL_EFFECTIVE("mineable/shovel"),
|
||||
NEEDS_STONE_TOOL("needs_stone_tool"),
|
||||
NEEDS_IRON_TOOL("needs_iron_tool"),
|
||||
NEEDS_DIAMOND_TOOL("needs_diamond_tool");
|
||||
|
||||
BlockTag(String identifier) {
|
||||
register(identifier, this);
|
||||
}
|
||||
|
||||
private static void register(String name, BlockTag tag) {
|
||||
TagCache.ALL_BLOCK_TAGS.put("minecraft:" + name, tag);
|
||||
}
|
||||
}
|
47
core/src/main/java/org/geysermc/geyser/session/cache/tags/ItemTag.java
vendored
Normal file
47
core/src/main/java/org/geysermc/geyser/session/cache/tags/ItemTag.java
vendored
Normal file
|
@ -0,0 +1,47 @@
|
|||
/*
|
||||
* Copyright (c) 2019-2024 GeyserMC. http://geysermc.org
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*
|
||||
* @author GeyserMC
|
||||
* @link https://github.com/GeyserMC/Geyser
|
||||
*/
|
||||
|
||||
package org.geysermc.geyser.session.cache.tags;
|
||||
|
||||
import org.geysermc.geyser.session.cache.TagCache;
|
||||
|
||||
public enum ItemTag {
|
||||
AXOLOTL_FOOD("axolotl_food"),
|
||||
CREEPER_IGNITERS("creeper_igniters"),
|
||||
FISHES("fishes"),
|
||||
FLOWERS("flowers"),
|
||||
FOX_FOOD("fox_food"),
|
||||
PIGLIN_LOVED("piglin_loved"),
|
||||
SMALL_FLOWERS("small_flowers"),
|
||||
SNIFFER_FOOD("sniffer_food");
|
||||
|
||||
ItemTag(String identifier) {
|
||||
register(identifier, this);
|
||||
}
|
||||
|
||||
private static void register(String name, ItemTag tag) {
|
||||
TagCache.ALL_ITEM_TAGS.put("minecraft:" + name, tag);
|
||||
}
|
||||
}
|
|
@ -47,10 +47,6 @@ public class BiomeTranslator {
|
|||
public static int loadServerBiome(RegistryEntry entry) {
|
||||
String javaIdentifier = entry.getId();
|
||||
return Registries.BIOME_IDENTIFIERS.get().getOrDefault(javaIdentifier, 0);
|
||||
// if (javaId == 0) {
|
||||
// // Matches Java behavior when it sees an invalid biome - it just replaces it with ID 0
|
||||
// biomeTranslations.defaultReturnValue(bedrockId);
|
||||
// }
|
||||
}
|
||||
|
||||
public static BlockStorage toNewBedrockBiome(GeyserSession session, DataPalette biomeData) {
|
||||
|
|
|
@ -36,17 +36,18 @@ import org.geysermc.geyser.registry.BlockRegistries;
|
|||
import org.geysermc.geyser.registry.type.BlockMapping;
|
||||
import org.geysermc.geyser.registry.type.ItemMapping;
|
||||
import org.geysermc.geyser.session.GeyserSession;
|
||||
import org.geysermc.geyser.session.cache.tags.BlockTag;
|
||||
import org.geysermc.geyser.translator.collision.BlockCollision;
|
||||
|
||||
public final class BlockUtils {
|
||||
|
||||
private static boolean correctTool(GeyserSession session, BlockMapping blockMapping, String itemToolType) {
|
||||
return switch (itemToolType) {
|
||||
case "axe" -> session.getTagCache().isAxeEffective(blockMapping);
|
||||
case "hoe" -> session.getTagCache().isHoeEffective(blockMapping);
|
||||
case "pickaxe" -> session.getTagCache().isPickaxeEffective(blockMapping);
|
||||
case "shears" -> session.getTagCache().isShearsEffective(blockMapping);
|
||||
case "shovel" -> session.getTagCache().isShovelEffective(blockMapping);
|
||||
case "axe" -> session.getTagCache().is(BlockTag.AXE_EFFECTIVE, blockMapping);
|
||||
case "hoe" -> session.getTagCache().is(BlockTag.HOE_EFFECTIVE, blockMapping);
|
||||
case "pickaxe" -> session.getTagCache().is(BlockTag.PICKAXE_EFFECTIVE, blockMapping);
|
||||
case "shears" -> session.getTagCache().is(BlockTag.LEAVES, blockMapping) || session.getTagCache().is(BlockTag.WOOL, blockMapping);
|
||||
case "shovel" -> session.getTagCache().is(BlockTag.SHOVEL_EFFECTIVE, blockMapping);
|
||||
case "sword" -> blockMapping.getJavaBlockId() == BlockStateValues.JAVA_COBWEB_ID;
|
||||
default -> {
|
||||
session.getGeyser().getLogger().warning("Unknown tool type: " + itemToolType);
|
||||
|
@ -79,15 +80,15 @@ public final class BlockUtils {
|
|||
switch (toolTier) {
|
||||
// Use intentional fall-throughs to check each tier with this block
|
||||
default:
|
||||
if (session.getTagCache().requiresStoneTool(blockMapping)) {
|
||||
if (session.getTagCache().is(BlockTag.NEEDS_STONE_TOOL, blockMapping)) {
|
||||
return false;
|
||||
}
|
||||
case "stone":
|
||||
if (session.getTagCache().requiresIronTool(blockMapping)) {
|
||||
if (session.getTagCache().is(BlockTag.NEEDS_IRON_TOOL, blockMapping)) {
|
||||
return false;
|
||||
}
|
||||
case "iron":
|
||||
if (session.getTagCache().requiresDiamondTool(blockMapping)) {
|
||||
if (session.getTagCache().is(BlockTag.NEEDS_DIAMOND_TOOL, blockMapping)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
@ -131,7 +132,7 @@ public final class BlockUtils {
|
|||
}
|
||||
|
||||
public static double getBreakTime(GeyserSession session, BlockMapping blockMapping, ItemMapping item, @Nullable DataComponents components, boolean isSessionPlayer) {
|
||||
boolean isShearsEffective = session.getTagCache().isShearsEffective(blockMapping); //TODO called twice
|
||||
boolean isShearsEffective = session.getTagCache().is(BlockTag.LEAVES, blockMapping) || session.getTagCache().is(BlockTag.WOOL, blockMapping); //TODO called twice
|
||||
boolean canHarvestWithHand = blockMapping.isCanBreakWithHand();
|
||||
String toolType = "";
|
||||
String toolTier = "";
|
||||
|
|
Loading…
Reference in a new issue