9
0
mirror of https://github.com/Xiao-MoMi/craft-engine.git synced 2025-12-28 19:39:11 +00:00

Merge remote-tracking branch 'origin/dev-momi' into dev

# Conflicts:
#	bukkit/src/main/java/net/momirealms/craftengine/bukkit/util/Reflections.java
This commit is contained in:
jhqwqmc
2025-03-26 22:20:16 +08:00
35 changed files with 522 additions and 45 deletions

View File

@@ -37,6 +37,20 @@ public class CraftEngineFurniture {
return BukkitFurnitureManager.instance().getFurniture(id).orElse(null);
}
/**
* Places furniture at the certain location
*
* @param location location
* @param furnitureId furniture to place
* @return the loaded furniture
*/
@Nullable
public static LoadedFurniture place(Location location, Key furnitureId) {
CustomFurniture furniture = byId(furnitureId);
if (furniture == null) return null;
return place(location, furnitureId, furniture.getAnyPlacement());
}
/**
* Places furniture at the certain location
*

View File

@@ -308,10 +308,10 @@ public class BlockEventListener implements Listener {
@EventHandler(ignoreCancelled = true, priority = EventPriority.MONITOR)
public void onBlockPhysics(BlockPhysicsEvent event) {
if (!this.enableNoteBlockCheck) return;
Block block = event.getBlock();
// for vanilla blocks
if (block.getBlockData() instanceof NoteBlock) {
if (event.getChangedType() == Material.NOTE_BLOCK) {
try {
Block block = event.getBlock();
World world = block.getWorld();
Location location = block.getLocation();
Block sourceBlock = event.getSourceBlock();

View File

@@ -23,5 +23,6 @@ public class BukkitBlockBehaviors extends BlockBehaviors {
register(SAPLING_BLOCK, SaplingBlockBehavior.FACTORY);
register(ON_LIQUID_BLOCK, OnLiquidBlockBehavior.FACTORY);
register(WATERLOGGED_BLOCK, WaterLoggedBlockBehavior.FACTORY);
register(CONCRETE_POWDER_BLOCK, ConcretePowderBlockBehavior.FACTORY);
}
}

View File

@@ -8,6 +8,7 @@ import net.momirealms.craftengine.bukkit.util.Reflections;
import net.momirealms.craftengine.bukkit.world.BukkitWorld;
import net.momirealms.craftengine.core.block.CustomBlock;
import net.momirealms.craftengine.core.block.ImmutableBlockState;
import net.momirealms.craftengine.core.block.behavior.AbstractBlockBehavior;
import net.momirealms.craftengine.core.block.behavior.BlockBehaviorFactory;
import net.momirealms.craftengine.core.item.Item;
import net.momirealms.craftengine.core.loot.parameter.LootParameters;
@@ -24,7 +25,7 @@ import java.util.List;
import java.util.Map;
import java.util.concurrent.Callable;
public class BushBlockBehavior extends BlockBehavior {
public class BushBlockBehavior extends AbstractBlockBehavior {
public static final Factory FACTORY = new Factory();
protected static final Object DIRT_TAG = BlockTags.getOrCreate(Key.of("minecraft", "dirt"));
protected static final Object FARMLAND = BlockTags.getOrCreate(Key.of("minecraft", "farmland"));

View File

@@ -1,13 +1,157 @@
package net.momirealms.craftengine.bukkit.block.behavior;
public class ConcretePowderBlockBehavior extends FallingBlockBehavior {
import net.momirealms.craftengine.bukkit.block.BukkitBlockManager;
import net.momirealms.craftengine.bukkit.util.BlockStateUtils;
import net.momirealms.craftengine.bukkit.util.EventUtils;
import net.momirealms.craftengine.bukkit.util.LocationUtils;
import net.momirealms.craftengine.bukkit.util.Reflections;
import net.momirealms.craftengine.core.block.CustomBlock;
import net.momirealms.craftengine.core.block.EmptyBlock;
import net.momirealms.craftengine.core.block.ImmutableBlockState;
import net.momirealms.craftengine.core.block.UpdateOption;
import net.momirealms.craftengine.core.block.behavior.BlockBehaviorFactory;
import net.momirealms.craftengine.core.item.context.BlockPlaceContext;
import net.momirealms.craftengine.core.plugin.CraftEngine;
import net.momirealms.craftengine.core.util.Direction;
import net.momirealms.craftengine.core.util.Key;
import net.momirealms.craftengine.core.util.MiscUtils;
import net.momirealms.craftengine.shared.block.BlockBehavior;
import org.bukkit.block.BlockState;
import org.bukkit.event.block.BlockFormEvent;
public ConcretePowderBlockBehavior(float hurtAmount, int maxHurt) {
import java.util.Map;
import java.util.Optional;
import java.util.concurrent.Callable;
public class ConcretePowderBlockBehavior extends FallingBlockBehavior {
public static final Factory FACTORY = new Factory();
private final Key targetBlock;
private Object defaultBlockState;
private ImmutableBlockState defaultImmutableBlockState;
public ConcretePowderBlockBehavior(float hurtAmount, int maxHurt, Key block) {
super(hurtAmount, maxHurt);
this.targetBlock = block;
}
public ImmutableBlockState defaultImmutableBlockState() {
if (this.defaultImmutableBlockState == null) {
this.getDefaultBlockState();
}
return this.defaultImmutableBlockState;
}
public Object getDefaultBlockState() {
if (this.defaultBlockState != null) {
return this.defaultBlockState;
}
Optional<CustomBlock> optionalCustomBlock = BukkitBlockManager.instance().getBlock(this.targetBlock);
if (optionalCustomBlock.isPresent()) {
CustomBlock customBlock = optionalCustomBlock.get();
this.defaultBlockState = customBlock.defaultState().customBlockState().handle();
this.defaultImmutableBlockState = customBlock.defaultState();
} else {
CraftEngine.instance().logger().warn("Failed to create solid block " + this.targetBlock + " in ConcretePowderBlockBehavior");
this.defaultBlockState = Reflections.instance$Blocks$STONE$defaultState;
this.defaultImmutableBlockState = EmptyBlock.INSTANCE.defaultState();
}
return this.defaultBlockState;
}
@Override
public ImmutableBlockState updateStateForPlacement(BlockPlaceContext context, ImmutableBlockState state) {
Object level = context.getLevel().serverWorld();
Object blockPos = LocationUtils.toBlockPos(context.getClickedPos());
try {
Object previousState = Reflections.method$BlockGetter$getBlockState.invoke(level, blockPos);
if (!shouldSolidify(level, blockPos, previousState)) {
return super.updateStateForPlacement(context, state);
} else {
BlockState craftBlockState = (BlockState) Reflections.method$CraftBlockStates$getBlockState.invoke(null, level, blockPos);
craftBlockState.setBlockData(BlockStateUtils.fromBlockData(getDefaultBlockState()));
BlockFormEvent event = new BlockFormEvent(craftBlockState.getBlock(), craftBlockState);
if (!EventUtils.fireAndCheckCancel(event)) {
return defaultImmutableBlockState();
} else {
return super.updateStateForPlacement(context, state);
}
}
} catch (ReflectiveOperationException e) {
CraftEngine.instance().logger().warn("Failed to update state for placement " + context.getClickedPos(), e);
}
return super.updateStateForPlacement(context, state);
}
@Override
public void onLand(Object thisBlock, Object[] args) throws Exception {
super.onLand(thisBlock, args);
Object world = args[0];
Object blockPos = args[1];
Object replaceableState = args[3];
if (shouldSolidify(world, blockPos, replaceableState)) {
Reflections.method$CraftEventFactory$handleBlockFormEvent.invoke(null, world, blockPos, getDefaultBlockState(), UpdateOption.UPDATE_ALL.flags());
}
}
@Override
public Object updateShape(Object thisBlock, Object[] args, Callable<Object> superMethod) throws Exception {
Object level = args[1];
Object pos = args[3];
if (touchesLiquid(level, pos)) {
if (!Reflections.clazz$Level.isInstance(level)) {
return getDefaultBlockState();
} else {
BlockState craftBlockState = (BlockState) Reflections.method$CraftBlockStates$getBlockState.invoke(null, level, pos);
craftBlockState.setBlockData(BlockStateUtils.fromBlockData(getDefaultBlockState()));
BlockFormEvent event = new BlockFormEvent(craftBlockState.getBlock(), craftBlockState);
if (!EventUtils.fireAndCheckCancel(event)) {
return Reflections.method$CraftBlockState$getHandle.invoke(craftBlockState);
}
}
}
return super.updateShape(thisBlock, args, superMethod);
}
private static boolean shouldSolidify(Object level, Object blockPos, Object blockState) throws ReflectiveOperationException {
return canSolidify(blockState) || touchesLiquid(level, blockPos);
}
private static boolean canSolidify(Object state) throws ReflectiveOperationException {
Object fluidState = Reflections.field$BlockStateBase$fluidState.get(state);
if (fluidState == null) return false;
Object fluidType = Reflections.method$FluidState$getType.invoke(fluidState);
return fluidType == Reflections.instance$Fluids$WATER || fluidType == Reflections.instance$Fluids$FLOWING_WATER;
}
private static boolean touchesLiquid(Object level, Object pos) throws ReflectiveOperationException {
boolean flag = false;
Object mutablePos = Reflections.method$BlockPos$mutable.invoke(pos);
int j = Direction.values().length;
for (int k = 0; k < j; k++) {
Object direction = Reflections.instance$Directions[k];
Object blockState = Reflections.method$BlockGetter$getBlockState.invoke(level, mutablePos);
if (direction != Reflections.instance$Direction$DOWN || canSolidify(blockState)) {
Reflections.method$MutableBlockPos$setWithOffset.invoke(mutablePos, pos, direction);
blockState = Reflections.method$BlockGetter$getBlockState.invoke(level, mutablePos);
if (canSolidify(blockState) && !(boolean) Reflections.method$BlockStateBase$isFaceSturdy.invoke(blockState, level, pos, Reflections.getOppositeDirection(direction), Reflections.instance$SupportType$FULL)) {
flag = true;
break;
}
}
}
return flag;
}
public static class Factory implements BlockBehaviorFactory {
@Override
public BlockBehavior create(CustomBlock block, Map<String, Object> arguments) {
float hurtAmount = MiscUtils.getAsFloat(arguments.getOrDefault("hurt-amount", -1f));
int hurtMax = MiscUtils.getAsInt(arguments.getOrDefault("max-hurt", -1));
String solidBlock = (String) arguments.get("solid-block");
if (solidBlock == null) {
throw new IllegalArgumentException("No `solid-block` specified for concrete powder block behavior");
}
return new ConcretePowderBlockBehavior(hurtAmount, hurtMax, Key.of(solidBlock));
}
}
}

View File

@@ -7,6 +7,7 @@ import net.momirealms.craftengine.bukkit.util.Reflections;
import net.momirealms.craftengine.bukkit.world.BukkitWorld;
import net.momirealms.craftengine.core.block.CustomBlock;
import net.momirealms.craftengine.core.block.ImmutableBlockState;
import net.momirealms.craftengine.core.block.behavior.AbstractBlockBehavior;
import net.momirealms.craftengine.core.block.behavior.BlockBehaviorFactory;
import net.momirealms.craftengine.core.item.Item;
import net.momirealms.craftengine.core.loot.parameter.LootParameters;
@@ -20,7 +21,7 @@ import org.bukkit.World;
import java.util.Map;
import java.util.concurrent.Callable;
public class FallingBlockBehavior extends BlockBehavior {
public class FallingBlockBehavior extends AbstractBlockBehavior {
public static final Factory FACTORY = new Factory();
private final float hurtAmount;
private final int maxHurt;

View File

@@ -1,13 +1,14 @@
package net.momirealms.craftengine.bukkit.block.behavior;
import net.momirealms.craftengine.core.block.CustomBlock;
import net.momirealms.craftengine.core.block.behavior.AbstractBlockBehavior;
import net.momirealms.craftengine.core.block.behavior.BlockBehaviorFactory;
import net.momirealms.craftengine.core.util.Key;
import net.momirealms.craftengine.shared.block.BlockBehavior;
import java.util.Map;
public class StrippableBlockBehavior extends BlockBehavior {
public class StrippableBlockBehavior extends AbstractBlockBehavior {
public static final Factory FACTORY = new Factory();
private final Key stripped;

View File

@@ -1,6 +1,7 @@
package net.momirealms.craftengine.bukkit.block.behavior;
import net.momirealms.craftengine.core.block.CustomBlock;
import net.momirealms.craftengine.core.block.behavior.AbstractBlockBehavior;
import net.momirealms.craftengine.core.block.behavior.BlockBehaviorFactory;
import net.momirealms.craftengine.core.block.properties.Property;
import net.momirealms.craftengine.shared.block.BlockBehavior;
@@ -8,7 +9,7 @@ import org.jetbrains.annotations.Nullable;
import java.util.Map;
public class WaterLoggedBlockBehavior extends BlockBehavior {
public class WaterLoggedBlockBehavior extends AbstractBlockBehavior {
public static final Factory FACTORY = new Factory();
@Nullable
private final Property<Boolean> waterloggedProperty;

View File

@@ -12,7 +12,9 @@ import org.bukkit.event.HandlerList;
import org.bukkit.event.Listener;
import org.bukkit.event.player.PlayerCommandPreprocessEvent;
import java.util.*;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
// TODO A better command suggestion system
public class WorldEditCommandHelper implements Listener {

View File

@@ -16,6 +16,7 @@ import org.bukkit.entity.*;
import org.bukkit.event.HandlerList;
import org.bukkit.event.Listener;
import org.bukkit.persistence.PersistentDataType;
import org.incendo.cloud.suggestion.Suggestion;
import org.jetbrains.annotations.NotNull;
import org.joml.Vector3f;
@@ -41,6 +42,8 @@ public class BukkitFurnitureManager implements FurnitureManager {
private final FurnitureEventListener furnitureEventListener;
// tick task
private SchedulerTask tickTask;
// Cached command suggestions
private final List<Suggestion> cachedSuggestions = new ArrayList<>();
public static BukkitFurnitureManager instance() {
return instance;
@@ -54,10 +57,14 @@ public class BukkitFurnitureManager implements FurnitureManager {
}
public LoadedFurniture place(CustomFurniture furniture, Location location, AnchorType anchorType, boolean playSound) {
if (furniture.isAllowedPlacement(anchorType)) {
anchorType = furniture.getAnyPlacement();
}
AnchorType finalAnchorType = anchorType;
Entity furnitureEntity = EntityUtils.spawnEntity(location.getWorld(), location, EntityType.ITEM_DISPLAY, entity -> {
ItemDisplay display = (ItemDisplay) entity;
display.getPersistentDataContainer().set(BukkitFurnitureManager.FURNITURE_KEY, PersistentDataType.STRING, furniture.id().toString());
display.getPersistentDataContainer().set(BukkitFurnitureManager.FURNITURE_ANCHOR_KEY, PersistentDataType.STRING, anchorType.name());
display.getPersistentDataContainer().set(BukkitFurnitureManager.FURNITURE_ANCHOR_KEY, PersistentDataType.STRING, finalAnchorType.name());
handleEntityLoadEarly(display);
});
if (playSound) {
@@ -67,6 +74,24 @@ public class BukkitFurnitureManager implements FurnitureManager {
return getLoadedFurnitureByBaseEntityId(furnitureEntity.getEntityId());
}
@Override
public void delayedLoad() {
this.initSuggestions();
}
@Override
public void initSuggestions() {
this.cachedSuggestions.clear();
for (Key key : this.byId.keySet()) {
this.cachedSuggestions.add(Suggestion.suggestion(key.toString()));
}
}
@Override
public Collection<Suggestion> cachedSuggestions() {
return Collections.unmodifiableCollection(this.cachedSuggestions);
}
@SuppressWarnings("unchecked")
@Override
public void parseSection(Pack pack, Path path, Key id, Map<String, Object> section) {

View File

@@ -23,7 +23,6 @@ import net.momirealms.craftengine.core.util.MiscUtils;
import net.momirealms.craftengine.core.util.Pair;
import net.momirealms.craftengine.core.world.Vec3d;
import org.bukkit.Location;
import org.bukkit.SoundCategory;
import org.bukkit.World;
import java.nio.file.Path;

View File

@@ -4,7 +4,6 @@ import net.momirealms.antigrieflib.AntiGriefLib;
import net.momirealms.craftengine.bukkit.api.event.CraftEngineReloadEvent;
import net.momirealms.craftengine.bukkit.block.BukkitBlockManager;
import net.momirealms.craftengine.bukkit.block.behavior.BukkitBlockBehaviors;
import net.momirealms.craftengine.bukkit.block.worldedit.WorldEditCommandHelper;
import net.momirealms.craftengine.bukkit.entity.furniture.BukkitFurnitureManager;
import net.momirealms.craftengine.bukkit.font.BukkitImageManager;
import net.momirealms.craftengine.bukkit.item.BukkitItemManager;

View File

@@ -44,6 +44,7 @@ public class BukkitCommandManager extends AbstractCommandManager<CommandSender>
new DebugRealStateUsageCommand(this, plugin),
new DebugItemDataCommand(this, plugin),
new DebugSetBlockCommand(this, plugin),
new DebugSpawnFurnitureCommand(this, plugin),
new DebugTargetBlockCommand(this, plugin)
));
final LegacyPaperCommandManager<CommandSender> manager = (LegacyPaperCommandManager<CommandSender>) getCommandManager();

View File

@@ -0,0 +1,66 @@
package net.momirealms.craftengine.bukkit.plugin.command.feature;
import net.momirealms.craftengine.bukkit.entity.furniture.BukkitFurnitureManager;
import net.momirealms.craftengine.bukkit.plugin.command.BukkitCommandFeature;
import net.momirealms.craftengine.bukkit.util.KeyUtils;
import net.momirealms.craftengine.core.entity.furniture.AnchorType;
import net.momirealms.craftengine.core.entity.furniture.CustomFurniture;
import net.momirealms.craftengine.core.plugin.CraftEngine;
import net.momirealms.craftengine.core.plugin.command.CraftEngineCommandManager;
import net.momirealms.craftengine.core.plugin.command.FlagKeys;
import net.momirealms.craftengine.core.util.Key;
import org.bukkit.Location;
import org.bukkit.NamespacedKey;
import org.bukkit.command.CommandSender;
import org.checkerframework.checker.nullness.qual.NonNull;
import org.incendo.cloud.Command;
import org.incendo.cloud.bukkit.parser.NamespacedKeyParser;
import org.incendo.cloud.bukkit.parser.location.LocationParser;
import org.incendo.cloud.context.CommandContext;
import org.incendo.cloud.context.CommandInput;
import org.incendo.cloud.parser.standard.EnumParser;
import org.incendo.cloud.suggestion.Suggestion;
import org.incendo.cloud.suggestion.SuggestionProvider;
import java.util.Optional;
import java.util.concurrent.CompletableFuture;
public class DebugSpawnFurnitureCommand extends BukkitCommandFeature<CommandSender> {
public DebugSpawnFurnitureCommand(CraftEngineCommandManager<CommandSender> commandManager, CraftEngine plugin) {
super(commandManager, plugin);
}
@Override
public Command.Builder<? extends CommandSender> assembleCommand(org.incendo.cloud.CommandManager<CommandSender> manager, Command.Builder<CommandSender> builder) {
return builder
.required("location", LocationParser.locationParser())
.required("id", NamespacedKeyParser.namespacedKeyComponent().suggestionProvider(new SuggestionProvider<>() {
@Override
public @NonNull CompletableFuture<? extends @NonNull Iterable<? extends @NonNull Suggestion>> suggestionsFuture(@NonNull CommandContext<Object> context, @NonNull CommandInput input) {
return CompletableFuture.completedFuture(plugin().furnitureManager().cachedSuggestions());
}
}))
.optional("anchor-type", EnumParser.enumParser(AnchorType.class))
.flag(FlagKeys.SILENT_FLAG)
.handler(context -> {
NamespacedKey namespacedKey = context.get("id");
Key id = KeyUtils.namespacedKey2Key(namespacedKey);
BukkitFurnitureManager furnitureManager = BukkitFurnitureManager.instance();
Optional<CustomFurniture> optionalCustomFurniture = furnitureManager.getFurniture(id);
if (optionalCustomFurniture.isEmpty()) {
return;
}
Location location = context.get("location");
CustomFurniture customFurniture = optionalCustomFurniture.get();
AnchorType anchorType = (AnchorType) context.optional("anchor-type").orElse(customFurniture.getAnyPlacement());
boolean playSound = context.flags().hasFlag("silent");
furnitureManager.place(customFurniture, location, anchorType, !playSound);
});
}
@Override
public String getFeatureID() {
return "debug_spawn_furniture";
}
}

View File

@@ -49,7 +49,6 @@ import java.lang.invoke.MethodHandles;
import java.lang.invoke.MethodType;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.List;
import java.util.Objects;
import java.util.Optional;
@@ -589,16 +588,6 @@ public class BukkitInjector {
}
}
public static class PalettedContainerMethodInterceptor {
public static final PalettedContainerMethodInterceptor INSTANCE = new PalettedContainerMethodInterceptor();
@RuntimeType
public Object intercept(@This Object thisObj, @AllArguments Object[] args, @Origin Method method) throws Throwable {
InjectedPalettedContainerHolder holder = (InjectedPalettedContainerHolder) thisObj;
return method.invoke(holder.target(), args);
}
}
public static class GetAndSetInterceptor {
public static final GetAndSetInterceptor INSTANCE = new GetAndSetInterceptor();

View File

@@ -0,0 +1,6 @@
package net.momirealms.craftengine.bukkit.util;
public class OptimizedReflections {
}

View File

@@ -1488,18 +1488,37 @@ public class Reflections {
public static final Object instance$Direction$DOWN;
public static final Object instance$Direction$UP;
public static final Object instance$Direction$NORTH;
public static final Object instance$Direction$SOUTH;
public static final Object instance$Direction$WEST;
public static final Object instance$Direction$EAST;
public static final Object[] instance$Directions;
private static final Map<Object, Object> oppositeDirections = new HashMap<>();
static {
try {
instance$Directions = (Object[]) method$Direction$values.invoke(null);
instance$Direction$DOWN = instance$Directions[0];
instance$Direction$UP = instance$Directions[1];
instance$Direction$NORTH = instance$Directions[2];
instance$Direction$SOUTH = instance$Directions[3];
instance$Direction$WEST = instance$Directions[4];
instance$Direction$EAST = instance$Directions[5];
oppositeDirections.put(instance$Direction$DOWN, instance$Direction$UP);
oppositeDirections.put(instance$Direction$UP, instance$Direction$DOWN);
oppositeDirections.put(instance$Direction$NORTH, instance$Direction$SOUTH);
oppositeDirections.put(instance$Direction$SOUTH, instance$Direction$NORTH);
oppositeDirections.put(instance$Direction$WEST, instance$Direction$EAST);
oppositeDirections.put(instance$Direction$EAST, instance$Direction$WEST);
} catch (ReflectiveOperationException e) {
throw new RuntimeException(e);
}
}
public static Object getOppositeDirection(Object direction) {
return oppositeDirections.get(direction);
}
public static final Class<?> clazz$CraftBlock = requireNonNull(
ReflectionUtils.getClazz(
BukkitReflectionUtils.assembleCBClass("block.CraftBlock")
@@ -1536,6 +1555,12 @@ public class Reflections {
)
);
public static final Method method$CraftBlockState$getHandle = requireNonNull(
ReflectionUtils.getMethod(
clazz$CraftBlockState, clazz$BlockState
)
);
public static final Class<?> clazz$CraftBlockData = requireNonNull(
ReflectionUtils.getClazz(
BukkitReflectionUtils.assembleCBClass("block.data.CraftBlockData")
@@ -3452,6 +3477,12 @@ public class Reflections {
)
);
public static final Method method$BlockPos$mutable = requireNonNull(
ReflectionUtils.getMethod(
clazz$BlockPos, clazz$MutableBlockPos
)
);
public static final Class<?> clazz$LeavesBlock = requireNonNull(
ReflectionUtils.getClazz(
BukkitReflectionUtils.assembleMCClass("world.level.block.LeavesBlock"),
@@ -3944,15 +3975,21 @@ public class Reflections {
);
public static final Object instance$Fluids$WATER;
public static final Object instance$Fluids$FLOWING_WATER;
public static final Object instance$Fluids$LAVA;
public static final Object instance$Fluids$FLOWING_LAVA;
public static final Object instance$Fluids$EMPTY;
static {
try {
Object waterId = method$ResourceLocation$fromNamespaceAndPath.invoke(null, "minecraft", "water");
instance$Fluids$WATER = method$Registry$get.invoke(instance$BuiltInRegistries$FLUID, waterId);
Object flowingWaterId = method$ResourceLocation$fromNamespaceAndPath.invoke(null, "minecraft", "flowing_water");
instance$Fluids$FLOWING_WATER = method$Registry$get.invoke(instance$BuiltInRegistries$FLUID, flowingWaterId);
Object lavaId = method$ResourceLocation$fromNamespaceAndPath.invoke(null, "minecraft", "lava");
instance$Fluids$LAVA = method$Registry$get.invoke(instance$BuiltInRegistries$FLUID, lavaId);
Object flowingLavaId = method$ResourceLocation$fromNamespaceAndPath.invoke(null, "minecraft", "flowing_lava");
instance$Fluids$FLOWING_LAVA = method$Registry$get.invoke(instance$BuiltInRegistries$FLUID, flowingLavaId);
Object emptyId = method$ResourceLocation$fromNamespaceAndPath.invoke(null, "minecraft", "empty");
instance$Fluids$EMPTY = method$Registry$get.invoke(instance$BuiltInRegistries$FLUID, emptyId);
} catch (ReflectiveOperationException e) {
@@ -5497,6 +5534,45 @@ public class Reflections {
)
);
public static final Class<?> clazz$SupportType = requireNonNull(
ReflectionUtils.getClazz(
BukkitReflectionUtils.assembleMCClass("world.level.block.SupportType")
)
);
public static final Method method$SupportType$values = requireNonNull(
ReflectionUtils.getStaticMethod(
clazz$SupportType, clazz$SupportType.arrayType()
)
);
public static final Object instance$SupportType$FULL;
public static final Object instance$SupportType$CENTER;
public static final Object instance$SupportType$RIGID;
static {
try {
Object[] values = (Object[]) method$SupportType$values.invoke(null);
instance$SupportType$FULL = values[0];
instance$SupportType$CENTER = values[1];
instance$SupportType$RIGID = values[2];
} catch (ReflectiveOperationException e) {
throw new RuntimeException(e);
}
}
public static final Method method$BlockStateBase$isFaceSturdy = requireNonNull(
ReflectionUtils.getMethod(
clazz$BlockStateBase, boolean.class, clazz$BlockGetter, clazz$BlockPos, clazz$Direction, clazz$SupportType
)
);
public static final Method method$CraftEventFactory$handleBlockFormEvent = requireNonNull(
ReflectionUtils.getStaticMethod(
clazz$CraftEventFactory, boolean.class, new String[] { "handleBlockFormEvent" }, clazz$Level, clazz$BlockPos, clazz$BlockState, int.class
)
);
public static final Constructor<?> constructor$ClientboundLevelChunkWithLightPacket = requireNonNull(
ReflectionUtils.getConstructor(
clazz$ClientboundLevelChunkWithLightPacket, clazz$LevelChunk, clazz$LevelLightEngine, BitSet.class, BitSet.class