diff --git a/arclight-common/src/main/java/io/izzel/arclight/common/bridge/core/world/WorldBridge.java b/arclight-common/src/main/java/io/izzel/arclight/common/bridge/core/world/WorldBridge.java index 415a8069..2b7e3b87 100644 --- a/arclight-common/src/main/java/io/izzel/arclight/common/bridge/core/world/WorldBridge.java +++ b/arclight-common/src/main/java/io/izzel/arclight/common/bridge/core/world/WorldBridge.java @@ -39,5 +39,7 @@ public interface WorldBridge extends IWorldWriterBridge, IWorldBridge { long bridge$ticksPerWaterAmbientSpawns(); + long bridge$ticksPerWaterUndergroundSpawns(); + ResourceKey bridge$getTypeKey(); } diff --git a/arclight-common/src/main/java/io/izzel/arclight/common/mixin/bukkit/MaterialMixin.java b/arclight-common/src/main/java/io/izzel/arclight/common/mixin/bukkit/MaterialMixin.java index f2be5b1d..99c7fcfe 100644 --- a/arclight-common/src/main/java/io/izzel/arclight/common/mixin/bukkit/MaterialMixin.java +++ b/arclight-common/src/main/java/io/izzel/arclight/common/mixin/bukkit/MaterialMixin.java @@ -1,26 +1,23 @@ package io.izzel.arclight.common.mixin.bukkit; import com.google.common.collect.ImmutableMap; -import io.izzel.arclight.common.bridge.core.block.FireBlockBridge; import io.izzel.arclight.common.bridge.bukkit.MaterialBridge; +import io.izzel.arclight.common.bridge.core.block.FireBlockBridge; import io.izzel.arclight.common.mod.ArclightMod; -import io.izzel.arclight.common.mod.server.block.ArclightTileInventory; import io.izzel.arclight.i18n.LocalizedException; import io.izzel.arclight.i18n.conf.MaterialPropertySpec; import net.minecraft.resources.ResourceLocation; -import net.minecraft.world.Container; import net.minecraft.world.item.Item; import net.minecraft.world.item.ItemStack; import net.minecraft.world.level.block.Block; import net.minecraft.world.level.block.Blocks; import net.minecraft.world.level.block.FallingBlock; -import net.minecraft.world.level.block.entity.BlockEntity; import org.bukkit.Material; import org.bukkit.NamespacedKey; import org.bukkit.block.BlockState; import org.bukkit.craftbukkit.v.block.CraftBlock; -import org.bukkit.craftbukkit.v.block.CraftBlockEntityState; import org.bukkit.craftbukkit.v.block.CraftBlockState; +import org.bukkit.craftbukkit.v.block.CraftBlockStates; import org.bukkit.craftbukkit.v.inventory.CraftMetaArmorStand; import org.bukkit.craftbukkit.v.inventory.CraftMetaBanner; import org.bukkit.craftbukkit.v.inventory.CraftMetaBlockState; @@ -357,7 +354,6 @@ public abstract class MaterialMixin implements MaterialBridge { this.setupBlockStateFunc(); } - @SuppressWarnings({"rawtypes", "unchecked"}) private void setupBlockStateFunc() { if (arclight$spec.blockStateClass != null && !arclight$spec.blockStateClass.equalsIgnoreCase("auto")) { try { @@ -390,13 +386,7 @@ public abstract class MaterialMixin implements MaterialBridge { } } if (this.arclight$stateFunc == null) { - this.arclight$stateFunc = b -> { - BlockEntity tileEntity = b.getCraftWorld().getHandle().getBlockEntity(b.getPosition()); - if (tileEntity instanceof Container) { - return new ArclightTileInventory(b, tileEntity.getClass()); - } - return tileEntity == null ? new CraftBlockState(b) : new CraftBlockEntityState<>(b, tileEntity.getClass()); - }; + this.arclight$stateFunc = CraftBlockStates::getBlockState; } } diff --git a/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/server/management/PlayerListMixin.java b/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/server/management/PlayerListMixin.java index 7cc87a87..efb418f9 100644 --- a/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/server/management/PlayerListMixin.java +++ b/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/server/management/PlayerListMixin.java @@ -297,6 +297,7 @@ public abstract class PlayerListMixin implements PlayerListBridge { location = new Location(((WorldBridge) spawnWorld).bridge$getWorld(), vec3d.x, vec3d.y, vec3d.z); } else if (pos != null) { playerIn.connection.send(new ClientboundGameEventPacket(ClientboundGameEventPacket.NO_RESPAWN_BLOCK_AVAILABLE, 0.0f)); + playerIn.setRespawnPosition(Level.OVERWORLD, null, 0f, false, false); // CraftBukkit - SPIGOT-5988: Clear respawn location when obstructed } } if (location == null) { @@ -413,6 +414,7 @@ public abstract class PlayerListMixin implements PlayerListBridge { location = new Location(((WorldBridge) spawnWorld).bridge$getWorld(), vec3d.x, vec3d.y, vec3d.z); } else if (pos != null) { playerIn.connection.send(new ClientboundGameEventPacket(ClientboundGameEventPacket.NO_RESPAWN_BLOCK_AVAILABLE, 0.0f)); + playerIn.setRespawnPosition(Level.OVERWORLD, null, 0f, false, false); } } if (location == null) { diff --git a/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/entity/ExperienceOrbMixin.java b/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/entity/ExperienceOrbMixin.java index e19bf132..3ab9f5b5 100644 --- a/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/entity/ExperienceOrbMixin.java +++ b/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/entity/ExperienceOrbMixin.java @@ -88,6 +88,7 @@ public abstract class ExperienceOrbMixin extends EntityMixin { itemstack.setDamageValue(itemstack.getDamageValue() - j); int k = i - this.durabilityToXp(j); + this.value = k; return k > 0 ? this.repairPlayerItems(player, k) : 0; } else { diff --git a/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/entity/LivingEntityMixin.java b/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/entity/LivingEntityMixin.java index 72b8cf36..0bcb7117 100644 --- a/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/entity/LivingEntityMixin.java +++ b/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/entity/LivingEntityMixin.java @@ -46,6 +46,7 @@ import net.minecraft.world.item.ItemStack; import net.minecraft.world.item.Items; import net.minecraft.world.level.GameRules; import net.minecraft.world.level.Level; +import net.minecraft.world.level.block.state.BlockState; import net.minecraft.world.level.gameevent.GameEvent; import net.minecraftforge.common.ForgeHooks; import net.minecraftforge.common.MinecraftForge; @@ -910,7 +911,8 @@ public abstract class LivingEntityMixin extends EntityMixin implements LivingEnt this.setHealth(1.0F); this.removeAllEffects(EntityPotionEffectEvent.Cause.TOTEM); - this.addEffect(new MobEffectInstance(MobEffects.REGENERATION, 900, 1), EntityPotionEffectEvent.Cause.TOTEM);bridge$pushEffectCause(EntityPotionEffectEvent.Cause.TOTEM); + this.addEffect(new MobEffectInstance(MobEffects.REGENERATION, 900, 1), EntityPotionEffectEvent.Cause.TOTEM); + bridge$pushEffectCause(EntityPotionEffectEvent.Cause.TOTEM); this.addEffect(new MobEffectInstance(MobEffects.ABSORPTION, 100, 1), EntityPotionEffectEvent.Cause.TOTEM); this.addEffect(new MobEffectInstance(MobEffects.FIRE_RESISTANCE, 800, 1), EntityPotionEffectEvent.Cause.TOTEM); this.level.broadcastEntityEvent((Entity) (Object) this, (byte) 35); @@ -928,6 +930,11 @@ public abstract class LivingEntityMixin extends EntityMixin implements LivingEnt } } + @Redirect(method = "createWitherRose", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/level/Level;setBlock(Lnet/minecraft/core/BlockPos;Lnet/minecraft/world/level/block/state/BlockState;I)Z")) + private boolean arclight$fireWitherRoseForm(Level instance, BlockPos pPos, BlockState pNewState, int pFlags) { + return CraftEventFactory.handleBlockFormEvent(instance, pPos, pNewState, 3, (Entity) (Object) this); + } + @Redirect(method = "getDamageAfterArmorAbsorb", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/entity/LivingEntity;hurtArmor(Lnet/minecraft/world/damagesource/DamageSource;F)V")) public void arclight$muteDamageArmor(LivingEntity entity, DamageSource damageSource, float damage) { } diff --git a/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/entity/player/ServerPlayerMixin.java b/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/entity/player/ServerPlayerMixin.java index 855d7e6a..d9d017a4 100644 --- a/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/entity/player/ServerPlayerMixin.java +++ b/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/entity/player/ServerPlayerMixin.java @@ -594,7 +594,7 @@ public abstract class ServerPlayerMixin extends PlayerMixin implements ServerPla private Either getBedResult(BlockPos blockposition, Direction enumdirection) { if (!this.isSleeping() && this.isAlive()) { - if (!this.level.dimensionType().natural()) { + if (!this.level.dimensionType().natural() || !this.level.dimensionType().bedWorks()) { return Either.left(Player.BedSleepingProblem.NOT_POSSIBLE_HERE); } if (!this.bedInRange(blockposition, enumdirection)) { diff --git a/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/gen/feature/structure/StructureManagerMixin.java b/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/gen/feature/structure/StructureFeatureManagerMixin.java similarity index 93% rename from arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/gen/feature/structure/StructureManagerMixin.java rename to arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/gen/feature/structure/StructureFeatureManagerMixin.java index b3803afd..a14422cc 100644 --- a/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/gen/feature/structure/StructureManagerMixin.java +++ b/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/gen/feature/structure/StructureFeatureManagerMixin.java @@ -9,7 +9,7 @@ import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Shadow; @Mixin(StructureFeatureManager.class) -public class StructureManagerMixin { +public class StructureFeatureManagerMixin { @Shadow @Final private LevelAccessor level; diff --git a/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/inventory/RepairContainerMixin.java b/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/inventory/RepairContainerMixin.java index 8888d8e1..95997fc3 100644 --- a/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/inventory/RepairContainerMixin.java +++ b/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/inventory/RepairContainerMixin.java @@ -214,6 +214,7 @@ public abstract class RepairContainerMixin extends ItemCombinerMixin { // this.outputSlot.setInventorySlotContents(0, itemstack1); CraftEventFactory.callPrepareAnvilEvent(getBukkitView(), itemstack1); + this.sendAllDataToRemote(); this.broadcastChanges(); } } diff --git a/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/item/BlockItemMixin.java b/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/item/BlockItemMixin.java index dc221daf..2b864b0d 100644 --- a/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/item/BlockItemMixin.java +++ b/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/item/BlockItemMixin.java @@ -15,7 +15,7 @@ import net.minecraft.world.level.block.state.properties.Property; import net.minecraft.world.phys.shapes.CollisionContext; import org.bukkit.Bukkit; import org.bukkit.craftbukkit.v.block.CraftBlock; -import org.bukkit.craftbukkit.v.block.CraftBlockState; +import org.bukkit.craftbukkit.v.block.CraftBlockStates; import org.bukkit.craftbukkit.v.block.data.CraftBlockData; import org.bukkit.craftbukkit.v.event.CraftEventFactory; import org.bukkit.entity.Player; @@ -42,7 +42,7 @@ public abstract class BlockItemMixin { at = @At(value = "INVOKE", shift = At.Shift.AFTER, target = "Lnet/minecraft/world/item/BlockItem;getPlacementState(Lnet/minecraft/world/item/context/BlockPlaceContext;)Lnet/minecraft/world/level/block/state/BlockState;")) private void arclight$prePlaceLilypad(BlockPlaceContext context, CallbackInfoReturnable cir, BlockPlaceContext context1) { if ((Object) this instanceof WaterLilyBlockItem) { - this.arclight$state = CraftBlockState.getBlockState(context1.getLevel(), context1.getClickedPos()); + this.arclight$state = CraftBlockStates.getBlockState(context1.getLevel(), context1.getClickedPos()); } } diff --git a/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/level/LevelMixin.java b/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/level/LevelMixin.java index 6367f37d..699767da 100644 --- a/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/level/LevelMixin.java +++ b/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/level/LevelMixin.java @@ -86,6 +86,7 @@ public abstract class LevelMixin implements WorldBridge, LevelWriter { public long ticksPerMonsterSpawns; public long ticksPerWaterSpawns; public long ticksPerWaterAmbientSpawns; + public long ticksPerWaterUndergroundCreatureSpawns; public long ticksPerAmbientSpawns; public boolean populating; public org.bukkit.generator.ChunkGenerator generator; @@ -116,6 +117,7 @@ public abstract class LevelMixin implements WorldBridge, LevelWriter { this.ticksPerMonsterSpawns = this.getCraftServer().getTicksPerMonsterSpawns(); this.ticksPerWaterSpawns = this.getCraftServer().getTicksPerWaterSpawns(); this.ticksPerWaterAmbientSpawns = this.getCraftServer().getTicksPerWaterAmbientSpawns(); + this.ticksPerWaterUndergroundCreatureSpawns = this.getCraftServer().getTicksPerWaterUndergroundCreatureSpawns(); this.ticksPerAmbientSpawns = this.getCraftServer().getTicksPerAmbientSpawns(); this.typeKey = this.getCraftServer().getHandle().getServer().registryAccess().registryOrThrow(Registry.DIMENSION_TYPE_REGISTRY) .getResourceKey(dimensionType) @@ -152,6 +154,11 @@ public abstract class LevelMixin implements WorldBridge, LevelWriter { return ticksPerWaterAmbientSpawns; } + @Override + public long bridge$ticksPerWaterUndergroundSpawns() { + return ticksPerWaterUndergroundCreatureSpawns; + } + public ResourceKey getTypeKey() { return this.typeKey; } diff --git a/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/level/block/ChestBlockMixin.java b/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/level/block/ChestBlockMixin.java new file mode 100644 index 00000000..d51a1665 --- /dev/null +++ b/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/level/block/ChestBlockMixin.java @@ -0,0 +1,29 @@ +package io.izzel.arclight.common.mixin.core.world.level.block; + +import net.minecraft.core.BlockPos; +import net.minecraft.world.MenuProvider; +import net.minecraft.world.level.Level; +import net.minecraft.world.level.block.ChestBlock; +import net.minecraft.world.level.block.DoubleBlockCombiner; +import net.minecraft.world.level.block.entity.ChestBlockEntity; +import net.minecraft.world.level.block.state.BlockState; +import org.spongepowered.asm.mixin.Final; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Shadow; + +import javax.annotation.Nullable; +import java.util.Optional; + +@Mixin(ChestBlock.class) +public abstract class ChestBlockMixin { + + // @formatter:off + @Shadow public abstract DoubleBlockCombiner.NeighborCombineResult combine(BlockState pState, Level pLevel, BlockPos pPos, boolean pOverride); + @Shadow @Final private static DoubleBlockCombiner.Combiner> MENU_PROVIDER_COMBINER; + // @formatter:on + + @Nullable + public MenuProvider getInventory(BlockState state, Level level, BlockPos pos, boolean ignoreObstructions) { + return this.combine(state, level, pos, ignoreObstructions).apply(MENU_PROVIDER_COMBINER).orElse(null); + } +} diff --git a/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/level/block/ConcretePowderBlockMixin.java b/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/level/block/ConcretePowderBlockMixin.java index c74a89c1..082a3a8a 100644 --- a/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/level/block/ConcretePowderBlockMixin.java +++ b/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/level/block/ConcretePowderBlockMixin.java @@ -9,6 +9,7 @@ import net.minecraft.world.level.block.ConcretePowderBlock; import net.minecraft.world.level.block.state.BlockState; import org.bukkit.Bukkit; import org.bukkit.craftbukkit.v.block.CraftBlockState; +import org.bukkit.craftbukkit.v.block.CraftBlockStates; import org.bukkit.craftbukkit.v.event.CraftEventFactory; import org.bukkit.event.block.BlockFormEvent; import org.spongepowered.asm.mixin.Final; @@ -34,7 +35,7 @@ public abstract class ConcretePowderBlockMixin extends FallingBlockMixin { public BlockState arclight$blockForm(@Coerce ConcretePowderBlockMixin block, BlockPlaceContext context) { Level world = context.getLevel(); BlockPos blockPos = context.getClickedPos(); - CraftBlockState blockState = CraftBlockState.getBlockState(world, blockPos); + CraftBlockState blockState = CraftBlockStates.getBlockState(world, blockPos); blockState.setData(this.concrete); BlockFormEvent event = new BlockFormEvent(blockState.getBlock(), blockState); Bukkit.getPluginManager().callEvent(event); @@ -49,7 +50,7 @@ public abstract class ConcretePowderBlockMixin extends FallingBlockMixin { if (!(worldIn instanceof Level)) { return this.concrete; } - CraftBlockState blockState = CraftBlockState.getBlockState(worldIn, currentPos); + CraftBlockState blockState = CraftBlockStates.getBlockState(worldIn, currentPos); blockState.setData(this.concrete); BlockFormEvent event = new BlockFormEvent(blockState.getBlock(), blockState); Bukkit.getPluginManager().callEvent(event); diff --git a/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/level/block/FireBlockMixin.java b/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/level/block/FireBlockMixin.java index 5d74abc3..45233569 100644 --- a/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/level/block/FireBlockMixin.java +++ b/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/level/block/FireBlockMixin.java @@ -15,6 +15,7 @@ import org.bukkit.Bukkit; import org.bukkit.block.Block; import org.bukkit.craftbukkit.v.block.CraftBlock; import org.bukkit.craftbukkit.v.block.CraftBlockState; +import org.bukkit.craftbukkit.v.block.CraftBlockStates; import org.bukkit.craftbukkit.v.event.CraftEventFactory; import org.bukkit.event.block.BlockBurnEvent; import org.bukkit.event.block.BlockFadeEvent; @@ -71,7 +72,7 @@ public abstract class FireBlockMixin implements FireBlockBridge { if (!(worldIn instanceof Level)) { return Blocks.AIR.defaultBlockState(); } - CraftBlockState blockState = CraftBlockState.getBlockState(worldIn, currentPos); + CraftBlockState blockState = CraftBlockStates.getBlockState(worldIn, currentPos); blockState.setData(Blocks.AIR.defaultBlockState()); BlockFadeEvent event = new BlockFadeEvent(blockState.getBlock(), blockState); Bukkit.getPluginManager().callEvent(event); diff --git a/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/level/block/PortalSizeMixin.java b/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/level/block/PortalSizeMixin.java index 50dfaffc..5bbf77ae 100644 --- a/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/level/block/PortalSizeMixin.java +++ b/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/level/block/PortalSizeMixin.java @@ -23,6 +23,7 @@ import org.bukkit.World; import org.bukkit.block.BlockState; import org.bukkit.craftbukkit.v.block.CraftBlock; import org.bukkit.craftbukkit.v.block.CraftBlockState; +import org.bukkit.craftbukkit.v.block.CraftBlockStates; import org.bukkit.craftbukkit.v.event.CraftPortalEvent; import org.bukkit.event.world.PortalCreateEvent; import org.spongepowered.asm.mixin.Final; @@ -67,7 +68,7 @@ public abstract class PortalSizeMixin implements PortalSizeBridge { World world = ((WorldBridge) ((IWorldBridge) this.level).bridge$getMinecraftWorld()).bridge$getWorld(); net.minecraft.world.level.block.state.BlockState blockState = Blocks.NETHER_PORTAL.defaultBlockState().setValue(NetherPortalBlock.AXIS, this.axis); BlockPos.betweenClosed(this.bottomLeft, this.bottomLeft.relative(Direction.UP, this.height - 1).relative(this.rightDir, this.width - 1)).forEach(pos -> { - CraftBlockState state = CraftBlockState.getBlockState(((IWorldBridge) this.level).bridge$getMinecraftWorld(), pos, 18); + CraftBlockState state = CraftBlockStates.getBlockState(((IWorldBridge) this.level).bridge$getMinecraftWorld(), pos, 18); state.setData(blockState); this.blocks.add(state); }); diff --git a/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/level/block/entity/BlockEntityMixin.java b/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/level/block/entity/BlockEntityMixin.java index e75af3f2..5cbd4866 100644 --- a/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/level/block/entity/BlockEntityMixin.java +++ b/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/level/block/entity/BlockEntityMixin.java @@ -1,7 +1,6 @@ package io.izzel.arclight.common.mixin.core.world.level.block.entity; import io.izzel.arclight.common.bridge.core.tileentity.TileEntityBridge; -import io.izzel.arclight.common.bridge.core.world.WorldBridge; import net.minecraft.core.BlockPos; import net.minecraft.nbt.CompoundTag; import net.minecraft.world.level.Level; @@ -57,10 +56,6 @@ public abstract class BlockEntityMixin implements TileEntityBridge { public InventoryHolder getOwner() { if (this.level == null) return null; org.bukkit.block.Block block = CraftBlock.at(this.level, this.worldPosition); - if (block == null) { - org.bukkit.Bukkit.getLogger().log(java.util.logging.Level.WARNING, "No block for owner at %s %d %d %d", new Object[]{((WorldBridge) level).bridge$getWorld(), worldPosition.getX(), worldPosition.getY(), worldPosition.getZ()}); - return null; - } org.bukkit.block.BlockState state = block.getState(); if (state instanceof InventoryHolder) return (InventoryHolder) state; return null; diff --git a/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/level/entity/PersistentEntitySectionManagerMixin.java b/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/level/entity/PersistentEntitySectionManagerMixin.java new file mode 100644 index 00000000..a746105a --- /dev/null +++ b/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/level/entity/PersistentEntitySectionManagerMixin.java @@ -0,0 +1,78 @@ +package io.izzel.arclight.common.mixin.core.world.level.entity; + +import com.google.common.collect.ImmutableList; +import net.minecraft.world.entity.Entity; +import net.minecraft.world.level.ChunkPos; +import net.minecraft.world.level.chunk.storage.EntityStorage; +import net.minecraft.world.level.entity.ChunkEntities; +import net.minecraft.world.level.entity.EntityAccess; +import net.minecraft.world.level.entity.EntityPersistentStorage; +import net.minecraft.world.level.entity.EntitySection; +import net.minecraft.world.level.entity.EntitySectionStorage; +import net.minecraft.world.level.entity.PersistentEntitySectionManager; +import org.bukkit.craftbukkit.v.event.CraftEventFactory; +import org.spongepowered.asm.mixin.Final; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Shadow; +import org.spongepowered.asm.mixin.Unique; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Coerce; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; +import org.spongepowered.asm.mixin.injection.callback.LocalCapture; + +import java.io.IOException; +import java.util.List; +import java.util.function.Consumer; +import java.util.stream.Collectors; + +@Mixin(PersistentEntitySectionManager.class) +public abstract class PersistentEntitySectionManagerMixin { + + // @formatter:off + @Shadow public abstract void close() throws IOException; + @Shadow @Final private EntityPersistentStorage permanentStorage; + @Shadow @Final EntitySectionStorage sectionStorage; + // @formatter:on + + public void close(boolean save) throws IOException { + if (save) { + this.close(); + } else { + this.permanentStorage.close(); + } + } + + public List getEntities(ChunkPos chunkCoordIntPair) { + return sectionStorage.getExistingSectionsInChunk(chunkCoordIntPair.toLong()) + .flatMap(EntitySection::getEntities).map(o -> (Entity) o).collect(Collectors.toList()); + } + + @Unique private boolean arclight$fireEvent = false; + + @Inject(method = "storeChunkSections", locals = LocalCapture.CAPTURE_FAILHARD, + at = @At(value = "INVOKE", target = "Lnet/minecraft/world/level/entity/EntityPersistentStorage;storeEntities(Lnet/minecraft/world/level/entity/ChunkEntities;)V")) + private void arclight$fireUnload(long pos, Consumer consumer, CallbackInfoReturnable cir, @Coerce Object status, List list) { + if (arclight$fireEvent) { + CraftEventFactory.callEntitiesUnloadEvent(((EntityStorage) permanentStorage).level, new ChunkPos(pos), + list.stream().map(entity -> (Entity) entity).collect(Collectors.toList())); + } + } + + @Inject(method = "storeChunkSections", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/level/entity/EntityPersistentStorage;storeEntities(Lnet/minecraft/world/level/entity/ChunkEntities;)V")) + private void arclight$resetFlag(long pos, Consumer consumer, CallbackInfoReturnable cir) { + arclight$fireEvent = false; + } + + @Inject(method = "processChunkUnload", at = @At("HEAD")) + private void arclight$fireEvent(long pChunkPosValue, CallbackInfoReturnable cir) { + arclight$fireEvent = true; + } + + @Inject(method = "processPendingLoads", locals = LocalCapture.CAPTURE_FAILHARD, at = @At(value = "INVOKE", shift = At.Shift.AFTER, remap = false, target = "Lit/unimi/dsi/fastutil/longs/Long2ObjectMap;put(JLjava/lang/Object;)Ljava/lang/Object;")) + private void arclight$fireLoad(CallbackInfo ci, ChunkEntities chunkEntities) { + List entities = getEntities(chunkEntities.getPos()); + CraftEventFactory.callEntitiesLoadEvent(((EntityStorage) permanentStorage).level, chunkEntities.getPos(), entities); + } +} diff --git a/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/spawner/WorldEntitySpawnerMixin.java b/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/spawner/WorldEntitySpawnerMixin.java index a27ea682..4745dd33 100644 --- a/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/spawner/WorldEntitySpawnerMixin.java +++ b/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/spawner/WorldEntitySpawnerMixin.java @@ -58,6 +58,7 @@ public abstract class WorldEntitySpawnerMixin { boolean spawnWaterThisTick = ((WorldBridge) world).bridge$ticksPerWaterSpawns() != 0L && worldInfo.getGameTime() % ((WorldBridge) world).bridge$ticksPerWaterSpawns() == 0L; boolean spawnAmbientThisTick = ((WorldBridge) world).bridge$ticksPerAmbientSpawns() != 0L && worldInfo.getGameTime() % ((WorldBridge) world).bridge$ticksPerAmbientSpawns() == 0L; boolean spawnWaterAmbientThisTick = ((WorldBridge) world).bridge$ticksPerWaterAmbientSpawns() != 0L && worldInfo.getGameTime() % ((WorldBridge) world).bridge$ticksPerWaterAmbientSpawns() == 0L; + boolean spawnWaterUndergroundThisTick = ((WorldBridge) world).bridge$ticksPerWaterUndergroundSpawns() != 0L && worldInfo.getGameTime() % ((WorldBridge) world).bridge$ticksPerWaterUndergroundSpawns() == 0L; for (MobCategory classification : classifications) { boolean spawnThisTick = true; int limit = classification.getMaxInstancesPerChunk(); @@ -70,6 +71,10 @@ public abstract class WorldEntitySpawnerMixin { spawnThisTick = spawnAnimalThisTick; limit = ((WorldBridge) world).bridge$getWorld().getAnimalSpawnLimit(); } + case UNDERGROUND_WATER_CREATURE -> { + spawnThisTick = spawnWaterUndergroundThisTick; + limit = ((WorldBridge) world).bridge$getWorld().getWaterUndergroundCreatureSpawnLimit(); + } case WATER_CREATURE -> { spawnThisTick = spawnWaterThisTick; limit = ((WorldBridge) world).bridge$getWorld().getWaterAnimalSpawnLimit(); diff --git a/arclight-common/src/main/java/io/izzel/arclight/common/mod/server/block/ArclightTileInventory.java b/arclight-common/src/main/java/io/izzel/arclight/common/mod/server/block/ArclightTileInventory.java deleted file mode 100644 index 83be1559..00000000 --- a/arclight-common/src/main/java/io/izzel/arclight/common/mod/server/block/ArclightTileInventory.java +++ /dev/null @@ -1,22 +0,0 @@ -package io.izzel.arclight.common.mod.server.block; - -import net.minecraft.world.Container; -import net.minecraft.world.level.block.entity.BlockEntity; -import org.bukkit.block.Block; -import org.bukkit.craftbukkit.v.block.CraftBlockEntityState; -import org.bukkit.craftbukkit.v.inventory.CraftInventory; -import org.bukkit.inventory.BlockInventoryHolder; -import org.bukkit.inventory.Inventory; -import org.jetbrains.annotations.NotNull; - -public class ArclightTileInventory extends CraftBlockEntityState implements BlockInventoryHolder { - - public ArclightTileInventory(Block block, Class tileEntityClass) { - super(block, tileEntityClass); - } - - @Override - public @NotNull Inventory getInventory() { - return new CraftInventory(this.getTileEntity()); - } -} diff --git a/arclight-common/src/main/java/io/izzel/arclight/common/mod/server/block/CauldronHooks.java b/arclight-common/src/main/java/io/izzel/arclight/common/mod/server/block/CauldronHooks.java index c1522f00..f48b7911 100644 --- a/arclight-common/src/main/java/io/izzel/arclight/common/mod/server/block/CauldronHooks.java +++ b/arclight-common/src/main/java/io/izzel/arclight/common/mod/server/block/CauldronHooks.java @@ -8,6 +8,7 @@ import net.minecraft.world.level.block.state.BlockState; import org.bukkit.Bukkit; import org.bukkit.craftbukkit.v.block.CraftBlock; import org.bukkit.craftbukkit.v.block.CraftBlockState; +import org.bukkit.craftbukkit.v.block.CraftBlockStates; import org.bukkit.event.block.CauldronLevelChangeEvent; public class CauldronHooks { @@ -40,7 +41,7 @@ public class CauldronHooks { } public static boolean changeLevel(BlockState old, Level world, BlockPos pos, BlockState state, Entity entity, CauldronLevelChangeEvent.ChangeReason reason) { - CraftBlockState newState = CraftBlockState.getBlockState(world, pos); + CraftBlockState newState = CraftBlockStates.getBlockState(world, pos); newState.setData(state); CauldronLevelChangeEvent event = new CauldronLevelChangeEvent( CraftBlock.at(world, pos), diff --git a/arclight-common/src/main/resources/META-INF/accesstransformer.cfg b/arclight-common/src/main/resources/META-INF/accesstransformer.cfg index 82fd3cea..9f0ef8d1 100644 --- a/arclight-common/src/main/resources/META-INF/accesstransformer.cfg +++ b/arclight-common/src/main/resources/META-INF/accesstransformer.cfg @@ -9,6 +9,10 @@ public net.minecraft.server.MinecraftServer$TimeProfiler public net.minecraft.world.level.chunk.ChunkGenerator f_62140_ # strongholdSeed public net.minecraft.world.level.levelgen.NoiseBasedChunkGenerator f_64318_ # settings public net.minecraft.world.entity.monster.piglin.PiglinAi m_149965_(Lnet/minecraft/world/item/ItemStack;)Z # isLovedItem +public net.minecraft.world.level.chunk.storage.EntityStorage f_156538_ # level +public net.minecraft.world.level.levelgen.structure.templatesystem.StructureTemplate f_74482_ # palettes +public net.minecraft.world.level.levelgen.structure.templatesystem.StructureTemplate f_74483_ # entityInfoList +public net.minecraft.world.level.levelgen.structure.templatesystem.StructureManager f_74326_ # structureRepository # Misc public net.minecraft.server.PlayerAdvancements f_135964_ public net.minecraft.server.level.PlayerRespawnLogic m_8264_(Lnet/minecraft/server/level/ServerLevel;IIZ)Lnet/minecraft/core/BlockPos; diff --git a/arclight-common/src/main/resources/mixins.arclight.core.json b/arclight-common/src/main/resources/mixins.arclight.core.json index dd2bf6ef..9b394ccc 100644 --- a/arclight-common/src/main/resources/mixins.arclight.core.json +++ b/arclight-common/src/main/resources/mixins.arclight.core.json @@ -227,7 +227,7 @@ "world.entity.vehicle.MinecartCommandBlock_MinecartCommandBaseMixin", "world.food.FoodDataMixin", "world.gen.WorldGenRegionMixin", - "world.gen.feature.structure.StructureManagerMixin", + "world.gen.feature.structure.StructureFeatureManagerMixin", "world.gen.feature.structure.SwampHutPieceMixin", "world.gen.feature.template.TemplateManagerMixin", "world.inventory.AbstractContainerMenuMixin", @@ -326,6 +326,7 @@ "world.level.block.CauldronBlockMixin", "world.level.block.CaveVinesMixin", "world.level.block.ChestBlock2Mixin", + "world.level.block.ChestBlockMixin", "world.level.block.ChorusFlowerBlockMixin", "world.level.block.CocoaBlockMixin", "world.level.block.CommandBlockMixin", @@ -425,6 +426,7 @@ "world.level.chunk.LevelChunkMixin", "world.level.chunk.storage.ChunkLoaderMixin", "world.level.chunk.storage.RegionFileCacheMixin", + "world.level.entity.PersistentEntitySectionManagerMixin", "world.level.levelgen.ChunkGeneratorMixin", "world.level.levelgen.NoiseBasedChunkGeneratorMixin", "world.level.portal.PortalForcerMixin",