[NeoForge] 1.21.2

Also some adjustments to align Fabric and NF closer
This commit is contained in:
Octavia Togami 2024-10-22 11:08:46 -07:00
parent cdbcab8ec5
commit 75c87ce540
No known key found for this signature in database
GPG Key ID: CC364524D1983C99
20 changed files with 148 additions and 140 deletions

1
.gitignore vendored
View File

@ -14,6 +14,7 @@ target
forge-download
out
run
runs
.jqwik-database
/dependency-reduced-pom.xml

View File

@ -1,6 +1,6 @@
[plugins]
codecov = "org.enginehub.codecov:0.2.0"
neogradle-userdev = "net.neoforged.gradle.userdev:7.0.142"
neogradle-userdev = { id = "net.neoforged.gradle.userdev", version.ref = "neogradle" }
sponge-spongegradle = "org.spongepowered.gradle.plugin:2.2.0"
sponge-vanillagradle = { id = "org.spongepowered.gradle.vanilla", version.ref = "sponge-vanillagradle" }
@ -12,7 +12,8 @@ antlr = "4.13.1"
fabric-api = "0.106.1+1.21.2"
neoforge-minecraft = "1.21"
neogradle = "7.0.165"
neoforge-minecraft = "1.21.2"
sponge-minecraft = "1.21"
# https://repo.spongepowered.org/service/rest/repository/browse/maven-public/org/spongepowered/spongeapi/
@ -35,7 +36,7 @@ lang-worldeditBase = "7.3.7"
lang-version = "1589"
[libraries]
neogradle-neoform = "net.neoforged.gradle:neoform:7.0.142"
neogradle-neoform = { module = "net.neoforged.gradle:neoform", version.ref = "neogradle" }
sponge-vanillagradle = { module = "org.spongepowered:vanillagradle", version.ref = "sponge-vanillagradle" }
licenser = "gradle.plugin.org.cadixdev.gradle:licenser:0.6.1"
@ -90,7 +91,7 @@ fabric-minecraft = "com.mojang:minecraft:1.21.2"
fabric-loader = "net.fabricmc:fabric-loader:0.16.7"
fabric-permissions-api = "me.lucko:fabric-permissions-api:0.3.1"
neoforge = "net.neoforged:neoforge:21.0.16-beta"
neoforge = "net.neoforged:neoforge:21.2.0-beta"
# Mojang-provided libraries, CHECK AGAINST MINECRAFT for versions
guava = "com.google.guava:guava:32.1.3-jre!!"

View File

@ -31,13 +31,13 @@ import net.minecraft.world.entity.player.ChatVisiblity;
import java.util.UUID;
public class WorldEditFakePlayer extends ServerPlayer {
public class FabricFakePlayer extends ServerPlayer {
private static final GameProfile FAKE_WORLDEDIT_PROFILE = new GameProfile(UUID.nameUUIDFromBytes("worldedit".getBytes()), "[WorldEdit]");
private static final ClientInformation FAKE_CLIENT_INFO = new ClientInformation(
"en_US", 16, ChatVisiblity.FULL, true, 0, HumanoidArm.LEFT, false, false, ParticleStatus.MINIMAL
);
public WorldEditFakePlayer(ServerLevel world) {
public FabricFakePlayer(ServerLevel world) {
super(world.getServer(), world, FAKE_WORLDEDIT_PROFILE, FAKE_CLIENT_INFO);
}

View File

@ -22,6 +22,7 @@ package com.sk89q.worldedit.fabric;
import com.sk89q.worldedit.blocks.BaseItemStack;
import com.sk89q.worldedit.util.formatting.text.Component;
import com.sk89q.worldedit.util.formatting.text.TranslatableComponent;
import com.sk89q.worldedit.util.formatting.text.serializer.gson.GsonComponentSerializer;
import com.sk89q.worldedit.world.item.ItemType;
import com.sk89q.worldedit.world.registry.BundledItemRegistry;
@ -36,8 +37,11 @@ public class FabricItemRegistry extends BundledItemRegistry {
@Override
public Component getRichName(BaseItemStack itemStack) {
return TranslatableComponent.of(
FabricAdapter.adapt(itemStack).getItem().getDescriptionId()
return GsonComponentSerializer.INSTANCE.deserialize(
net.minecraft.network.chat.Component.Serializer.toJson(
FabricAdapter.adapt(itemStack).getItemName(),
FabricWorldEdit.LIFECYCLED_SERVER.valueOrThrow().registryAccess()
)
);
}

View File

@ -256,14 +256,14 @@ public class FabricWorld extends AbstractWorld {
return true;
}
private static final LoadingCache<ServerLevel, WorldEditFakePlayer> fakePlayers
= CacheBuilder.newBuilder().weakKeys().softValues().build(CacheLoader.from(WorldEditFakePlayer::new));
private static final LoadingCache<ServerLevel, FabricFakePlayer> fakePlayers
= CacheBuilder.newBuilder().weakKeys().softValues().build(CacheLoader.from(FabricFakePlayer::new));
@Override
public boolean useItem(BlockVector3 position, BaseItem item, Direction face) {
ItemStack stack = FabricAdapter.adapt(new BaseItemStack(item.getType(), item.getNbtReference(), 1));
ServerLevel world = (ServerLevel) getWorld();
final WorldEditFakePlayer fakePlayer;
final FabricFakePlayer fakePlayer;
try {
fakePlayer = fakePlayers.get(world);
} catch (ExecutionException ignored) {

View File

@ -176,7 +176,7 @@ public class FabricWorldEdit implements ModInitializer {
ServerPlayConnectionEvents.DISCONNECT.register(this::onPlayerDisconnect);
AttackBlockCallback.EVENT.register(this::onLeftClickBlock);
UseBlockCallback.EVENT.register(this::onRightClickBlock);
UseItemCallback.EVENT.register(this::onRightClickAir);
UseItemCallback.EVENT.register(this::onRightClickItem);
LOGGER.info("WorldEdit for Fabric (version " + getInternalVersion() + ") is loaded");
}
@ -373,7 +373,7 @@ public class FabricWorldEdit implements ModInitializer {
debouncer.setLastInteraction(player, result);
}
private InteractionResult onRightClickAir(Player playerEntity, Level world, InteractionHand hand) {
private InteractionResult onRightClickItem(Player playerEntity, Level world, InteractionHand hand) {
if (skipInteractionEvent(playerEntity, hand)) {
return InteractionResult.PASS;
}

View File

@ -27,12 +27,12 @@ import java.util.Optional;
import static com.google.common.base.Preconditions.checkArgument;
class PropertyAdapter<T extends Comparable<T>> implements Property<T> {
class FabricPropertyAdapter<T extends Comparable<T>> implements Property<T> {
private final net.minecraft.world.level.block.state.properties.Property<T> property;
private final List<T> values;
public PropertyAdapter(net.minecraft.world.level.block.state.properties.Property<T> property) {
public FabricPropertyAdapter(net.minecraft.world.level.block.state.properties.Property<T> property) {
this.property = property;
this.values = ImmutableList.copyOf(property.getPossibleValues());
}

View File

@ -30,10 +30,10 @@ import com.sk89q.worldedit.registry.state.EnumProperty;
import com.sk89q.worldedit.registry.state.IntegerProperty;
import com.sk89q.worldedit.registry.state.Property;
import com.sk89q.worldedit.util.Direction;
import com.sk89q.worldedit.world.block.BlockState;
import com.sk89q.worldedit.world.block.BlockType;
import net.minecraft.util.StringRepresentable;
import net.minecraft.world.level.block.Block;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.level.block.state.StateDefinition;
import java.util.Comparator;
@ -66,7 +66,7 @@ public class FabricTransmogrifier {
.map(x -> x.getSerializedName())
.collect(ImmutableList.toImmutableList()));
}
default -> new PropertyAdapter<>(property);
default -> new FabricPropertyAdapter<>(property);
};
}
});
@ -93,7 +93,7 @@ public class FabricTransmogrifier {
@SuppressWarnings({ "unchecked", "rawtypes" })
private static net.minecraft.world.level.block.state.BlockState transmogToMinecraftProperties(
StateDefinition<Block, BlockState> stateContainer,
StateDefinition<Block, net.minecraft.world.level.block.state.BlockState> stateContainer,
net.minecraft.world.level.block.state.BlockState newState,
Map<Property<?>, Object> states
) {
@ -118,7 +118,7 @@ public class FabricTransmogrifier {
return newState;
}
public static net.minecraft.world.level.block.state.BlockState transmogToMinecraft(com.sk89q.worldedit.world.block.BlockState blockState) {
public static net.minecraft.world.level.block.state.BlockState transmogToMinecraft(BlockState blockState) {
Block mcBlock = FabricAdapter.adapt(blockState.getBlockType());
net.minecraft.world.level.block.state.BlockState newState = mcBlock.defaultBlockState();
Map<Property<?>, Object> states = blockState.getStates();

View File

@ -57,8 +57,8 @@ runs {
runtime(apiClasspath)
}
}
named("client").configure(runConfig)
named("server").configure(runConfig)
register("client").configure(runConfig)
register("server").configure(runConfig)
}
subsystems {

View File

@ -54,7 +54,6 @@ import net.minecraft.world.item.ItemStack;
import net.minecraft.world.level.BaseCommandBlock;
import net.minecraft.world.level.biome.Biome;
import net.minecraft.world.level.block.Block;
import net.minecraft.world.level.block.state.properties.DirectionProperty;
import net.minecraft.world.phys.Vec3;
import net.neoforged.neoforge.server.ServerLifecycleHooks;
import org.enginehub.linbus.tree.LinCompoundTag;
@ -95,7 +94,7 @@ public final class NeoForgeAdapter {
public static Biome adapt(BiomeType biomeType) {
return ServerLifecycleHooks.getCurrentServer()
.registryAccess()
.registryOrThrow(Registries.BIOME)
.lookupOrThrow(Registries.BIOME)
.getOptional(ResourceLocation.parse(biomeType.id()))
.orElseThrow(() -> new IllegalStateException("No biome for " + biomeType.id()));
}
@ -103,7 +102,7 @@ public final class NeoForgeAdapter {
public static BiomeType adapt(Biome biome) {
ResourceLocation id = ServerLifecycleHooks.getCurrentServer()
.registryAccess()
.registryOrThrow(Registries.BIOME)
.lookupOrThrow(Registries.BIOME)
.getKey(biome);
Objects.requireNonNull(id, "biome is not registered");
return BiomeTypes.get(id.toString());
@ -122,32 +121,28 @@ public final class NeoForgeAdapter {
}
public static net.minecraft.core.Direction adapt(Direction face) {
switch (face) {
case NORTH: return net.minecraft.core.Direction.NORTH;
case SOUTH: return net.minecraft.core.Direction.SOUTH;
case WEST: return net.minecraft.core.Direction.WEST;
case EAST: return net.minecraft.core.Direction.EAST;
case DOWN: return net.minecraft.core.Direction.DOWN;
case UP:
default:
return net.minecraft.core.Direction.UP;
}
return switch (face) {
case NORTH -> net.minecraft.core.Direction.NORTH;
case SOUTH -> net.minecraft.core.Direction.SOUTH;
case WEST -> net.minecraft.core.Direction.WEST;
case EAST -> net.minecraft.core.Direction.EAST;
case DOWN -> net.minecraft.core.Direction.DOWN;
default -> net.minecraft.core.Direction.UP;
};
}
public static Direction adaptEnumFacing(@Nullable net.minecraft.core.Direction face) {
if (face == null) {
return null;
}
switch (face) {
case NORTH: return Direction.NORTH;
case SOUTH: return Direction.SOUTH;
case WEST: return Direction.WEST;
case EAST: return Direction.EAST;
case DOWN: return Direction.DOWN;
case UP:
default:
return Direction.UP;
}
return switch (face) {
case NORTH -> Direction.NORTH;
case SOUTH -> Direction.SOUTH;
case WEST -> Direction.WEST;
case EAST -> Direction.EAST;
case DOWN -> Direction.DOWN;
default -> Direction.UP;
};
}
public static BlockPos toBlockPos(BlockVector3 vector) {
@ -174,10 +169,12 @@ public final class NeoForgeAdapter {
Map<Property<?>, Object> props = new TreeMap<>(Comparator.comparing(Property::getName));
for (Map.Entry<net.minecraft.world.level.block.state.properties.Property<?>, Comparable<?>> prop : mcProps.entrySet()) {
Object value = prop.getValue();
if (prop.getKey() instanceof DirectionProperty) {
value = adaptEnumFacing((net.minecraft.core.Direction) value);
} else if (prop.getKey() instanceof net.minecraft.world.level.block.state.properties.EnumProperty) {
value = ((StringRepresentable) value).getSerializedName();
if (prop.getKey() instanceof net.minecraft.world.level.block.state.properties.EnumProperty) {
if (prop.getKey().getValueClass() == net.minecraft.core.Direction.class) {
value = adaptEnumFacing((net.minecraft.core.Direction) value);
} else {
value = ((StringRepresentable) value).getSerializedName();
}
}
props.put(block.getProperty(prop.getKey().getName()), value);
}
@ -202,7 +199,7 @@ public final class NeoForgeAdapter {
}
public static Block adapt(BlockType blockType) {
return BuiltInRegistries.BLOCK.get(ResourceLocation.parse(blockType.id()));
return BuiltInRegistries.BLOCK.getValue(ResourceLocation.parse(blockType.id()));
}
public static BlockType adapt(Block block) {
@ -210,7 +207,7 @@ public final class NeoForgeAdapter {
}
public static Item adapt(ItemType itemType) {
return BuiltInRegistries.ITEM.get(ResourceLocation.parse(itemType.id()));
return BuiltInRegistries.ITEM.getValue(ResourceLocation.parse(itemType.id()));
}
public static ItemType adapt(Item item) {

View File

@ -34,8 +34,8 @@ import java.util.Set;
public class NeoForgeBlockCategoryRegistry implements BlockCategoryRegistry {
@Override
public Set<BlockType> getCategorisedByName(String category) {
return ServerLifecycleHooks.getCurrentServer().registryAccess().registryOrThrow(Registries.BLOCK)
.getTag(TagKey.create(
return ServerLifecycleHooks.getCurrentServer().registryAccess().lookupOrThrow(Registries.BLOCK)
.get(TagKey.create(
Registries.BLOCK,
ResourceLocation.parse(category)
))

View File

@ -22,22 +22,22 @@ package com.sk89q.worldedit.neoforge;
import com.mojang.authlib.GameProfile;
import net.minecraft.network.chat.Component;
import net.minecraft.server.level.ClientInformation;
import net.minecraft.server.level.ParticleStatus;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.server.level.ServerPlayer;
import net.minecraft.stats.Stat;
import net.minecraft.world.damagesource.DamageSource;
import net.minecraft.world.entity.HumanoidArm;
import net.minecraft.world.entity.player.ChatVisiblity;
import java.util.UUID;
public class WorldEditFakePlayer extends ServerPlayer {
public class NeoForgeFakePlayer extends ServerPlayer {
private static final GameProfile FAKE_WORLDEDIT_PROFILE = new GameProfile(UUID.nameUUIDFromBytes("worldedit".getBytes()), "[WorldEdit]");
private static final ClientInformation FAKE_CLIENT_INFO = new ClientInformation(
"en_US", 16, ChatVisiblity.FULL, true, 0, HumanoidArm.LEFT, false, false
"en_US", 16, ChatVisiblity.FULL, true, 0, HumanoidArm.LEFT, false, false, ParticleStatus.MINIMAL
);
public WorldEditFakePlayer(ServerLevel world) {
public NeoForgeFakePlayer(ServerLevel world) {
super(world.getServer(), world, FAKE_WORLDEDIT_PROFILE, FAKE_CLIENT_INFO);
}
@ -57,9 +57,4 @@ public class WorldEditFakePlayer extends ServerPlayer {
public void displayClientMessage(Component message, boolean actionBar) {
super.displayClientMessage(message, actionBar);
}
@Override
public boolean isInvulnerableTo(DamageSource damageSource) {
return true;
}
}

View File

@ -34,8 +34,8 @@ import java.util.Set;
public class NeoForgeItemCategoryRegistry implements ItemCategoryRegistry {
@Override
public Set<ItemType> getCategorisedByName(String category) {
return ServerLifecycleHooks.getCurrentServer().registryAccess().registryOrThrow(Registries.ITEM)
.getTag(TagKey.create(
return ServerLifecycleHooks.getCurrentServer().registryAccess().lookupOrThrow(Registries.ITEM)
.get(TagKey.create(
Registries.ITEM,
ResourceLocation.parse(category)
))

View File

@ -22,8 +22,10 @@ package com.sk89q.worldedit.neoforge;
import com.sk89q.worldedit.blocks.BaseItemStack;
import com.sk89q.worldedit.util.formatting.text.Component;
import com.sk89q.worldedit.util.formatting.text.TranslatableComponent;
import com.sk89q.worldedit.util.formatting.text.serializer.gson.GsonComponentSerializer;
import com.sk89q.worldedit.world.item.ItemType;
import com.sk89q.worldedit.world.registry.BundledItemRegistry;
import net.neoforged.neoforge.server.ServerLifecycleHooks;
public class NeoForgeItemRegistry extends BundledItemRegistry {
@ -36,8 +38,11 @@ public class NeoForgeItemRegistry extends BundledItemRegistry {
@Override
public Component getRichName(BaseItemStack itemStack) {
return TranslatableComponent.of(
NeoForgeAdapter.adapt(itemStack).getDescriptionId()
return GsonComponentSerializer.INSTANCE.deserialize(
net.minecraft.network.chat.Component.Serializer.toJson(
NeoForgeAdapter.adapt(itemStack).getItemName(),
ServerLifecycleHooks.getCurrentServer().registryAccess()
)
);
}

View File

@ -53,6 +53,7 @@ import net.neoforged.neoforge.network.PacketDistributor;
import org.enginehub.linbus.tree.LinCompoundTag;
import java.util.Locale;
import java.util.Set;
import java.util.UUID;
import javax.annotation.Nullable;
@ -106,7 +107,9 @@ public class NeoForgePlayer extends AbstractPlayerActor {
this.player.teleportTo(
level,
location.getX(), location.getY(), location.getZ(),
location.getYaw(), location.getPitch()
Set.of(),
location.getYaw(), location.getPitch(),
true
);
// This may be false if the teleport was cancelled by a mod
return this.player.serverLevel() == level;

View File

@ -79,6 +79,7 @@ import net.minecraft.util.thread.BlockableEventLoop;
import net.minecraft.world.Clearable;
import net.minecraft.world.InteractionHand;
import net.minecraft.world.InteractionResult;
import net.minecraft.world.entity.EntitySpawnReason;
import net.minecraft.world.entity.EntityType;
import net.minecraft.world.entity.item.ItemEntity;
import net.minecraft.world.item.ItemStack;
@ -138,7 +139,7 @@ public class NeoForgeWorld extends AbstractWorld {
private static ResourceLocation getDimensionRegistryKey(ServerLevel world) {
return Objects.requireNonNull(world.getServer(), "server cannot be null")
.registryAccess()
.registryOrThrow(Registries.DIMENSION_TYPE)
.lookupOrThrow(Registries.DIMENSION_TYPE)
.getKey(world.dimensionType());
}
@ -240,22 +241,21 @@ public class NeoForgeWorld extends AbstractWorld {
var biomes = (PalettedContainer<Holder<Biome>>) chunk.getSection(chunk.getSectionIndex(position.y())).getBiomes();
biomes.getAndSetUnchecked(
position.x() & 3, position.y() & 3, position.z() & 3,
getWorld().registryAccess().registry(Registries.BIOME)
.orElseThrow()
.getHolderOrThrow(ResourceKey.create(Registries.BIOME, ResourceLocation.parse(biome.id())))
getWorld().registryAccess().lookupOrThrow(Registries.BIOME)
.getOrThrow(ResourceKey.create(Registries.BIOME, ResourceLocation.parse(biome.id())))
);
chunk.setUnsaved(true);
chunk.markUnsaved();
return true;
}
private static final LoadingCache<ServerLevel, WorldEditFakePlayer> fakePlayers
= CacheBuilder.newBuilder().weakKeys().softValues().build(CacheLoader.from(WorldEditFakePlayer::new));
private static final LoadingCache<ServerLevel, NeoForgeFakePlayer> fakePlayers
= CacheBuilder.newBuilder().weakKeys().softValues().build(CacheLoader.from(NeoForgeFakePlayer::new));
@Override
public boolean useItem(BlockVector3 position, BaseItem item, Direction face) {
ItemStack stack = NeoForgeAdapter.adapt(new BaseItemStack(item.getType(), item.getNbtReference(), 1));
ServerLevel world = getWorld();
final WorldEditFakePlayer fakePlayer;
final NeoForgeFakePlayer fakePlayer;
try {
fakePlayer = fakePlayers.get(world);
} catch (ExecutionException ignored) {
@ -271,12 +271,11 @@ public class NeoForgeWorld extends AbstractWorld {
InteractionResult used = stack.onItemUseFirst(itemUseContext);
if (used != InteractionResult.SUCCESS) {
// try activating the block
InteractionResult resultType = getWorld().getBlockState(blockPos).useItemOn(stack, world, fakePlayer, InteractionHand.MAIN_HAND, rayTraceResult)
.result();
InteractionResult resultType = getWorld().getBlockState(blockPos).useItemOn(stack, world, fakePlayer, InteractionHand.MAIN_HAND, rayTraceResult);
if (resultType.consumesAction()) {
used = resultType;
} else {
used = stack.getItem().use(world, fakePlayer, InteractionHand.MAIN_HAND).getResult();
used = stack.getItem().use(world, fakePlayer, InteractionHand.MAIN_HAND);
}
}
return used == InteractionResult.SUCCESS;
@ -455,7 +454,7 @@ public class NeoForgeWorld extends AbstractWorld {
public boolean generateTree(TreeType type, EditSession editSession, BlockVector3 position) {
ServerLevel world = getWorld();
ConfiguredFeature<?, ?> generator = Optional.ofNullable(createTreeFeatureGenerator(type))
.map(k -> world.registryAccess().registryOrThrow(Registries.CONFIGURED_FEATURE).get(k))
.flatMap(k -> world.registryAccess().lookupOrThrow(Registries.CONFIGURED_FEATURE).getOptional(k))
.orElse(null);
ServerChunkCache chunkManager = world.getChunkSource();
if (type == TreeType.CHORUS_PLANT) {
@ -469,7 +468,7 @@ public class NeoForgeWorld extends AbstractWorld {
public boolean generateFeature(ConfiguredFeatureType type, EditSession editSession, BlockVector3 position) {
ServerLevel world = getWorld();
ConfiguredFeature<?, ?> k = world.registryAccess().registryOrThrow(Registries.CONFIGURED_FEATURE).get(ResourceLocation.tryParse(type.id()));
ConfiguredFeature<?, ?> k = world.registryAccess().lookupOrThrow(Registries.CONFIGURED_FEATURE).getValue(ResourceLocation.tryParse(type.id()));
ServerChunkCache chunkManager = world.getChunkSource();
WorldGenLevel levelProxy = NeoForgeServerLevelDelegateProxy.newInstance(editSession, world);
return k != null && k.place(levelProxy, chunkManager.getGenerator(), random, NeoForgeAdapter.toBlockPos(position));
@ -478,7 +477,7 @@ public class NeoForgeWorld extends AbstractWorld {
@Override
public boolean generateStructure(StructureType type, EditSession editSession, BlockVector3 position) {
ServerLevel world = getWorld();
Structure k = world.registryAccess().registryOrThrow(Registries.STRUCTURE).get(ResourceLocation.tryParse(type.id()));
Structure k = world.registryAccess().lookupOrThrow(Registries.STRUCTURE).getValue(ResourceLocation.tryParse(type.id()));
if (k == null) {
return false;
}
@ -494,7 +493,7 @@ public class NeoForgeWorld extends AbstractWorld {
BoundingBox boundingBox = structureStart.getBoundingBox();
ChunkPos min = new ChunkPos(SectionPos.blockToSectionCoord(boundingBox.minX()), SectionPos.blockToSectionCoord(boundingBox.minZ()));
ChunkPos max = new ChunkPos(SectionPos.blockToSectionCoord(boundingBox.maxX()), SectionPos.blockToSectionCoord(boundingBox.maxZ()));
ChunkPos.rangeClosed(min, max).forEach((chunkPosx) -> structureStart.placeInChunk(proxyLevel, world.structureManager(), chunkManager.getGenerator(), world.getRandom(), new BoundingBox(chunkPosx.getMinBlockX(), world.getMinBuildHeight(), chunkPosx.getMinBlockZ(), chunkPosx.getMaxBlockX(), world.getMaxBuildHeight(), chunkPosx.getMaxBlockZ()), chunkPosx));
ChunkPos.rangeClosed(min, max).forEach((chunkPosx) -> structureStart.placeInChunk(proxyLevel, world.structureManager(), chunkManager.getGenerator(), world.getRandom(), new BoundingBox(chunkPosx.getMinBlockX(), world.getMinY(), chunkPosx.getMinBlockZ(), chunkPosx.getMaxBlockX(), world.getMaxY(), chunkPosx.getMaxBlockZ()), chunkPosx));
return true;
}
}
@ -586,12 +585,12 @@ public class NeoForgeWorld extends AbstractWorld {
@Override
public int getMinY() {
return getWorld().getMinBuildHeight();
return getWorld().getMinY();
}
@Override
public int getMaxY() {
return getWorld().getMaxBuildHeight() - 1;
return getWorld().getMaxY() - 1;
}
@Override
@ -685,7 +684,7 @@ public class NeoForgeWorld extends AbstractWorld {
}
tag.putString("id", entityId);
net.minecraft.world.entity.Entity createdEntity = EntityType.loadEntityRecursive(tag, world, (loadedEntity) -> {
net.minecraft.world.entity.Entity createdEntity = EntityType.loadEntityRecursive(tag, world, EntitySpawnReason.COMMAND, (loadedEntity) -> {
loadedEntity.absMoveTo(location.getX(), location.getY(), location.getZ(), location.getYaw(), location.getPitch());
return loadedEntity;
});

View File

@ -57,7 +57,6 @@ import net.minecraft.resources.ResourceLocation;
import net.minecraft.server.MinecraftServer;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.server.level.ServerPlayer;
import net.minecraft.tags.TagKey;
import net.minecraft.world.InteractionHand;
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.level.biome.Biome;
@ -178,32 +177,32 @@ public class NeoForgeWorldEdit {
}
}
// Biomes
for (ResourceLocation name : server.registryAccess().registryOrThrow(Registries.BIOME).keySet()) {
for (ResourceLocation name : server.registryAccess().lookupOrThrow(Registries.BIOME).keySet()) {
String key = name.toString();
if (BiomeType.REGISTRY.get(key) == null) {
BiomeType.REGISTRY.register(key, new BiomeType(key));
}
}
// Tags
server.registryAccess().registryOrThrow(Registries.BLOCK).getTagNames().map(TagKey::location).forEach(name -> {
server.registryAccess().lookupOrThrow(Registries.BLOCK).getTags().map(t -> t.key().location()).forEach(name -> {
String key = name.toString();
if (BlockCategory.REGISTRY.get(key) == null) {
BlockCategory.REGISTRY.register(key, new BlockCategory(key));
}
});
server.registryAccess().registryOrThrow(Registries.ITEM).getTagNames().map(TagKey::location).forEach(name -> {
server.registryAccess().lookupOrThrow(Registries.ITEM).getTags().map(t -> t.key().location()).forEach(name -> {
String key = name.toString();
if (ItemCategory.REGISTRY.get(key) == null) {
ItemCategory.REGISTRY.register(key, new ItemCategory(key));
}
});
Registry<Biome> biomeRegistry = server.registryAccess().registryOrThrow(Registries.BIOME);
biomeRegistry.getTagNames().forEach(tagKey -> {
String key = tagKey.location().toString();
Registry<Biome> biomeRegistry = server.registryAccess().lookupOrThrow(Registries.BIOME);
biomeRegistry.getTags().forEach(tag -> {
String key = tag.key().location().toString();
if (BiomeCategory.REGISTRY.get(key) == null) {
BiomeCategory.REGISTRY.register(key, new BiomeCategory(
key,
() -> biomeRegistry.getTag(tagKey)
() -> biomeRegistry.get(tag.key())
.stream()
.flatMap(HolderSet.Named::stream)
.map(Holder::value)
@ -213,14 +212,14 @@ public class NeoForgeWorldEdit {
}
});
// Features
for (ResourceLocation name : server.registryAccess().registryOrThrow(Registries.CONFIGURED_FEATURE).keySet()) {
for (ResourceLocation name : server.registryAccess().lookupOrThrow(Registries.CONFIGURED_FEATURE).keySet()) {
String key = name.toString();
if (ConfiguredFeatureType.REGISTRY.get(key) == null) {
ConfiguredFeatureType.REGISTRY.register(key, new ConfiguredFeatureType(key));
}
}
// Structures
for (ResourceLocation name : server.registryAccess().registryOrThrow(Registries.STRUCTURE).keySet()) {
for (ResourceLocation name : server.registryAccess().lookupOrThrow(Registries.STRUCTURE).keySet()) {
String key = name.toString();
if (StructureType.REGISTRY.get(key) == null) {
StructureType.REGISTRY.register(key, new StructureType(key));

View File

@ -27,12 +27,12 @@ import java.util.Optional;
import static com.google.common.base.Preconditions.checkArgument;
class IPropertyAdapter<T extends Comparable<T>> implements Property<T> {
class NeoForgePropertyAdapter<T extends Comparable<T>> implements Property<T> {
private final net.minecraft.world.level.block.state.properties.Property<T> property;
private final List<T> values;
public IPropertyAdapter(net.minecraft.world.level.block.state.properties.Property<T> property) {
public NeoForgePropertyAdapter(net.minecraft.world.level.block.state.properties.Property<T> property) {
this.property = property;
this.values = ImmutableList.copyOf(property.getPossibleValues());
}

View File

@ -35,12 +35,10 @@ import com.sk89q.worldedit.world.block.BlockType;
import net.minecraft.util.StringRepresentable;
import net.minecraft.world.level.block.Block;
import net.minecraft.world.level.block.state.StateDefinition;
import net.minecraft.world.level.block.state.properties.DirectionProperty;
import java.util.Comparator;
import java.util.Map;
import java.util.TreeMap;
import java.util.stream.Collectors;
/**
* Raw, un-cached transformations.
@ -50,26 +48,26 @@ public class NeoForgeTransmogrifier {
private static final LoadingCache<net.minecraft.world.level.block.state.properties.Property<?>, Property<?>> PROPERTY_CACHE = CacheBuilder.newBuilder().build(new CacheLoader<>() {
@Override
public Property<?> load(net.minecraft.world.level.block.state.properties.Property<?> property) throws Exception {
if (property instanceof net.minecraft.world.level.block.state.properties.BooleanProperty) {
return new BooleanProperty(property.getName(), ImmutableList.copyOf(((net.minecraft.world.level.block.state.properties.BooleanProperty) property).getPossibleValues()));
}
if (property instanceof net.minecraft.world.level.block.state.properties.IntegerProperty) {
return new IntegerProperty(property.getName(), ImmutableList.copyOf(((net.minecraft.world.level.block.state.properties.IntegerProperty) property).getPossibleValues()));
}
if (property instanceof DirectionProperty) {
return new DirectionalProperty(property.getName(), ((DirectionProperty) property).getPossibleValues().stream()
.map(NeoForgeAdapter::adaptEnumFacing)
.collect(Collectors.toList()));
}
if (property instanceof net.minecraft.world.level.block.state.properties.EnumProperty) {
// Note: do not make x.getSerializedName a method reference.
// It will cause runtime bootstrap exceptions.
//noinspection Convert2MethodRef
return new EnumProperty(property.getName(), ((net.minecraft.world.level.block.state.properties.EnumProperty<?>) property).getPossibleValues().stream()
.map(x -> x.getSerializedName())
.collect(Collectors.toList()));
}
return new IPropertyAdapter<>(property);
return switch (property) {
case net.minecraft.world.level.block.state.properties.BooleanProperty booleanProperty ->
new BooleanProperty(property.getName(), ImmutableList.copyOf(booleanProperty.getPossibleValues()));
case net.minecraft.world.level.block.state.properties.IntegerProperty integerProperty ->
new IntegerProperty(property.getName(), ImmutableList.copyOf(integerProperty.getPossibleValues()));
case net.minecraft.world.level.block.state.properties.EnumProperty<?> enumProperty -> {
if (property.getValueClass() == net.minecraft.core.Direction.class) {
yield new DirectionalProperty(property.getName(), property.getPossibleValues().stream()
.map(v -> NeoForgeAdapter.adaptEnumFacing((net.minecraft.core.Direction) v))
.collect(ImmutableList.toImmutableList()));
}
// Note: do not make x.asString a method reference.
// It will cause runtime bootstrap exceptions.
//noinspection Convert2MethodRef
yield new EnumProperty(property.getName(), enumProperty.getPossibleValues().stream()
.map(x -> x.getSerializedName())
.collect(ImmutableList.toImmutableList()));
}
default -> new NeoForgePropertyAdapter<>(property);
};
}
});
@ -81,29 +79,38 @@ public class NeoForgeTransmogrifier {
Map<Property<?>, Object> props = new TreeMap<>(Comparator.comparing(Property::getName));
for (Map.Entry<net.minecraft.world.level.block.state.properties.Property<?>, Comparable<?>> prop : mcProps.entrySet()) {
Object value = prop.getValue();
if (prop.getKey() instanceof DirectionProperty) {
value = NeoForgeAdapter.adaptEnumFacing((net.minecraft.core.Direction) value);
} else if (prop.getKey() instanceof net.minecraft.world.level.block.state.properties.EnumProperty) {
value = ((StringRepresentable) value).getSerializedName();
if (prop.getKey() instanceof net.minecraft.world.level.block.state.properties.EnumProperty) {
if (prop.getKey().getValueClass() == net.minecraft.core.Direction.class) {
value = NeoForgeAdapter.adaptEnumFacing((net.minecraft.core.Direction) value);
} else {
value = ((StringRepresentable) value).getSerializedName();
}
props.put(block.getProperty(prop.getKey().getName()), value);
}
props.put(block.getProperty(prop.getKey().getName()), value);
}
return props;
}
@SuppressWarnings({ "rawtypes", "unchecked" })
private static net.minecraft.world.level.block.state.BlockState transmogToMinecraftProperties(StateDefinition<Block, net.minecraft.world.level.block.state.BlockState> stateContainer, net.minecraft.world.level.block.state.BlockState newState, Map<Property<?>, Object> states) {
@SuppressWarnings({"rawtypes", "unchecked"})
private static net.minecraft.world.level.block.state.BlockState transmogToMinecraftProperties(
StateDefinition<Block, net.minecraft.world.level.block.state.BlockState> stateContainer,
net.minecraft.world.level.block.state.BlockState newState,
Map<Property<?>, Object> states
) {
for (Map.Entry<Property<?>, Object> state : states.entrySet()) {
net.minecraft.world.level.block.state.properties.Property property = stateContainer.getProperty(state.getKey().getName());
Comparable value = (Comparable) state.getValue();
// we may need to adapt this value, depending on the source prop
if (property instanceof DirectionProperty) {
Direction dir = (Direction) value;
value = NeoForgeAdapter.adapt(dir);
} else if (property instanceof net.minecraft.world.level.block.state.properties.EnumProperty) {
String enumName = (String) value;
value = ((net.minecraft.world.level.block.state.properties.EnumProperty<?>) property).getValue((String) value)
.orElseThrow(() -> new IllegalStateException("Enum property " + property.getName() + " does not contain " + enumName));
if (property instanceof net.minecraft.world.level.block.state.properties.EnumProperty) {
if (property.getValueClass() == net.minecraft.core.Direction.class) {
Direction dir = (Direction) value;
value = NeoForgeAdapter.adapt(dir);
} else {
String enumName = (String) value;
value = ((net.minecraft.world.level.block.state.properties.EnumProperty<?>) property).getValue((String) value).orElseThrow(() ->
new IllegalStateException("Enum property " + property.getName() + " does not contain " + enumName)
);
}
}
newState = newState.setValue(property, value);

View File

@ -32,6 +32,7 @@ import net.minecraft.world.level.block.Block;
import net.minecraft.world.level.block.entity.BlockEntity;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.level.chunk.LevelChunk;
import net.minecraft.world.level.redstone.ExperimentalRedstoneUtils;
import org.enginehub.linbus.tree.LinCompoundTag;
import java.lang.ref.WeakReference;
@ -140,14 +141,10 @@ public class NeoForgeWorldNativeAccess implements WorldNativeAccess<LevelChunk,
if (sideEffectSet.shouldApply(SideEffect.EVENTS)) {
world.updateNeighborsAt(pos, oldState.getBlock());
} else {
// Manually update each side
Block block = oldState.getBlock();
world.neighborChanged(pos.west(), block, pos);
world.neighborChanged(pos.east(), block, pos);
world.neighborChanged(pos.below(), block, pos);
world.neighborChanged(pos.above(), block, pos);
world.neighborChanged(pos.north(), block, pos);
world.neighborChanged(pos.south(), block, pos);
// Bypasses events currently, watch for changes...
world.updateNeighborsAt(pos, oldState.getBlock(), ExperimentalRedstoneUtils.initialOrientation(
world, null, null
));
}
if (newState.hasAnalogOutputSignal()) {
world.updateNeighbourForOutputSignal(pos, newState.getBlock());