diff --git a/forge/src/main/java/org/spongepowered/forge/SpongeForge.java b/forge/src/main/java/org/spongepowered/forge/SpongeForge.java index 5cc4f6ee25a..32dba8c4e69 100644 --- a/forge/src/main/java/org/spongepowered/forge/SpongeForge.java +++ b/forge/src/main/java/org/spongepowered/forge/SpongeForge.java @@ -49,6 +49,7 @@ import org.spongepowered.forge.data.SpongeLevelDataPersistence; import org.spongepowered.forge.hook.ForgeEntityHooks; import org.spongepowered.forge.hook.ForgeEventHooks; +import org.spongepowered.forge.hook.ForgeWorldHooks; @Mod(Constants.MOD_ID) public final class SpongeForge { @@ -70,6 +71,7 @@ public SpongeForge() { // Set platform hooks as required PlatformHooks.INSTANCE.setEventHooks(new ForgeEventHooks()); PlatformHooks.INSTANCE.setEntityHooks(new ForgeEntityHooks()); + PlatformHooks.INSTANCE.setWorldHooks(new ForgeWorldHooks()); } private void onCommonSetup(final FMLCommonSetupEvent event) { diff --git a/forge/src/main/java/org/spongepowered/forge/hook/ForgeWorldHooks.java b/forge/src/main/java/org/spongepowered/forge/hook/ForgeWorldHooks.java new file mode 100644 index 00000000000..da7d8c9629f --- /dev/null +++ b/forge/src/main/java/org/spongepowered/forge/hook/ForgeWorldHooks.java @@ -0,0 +1,64 @@ +/* + * This file is part of Sponge, licensed under the MIT License (MIT). + * + * Copyright (c) SpongePowered + * Copyright (c) contributors + * + * 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. + */ +package org.spongepowered.forge.hook; + +import net.minecraft.server.level.ServerLevel; +import net.minecraft.world.entity.Entity; +import net.minecraft.world.entity.item.ItemEntity; +import net.minecraft.world.item.Item; +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.level.Level; +import net.minecraftforge.common.MinecraftForge; +import net.minecraftforge.event.world.WorldEvent; +import org.spongepowered.common.hooks.WorldHooks; + +public class ForgeWorldHooks implements WorldHooks { + + @Override + public Entity getCustomEntityIfItem(final Entity entity) { + if (entity.getClass().equals(ItemEntity.class)) { + final ItemStack stack = ((ItemEntity) entity).getItem(); + final Item item = stack.getItem(); + if (item.hasCustomEntity(stack)) { + final Entity newEntity = item.createEntity(entity.level, entity, stack); + if (newEntity != null) { + entity.remove(); + return newEntity; + } + } + } + return null; + } + + @Override + public boolean isRestoringBlocks(final Level world) { + return world.restoringBlockSnapshots; + } + + @Override + public void postLoadWorld(final ServerLevel world) { + MinecraftForge.EVENT_BUS.post(new WorldEvent.Load(world)); + } +} diff --git a/src/main/java/org/spongepowered/common/hooks/WorldHooks.java b/src/main/java/org/spongepowered/common/hooks/WorldHooks.java index bf64b8dc93b..c7d727c795b 100644 --- a/src/main/java/org/spongepowered/common/hooks/WorldHooks.java +++ b/src/main/java/org/spongepowered/common/hooks/WorldHooks.java @@ -24,6 +24,7 @@ */ package org.spongepowered.common.hooks; +import net.minecraft.server.level.ServerLevel; import net.minecraft.world.entity.Entity; import net.minecraft.world.level.Level; import org.spongepowered.common.event.tracking.PhaseTracker; @@ -37,4 +38,6 @@ default Entity getCustomEntityIfItem(final Entity entity) { default boolean isRestoringBlocks(final Level world) { return PhaseTracker.getInstance().getPhaseContext().isRestoring(); } + + default void postLoadWorld(ServerLevel world) { } } diff --git a/src/main/java/org/spongepowered/common/world/server/SpongeWorldManager.java b/src/main/java/org/spongepowered/common/world/server/SpongeWorldManager.java index 57855cdbfcc..0e03e7f588c 100644 --- a/src/main/java/org/spongepowered/common/world/server/SpongeWorldManager.java +++ b/src/main/java/org/spongepowered/common/world/server/SpongeWorldManager.java @@ -103,6 +103,7 @@ import org.spongepowered.common.config.inheritable.WorldConfig; import org.spongepowered.common.datapack.DataPackSerializer; import org.spongepowered.common.event.tracking.PhaseTracker; +import org.spongepowered.common.hooks.PlatformHooks; import org.spongepowered.common.launch.Launch; import org.spongepowered.common.server.BootstrapProperties; import org.spongepowered.common.user.SpongeUserManager; @@ -1037,6 +1038,7 @@ private ServerLevel prepareWorld(final ServerLevel world, final boolean isDebugG SpongeCommon.post(SpongeEventFactory.createLoadWorldEvent(PhaseTracker.getCauseStackManager().currentCause(), (org.spongepowered.api.world.server.ServerWorld) world, isInitialized)); + PlatformHooks.INSTANCE.getWorldHooks().postLoadWorld(world); // Set the view distance back on it's self to trigger the logic ((PrimaryLevelDataBridge) world.getLevelData()).bridge$viewDistance().ifPresent(v -> ((PrimaryLevelDataBridge) world.getLevelData()).bridge$setViewDistance(v));