diff --git a/src/main/java/twilightforest/asmhooks/EntityHooks.java b/src/main/java/twilightforest/asmhooks/EntityHooks.java
index 70c27121be..820f57a75e 100644
--- a/src/main/java/twilightforest/asmhooks/EntityHooks.java
+++ b/src/main/java/twilightforest/asmhooks/EntityHooks.java
@@ -5,11 +5,11 @@
import net.minecraft.world.entity.LivingEntity;
import net.minecraft.world.entity.MoverType;
import net.minecraft.world.entity.PathfinderMob;
+import net.minecraft.world.level.block.Blocks;
import net.minecraft.world.level.material.FluidState;
import net.minecraft.world.phys.Vec3;
import net.neoforged.neoforge.common.NeoForgeMod;
import net.neoforged.neoforge.fluids.FluidType;
-import org.jetbrains.annotations.Nullable;
import twilightforest.init.TFDataAttachments;
import twilightforest.init.custom.TravellersModifiersManager;
import twilightforest.item.travellers_gear.TravellersGearLogic;
@@ -25,7 +25,6 @@ public class EntityHooks {
* Injection Point:
* {@link net.minecraft.world.entity.LivingEntity#canStandOnFluid(FluidState)}
*/
- @Nullable
public static boolean processWaterWalking(boolean o, LivingEntity livingEntity, FluidState fluidState) {
if (!fluidState.is(FluidTags.WATER))
return o;
@@ -34,7 +33,7 @@ public static boolean processWaterWalking(boolean o, LivingEntity livingEntity,
return o;
boolean isWaterWalking = TravellersGearLogic.isBelowMaxWaterWalkingSubmergedHeight(livingEntity) && !livingEntity.isShiftKeyDown();
- if (livingEntity.getFluidTypeHeight(NeoForgeMod.WATER_TYPE.value()) > 0 && isWaterWalking && livingEntity.level().getGameTime() % 3 == 1)
+ if (livingEntity.getFluidHeight(FluidTags.WATER) > 0.0D && isWaterWalking && livingEntity.level().getGameTime() % 3 == 1)
TravellersGearLogic.waterWalkingSplashEffect(livingEntity);
return isWaterWalking;
}
@@ -99,9 +98,9 @@ public static float resetFactorWithUnrestrained(float o, Entity entity) {
* {@link net.minecraft.world.entity.Entity#move(MoverType, Vec3)}
*/
public static Entity resetStuckUnrestrained(Entity entity) {
- if (!(entity instanceof LivingEntity living) || living.stuckSpeedMultiplier.lengthSqr() <= 1.0E-7 || !TravellersModifiersManager.isModifierActive(entity, TravellersModifiersManager.UNRESTRAINED_MODIFIER))
+ if (!(entity instanceof LivingEntity living) || !TravellersModifiersManager.isModifierActive(entity, TravellersModifiersManager.UNRESTRAINED_MODIFIER))
return entity;
- living.stuckSpeedMultiplier = Vec3.ZERO;
+ living.makeStuckInBlock(Blocks.AIR.defaultBlockState(), Vec3.ZERO);
return entity;
}
diff --git a/src/main/java/twilightforest/asmhooks/MultipartHooks.java b/src/main/java/twilightforest/asmhooks/MultipartHooks.java
index a21d18315f..c9b3eb2099 100644
--- a/src/main/java/twilightforest/asmhooks/MultipartHooks.java
+++ b/src/main/java/twilightforest/asmhooks/MultipartHooks.java
@@ -3,13 +3,11 @@
import net.minecraft.client.Camera;
import net.minecraft.client.DeltaTracker;
import net.minecraft.client.renderer.GameRenderer;
-import net.minecraft.client.renderer.LightTexture;
import net.minecraft.client.renderer.entity.EntityRenderer;
import net.minecraft.world.entity.Entity;
import org.jetbrains.annotations.Nullable;
import org.joml.Matrix4f;
import tamaized.beanification.Autowired;
-import twilightforest.asm.transformers.multipart.SendDirtyEntityDataTransformer;
import twilightforest.util.multiparts.MultipartEntityUtil;
import java.util.Iterator;
@@ -39,7 +37,7 @@ public static Iterator resolveEntitiesForRendering(Iterator iter
* Targets: {@link net.minecraft.client.renderer.entity.EntityRenderDispatcher#renderers}
*/
@Nullable
- public static EntityRenderer> resolveEntityRenderer(@Nullable EntityRenderer> renderer, Entity entity) {
+ public static EntityRenderer, ?> resolveEntityRenderer(@Nullable EntityRenderer, ?> renderer, Entity entity) {
return multipartEntityUtil.tryLookupTFPartRenderer(renderer, entity);
}
diff --git a/src/main/java/twilightforest/asmhooks/PlayerHooks.java b/src/main/java/twilightforest/asmhooks/PlayerHooks.java
index f1aae7045b..1398796700 100644
--- a/src/main/java/twilightforest/asmhooks/PlayerHooks.java
+++ b/src/main/java/twilightforest/asmhooks/PlayerHooks.java
@@ -8,8 +8,6 @@
import net.minecraft.world.entity.ai.attributes.Attributes;
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.item.ItemStack;
-import twilightforest.asm.transformers.player.GetFieldOfViewModifierTransformer;
-import twilightforest.asm.transformers.player.ReduceMovementFoodExhaustionTransformer;
import twilightforest.init.TFAttributeModifiers;
import twilightforest.init.TFDataAttachments;
import twilightforest.init.TFDataComponents;
diff --git a/src/main/java/twilightforest/client/event/ClientGameEvents.java b/src/main/java/twilightforest/client/event/ClientGameEvents.java
index d96376a093..a65ca5a634 100644
--- a/src/main/java/twilightforest/client/event/ClientGameEvents.java
+++ b/src/main/java/twilightforest/client/event/ClientGameEvents.java
@@ -1,17 +1,13 @@
package twilightforest.client.event;
import com.ibm.icu.text.RuleBasedNumberFormat;
-import com.mojang.blaze3d.systems.RenderSystem;
import com.mojang.blaze3d.vertex.*;
import net.minecraft.ChatFormatting;
import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.components.SplashRenderer;
import net.minecraft.client.gui.screens.TitleScreen;
-import net.minecraft.client.model.HeadedModel;
-import net.minecraft.client.model.HumanoidModel;
import net.minecraft.client.player.LocalPlayer;
-import net.minecraft.client.renderer.LevelRenderer;
-import net.minecraft.client.renderer.RenderType;
+import net.minecraft.client.renderer.rendertype.RenderTypes;
import net.minecraft.core.BlockPos;
import net.minecraft.core.Holder;
import net.minecraft.core.RegistryAccess;
@@ -21,8 +17,8 @@
import net.minecraft.sounds.Music;
import net.minecraft.sounds.Musics;
import net.minecraft.util.Mth;
-import net.minecraft.world.entity.EquipmentSlot;
-import net.minecraft.world.entity.LivingEntity;
+import net.minecraft.world.attribute.BackgroundMusic;
+import net.minecraft.world.attribute.EnvironmentAttributes;
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.item.*;
import net.minecraft.world.level.ChunkPos;
@@ -34,7 +30,6 @@
import net.minecraft.world.phys.shapes.Shapes;
import net.minecraft.world.phys.shapes.VoxelShape;
import net.neoforged.api.distmarker.Dist;
-import net.neoforged.fml.ModList;
import net.neoforged.neoforge.client.event.*;
import net.neoforged.neoforge.client.gui.VanillaGuiLayers;
import net.neoforged.neoforge.common.NeoForge;
@@ -48,13 +43,12 @@
import twilightforest.client.*;
import twilightforest.client.renderer.TFSkyRenderer;
import twilightforest.client.renderer.entity.MagicPaintingRenderer;
-import twilightforest.compat.curios.CuriosCompat;
import twilightforest.config.TFConfig;
-import twilightforest.tags.TFItemTags;
import twilightforest.entity.boss.bar.ClientTFBossBar;
import twilightforest.events.HostileMountEvents;
import twilightforest.init.*;
import twilightforest.item.*;
+import twilightforest.tags.TFItemTags;
import twilightforest.util.HolderMatcher;
import java.time.LocalDate;
@@ -95,7 +89,8 @@ private void setup() {
NeoForge.EVENT_BUS.addListener(this::setMusicInDimension);
NeoForge.EVENT_BUS.addListener(this::shakeCamera);
NeoForge.EVENT_BUS.addListener(this::translateBookAuthor);
- NeoForge.EVENT_BUS.addListener(this::unrenderHeadWithTrophies);
+ // Uncomment this when Curios compat is ready
+// NeoForge.EVENT_BUS.addListener(this::unrenderHeadWithTrophies);
NeoForge.EVENT_BUS.addListener(this::updateBowFOV);
NeoForge.EVENT_BUS.addListener(CloudEvents::renderPrecipitation);
@@ -139,7 +134,7 @@ private void clearEntityRenderUtilMap(ScreenEvent.Closing event) {
private void setMusicInDimension(SelectMusicEvent event) {
Music music = event.getOriginalMusic();
if (Minecraft.getInstance().level != null && Minecraft.getInstance().player != null && (music == Musics.CREATIVE || music == Musics.UNDER_WATER) && TFDimension.isTwilightWorldOnClient(Minecraft.getInstance().level)) {
- event.setMusic(Minecraft.getInstance().level.getBiomeManager().getNoiseBiomeAtPosition(Minecraft.getInstance().player.blockPosition()).value().getBackgroundMusic().orElse(Musics.GAME));
+ event.setMusic(Minecraft.getInstance().level.getBiomeManager().getNoiseBiomeAtPosition(Minecraft.getInstance().player.blockPosition()).value().getAttributes().applyModifier(EnvironmentAttributes.BACKGROUND_MUSIC, new BackgroundMusic(Musics.GAME)).defaultMusic().orElse(Musics.GAME));
}
}
@@ -157,30 +152,24 @@ private void removeHostileMountHealth(RenderGuiLayerEvent.Pre event) {
/**
* Render aurora effect as needed
*/
- private void renderAurora(RenderLevelStageEvent event) {
+ private void renderAurora(RenderLevelStageEvent.AfterWeather event) {
if (Minecraft.getInstance().level == null) return;
- if (event.getStage() == RenderLevelStageEvent.Stage.AFTER_WEATHER && (aurora > 0 || lastAurora > 0) && TFShaders.AURORA != null) {
+ if ((aurora > 0 || lastAurora > 0) && TFShaders.AURORA != null) {
Tesselator tesselator = Tesselator.getInstance();
BufferBuilder buffer = tesselator.begin(VertexFormat.Mode.QUADS, DefaultVertexFormat.POSITION_COLOR);
- final float scale = 2048F * (Minecraft.getInstance().gameRenderer.getRenderDistance() / 32F);
- Vec3 pos = event.getCamera().getPosition();
+ final float scale = 2048F * (Minecraft.getInstance().options.getEffectiveRenderDistance() / 2F);
+ Vec3 pos = Minecraft.getInstance().gameRenderer.getMainCamera().position();
float y = (float) (256F - pos.y());
buffer.addVertex(-scale, y, scale).setColor(1F, 1F, 1F, 1F);
buffer.addVertex(-scale, y, -scale).setColor(1F, 1F, 1F, 1F);
buffer.addVertex(scale, y, -scale).setColor(1F, 1F, 1F, 1F);
buffer.addVertex(scale, y, scale).setColor(1F, 1F, 1F, 1F);
- RenderSystem.enableBlend();
- RenderSystem.enableDepthTest();
- RenderSystem.setShaderColor(1F, 1F, 1F, (Mth.lerp(event.getPartialTick().getGameTimeDeltaTicks(), lastAurora, aurora)) / 60F * 0.5F);
TFShaders.AURORA.invokeThenEndTesselator(
Minecraft.getInstance().level == null ? 0 : Mth.abs((int) Minecraft.getInstance().level.getBiomeManager().biomeZoomSeed),
(float) pos.x(), (float) pos.y(), (float) pos.z(), buffer);
- RenderSystem.setShaderColor(1F, 1F, 1F, 1F);
- RenderSystem.disableDepthTest();
- RenderSystem.disableBlend();
}
}
@@ -203,9 +192,9 @@ private void clientTick(ClientTickEvent.Post event) {
time++;
lastAurora = aurora;
- if (mc.level != null && mc.cameraEntity != null && !TFConfig.getValidAuroraBiomes(mc.level.registryAccess()).isEmpty()) {
+ if (mc.level != null && mc.getCameraEntity() != null && !TFConfig.getValidAuroraBiomes(mc.level.registryAccess()).isEmpty()) {
RegistryAccess access = mc.level.registryAccess();
- Holder biome = mc.level.getBiome(mc.cameraEntity.blockPosition());
+ Holder biome = mc.level.getBiome(mc.getCameraEntity().blockPosition());
if (TFConfig.getValidAuroraBiomes(access).stream().anyMatch(c -> holderMatcher.match(c, biome)))
aurora++;
else
@@ -239,7 +228,7 @@ private void clientTick(ClientTickEvent.Post event) {
Player player = mc.player;
shakeIntensity = (float) (1.0F - mc.player.distanceToSqr(Vec3.atCenterOf(beanstalk.getBlockPos())) / Math.pow(16, 2));
if (shakeIntensity > 0) {
- player.moveTo(player.getX(), player.getY(), player.getZ(),
+ player.snapTo(player.getX(), player.getY(), player.getZ(),
player.getYRot() + (player.getRandom().nextFloat() - 0.5F) * shakeIntensity,
player.getXRot() + (player.getRandom().nextFloat() * 2.5F - 1.25F) * shakeIntensity);
shakeIntensity = 0.0F;
@@ -289,24 +278,25 @@ private void updateBowFOV(ComputeFovModifierEvent event) {
}
}
- private void unrenderHeadWithTrophies(RenderLivingEvent.Pre, ?> event) {
- ItemStack stack = event.getEntity().getItemBySlot(EquipmentSlot.HEAD);
- boolean visible = !(stack.getItem() instanceof TrophyItem) && !areCuriosEquipped(event.getEntity());
- boolean isPlayer = event.getEntity() instanceof Player;
- if (event.getRenderer().getModel() instanceof HeadedModel headedModel) {
- headedModel.getHead().visible = visible && (!isPlayer || headedModel.getHead().visible); // some mods like Better Combat can move player's head and hide it in the first person view
- if (event.getRenderer().getModel() instanceof HumanoidModel> humanoidModel) {
- humanoidModel.hat.visible = visible && (!isPlayer || humanoidModel.hat.visible);
- }
- }
- }
-
- private boolean areCuriosEquipped(LivingEntity entity) {
- if (ModList.get().isLoaded("curios")) {
- return CuriosCompat.isCurioEquippedAndVisible(entity, stack -> stack.getItem() instanceof TrophyItem);
- }
- return false;
- }
+ // Uncomment this when Curios compat is ready
+// private void unrenderHeadWithTrophies(RenderLivingEvent.Pre, ?, ?> event) {
+// ItemStack stack = event.getEntity().getItemBySlot(EquipmentSlot.HEAD);
+// boolean visible = !(stack.getItem() instanceof TrophyItem) && !areCuriosEquipped(event.getEntity());
+// boolean isPlayer = event.getEntity() instanceof Player;
+// if (event.getRenderer().getModel() instanceof HeadedModel headedModel) {
+// headedModel.getHead().visible = visible && (!isPlayer || headedModel.getHead().visible); // some mods like Better Combat can move player's head and hide it in the first person view
+// if (event.getRenderer().getModel() instanceof HumanoidModel> humanoidModel) {
+// humanoidModel.hat.visible = visible && (!isPlayer || humanoidModel.hat.visible);
+// }
+// }
+// }
+//
+// private boolean areCuriosEquipped(LivingEntity entity) {
+// if (ModList.get().isLoaded("curios")) {
+// return CuriosCompat.isCurioEquippedAndVisible(entity, stack -> stack.getItem() instanceof TrophyItem);
+// }
+// return false;
+// }
private void translateBookAuthor(ItemTooltipEvent event) {
ItemStack stack = event.getItemStack();
@@ -323,9 +313,42 @@ private void translateBookAuthor(ItemTooltipEvent event) {
}
}
- private void renderGiantBlockOutlines(RenderHighlightEvent.Block event) {
- BlockPos pos = event.getTarget().getBlockPos();
- BlockState state = event.getCamera().getEntity().level().getBlockState(pos);
+ // [VanillaCopy] the copy of removed LevelRenderer.renderShape
+ private void renderShape(
+ PoseStack poseStack,
+ VertexConsumer consumer,
+ VoxelShape shape,
+ double x,
+ double y,
+ double z,
+ float red,
+ float green,
+ float blue,
+ float alpha
+ ) {
+ PoseStack.Pose posestack$pose = poseStack.last();
+ shape.forAllEdges(
+ (p_323073_, p_323074_, p_323075_, p_323076_, p_323077_, p_323078_) -> {
+ float f = (float)(p_323076_ - p_323073_);
+ float f1 = (float)(p_323077_ - p_323074_);
+ float f2 = (float)(p_323078_ - p_323075_);
+ float f3 = Mth.sqrt(f * f + f1 * f1 + f2 * f2);
+ f /= f3;
+ f1 /= f3;
+ f2 /= f3;
+ consumer.addVertex(posestack$pose, (float)(p_323073_ + x), (float)(p_323074_ + y), (float)(p_323075_ + z))
+ .setColor(red, green, blue, alpha)
+ .setNormal(posestack$pose, f, f1, f2);
+ consumer.addVertex(posestack$pose, (float)(p_323076_ + x), (float)(p_323077_ + y), (float)(p_323078_ + z))
+ .setColor(red, green, blue, alpha)
+ .setNormal(posestack$pose, f, f1, f2);
+ }
+ );
+ }
+
+ private void renderGiantBlockOutlines(ExtractBlockOutlineRenderStateEvent event) {
+ BlockPos pos = event.getBlockPos();
+ BlockState state = event.getBlockState();
if (state.getBlock() instanceof MiniatureStructureBlock) {
event.setCanceled(true);
@@ -336,10 +359,13 @@ private void renderGiantBlockOutlines(RenderHighlightEvent.Block event) {
if (player != null && (player.getMainHandItem().getItem() instanceof GiantPickItem || (player.getMainHandItem().getItem() instanceof BlockItem blockItem && blockItem.getBlock() instanceof GiantBlock))) {
event.setCanceled(true);
if (!state.isAir() && player.level().getWorldBorder().isWithinBounds(pos)) {
- BlockPos offsetPos = new BlockPos(pos.getX() & ~0b11, pos.getY() & ~0b11, pos.getZ() & ~0b11);
- VertexConsumer consumer = event.getMultiBufferSource().getBuffer(RenderType.lines());
- Vec3 xyz = Vec3.atLowerCornerOf(offsetPos).subtract(event.getCamera().getPosition());
- LevelRenderer.renderShape(event.getPoseStack(), consumer, GIANT_BLOCK, xyz.x(), xyz.y(), xyz.z(), 0.0F, 0.0F, 0.0F, 0.45F);
+ event.addCustomRenderer((renderState, buffer, stack, translucentPass, levelRenderState) -> {
+ BlockPos offsetPos = new BlockPos(renderState.pos().getX() & ~0b11, renderState.pos().getY() & ~0b11, renderState.pos().getZ() & ~0b11);
+ Vec3 xyz = Vec3.atLowerCornerOf(offsetPos).subtract(event.getCamera().position());
+ VertexConsumer consumer = buffer.getBuffer(RenderTypes.lines());
+ renderShape(stack, consumer, GIANT_BLOCK, xyz.x(), xyz.y(), xyz.z(), 0.0F, 0.0F, 0.0F, 0.45F);
+ return true;
+ });
}
}
}
diff --git a/src/main/java/twilightforest/client/event/ClientRegistrationEvents.java b/src/main/java/twilightforest/client/event/ClientRegistrationEvents.java
index 06ed012b8c..2f85fa0ab7 100644
--- a/src/main/java/twilightforest/client/event/ClientRegistrationEvents.java
+++ b/src/main/java/twilightforest/client/event/ClientRegistrationEvents.java
@@ -20,6 +20,7 @@
import net.minecraft.client.renderer.entity.NoopRenderer;
import net.minecraft.client.renderer.entity.ThrownItemRenderer;
import net.minecraft.client.renderer.entity.player.AvatarRenderer;
+import net.minecraft.client.renderer.entity.state.AvatarRenderState;
import net.minecraft.client.renderer.entity.state.LivingEntityRenderState;
import net.minecraft.client.resources.model.sprite.AtlasManager;
import net.minecraft.core.BlockPos;
@@ -27,6 +28,8 @@
import net.minecraft.resources.Identifier;
import net.minecraft.util.Mth;
import net.minecraft.world.entity.EntityType;
+import net.minecraft.world.entity.LivingEntity;
+import net.minecraft.world.entity.player.Player;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.block.RenderShape;
import net.minecraft.world.level.block.state.BlockState;
@@ -48,7 +51,6 @@
import twilightforest.client.model.TFModelLayers;
import twilightforest.client.model.armor.*;
import twilightforest.client.model.block.BrazierModel;
-import twilightforest.client.model.block.ReactorDebrisModel;
import twilightforest.client.model.block.aurorablock.UnbakedNoiseVaryingBlockStateModel;
import twilightforest.client.model.block.carpet.RoyalRagsModelLoader;
import twilightforest.client.model.block.connected.ConnectedTextureModelLoader;
@@ -57,7 +59,6 @@
import twilightforest.client.model.block.patch.PatchModelLoader;
import twilightforest.client.model.entity.*;
import twilightforest.client.model.item.TravellersGearItemModel;
-import twilightforest.client.model.item.TrollsteinnModel;
import twilightforest.client.particle.*;
import twilightforest.client.properties.*;
import twilightforest.client.renderer.armor.TFArmorRenderer;
@@ -72,8 +73,7 @@
import twilightforest.client.renderer.tooltip.PotionFlaskTooltipComponent;
import twilightforest.client.renderer.tooltip.TravellersBeltTooltipComponent;
import twilightforest.init.*;
-import twilightforest.item.ArcticArmorItem;
-import twilightforest.item.PotionFlaskItem;
+import twilightforest.item.*;
import twilightforest.item.travellers_gear.TravellersArmorBeltItem;
import twilightforest.item.travellers_gear.TravellersArmorItem;
import twilightforest.item.travellers_gear.TravellersGogglesItem;
@@ -89,7 +89,6 @@ public class ClientRegistrationEvents {
@PostConstruct
private void setup(IEventBus bus) {
bus.addListener(EntityRenderersEvent.AddLayers.class, this::attachRenderLayers);
- bus.addListener(this::bakeCustomModels);
bus.addListener(this::cacheJarLids);
bus.addListener(this::clientSetup);
bus.addListener(this::registerAdditionalModels);
@@ -154,20 +153,8 @@ private void registerSelectProperties(RegisterSelectItemModelPropertyEvent event
event.register(TwilightForestMod.prefix("experiment_115_variant"), Experiment115Type.TYPE);
}
- private void bakeCustomModels(ModelEvent.ModifyBakingResult event) {
- BakedModel oldModel = event.getModels().get(ModelResourceLocation.inventory(TwilightForestMod.prefix("trollsteinn")));
- models.put(ModelResourceLocation.inventory(TwilightForestMod.prefix("trollsteinn")), new TrollsteinnModel(oldModel));
- BakedModel defaultReactorDebrisModel = event.getModels().get(ModelResourceLocation.vanilla("netherrack", ""));
- models.put(new ModelResourceLocation(TwilightForestMod.prefix("reactor_debris"), ""), new ReactorDebrisModel(defaultReactorDebrisModel));
- }
-
- private void registerAdditionalModels(ModelEvent.RegisterAdditional event) {
- event.register(ShieldLayer.LOC);
- event.register(ModelResourceLocation.standalone(TwilightForestMod.prefix("item/trophy")));
- event.register(ModelResourceLocation.standalone(TwilightForestMod.prefix("item/trophy_minor")));
- event.register(ModelResourceLocation.standalone(TwilightForestMod.prefix("item/trophy_quest")));
- event.register(TrollsteinnModel.LIT_TROLLSTEINN);
-
+ // FIXME should be fixed after JarRenderer
+ private void registerAdditionalModels(RegisterBlockModelsEvent event) {
for (JarRenderer.LidResource lid : JarRenderer.LID_LOCATION_LIST.get()) {
Identifier location = lid.identifier();
String name = location.getPath();
@@ -176,11 +163,12 @@ private void registerAdditionalModels(ModelEvent.RegisterAdditional event) {
}
}
+ // FIXME should be fixed after JarRenderer
private void cacheJarLids(ModelEvent.BakingCompleted event) {
JarRenderer.LID_LOCATION_LIST.get().forEach((lid) -> {
String name = lid.identifier().getPath();
if (lid.customPath() != null) name = lid.customPath();
- JarRenderer.LIDS.put(lid.lid(), event.getModels().get(ModelResourceLocation.standalone(TwilightForestMod.prefix("block/lid/" + name))));
+ JarRenderer.LIDS.put(lid.lid(), event.getModelManager().getBlockModelSet().get(ModelResourceLocation.standalone(TwilightForestMod.prefix("block/lid/" + name))));
});
}
@@ -588,18 +576,18 @@ private void attachRenderLayers(EntityRenderersEvent.AddLayers event) {
BakedMultiPartRenderers.bakeMultiPartRenderers(event.getContext());
for (EntityType> type : event.getEntityTypes()) {
var renderer = event.getRenderer(type);
- if (renderer instanceof LivingEntityRenderer living) {
- attachRenderLayers(living);
+ if (renderer instanceof LivingEntityRenderer, ?, ?> living) {
+ attachRenderLayers((LivingEntityRenderer) living); // FIXME find the better way to avoid raw types
}
}
- event.getSkins().forEach(renderer -> {
- AvatarRenderer skin = event.getPlayerRenderer(renderer);
+ event.getSkins().forEach(modelType -> {
+ AvatarRenderer skin = event.getPlayerRenderer(modelType);
attachRenderLayers(Objects.requireNonNull(skin));
});
}
- private > void attachRenderLayers(LivingEntityRenderer, T, M> renderer) {
+ private > void attachRenderLayers(LivingEntityRenderer renderer) {
renderer.addLayer(new ShieldLayer<>(renderer));
renderer.addLayer(new IceLayer<>(renderer));
}
diff --git a/src/main/java/twilightforest/client/event/FogHandler.java b/src/main/java/twilightforest/client/event/FogHandler.java
index cf8630350d..6512a831b6 100644
--- a/src/main/java/twilightforest/client/event/FogHandler.java
+++ b/src/main/java/twilightforest/client/event/FogHandler.java
@@ -3,12 +3,10 @@
import net.minecraft.client.Minecraft;
import net.minecraft.client.multiplayer.ClientLevel;
import net.minecraft.client.player.LocalPlayer;
-import net.minecraft.client.renderer.FogRenderer;
import net.minecraft.util.Mth;
import net.minecraft.world.level.material.FogType;
import net.neoforged.neoforge.client.event.ViewportEvent;
import net.neoforged.neoforge.event.level.LevelEvent;
-import twilightforest.client.TwilightForestRenderInfo;
import twilightforest.init.TFBiomes;
import javax.annotation.Nullable;
@@ -26,10 +24,9 @@ public class FogHandler {
private static float TERRAIN_NEAR = 0.0F;
protected static void renderFog(ViewportEvent.RenderFog event) {
- if (event.getType().equals(FogType.NONE) && Minecraft.getInstance().cameraEntity instanceof LocalPlayer player && player.level() instanceof ClientLevel clientLevel && clientLevel.effects() instanceof TwilightForestRenderInfo) {
- if (event.getMode().equals(FogRenderer.FogMode.FOG_SKY)) {
+ if (event.getType().equals(FogType.NONE) && Minecraft.getInstance().getCameraEntity() instanceof LocalPlayer player && player.level() instanceof ClientLevel clientLevel) {
+ if (event.getType().equals(FogType.ATMOSPHERIC)) {
if (SKY_CHUNK_LOADED) {
- event.setCanceled(true);
boolean spooky = isSpooky(clientLevel, player);
float far = spooky ? event.getFarPlaneDistance() * 0.5F : event.getFarPlaneDistance();
@@ -47,7 +44,6 @@ protected static void renderFog(ViewportEvent.RenderFog event) {
}
} else {
if (TERRAIN_CHUNK_LOADED) {
- event.setCanceled(true);
boolean spooky = isSpooky(clientLevel, player);
float far = spooky ? event.getFarPlaneDistance() * 0.5F : event.getFarPlaneDistance();
diff --git a/src/main/java/twilightforest/client/event/OverlayHandler.java b/src/main/java/twilightforest/client/event/OverlayHandler.java
index 8587f4040a..0b22c90494 100644
--- a/src/main/java/twilightforest/client/event/OverlayHandler.java
+++ b/src/main/java/twilightforest/client/event/OverlayHandler.java
@@ -1,16 +1,13 @@
package twilightforest.client.event;
import com.google.common.collect.ImmutableList;
-import com.mojang.blaze3d.platform.GlStateManager;
-import com.mojang.blaze3d.platform.Window;
-import com.mojang.blaze3d.systems.RenderSystem;
import com.mojang.datafixers.util.Pair;
import net.minecraft.ChatFormatting;
import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.Gui;
-import net.minecraft.client.gui.GuiGraphics;
+import net.minecraft.client.gui.GuiGraphicsExtractor;
import net.minecraft.client.player.LocalPlayer;
-import net.minecraft.client.renderer.texture.TextureAtlasSprite;
+import net.minecraft.client.renderer.RenderPipelines;
import net.minecraft.network.chat.Component;
import net.minecraft.network.chat.MutableComponent;
import net.minecraft.resources.Identifier;
@@ -26,13 +23,12 @@
import twilightforest.TwilightForestMod;
import tamaized.beanification.Autowired;
import twilightforest.client.overlay.ItemDisplayOverlay;
-import twilightforest.components.entity.TFPortalAttachment;
+import twilightforest.client.overlay.PortalOverlay;
import twilightforest.components.item.OreScannerData;
import twilightforest.config.TFConfig;
import twilightforest.entity.passive.QuestRam;
import twilightforest.entity.passive.quest.ram.QuestingRamCurrentContext;
import twilightforest.events.HostileMountEvents;
-import twilightforest.init.TFBlocks;
import twilightforest.init.TFDataAttachments;
import twilightforest.init.TFDataComponents;
import twilightforest.init.TFItems;
@@ -57,9 +53,7 @@ protected static void registerOverlays(RegisterGuiLayersEvent event) {
LocalPlayer player = minecraft.player;
Gui gui = minecraft.gui;
if (player != null && !minecraft.options.hideGui && TFConfig.showQuestRamCrosshairIndicator) {
- RenderSystem.enableBlend();
renderIndicator(minecraft, graphics, gui, player, graphics.guiWidth(), graphics.guiHeight());
- RenderSystem.disableBlend();
}
});
event.registerAbove(VanillaGuiLayers.VEHICLE_HEALTH, TwilightForestMod.prefix("hostile_mount_hunger_bar"), (graphics, partialTicks) -> {
@@ -69,7 +63,7 @@ protected static void registerOverlays(RegisterGuiLayersEvent event) {
if (!minecraft.options.hideGui && minecraft.gameMode.canHurtPlayer() && player != null && HostileMountEvents.isRidingUnfriendly(player)) {
int xPos = graphics.guiWidth() / 2 + 91;
int yPos = graphics.guiHeight() - gui.rightHeight;
- gui.renderFood(graphics, player, yPos, xPos);
+ gui.extractFood(graphics, player, yPos, xPos);
gui.rightHeight += 10;
}
});
@@ -93,23 +87,10 @@ protected static void registerOverlays(RegisterGuiLayersEvent event) {
event.registerAboveAll(TwilightForestMod.prefix("portal_overlay"), (graphics, partialTick) -> {
Minecraft minecraft = Minecraft.getInstance();
- Window window = minecraft.getWindow();
LocalPlayer player = minecraft.player;
if (player != null) {
- TFPortalAttachment portal = player.getData(TFDataAttachments.TF_PORTAL_COOLDOWN);
- if (portal.getPortalTimer() > 0) {
- RenderSystem.disableDepthTest();
- RenderSystem.depthMask(false);
- RenderSystem.enableBlend();
- graphics.setColor(1.0F, 1.0F, 1.0F, (float) portal.getPortalTimer() / (float) TFPortalAttachment.MAX_TICKS);
- TextureAtlasSprite textureatlassprite = minecraft.getBlockRenderer().getBlockModelShaper().getParticleIcon(TFBlocks.TWILIGHT_PORTAL.get().defaultBlockState());
- graphics.blit(0, 0, -90, window.getGuiScaledWidth(), window.getGuiScaledHeight(), textureatlassprite);
- RenderSystem.disableBlend();
- RenderSystem.depthMask(true);
- RenderSystem.enableDepthTest();
- graphics.setColor(1.0F, 1.0F, 1.0F, 1.0F);
- }
+ PortalOverlay.render(graphics, minecraft, player);
}
});
@@ -120,21 +101,19 @@ protected static void registerOverlays(RegisterGuiLayersEvent event) {
});
}
- private static void renderIndicator(Minecraft minecraft, GuiGraphics graphics, Gui gui, Player player, int screenWidth, int screenHeight) {
+ private static void renderIndicator(Minecraft minecraft, GuiGraphicsExtractor graphics, Gui gui, Player player, int screenWidth, int screenHeight) {
if (minecraft.options.getCameraType().isFirstPerson() && (minecraft.gameMode.getPlayerMode() != GameType.SPECTATOR || gui.canRenderCrosshairForSpectator(minecraft.hitResult)) && minecraft.crosshairPickEntity instanceof QuestRam ram) {
- ItemStack stack = player.getInventory().getItem(player.getInventory().selected);
+ ItemStack stack = player.getInventory().getItem(player.getInventory().getSelectedSlot());
if (!stack.isEmpty()) {
for (var questEntry : questingRamCurrentContext.getContext().questItems().entrySet()) {
if (questEntry.getValue().test(stack)) {
- RenderSystem.blendFuncSeparate(GlStateManager.SourceFactor.ONE_MINUS_DST_COLOR, GlStateManager.DestFactor.ONE_MINUS_SRC_COLOR, GlStateManager.SourceFactor.ONE, GlStateManager.DestFactor.ZERO);
int j = ((screenHeight - 1) / 2) - 11;
int k = ((screenWidth - 1) / 2) - 3;
if (!ram.isColorPresent(questEntry.getKey())) {
- graphics.blitSprite(QUESTING_RAM_X_SPRITE, k, j, 7, 7);
+ graphics.blitSprite(RenderPipelines.CROSSHAIR, QUESTING_RAM_X_SPRITE, k, j, 7, 7);
} else {
- graphics.blitSprite(QUESTING_RAM_CHECK_SPRITE, k, j, 7, 7);
+ graphics.blitSprite(RenderPipelines.CROSSHAIR, QUESTING_RAM_CHECK_SPRITE, k, j, 7, 7);
}
- RenderSystem.defaultBlendFunc();
break;
}
}
@@ -142,14 +121,14 @@ private static void renderIndicator(Minecraft minecraft, GuiGraphics graphics, G
}
}
- private static void renderShieldCount(GuiGraphics graphics, Gui gui, int screenWidth, int screenHeight, int shieldCount) {
+ private static void renderShieldCount(GuiGraphicsExtractor graphics, Gui gui, int screenWidth, int screenHeight, int shieldCount) {
for (int i = 0; i < Math.min(shieldCount, 10); i++) {
- graphics.blitSprite(FORTIFICATION_SHIELD_SPRITE, screenWidth / 2 - 91 + (i * 8), screenHeight - gui.leftHeight, 9, 9);
+ graphics.blitSprite(RenderPipelines.GUI_TEXTURED, FORTIFICATION_SHIELD_SPRITE, screenWidth / 2 - 91 + (i * 8), screenHeight - gui.leftHeight, 9, 9);
}
gui.leftHeight += 10;
}
- private static void renderOreMeterStats(GuiGraphics graphics, Player player) {
+ private static void renderOreMeterStats(GuiGraphicsExtractor graphics, Player player) {
if (player.isHolding(TFItems.ORE_METER.get())) {
InteractionHand handToUse = player.getItemInHand(InteractionHand.MAIN_HAND).is(TFItems.ORE_METER.get()) ? InteractionHand.MAIN_HAND : InteractionHand.OFF_HAND;
ItemStack selectedMeter = player.getItemInHand(handToUse);
@@ -160,7 +139,7 @@ private static void renderOreMeterStats(GuiGraphics graphics, Player player) {
component = component.copy().append(".");
}
graphics.fill(0, 0, 56, 16, 0x9b000000);
- graphics.drawString(Minecraft.getInstance().font, component, 4, 4, 16777215, false);
+ graphics.text(Minecraft.getInstance().font, component, 4, 4, 16777215, false);
} else {
OreScannerData oreScannerData = selectedMeter.get(TFDataComponents.ORE_DATA);
@@ -189,7 +168,7 @@ private static void initTooltips(long id, int range, OreScannerData data) {
int totalScanned = data.totalScannedBlocks();
List headerRowTexts = ImmutableList.of(
- Component.translatable("misc.twilightforest.ore_meter_range", range, pos.x, pos.z),
+ Component.translatable("misc.twilightforest.ore_meter_range", range, pos.x(), pos.z()),
Component.translatable("misc.twilightforest.ore_meter_total", totalScanned)
);
@@ -294,11 +273,11 @@ public static ComponentColumn padding(int forcedExtraMaxWidthBySpaces) {
return new ComponentColumn(List.of(), forcedExtraMaxWidthBySpaces * Minecraft.getInstance().font.width(" "), ComponentAlignment.LEFT);
}
- private int renderColumn(GuiGraphics graphics, ComponentColumn column, int xOff, int yOff, int verticalTextPixelsAdvance) {
+ private int renderColumn(GuiGraphicsExtractor graphics, ComponentColumn column, int xOff, int yOff, int verticalTextPixelsAdvance) {
for (Component rowText : column.textRows) {
int textPixelWidth = Minecraft.getInstance().font.width(rowText);
int textXPos = xOff + this.textAlignment.getTextOffset(textPixelWidth, this.maxPixelWidth);
- graphics.drawString(Minecraft.getInstance().font, rowText, textXPos, yOff, 0x00_ff_ff_ff, false);
+ graphics.text(Minecraft.getInstance().font, rowText, textXPos, yOff, 0x00_ff_ff_ff, false);
yOff += verticalTextPixelsAdvance;
}
@@ -320,7 +299,7 @@ public static OreMeterInfoCache build(List headers, List 0;
+ if (lastImpulseZero && sameImpulseDirection && hasDoubleTapped && input.getMoveVector().x != 0) {
+ boolean isLeftSidestep = input.getMoveVector().x > 0;
if (TravellersGearLogic.tryPerformSidestep(localPlayer, isLeftSidestep)) {
localPlayer.connection.send(new PerformSidestepPacket(isLeftSidestep));
}
}
- localPlayer.setData(TFDataAttachments.LAST_HORIZONTAL_IMPULSE, input.leftImpulse);
- if (input.leftImpulse != 0) {
+ localPlayer.setData(TFDataAttachments.LAST_HORIZONTAL_IMPULSE, input.getMoveVector().x);
+ if (input.getMoveVector().x != 0) {
localPlayer.setData(TFDataAttachments.LAST_HORIZONTAL_WALKING_TIME, currentTime);
- localPlayer.setData(TFDataAttachments.LAST_NON_ZERO_HORIZONTAL_IMPULSE, input.leftImpulse);
+ localPlayer.setData(TFDataAttachments.LAST_NON_ZERO_HORIZONTAL_IMPULSE, input.getMoveVector().x);
}
}
@@ -242,40 +245,40 @@ private void slowZoomSensitivity(CalculatePlayerTurnEvent event) {
}
private boolean ignoreKeyEvent(InputEvent.Key event, KeyMapping key) {
- return !key.matches(event.getKey(), event.getScanCode()) || event.getAction() != InputConstants.PRESS || Minecraft.getInstance().screen != null;
+ return !key.matches(event.getKeyEvent()) || event.getAction() != InputConstants.PRESS || Minecraft.getInstance().screen != null;
}
@SuppressWarnings("unchecked") //meh
private void renderGlovesInFirstPerson(RenderArmEvent event) {
- if (!TFConfig.firstPersonGloveOverlay)
- return;
-
- AbstractClientPlayer player = event.getPlayer();
- ItemStack chestStack = player.getItemBySlot(EquipmentSlot.CHEST);
- if (!chestStack.has(TFDataComponents.TRAVELLERS_HAS_GLOVES) || chestStack.has(TFDataComponents.EMPERORS_CLOTH))
- return;
-
- Minecraft minecraft = Minecraft.getInstance();
- EntityRenderDispatcher renderDispatcher = minecraft.getEntityRenderDispatcher();
-
- if (!(renderDispatcher.getRenderer(player) instanceof AvatarRenderer avatarRenderer))
- return;
-
- if (!(IClientItemExtensions.of(TFItems.TRAVELLERS_GLOVES.get()).getHumanoidArmorModel(chestStack, EquipmentClientInfo.LayerType.HUMANOID, avatarRenderer.getModel()) instanceof HumanoidModel model))
- return;
-
- if (!(avatarRenderer.createRenderState(player, minecraft.getDeltaTracker().getGameTimeDeltaPartialTick(false)) instanceof AvatarRenderState renderState))
- return;
-
- renderState.attackTime = 0.0F;
- renderState.isCrouching = false;
- renderState.swimAmount = 0.0F;
- model.setupAnim(renderState);
-
- ModelPart armPart = event.getArm() == HumanoidArm.RIGHT ? model.rightArm : model.leftArm;
- armPart.xRot = 0.0F;
-
- Identifier gloveLocation = TwilightForestMod.prefix("textures/models/armor/travellers_layer_1.png");
- event.getSubmitNodeCollector().submitModelPart(armPart, event.getPoseStack(), RenderTypes.armorCutoutNoCull(gloveLocation), event.getPackedLight(), OverlayTexture.NO_OVERLAY, null);
- }
+ if (TFConfig.firstPersonGloveOverlay) {
+ AbstractClientPlayer player = event.getPlayer();
+ ItemStack chestStack = player.getItemBySlot(EquipmentSlot.CHEST);
+ if (chestStack.has(TFDataComponents.TRAVELLERS_HAS_GLOVES) && !chestStack.has(TFDataComponents.EMPERORS_CLOTH)) {
+ AvatarRenderer renderer = (AvatarRenderer) Minecraft.getInstance().getEntityRenderDispatcher().getRenderer(player);
+ HumanoidModel model = (HumanoidModel) IClientItemExtensions.of(TFItems.TRAVELLERS_GLOVES.get()).getHumanoidArmorModel(chestStack, EquipmentClientInfo.LayerType.HUMANOID, renderer.getModel());
+ ModelPart armPart = event.getArm() == HumanoidArm.RIGHT ? model.rightArm : model.leftArm;
+ AvatarRenderState renderState = renderer.createRenderState();
+ renderState.attackTime = 0.0F;
+ renderState.isCrouching = false;
+ renderState.swimAmount = 0.0F;
+ renderState.walkAnimationPos = 0.0F;
+ renderState.walkAnimationSpeed = 0.0F;
+ renderState.ageInTicks = 0.0F;
+ renderState.yRot = 0.0F;
+ renderState.xRot = 0.0F;
+ model.setupAnim(renderState);
+ armPart.xRot = 0.0F;
+ Identifier gloveLocation = TwilightForestMod.prefix("textures/models/armor/travellers_layer_1.png");
+ TextureAtlasSprite glove = Minecraft.getInstance().getAtlasManager().getAtlasOrThrow(AtlasIds.ARMOR_TRIMS).getSprite(gloveLocation);
+ event.getSubmitNodeCollector().submitModelPart(
+ armPart,
+ event.getPoseStack(),
+ RenderTypes.armorCutoutNoCull(gloveLocation),
+ event.getPackedLight(),
+ OverlayTexture.NO_OVERLAY,
+ glove
+ );
+ }
+ }
+ }
}
diff --git a/src/main/java/twilightforest/events/CapabilityEvents.java b/src/main/java/twilightforest/events/CapabilityEvents.java
index f487228b61..3eb553e588 100644
--- a/src/main/java/twilightforest/events/CapabilityEvents.java
+++ b/src/main/java/twilightforest/events/CapabilityEvents.java
@@ -1,6 +1,7 @@
package twilightforest.events;
import net.minecraft.core.BlockPos;
+import net.minecraft.core.GlobalPos;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.server.level.ServerPlayer;
@@ -9,6 +10,8 @@
import net.minecraft.world.entity.LivingEntity;
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.level.levelgen.Heightmap;
+import net.minecraft.world.level.storage.LevelData;
+import net.minecraft.world.phys.Vec3;
import net.neoforged.neoforge.common.NeoForge;
import net.neoforged.neoforge.event.entity.living.LivingIncomingDamageEvent;
import net.neoforged.neoforge.event.entity.player.PlayerEvent;
@@ -26,6 +29,8 @@
@Component
public class CapabilityEvents {
+ private static final int COMMON_INVULNERABLE_DURATION = 20;
+
@PostConstruct
private void setup() {
NeoForge.EVENT_BUS.addListener(this::updateShields);
@@ -43,7 +48,7 @@ private void updateShields(EntityTickEvent.Post event) {
private void updatePlayerCaps(PlayerTickEvent.Post event) {
if (event.getEntity().getData(TFDataAttachments.FEATHER_FAN)) {
- event.getEntity().setIgnoreFallDamageFromCurrentImpulse(true);
+ event.getEntity().setIgnoreFallDamageFromCurrentImpulse(true, Vec3.ZERO);
event.getEntity().currentImpulseImpactPos = event.getEntity().position();
if (event.getEntity().onGround() || event.getEntity().isSwimming() || event.getEntity().isInWater()) {
@@ -58,12 +63,12 @@ private void absorbShieldHits(LivingIncomingDamageEvent event) {
LivingEntity living = event.getEntity();
// shields
if (!living.level().isClientSide() && !event.getSource().is(DamageTypeTags.BYPASSES_ARMOR)) {
- FortificationShieldAttachment attachment = living.getData(TFDataAttachments.FORTIFICATION_SHIELDS);
+ FortificationShieldAttachment attachment = living.getData(TFDataAttachments.FORTIFICATION_SHIELDS);
if (attachment.shieldsLeft() > 0) {
if (living.invulnerableTime <= 0) {
attachment.breakShield(living, false);
FortificationShieldAttachment.addShieldBreakParticles(event.getSource(), living);
- living.invulnerableTime = living.invulnerableDuration;
+ living.invulnerableTime = COMMON_INVULNERABLE_DURATION;
}
event.setCanceled(true);
}
@@ -73,7 +78,7 @@ private void absorbShieldHits(LivingIncomingDamageEvent event) {
private void spawnInTFIfNecessary(PlayerEvent.PlayerRespawnEvent event) {
if (!(event.getEntity() instanceof ServerPlayer serverPlayer)) return;
- if (serverPlayer.getRespawnPosition() == null) {
+ if (serverPlayer.getRespawnConfig() == null) {
newSpawnInTwilightForest(serverPlayer);
}
}
@@ -92,16 +97,18 @@ public void playerLogsIn(PlayerEvent.PlayerLoggedInEvent event) {
private static void newSpawnInTwilightForest(ServerPlayer player) {
if (!TFConfig.newPlayersSpawnInTF)
return;
- ServerLevel level = player.getServer().getLevel(TFDimension.DIMENSION_KEY);
+ ServerLevel level = player.level().getServer().getLevel(TFDimension.DIMENSION_KEY);
if (level == null)
return;
BlockPos newDefaultSpawn = level.getHeightmapPos(Heightmap.Types.MOTION_BLOCKING_NO_LEAVES, player.blockPosition());
- player.changeDimension(TFConfig.portalForNewPlayerSpawn ?
+ player.teleport(TFConfig.portalForNewPlayerSpawn ?
TFTeleporter.createTransition(player, level, newDefaultSpawn, true) :
NoReturnTeleporter.createNoPortalTransition(level, player, newDefaultSpawn));
- player.setRespawnPosition(TFDimension.DIMENSION_KEY, newDefaultSpawn, player.getYRot(), true, false);
+ LevelData.RespawnData respawnData = new LevelData.RespawnData(new GlobalPos(TFDimension.DIMENSION_KEY, newDefaultSpawn), player.getYRot(), player.getXRot());
+ ServerPlayer.RespawnConfig respawnConfig = new ServerPlayer.RespawnConfig(respawnData, true);
+ player.setRespawnPosition(respawnConfig, false);
player.setData(TFDataAttachments.BANISHED_TO_TWILIGHT_FOREST, Unit.INSTANCE);
}
@@ -110,7 +117,7 @@ private static void dataFixLegacyBanish(ServerPlayer player) {
CompoundTag tagCompound = player.getPersistentData();
if (!tagCompound.contains(Player.PERSISTED_NBT_TAG))
return;
- CompoundTag playerData = tagCompound.getCompound(Player.PERSISTED_NBT_TAG);
+ CompoundTag playerData = tagCompound.getCompoundOrEmpty(Player.PERSISTED_NBT_TAG);
if (!playerData.contains("twilightforest_banished"))
return;
diff --git a/src/main/java/twilightforest/events/CharmEvents.java b/src/main/java/twilightforest/events/CharmEvents.java
index 0ab2c55876..b60c31c381 100644
--- a/src/main/java/twilightforest/events/CharmEvents.java
+++ b/src/main/java/twilightforest/events/CharmEvents.java
@@ -2,23 +2,35 @@
import net.minecraft.core.BlockPos;
import net.minecraft.core.Direction;
+import net.minecraft.core.HolderLookup;
import net.minecraft.core.NonNullList;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.nbt.ListTag;
+import net.minecraft.nbt.NbtOps;
import net.minecraft.network.chat.Component;
+import net.minecraft.server.level.ServerLevel;
import net.minecraft.server.level.ServerPlayer;
+import net.minecraft.util.ProblemReporter;
+import net.minecraft.world.ItemStackWithSlot;
import net.minecraft.world.effect.MobEffectInstance;
import net.minecraft.world.effect.MobEffects;
+import net.minecraft.world.entity.EntityEquipment;
+import net.minecraft.world.entity.EquipmentSlot;
import net.minecraft.world.entity.LivingEntity;
import net.minecraft.world.entity.player.Inventory;
import net.minecraft.world.entity.player.Player;
+import net.minecraft.world.entity.player.PlayerEquipment;
import net.minecraft.world.item.Item;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.item.component.ResolvableProfile;
-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.gamerules.GameRules;
import net.minecraft.world.level.material.FluidState;
+import net.minecraft.world.level.storage.TagValueInput;
+import net.minecraft.world.level.storage.TagValueOutput;
+import net.minecraft.world.level.storage.ValueInput;
+import net.minecraft.world.level.storage.ValueOutput;
import net.neoforged.bus.api.EventPriority;
import net.neoforged.fml.ModList;
import net.neoforged.neoforge.common.NeoForge;
@@ -33,13 +45,13 @@
import twilightforest.block.entity.SkullChestBlockEntity;
import twilightforest.compat.curios.CuriosCompat;
import twilightforest.config.TFConfig;
-import twilightforest.tags.TFItemTags;
import twilightforest.enums.BlockLoggingEnum;
import twilightforest.init.TFBlocks;
import twilightforest.init.TFItems;
import twilightforest.init.TFSounds;
import twilightforest.init.TFStats;
import twilightforest.network.SpawnCharmPacket;
+import twilightforest.tags.TFItemTags;
import twilightforest.util.TFItemStackUtils;
import java.util.ArrayList;
@@ -51,6 +63,7 @@ public class CharmEvents {
public static final String CHARM_INV_TAG = "TFCharmInventory";
public static final String CASKET_DAMAGE_TAG = "CasketDamage";
public static final String CONSUMED_CHARM_TAG = "CharmStack";
+ public static final EquipmentSlot[] ARMOR_SLOTS = new EquipmentSlot[]{EquipmentSlot.HEAD, EquipmentSlot.CHEST, EquipmentSlot.LEGS, EquipmentSlot.FEET};
@PostConstruct
private void setup() {
@@ -65,7 +78,7 @@ private void applyCharmOfLife(LivingDeathEvent event) {
//ensure our player is real and in survival before attempting anything
if (event.isCanceled() || living.level().isClientSide() || !(living instanceof Player player) || living instanceof FakePlayer ||
- player.isCreative() || player.isSpectator()) return;
+ player.isCreative() || player.isSpectator()) return;
if (handleCharmOfLife(player)) event.setCanceled(true); // Executes if the player had charms
}
@@ -76,14 +89,16 @@ private void applyKeepingAndCasket(LivingDeathEvent event) {
//ensure our player is real and in survival before attempting anything
if (event.isCanceled() || living.level().isClientSide() || !(living instanceof Player player) || living instanceof FakePlayer ||
- player.isCreative() || player.isSpectator()) return;
+ player.isCreative() || player.isSpectator()) return;
- if (!living.level().getGameRules().getBoolean(GameRules.RULE_KEEPINVENTORY)) {
- // Did the player recover? No? Let's give them their stuff based on the keeping charms
- handleCharmOfKeeping(player);
+ if (living.level() instanceof ServerLevel serverLevel) {
+ if (serverLevel.getGameRules().get(GameRules.KEEP_INVENTORY)) {
+ // Did the player recover? No? Let's give them their stuff based on the keeping charms
+ handleCharmOfKeeping(player);
- // Then let's store the rest of their stuff in the casket
- stockKeepsakeCasket(player);
+ // Then let's store the rest of their stuff in the casket
+ stockKeepsakeCasket(player);
+ }
}
}
@@ -108,7 +123,7 @@ private static boolean handleCharmOfLife(Player player) {
player.setHealth(player.getMaxHealth());
player.addEffect(new MobEffectInstance(MobEffects.REGENERATION, 600, 3));
- player.addEffect(new MobEffectInstance(MobEffects.DAMAGE_RESISTANCE, 600, 0));
+ player.addEffect(new MobEffectInstance(MobEffects.RESISTANCE, 600, 0));
player.addEffect(new MobEffectInstance(MobEffects.FIRE_RESISTANCE, 600, 0));
}
@@ -125,44 +140,50 @@ private static boolean handleCharmOfLife(Player player) {
private static void handleCharmOfKeeping(Player player) {
//create a fake inventory to organize our kept inventory in
- Inventory keepInventory = new Inventory(player);
- ListTag tagList = new ListTag();
+ Inventory keepInventory = new Inventory(player, new PlayerEquipment(player));
- if (!applyCharm(TFItems.CHARM_OF_KEEPING_3, keepInventory, player, player.getInventory().items)) {
- if (!applyCharm(TFItems.CHARM_OF_KEEPING_2, keepInventory, player, player.getInventory().items.subList(0, 9))) {
- int i = player.getInventory().selected;
+ if (!applyCharm(TFItems.CHARM_OF_KEEPING_3, keepInventory, player, player.getInventory().getNonEquipmentItems())) {
+ if (!applyCharm(TFItems.CHARM_OF_KEEPING_2, keepInventory, player, player.getInventory().getNonEquipmentItems().subList(0, 9))) {
+ int i = player.getInventory().getSelectedSlot();
if (Inventory.isHotbarSlot(i)) {
- applyCharm(TFItems.CHARM_OF_KEEPING_1, keepInventory, player, NonNullList.of(player.getInventory().items.get(i)));
+ applyCharm(TFItems.CHARM_OF_KEEPING_1, keepInventory, player, NonNullList.of(player.getInventory().getNonEquipmentItems().get(i)));
}
}
}
//keep all items in the kept_on_death tag. This allows modpacks to support other items to keep on death
- for (int i = 0; i < player.getInventory().items.size(); i++) {
- ItemStack stack = player.getInventory().items.get(i);
+ for (int i = 0; i < player.getInventory().getNonEquipmentItems().size(); i++) {
+ ItemStack stack = player.getInventory().getNonEquipmentItems().get(i);
if (stack.is(TFItemTags.KEPT_ON_DEATH)) {
- keepInventory.items.set(i, stack.copy());
- player.getInventory().items.set(i, ItemStack.EMPTY);
+ keepInventory.getNonEquipmentItems().set(i, stack.copy());
+ player.getInventory().getNonEquipmentItems().set(i, ItemStack.EMPTY);
}
}
- for (int i = 0; i < player.getInventory().armor.size(); i++) {
- ItemStack armor = player.getInventory().armor.get(i);
+ for (int i = 0; i < CharmEvents.ARMOR_SLOTS.length; i++) {
+ int slotIndex = i + Inventory.INVENTORY_SIZE;
+ ItemStack armor = player.getInventory().getItem(slotIndex);
if (armor.is(TFItemTags.KEPT_ON_DEATH)) {
- keepInventory.armor.set(i, armor.copy());
- player.getInventory().armor.set(i, ItemStack.EMPTY);
+ keepInventory.setItem(slotIndex, armor.copy());
+ player.getInventory().setItem(slotIndex, ItemStack.EMPTY);
}
}
- if (player.getInventory().offhand.getFirst().is(TFItemTags.KEPT_ON_DEATH)) {
- keepInventory.offhand.set(0, player.getInventory().offhand.getFirst().copy());
- player.getInventory().offhand.set(0, ItemStack.EMPTY);
+ if (player.getInventory().getItem(Inventory.SLOT_OFFHAND).is(TFItemTags.KEPT_ON_DEATH)) {
+ keepInventory.setItem(Inventory.SLOT_OFFHAND, player.getInventory().getItem(Inventory.SLOT_OFFHAND));
+ player.getInventory().setItem(Inventory.SLOT_OFFHAND, ItemStack.EMPTY);
}
//take our fake inventory and save it to the persistent player data.
//by saving it there we can guarantee we will always get all of our items back, even if the player logs out and back in.
if (!keepInventory.isEmpty()) {
- keepInventory.save(tagList);
+ ProblemReporter.Collector reporter = new ProblemReporter.Collector();
+ TagValueOutput valueOutput = TagValueOutput.createWithContext(reporter, player.level().registryAccess());
+ ValueOutput.TypedOutputList typedList = valueOutput.list("items", ItemStackWithSlot.CODEC);
+ keepInventory.save(typedList);
+ CompoundTag resultTag = valueOutput.buildResult();
+ ListTag tagList = resultTag.getListOrEmpty("items");
+ getPlayerData(player).put(CHARM_INV_TAG, tagList);
getPlayerData(player).put(CHARM_INV_TAG, tagList);
}
}
@@ -170,8 +191,10 @@ private static void handleCharmOfKeeping(Player player) {
private static boolean applyCharm(DeferredItem- charm, Inventory keptInventory, Player player, List inventorySlots) {
List mergedCheck = new ArrayList<>(inventorySlots);
//merge armor and offhand into check slots since theyll always be kept by a charm
- mergedCheck.addAll(player.getInventory().armor);
- mergedCheck.addAll(player.getInventory().offhand);
+ for (int i = 0; i < ARMOR_SLOTS.length; i++) {
+ mergedCheck.add(player.getInventory().getItem(Inventory.INVENTORY_SIZE + i));
+ }
+ mergedCheck.add(player.getInventory().getItem(Inventory.SLOT_OFFHAND));
//first, check all affected slots to make sure they arent empty.
//filter out the charm so it doesnt count towards keeping items if its the only thing we are holding
if (mergedCheck.stream().filter(stack -> !stack.is(charm)).allMatch(ItemStack::isEmpty)) return false;
@@ -179,9 +202,9 @@ private static boolean applyCharm(DeferredItem
- charm, Inventory keptInvent
//do we even have a charm? No? Then stop operation
if (!TFItemStackUtils.consumeInventoryItem(player, charm, getPlayerData(player), true) && !hasCharmCurio(charm.value(), player)) return false;
- boolean keptACasket = keepWholeListAndCheckCasket(keptInventory.items, inventorySlots, charm == TFItems.CHARM_OF_KEEPING_3);
- keptACasket = keepWholeListAndCheckCasket(keptInventory.armor, player.getInventory().armor, keptACasket);
- keepWholeListAndCheckCasket(keptInventory.offhand, player.getInventory().offhand, keptACasket);
+ boolean keptACasket = keepWholeListAndCheckCasket(keptInventory.getNonEquipmentItems(), inventorySlots, charm == TFItems.CHARM_OF_KEEPING_3);
+ keptACasket = keepWholeListAndCheckCasket(keptInventory, player.getInventory(), 0, Inventory.INVENTORY_SIZE, keptACasket);
+ keepWholeListAndCheckCasket(keptInventory, player.getInventory(), Inventory.SLOT_OFFHAND, Inventory.SLOT_OFFHAND + 1, keptACasket);
return true;
}
@@ -216,7 +239,7 @@ private static void stockKeepsakeCasket(Player player) {
BlockPos immutablePos = pos.immutable();
FluidState fluidState = level.getFluidState(immutablePos);
- int damage = getPlayerData(player).contains(CASKET_DAMAGE_TAG) ? getPlayerData(player).getInt(CASKET_DAMAGE_TAG) : 0;
+ int damage = getPlayerData(player).getIntOr(CASKET_DAMAGE_TAG, 0);
BlockState setState = TFBlocks.KEEPSAKE_CASKET.get().defaultBlockState()
.setValue(BlockLoggingEnum.MULTILOGGED, BlockLoggingEnum.getFromFluid(fluidState.getType()))
.setValue(KeepsakeCasketBlock.BREAKAGE, damage)
@@ -245,7 +268,7 @@ private static void stockKeepsakeCasket(Player player) {
if (TFConfig.casketUUIDLocking) {
//make it so only the player who died can open the chest if our config allows us
- casket.owner = new ResolvableProfile(player.getGameProfile());
+ casket.owner = ResolvableProfile.createResolved(player.getGameProfile());
} else {
casket.owner = null;
}
@@ -260,24 +283,34 @@ private static void stockKeepsakeCasket(Player player) {
// lets add our inventory exactly how it was on us
list.addAll(TFItemStackUtils.sortArmorForCasket(player));
- player.getInventory().armor.clear();
list.addAll(filler);
- list.addAll(player.getInventory().offhand);
- player.getInventory().offhand.clear();
+ list.add(player.getInventory().getItem(Inventory.SLOT_OFFHAND));
list.addAll(TFItemStackUtils.sortInvForCasket(player));
- player.getInventory().items.clear();
+ player.getInventory().clearContent();
casket.setItems(NonNullList.of(ItemStack.EMPTY, list.toArray(new ItemStack[casketCapacity])));
getPlayerData(player).remove(CASKET_DAMAGE_TAG);
} else {
//inventory is empty minus the casket: put the casket into the kept inventory
for (int i = 0; i < player.getInventory().getContainerSize(); i++) {
- if (player.getInventory().getItem(i).is(TFItems.KEEPSAKE_CASKET)) {
- Inventory tmp = new Inventory(player);
- tmp.load(getPlayerData(player).getList(CHARM_INV_TAG, 10));
+ if (player.getInventory().getItem(i).is(TFItems.KEEPSAKE_CASKET.get())) {
+ Inventory tmp = new Inventory(player, new PlayerEquipment(player));
+ ListTag savedListTag = getPlayerData(player).getListOrEmpty(CHARM_INV_TAG);
+ CompoundTag rootLoadTag = new CompoundTag();
+ rootLoadTag.put("items", savedListTag);
+ ProblemReporter.Collector loadReporter = new ProblemReporter.Collector();
+ ValueInput valueInput = TagValueInput.create(loadReporter, player.level().registryAccess(), rootLoadTag);
+ ValueInput.TypedInputList typedInputList = valueInput.listOrEmpty("items", ItemStackWithSlot.CODEC);
+ tmp.load(typedInputList);
tmp.add(player.getInventory().getItem(i).copy());
player.getInventory().setItem(i, ItemStack.EMPTY);
- getPlayerData(player).put(CHARM_INV_TAG, tmp.save(new ListTag()));
+ ProblemReporter.Collector saveReporter = new ProblemReporter.Collector();
+ TagValueOutput valueOutput = TagValueOutput.createWithContext(saveReporter, player.level().registryAccess());
+ ValueOutput.TypedOutputList typedOutputList = valueOutput.list("items", ItemStackWithSlot.CODEC);
+ tmp.save(typedOutputList);
+ CompoundTag resultTag = valueOutput.buildResult();
+ ListTag finalTagList = resultTag.getListOrEmpty("items");
+ getPlayerData(player).put(CHARM_INV_TAG, finalTagList);
}
}
}
@@ -293,15 +326,18 @@ private static void returnStoredItems(Player player) {
//check if our tag is in the persistent player data. If so, copy that inventory over to our own. Cloud storage at its finest!
CompoundTag playerData = getPlayerData(player);
if (!player.level().isClientSide() && playerData.contains(CHARM_INV_TAG)) {
- ListTag tagList = playerData.getList(CHARM_INV_TAG, 10);
+ ListTag tagList = playerData.getListOrEmpty(CHARM_INV_TAG);
TFItemStackUtils.loadNoClear(player.registryAccess(), tagList, player.getInventory());
- getPlayerData(player).getList(CHARM_INV_TAG, 10).clear();
+ getPlayerData(player).getListOrEmpty(CHARM_INV_TAG).clear();
getPlayerData(player).remove(CHARM_INV_TAG);
}
// spawn effect thingers
if (getPlayerData(player).contains(CONSUMED_CHARM_TAG)) {
- ItemStack stack = ItemStack.parseOptional(player.registryAccess(), (CompoundTag) getPlayerData(player).get(CONSUMED_CHARM_TAG));
+ CompoundTag tag = (CompoundTag) getPlayerData(player).get(CONSUMED_CHARM_TAG);
+ HolderLookup.Provider lookupProvider = player.registryAccess();
+ ItemStack parsedStack = ItemStack.CODEC.parse(lookupProvider.createSerializationContext(NbtOps.INSTANCE), tag).resultOrPartial().orElse(ItemStack.EMPTY);
+ ItemStack stack = tag.isEmpty() ? ItemStack.EMPTY : parsedStack;
if (player instanceof ServerPlayer serverPlayer) {
PacketDistributor.sendToPlayer(serverPlayer, new SpawnCharmPacket(stack, TFSounds.CHARM_KEEP.getKey()));
@@ -315,7 +351,7 @@ public static CompoundTag getPlayerData(Player player) {
if (!player.getPersistentData().contains(Player.PERSISTED_NBT_TAG)) {
player.getPersistentData().put(Player.PERSISTED_NBT_TAG, new CompoundTag());
}
- return player.getPersistentData().getCompound(Player.PERSISTED_NBT_TAG);
+ return player.getPersistentData().getCompoundOrEmpty(Player.PERSISTED_NBT_TAG);
}
//transfers a list of items to another
@@ -338,6 +374,26 @@ private static boolean keepWholeListAndCheckCasket(NonNullList transf
return keptCasket || skipCasketCheck;
}
+ //transfers content from some slots to another slots
+ private static boolean keepWholeListAndCheckCasket(Inventory transferTo, Inventory transferFrom, int fromSlot, int toSlot, boolean skipCasketCheck) {
+ boolean keptCasket = false;
+ for (int i = fromSlot; i < toSlot; i++) {
+ var item = transferFrom.getItem(i).copy();
+ if (skipCasketCheck || (!item.is(TFItems.KEEPSAKE_CASKET) || keptCasket)) {
+ transferTo.setItem(i, item);
+ transferFrom.setItem(i, ItemStack.EMPTY);
+ } else {
+ keptCasket = true;
+ if (item.getCount() > 1) {
+ item.shrink(1);
+ transferTo.setItem(i, item);
+ transferFrom.setItem(i, item.copyWithCount(1));
+ }
+ }
+ }
+ return keptCasket || skipCasketCheck;
+ }
+
private static boolean hasCharmCurio(Item item, Player player) {
if (ModList.get().isLoaded("curios")) {
return CuriosCompat.findAndConsumeCurio(item, player);
diff --git a/src/main/java/twilightforest/events/EntityEvents.java b/src/main/java/twilightforest/events/EntityEvents.java
index b24a523923..bfaa7f4328 100644
--- a/src/main/java/twilightforest/events/EntityEvents.java
+++ b/src/main/java/twilightforest/events/EntityEvents.java
@@ -20,9 +20,10 @@
import net.minecraft.world.entity.*;
import net.minecraft.world.entity.ai.attributes.AttributeModifier;
import net.minecraft.world.entity.ai.attributes.Attributes;
+import net.minecraft.world.entity.ai.goal.Goal;
import net.minecraft.world.entity.item.ItemEntity;
import net.minecraft.world.entity.monster.EnderMan;
-import net.minecraft.world.entity.monster.Zombie;
+import net.minecraft.world.entity.monster.zombie.Zombie;
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.entity.projectile.Projectile;
import net.minecraft.world.entity.projectile.ProjectileDeflection;
@@ -34,10 +35,7 @@
import net.minecraft.world.level.Level;
import net.minecraft.world.level.StructureManager;
import net.minecraft.world.level.biome.MobSpawnSettings;
-import net.minecraft.world.level.block.AbstractSkullBlock;
-import net.minecraft.world.level.block.Block;
-import net.minecraft.world.level.block.SkullBlock;
-import net.minecraft.world.level.block.WallSkullBlock;
+import net.minecraft.world.level.block.*;
import net.minecraft.world.level.block.entity.BlockEntity;
import net.minecraft.world.level.block.entity.SkullBlockEntity;
import net.minecraft.world.level.block.state.BlockState;
@@ -46,6 +44,7 @@
import net.minecraft.world.phys.AABB;
import net.minecraft.world.phys.EntityHitResult;
import net.neoforged.fml.ModList;
+import net.neoforged.neoforge.client.network.ClientPacketDistributor;
import net.neoforged.neoforge.common.NeoForge;
import net.neoforged.neoforge.common.damagesource.DamageContainer;
import net.neoforged.neoforge.event.EventHooks;
@@ -55,12 +54,10 @@
import net.neoforged.neoforge.event.entity.living.*;
import net.neoforged.neoforge.event.entity.player.AdvancementEvent;
import net.neoforged.neoforge.event.entity.player.AttackEntityEvent;
-import net.neoforged.neoforge.event.entity.player.PlayerEvent;
import net.neoforged.neoforge.event.entity.player.PlayerInteractEvent;
-import net.neoforged.neoforge.event.level.BlockEvent;
import net.neoforged.neoforge.event.level.ExplosionEvent;
import net.neoforged.neoforge.event.level.LevelEvent;
-import net.neoforged.neoforge.items.ItemHandlerHelper;
+import net.neoforged.neoforge.event.level.block.BreakBlockEvent;
import net.neoforged.neoforge.network.PacketDistributor;
import tamaized.beanification.PostConstruct;
import twilightforest.TwilightForestMod;
@@ -71,7 +68,6 @@
import twilightforest.block.entity.SkullChestBlockEntity;
import twilightforest.components.item.SkullCandles;
import twilightforest.config.TFConfig;
-import twilightforest.tags.TFEntityTypeTags;
import twilightforest.enchantment.ApplyFrostedEffect;
import twilightforest.entity.passive.quest.ram.QuestingRamCurrentContext;
import twilightforest.entity.projectile.ITFProjectile;
@@ -81,6 +77,7 @@
import twilightforest.item.YetiArmorItem;
import twilightforest.network.SyncQuestsPacket;
import twilightforest.network.WipeOreMeterPacket;
+import twilightforest.tags.TFEntityTypeTags;
import twilightforest.util.datamaps.EntityTransformation;
import twilightforest.util.entities.EntityUtil;
import twilightforest.util.entities.OminousFireDamageSource;
@@ -90,6 +87,7 @@
import twilightforest.world.components.structures.util.ControlledSpawns;
import twilightforest.world.components.structures.util.ValidatedSpawnLocations;
+import java.net.URI;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
@@ -102,6 +100,7 @@ public class EntityEvents {
private QuestingRamCurrentContext questingRamCurrentContext;
private static final boolean SHIELD_PARRY_MOD_LOADED = ModList.get().isLoaded("parry");
+ private static final EquipmentSlot[] ARMOR_SLOTS = new EquipmentSlot[]{EquipmentSlot.HEAD, EquipmentSlot.CHEST, EquipmentSlot.LEGS, EquipmentSlot.FEET};
@PostConstruct
private void setup() {
@@ -133,13 +132,13 @@ private void ominousFireConversion(LivingDeathEvent event) {
EntityTransformation dataMap = event.getEntity().getType().builtInRegistryHolder().getData(TFDataMaps.OMINOUS_FIRE);
if (event.getEntity() instanceof ServerPlayer player) {
- var zombie = EntityType.ZOMBIE.create(player.level());
+ var zombie = EntityType.ZOMBIE.create(player.level(), EntitySpawnReason.CONVERSION);
zombie.setData(TFDataAttachments.ZOMBIFIED_PLAYER, player.getGameProfile());
zombie.setCustomName(player.getName());
zombie.copyPosition(player);
zombie.setCanPickUpLoot(true);
zombie.setBaby(false);
- EventHooks.finalizeMobSpawn(zombie, player.serverLevel(), player.level().getCurrentDifficultyAt(player.blockPosition()), EntitySpawnReason.CONVERSION, null);
+ EventHooks.finalizeMobSpawn(zombie, player.level(), player.level().getCurrentDifficultyAt(player.blockPosition()), EntitySpawnReason.CONVERSION, null);
player.level().addFreshEntity(zombie);
} else if (dataMap != null && event.getEntity().level() instanceof ServerLevel) {
EntityUtil.convertEntity(event.getEntity(), dataMap.result());
@@ -157,7 +156,7 @@ private void zombifiedPlayerAttacks(LivingIncomingDamageEvent event) {
private void alertPlayerCastleIsWIP(AdvancementEvent.AdvancementEarnEvent event) {
if (event.getAdvancement().id().equals(TwilightForestMod.prefix("progression_end"))) {
- event.getEntity().sendSystemMessage(Component.translatable("gui.twilightforest.progression_end.message", Component.translatable("gui.twilightforest.progression_end.discord").withStyle(style -> style.withColor(ChatFormatting.BLUE).applyFormat(ChatFormatting.UNDERLINE).withClickEvent(new ClickEvent(ClickEvent.Action.OPEN_URL, "https://discord.experiment115.com/")))));
+ event.getEntity().sendSystemMessage(Component.translatable("gui.twilightforest.progression_end.message", Component.translatable("gui.twilightforest.progression_end.discord").withStyle(style -> style.withColor(ChatFormatting.BLUE).applyFormat(ChatFormatting.UNDERLINE).withClickEvent(new ClickEvent.OpenUrl(URI.create("https://discord.experiment115.com/"))))));
}
}
@@ -180,10 +179,17 @@ private void attachLeadToWroughtFence(PlayerInteractEvent.RightClickBlock event)
private void wipeOreMeterOnLeftClick(PlayerInteractEvent.LeftClickEmpty event) {
ItemStack item = event.getItemStack();
if (item.is(TFItems.ORE_METER.get()) && (item.has(TFDataComponents.ORE_DATA) || item.has(TFDataComponents.ORE_FILTER))) {
- PacketDistributor.sendToServer(new WipeOreMeterPacket(event.getHand()));
+ ClientPacketDistributor.sendToServer(new WipeOreMeterPacket(event.getHand()));
item.remove(TFDataComponents.ORE_DATA);
item.remove(TFDataComponents.ORE_FILTER);
- event.getLevel().playSound(event.getEntity(), event.getEntity().blockPosition(), TFSounds.ORE_METER_CLEAR.get(), SoundSource.PLAYERS, 1.25F, event.getLevel().getRandom().nextFloat() * 0.2F + 0.6F);
+ event.getLevel().playSound(
+ event.getEntity(),
+ event.getEntity().blockPosition(),
+ TFSounds.ORE_METER_CLEAR.get(),
+ SoundSource.PLAYERS,
+ 1.25F,
+ event.getLevel().getRandom().nextFloat() * 0.2F + 0.6F
+ );
}
}
@@ -198,7 +204,7 @@ private void entityHurts(LivingDamageEvent.Post event) {
int chillLevel = getGearCoverage(living, true);
if (fireLevel > 0 && living.getRandom().nextInt(25) < fireLevel && !trueSource.fireImmune()) {
- trueSource.igniteForSeconds(fireLevel / 2);
+ trueSource.igniteForSeconds((float) fireLevel / 2);
}
if (trueSource instanceof LivingEntity target) {
@@ -216,14 +222,14 @@ private void entityHurts(LivingDamageEvent.Post event) {
}
//if our casket is owned by someone and that player isnt the one breaking it, stop them
- private void onCasketBreak(BlockEvent.BreakEvent event) {
+ private void onCasketBreak(BreakBlockEvent event) {
Player player = event.getPlayer();
if (event.getState().getBlock() instanceof SkullChestBlock) {
BlockEntity te = event.getLevel().getBlockEntity(event.getPos());
if (te instanceof SkullChestBlockEntity casket) {
ResolvableProfile checker = casket.owner;
if (checker != null && !casket.isEmpty()) {
- if (!Commands.LEVEL_ADMINS.check(player.permissions()) || !player.getGameProfile().equals(checker.gameProfile())) {
+ if (!Commands.LEVEL_ADMINS.check(player.permissions()) || !player.getGameProfile().equals(checker.partialProfile())) {
event.setCanceled(true);
}
}
@@ -251,13 +257,13 @@ private void reduceFrostedEffectIfOnFire(LivingIncomingDamageEvent event) {
private void onParryProjectile(ProjectileImpactEvent event) {
final Projectile projectile = event.getProjectile();
- if (!projectile.getCommandSenderWorld().isClientSide() && !SHIELD_PARRY_MOD_LOADED && (TFConfig.parryNonTwilightAttacks || projectile instanceof ITFProjectile)) {
+ if (!projectile.level().isClientSide() && !SHIELD_PARRY_MOD_LOADED && (TFConfig.parryNonTwilightAttacks || projectile instanceof ITFProjectile)) {
if (event.getRayTraceResult() instanceof EntityHitResult result) {
Entity entity = result.getEntity();
if (entity instanceof LivingEntity entityBlocking) {
if (entityBlocking.isBlocking() && entityBlocking.getUseItem().getUseDuration(entityBlocking) - entityBlocking.getUseItemRemainingTicks() <= TFConfig.shieldParryTicks) {
- projectile.deflect(ProjectileDeflection.AIM_DEFLECT, entityBlocking, entityBlocking, true);
+ projectile.deflect(ProjectileDeflection.AIM_DEFLECT, entityBlocking, EntityReference.of(entityBlocking), true);
event.setCanceled(true);
}
}
@@ -323,8 +329,9 @@ private void createSkullCandle(PlayerInteractEvent.RightClickBlock event) {
private static void makeSkullCandle(PlayerInteractEvent.RightClickBlock event, Block newBlock) {
ResolvableProfile profile = null;
Level level = event.getLevel();
- if (level.getBlockEntity(event.getPos()) instanceof SkullBlockEntity skull)
+ if (level.getBlockEntity(event.getPos()) instanceof SkullBlockEntity skull) {
profile = skull.getOwnerProfile();
+ }
level.playSound(null, event.getPos(), SoundEvents.CANDLE_PLACE, SoundSource.BLOCKS, 1.0F, 1.0F);
level.setBlockAndUpdate(event.getPos(), newBlock.withPropertiesOf(level.getBlockState(event.getPos()))
.setValue(AbstractSkullCandleBlock.LIGHTING, LightableBlock.Lighting.NONE));
@@ -343,7 +350,8 @@ private static void makeSkullCandle(PlayerInteractEvent.RightClickBlock event, B
public static int getGearCoverage(LivingEntity entity, boolean yeti) {
int amount = 0;
- for (ItemStack armor : entity.getArmorSlots()) {
+ for (EquipmentSlot armorSlot : ARMOR_SLOTS) {
+ ItemStack armor = entity.getItemBySlot(armorSlot);
if (!armor.isEmpty() && (yeti ? armor.getItem() instanceof YetiArmorItem : armor.getItem() instanceof FieryArmorItem)) {
amount++;
}
@@ -429,7 +437,7 @@ private void removeCastleTextIfAttacked(AttackEntityEvent event) {
// For clearing our Display text entities at the Final Castle Gazebo, there's no other way to remove them otherwise
// The tag distinguishes our Interaction entities from other Mods' utilization
if (event.getTarget().level() instanceof ServerLevel level && event.getTarget() instanceof Interaction interaction
- && interaction.getTags().contains(FinalCastleBossGazeboComponent.INTERACTION_TAG)) {
+ && interaction.entityTags().contains(FinalCastleBossGazeboComponent.INTERACTION_TAG)) {
AABB bounds = interaction.getBoundingBox();
level.getEntities(interaction, bounds, e -> e instanceof Display).forEach(Entity::discard);
interaction.discard();
@@ -507,29 +515,51 @@ private void handleLeashPathingOverrides(EntityJoinLevelEvent event) {
private void stopEndermenFromGrabbingBlocksInTF(EntityJoinLevelEvent event) {
if (event.getEntity() instanceof EnderMan enderMan) {
enderMan.goalSelector.getAvailableGoals().stream()
- .filter(g -> g.getGoal() instanceof EnderMan.EndermanTakeBlockGoal)
+ .filter(g -> g.getGoal().getClass().getName().endsWith("EndermanTakeBlockGoal"))
.findAny()
.ifPresent(g -> {
enderMan.goalSelector.removeGoal(g.getGoal());
- enderMan.goalSelector.addGoal(g.getPriority(), new ExtendedEndermanTakeBlockGoal((EnderMan.EndermanTakeBlockGoal) g.getGoal(), enderMan));
+ enderMan.goalSelector.addGoal(g.getPriority(), new ExtendedEndermanTakeBlockGoal(g.getGoal(), enderMan));
});
}
}
- static class ExtendedEndermanTakeBlockGoal extends EnderMan.EndermanTakeBlockGoal {
-
- private final EnderMan.EndermanTakeBlockGoal delegate;
+ static class ExtendedEndermanTakeBlockGoal extends Goal {
+ private final Goal delegate;
private final EnderMan enderman;
- public ExtendedEndermanTakeBlockGoal(EnderMan.EndermanTakeBlockGoal delegate, EnderMan enderman) {
- super(enderman);
+ public ExtendedEndermanTakeBlockGoal(Goal delegate, EnderMan enderman) {
this.delegate = delegate;
this.enderman = enderman;
+ this.setFlags(delegate.getFlags());
}
@Override
public boolean canUse() {
- return this.delegate.canUse() && !this.enderman.level().dimensionTypeRegistration().is(TFDimensionData.TWILIGHT_DIM_TYPE);
+ if (this.enderman.level().dimensionTypeRegistration().is(TFDimensionData.TWILIGHT_DIM_TYPE)) {
+ return false;
+ }
+ return this.delegate.canUse();
+ }
+
+ @Override
+ public boolean canContinueToUse() {
+ return this.delegate.canContinueToUse();
+ }
+
+ @Override
+ public boolean isInterruptable() {
+ return this.delegate.isInterruptable();
+ }
+
+ @Override
+ public void start() {
+ this.delegate.start();
+ }
+
+ @Override
+ public void stop() {
+ this.delegate.stop();
}
@Override
diff --git a/src/main/java/twilightforest/events/MiscEvents.java b/src/main/java/twilightforest/events/MiscEvents.java
index 224fe77dd3..8a955e8690 100644
--- a/src/main/java/twilightforest/events/MiscEvents.java
+++ b/src/main/java/twilightforest/events/MiscEvents.java
@@ -91,7 +91,7 @@ private void addTomesToLecterns(PlayerInteractEvent.RightClickBlock event) {
Player player = event.getEntity();
ItemStack stack = player.getItemInHand(event.getHand());
- if (!(stack.getItem() instanceof SpawnEggItem spawnEggItem) || spawnEggItem.getType(stack) != TFEntities.DEATH_TOME.get())
+ if (!(stack.getItem() instanceof SpawnEggItem) || SpawnEggItem.getType(stack) != TFEntities.DEATH_TOME.get())
return;
BlockPos pos = event.getPos();
@@ -103,7 +103,7 @@ private void addTomesToLecterns(PlayerInteractEvent.RightClickBlock event) {
level.playSound(null, pos, SoundEvents.BOOK_PUT, SoundSource.BLOCKS, 1.0F, 1.0F);
if (level instanceof ServerLevel serverLevel) {
- DeathTome tome = TFEntities.DEATH_TOME.get().spawn(serverLevel, stack, player, pos.below(), EntitySpawnReason.SPAWN_EGG, true, false);
+ DeathTome tome = TFEntities.DEATH_TOME.get().spawn(serverLevel, stack, player, pos.below(), EntitySpawnReason.SPAWN_ITEM_USE, true, false);
if (tome != null) {
stack.consume(1, player);
serverLevel.gameEvent(player, GameEvent.ENTITY_PLACE, pos);
diff --git a/src/main/java/twilightforest/events/ProgressionEvents.java b/src/main/java/twilightforest/events/ProgressionEvents.java
index 3b991f6753..d8f001408d 100644
--- a/src/main/java/twilightforest/events/ProgressionEvents.java
+++ b/src/main/java/twilightforest/events/ProgressionEvents.java
@@ -31,6 +31,7 @@
import net.neoforged.neoforge.event.entity.player.PlayerInteractEvent;
import net.neoforged.neoforge.event.level.BlockEvent;
import net.neoforged.neoforge.event.level.GameRuleChangedEvent;
+import net.neoforged.neoforge.event.level.block.BreakBlockEvent;
import net.neoforged.neoforge.event.tick.PlayerTickEvent;
import net.neoforged.neoforge.network.PacketDistributor;
import net.neoforged.neoforge.server.ServerLifecycleHooks;
@@ -90,7 +91,7 @@ private void gameRuleChanged(GameRuleChangedEvent event) {
/**
* Check if the player is trying to break a block in a structure that's considered unbreakable for progression reasons
*/
- private void preventLockedAreaBlockBreaking(BlockEvent.BreakEvent event) {
+ private void preventLockedAreaBlockBreaking(BreakBlockEvent event) {
if (!(event.getLevel() instanceof ServerLevel level) || event.isCanceled()) return;
BlockPos pos = event.getPos();
@@ -264,7 +265,7 @@ private static void checkForPortalCreation(ServerPlayer player, ServerLevel leve
if (!TFPortalBlock.isPlayerNotifiedOfRequirement(player)) {
// .doesPlayerHaveRequiredAdvancement null-checks already, so we can skip null-checking the `requirement`
DisplayInfo info = requirement.value().display().orElse(null);
- PacketDistributor.sendToPlayer(player, info == null ? new MissingAdvancementToastPacket(net.minecraft.network.chat.Component.translatable("twilightforest.ui.advancement.no_title"), new ItemStack(TFBlocks.TWILIGHT_PORTAL_MINIATURE_STRUCTURE.get())) : new MissingAdvancementToastPacket(info.getTitle(), info.getIcon()));
+ PacketDistributor.sendToPlayer(player, info == null ? new MissingAdvancementToastPacket(net.minecraft.network.chat.Component.translatable("twilightforest.ui.advancement.no_title"), new ItemStack(TFBlocks.TWILIGHT_PORTAL_MINIATURE_STRUCTURE.get())) : new MissingAdvancementToastPacket(info.getTitle(), info.getIcon().create()));
TFPortalBlock.playerNotifiedOfRequirement(player);
}
@@ -279,7 +280,7 @@ private static void checkForPortalCreation(ServerPlayer player, ServerLevel leve
double vy = rand.nextGaussian() * 0.02D;
double vz = rand.nextGaussian() * 0.02D;
- level.addParticle(ParticleTypes.EFFECT, qualified.getX(), qualified.getY() + 0.2, qualified.getZ(), vx, vy, vz);
+ level.addParticle(() -> ParticleTypes.EFFECT, qualified.getX(), qualified.getY() + 0.2, qualified.getZ(), vx, vy, vz);
}
if (TFBlocks.TWILIGHT_PORTAL.get().tryToCreatePortal(level, qualified.blockPosition(), qualified, player))
diff --git a/src/main/java/twilightforest/events/RegistrationEvents.java b/src/main/java/twilightforest/events/RegistrationEvents.java
index 1dd682033e..771553cff1 100644
--- a/src/main/java/twilightforest/events/RegistrationEvents.java
+++ b/src/main/java/twilightforest/events/RegistrationEvents.java
@@ -3,17 +3,16 @@
import com.google.common.collect.Maps;
import net.minecraft.core.Direction;
import net.minecraft.core.Registry;
-import net.minecraft.core.cauldron.CauldronInteraction;
import net.minecraft.core.registries.BuiltInRegistries;
import net.minecraft.core.registries.Registries;
import net.minecraft.world.entity.Mob;
import net.minecraft.world.entity.SpawnPlacementTypes;
import net.minecraft.world.entity.animal.Animal;
-import net.minecraft.world.entity.animal.Sheep;
-import net.minecraft.world.entity.monster.AbstractSkeleton;
+import net.minecraft.world.entity.animal.sheep.Sheep;
import net.minecraft.world.entity.monster.Monster;
-import net.minecraft.world.entity.monster.Spider;
-import net.minecraft.world.entity.monster.Zombie;
+import net.minecraft.world.entity.monster.skeleton.AbstractSkeleton;
+import net.minecraft.world.entity.monster.spider.Spider;
+import net.minecraft.world.entity.monster.zombie.Zombie;
import net.minecraft.world.item.AxeItem;
import net.minecraft.world.item.Items;
import net.minecraft.world.level.block.Blocks;
@@ -221,8 +220,8 @@ public void setupPackets(RegisterPayloadHandlersEvent event) {
registrar.playToClient(MissingAdvancementToastPacket.TYPE, MissingAdvancementToastPacket.STREAM_CODEC, MissingAdvancementToastPacket::handle);
registrar.playToClient(MovePlayerPacket.TYPE, MovePlayerPacket.STREAM_CODEC, MovePlayerPacket::handle);
registrar.playToClient(ParticlePacket.TYPE, ParticlePacket.STREAM_CODEC, ParticlePacket::handle);
- registrar.playBidirectional(GogglesZoomPacket.TYPE, GogglesZoomPacket.STREAM_CODEC, GogglesZoomPacket::handle);
- registrar.playBidirectional(GradualGlidePacket.TYPE, GradualGlidePacket.STREAM_CODEC, GradualGlidePacket::handle);
+ registrar.playToServer(GogglesZoomPacket.TYPE, GogglesZoomPacket.STREAM_CODEC, GogglesZoomPacket::handle);
+ registrar.playBidirectional(GradualGlidePacket.TYPE, GradualGlidePacket.STREAM_CODEC, GradualGlidePacket::handle, GradualGlidePacket::handle);
registrar.playToServer(PerformDoubleJumpPacket.TYPE, PerformDoubleJumpPacket.STREAM_CODEC, PerformDoubleJumpPacket::handle);
registrar.playToServer(SwapHotbarPacket.TYPE, SwapHotbarPacket.STREAM_CODEC, SwapHotbarPacket::handle);
registrar.playToServer(PerformSidestepPacket.TYPE, PerformSidestepPacket.STREAM_CODEC, PerformSidestepPacket::handle);
@@ -249,10 +248,11 @@ public void init(FMLCommonSetupEvent evt) {
TFDispenserBehaviors.init();
TFStats.init();
- CauldronInteraction.WATER.map().put(TFItems.ARCTIC_HELMET.get(), CauldronInteraction.DYED_ITEM);
- CauldronInteraction.WATER.map().put(TFItems.ARCTIC_CHESTPLATE.get(), CauldronInteraction.DYED_ITEM);
- CauldronInteraction.WATER.map().put(TFItems.ARCTIC_LEGGINGS.get(), CauldronInteraction.DYED_ITEM);
- CauldronInteraction.WATER.map().put(TFItems.ARCTIC_BOOTS.get(), CauldronInteraction.DYED_ITEM);
+ // No analogs in 26.1.x
+// CauldronInteractions.WATER.map().put(TFItems.ARCTIC_HELMET.get(), CauldronInteractions.DYED_ITEM);
+// CauldronInteractions.WATER.map().put(TFItems.ARCTIC_CHESTPLATE.get(), CauldronInteractions.DYED_ITEM);
+// CauldronInteractions.WATER.map().put(TFItems.ARCTIC_LEGGINGS.get(), CauldronInteractions.DYED_ITEM);
+// CauldronInteractions.WATER.map().put(TFItems.ARCTIC_BOOTS.get(), CauldronInteractions.DYED_ITEM);
AxeItem.STRIPPABLES = Maps.newHashMap(AxeItem.STRIPPABLES);
AxeItem.STRIPPABLES.put(TFBlocks.TWILIGHT_OAK_LOG.get(), TFBlocks.STRIPPED_TWILIGHT_OAK_LOG.get());
diff --git a/src/main/java/twilightforest/events/ToolEvents.java b/src/main/java/twilightforest/events/ToolEvents.java
index 1ac62fc537..a019bf4eea 100644
--- a/src/main/java/twilightforest/events/ToolEvents.java
+++ b/src/main/java/twilightforest/events/ToolEvents.java
@@ -1,6 +1,7 @@
package twilightforest.events;
import net.minecraft.core.BlockPos;
+import net.minecraft.core.HolderSet;
import net.minecraft.core.registries.BuiltInRegistries;
import net.minecraft.core.registries.Registries;
import net.minecraft.network.protocol.game.ClientboundAnimatePacket;
@@ -34,16 +35,17 @@
import net.neoforged.neoforge.event.entity.living.LivingIncomingDamageEvent;
import net.neoforged.neoforge.event.entity.living.MobEffectEvent;
import net.neoforged.neoforge.event.level.BlockEvent;
+import net.neoforged.neoforge.event.level.block.BreakBlockEvent;
import org.jetbrains.annotations.Nullable;
import tamaized.beanification.Component;
import tamaized.beanification.PostConstruct;
import twilightforest.block.GiantBlock;
import twilightforest.components.entity.GiantPickaxeMiningAttachment;
-import twilightforest.tags.TFBlockTags;
import twilightforest.init.TFDataAttachments;
import twilightforest.init.TFItems;
import twilightforest.item.*;
import twilightforest.loot.modifiers.GiantToolGroupingModifier;
+import twilightforest.tags.TFBlockTags;
import java.util.List;
@@ -82,7 +84,7 @@ private void onEnderBowHit(ProjectileImpactEvent evt) {
player.invulnerableTime = 40;
player.level().broadcastEntityEvent(player, (byte) 46);
if (living.isPassenger() && living.getVehicle() != null) {
- player.startRiding(living.getVehicle(), true);
+ player.startRiding(living.getVehicle(), true, false);
living.stopRiding();
}
player.playSound(SoundEvents.CHORUS_FRUIT_TELEPORT, 1.0F, 1.0F);
@@ -92,7 +94,7 @@ private void onEnderBowHit(ProjectileImpactEvent evt) {
living.teleportTo(sourceX, sourceY, sourceZ);
living.level().broadcastEntityEvent(player, (byte) 46);
if (playerVehicle != null) {
- living.startRiding(playerVehicle, true);
+ living.startRiding(playerVehicle, true, false);
player.stopRiding();
}
living.playSound(SoundEvents.CHORUS_FRUIT_TELEPORT, 1.0F, 1.0F);
@@ -123,11 +125,11 @@ private void doKnightmetalToolLogic(LivingIncomingDamageEvent event) {
container.setNewDamage(container.getNewDamage() + KNIGHTMETAL_BONUS_DAMAGE);
}
// enchantment attack sparkles
- ((ServerLevel) target.level()).getChunkSource().broadcastAndSend(target, new ClientboundAnimatePacket(target, 5));
+ ((ServerLevel) target.level()).getChunkSource().sendToTrackingPlayers(target, new ClientboundAnimatePacket(target, 5));
} else if (target.getArmorValue() == 0 && weapon.is(TFItems.KNIGHTMETAL_AXE.get())) {
container.setNewDamage(container.getOriginalDamage() + KNIGHTMETAL_BONUS_DAMAGE);
// enchantment attack sparkles
- ((ServerLevel) target.level()).getChunkSource().broadcastAndSend(target, new ClientboundAnimatePacket(target, 5));
+ ((ServerLevel) target.level()).getChunkSource().sendToTrackingPlayers(target, new ClientboundAnimatePacket(target, 5));
}
}
}
@@ -143,13 +145,13 @@ private void addExtraAxeChargingDamage(LivingIncomingDamageEvent event) {
if (!weapon.isEmpty() && weapon.getItem() instanceof MinotaurAxeItem) {
container.setNewDamage(container.getNewDamage() + MINOTAUR_AXE_BONUS_DAMAGE);
// enchantment attack sparkles
- ((ServerLevel) target.level()).getChunkSource().broadcastAndSend(target, new ClientboundAnimatePacket(target, 5));
+ ((ServerLevel) target.level()).getChunkSource().sendToTrackingPlayers(target, new ClientboundAnimatePacket(target, 5));
}
}
}
}
- private void damageNonMazebreakerToolsMore(BlockEvent.BreakEvent event) {
+ private void damageNonMazebreakerToolsMore(BreakBlockEvent event) {
ItemStack stack = event.getPlayer().getMainHandItem();
if (event.getState().is(TFBlockTags.MAZEBREAKER_ACCELERATED)) {
if (stack.isDamageableItem() && !(stack.getItem() instanceof MazebreakerPickItem)) {
@@ -159,12 +161,12 @@ private void damageNonMazebreakerToolsMore(BlockEvent.BreakEvent event) {
}
private void preventFatigueWithPocketWatch(MobEffectEvent.Applicable event) {
- if (event.getApplicationResult() && event.getEffectInstance().is(MobEffects.DIG_SLOWDOWN) && event.getEntity().isHolding(TFItems.POCKET_WATCH.get())) {
+ if (event.getApplicationResult() && event.getEffectInstance().is(MobEffects.MINING_FATIGUE) && event.getEntity().isHolding(TFItems.POCKET_WATCH.get())) {
event.setResult(MobEffectEvent.Applicable.Result.DO_NOT_APPLY);
}
}
- private void handleGiantPickaxeMining(BlockEvent.BreakEvent event) {
+ private void handleGiantPickaxeMining(BreakBlockEvent event) {
BlockPos pos = event.getPos();
BlockState state = event.getState();
@@ -174,7 +176,7 @@ private void handleGiantPickaxeMining(BlockEvent.BreakEvent event) {
if (shouldBreakGiantBlock(player, attachment)) {
attachment.setBreaking(true); // Tell the capability that a block breaking loop is happening, so it knows to fail the if check above. Otherwise, this would go on forever
- LootParams.Builder builder = new LootParams.Builder(player.serverLevel())
+ LootParams.Builder builder = new LootParams.Builder(player.level().getLevel())
.withParameter(LootContextParams.ORIGIN, Vec3.atCenterOf(pos))
.withParameter(LootContextParams.BLOCK_STATE, state)
.withOptionalParameter(LootContextParams.THIS_ENTITY, player)
@@ -224,13 +226,13 @@ private void refreshOreMagnetCache(TagsUpdatedEvent event) {
OreMagnetItem.TREE_ORE_TO_BLOCK_REPLACEMENTS.clear();
//collect all tags
- for (TagKey tag : BuiltInRegistries.BLOCK.getTagNames().filter(location -> location.location().getNamespace().equals("c")).toList()) {
+ for (TagKey tag : BuiltInRegistries.BLOCK.getTags().filter(location -> location.key().location().getNamespace().equals("c")).map(HolderSet.Named::key).toList()) {
//check if the tag is a valid ore tag
if (tag.location().getPath().contains("ores_in_ground/")) {
//grab the part after the slash for use later
String oreground = tag.location().getPath().substring(15);
//check if a tag for ore grounds matches up with our ores in ground tag
- if (BuiltInRegistries.BLOCK.getTagNames().filter(location -> location.location().getNamespace().equals("c")).anyMatch(blockTagKey -> blockTagKey.location().getPath().equals("ore_bearing_ground/" + oreground))) {
+ if (BuiltInRegistries.BLOCK.getTags().filter(location -> location.key().location().getNamespace().equals("c")).anyMatch(blockTagKey -> blockTagKey.key().location().getPath().equals("ore_bearing_ground/" + oreground))) {
//add each ground type to each ore
BuiltInRegistries.BLOCK.get(TagKey.create(Registries.BLOCK, Identifier.fromNamespaceAndPath("c", "ore_bearing_ground/" + oreground))).get().forEach(ground ->
BuiltInRegistries.BLOCK.get(tag).get().forEach(ore -> {
diff --git a/src/main/java/twilightforest/events/TravellersGearEvents.java b/src/main/java/twilightforest/events/TravellersGearEvents.java
index c71e37b8d7..60ce9ca1b4 100644
--- a/src/main/java/twilightforest/events/TravellersGearEvents.java
+++ b/src/main/java/twilightforest/events/TravellersGearEvents.java
@@ -8,7 +8,6 @@
import net.minecraft.resources.ResourceKey;
import net.minecraft.server.level.ServerPlayer;
import net.minecraft.sounds.SoundEvents;
-import net.minecraft.sounds.SoundSource;
import net.minecraft.util.Mth;
import net.minecraft.world.effect.MobEffectInstance;
import net.minecraft.world.effect.MobEffects;
@@ -18,8 +17,8 @@
import net.minecraft.world.entity.ai.attributes.AttributeInstance;
import net.minecraft.world.entity.ai.attributes.Attributes;
import net.minecraft.world.entity.player.Player;
-import net.minecraft.world.entity.projectile.arrow.AbstractArrow;
import net.minecraft.world.entity.projectile.Projectile;
+import net.minecraft.world.entity.projectile.arrow.AbstractArrow;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.item.component.ItemAttributeModifiers;
import net.minecraft.world.item.component.ItemContainerContents;
@@ -278,7 +277,7 @@ private void stopDamagingTravellersGear(ArmorHurtEvent event) {
if (damagedStack.getDamageValue() + event.getNewDamage(slot) >= damagedStack.getMaxDamage()) {
event.setNewDamage(slot, damagedStack.getMaxDamage() - damagedStack.getDamageValue() - 1);
} else if (damagedStack.getDamageValue() + event.getNewDamage(slot) >= damagedStack.getMaxDamage() - 1 && event.getEntity() instanceof ServerPlayer player) {
- player.level().playLocalSound(player.getX(), player.getY(), player.getZ(), SoundEvents.ITEM_BREAK.value(), SoundSource.PLAYERS, 1.0F, player.getVoicePitch(), false);
+ player.playSound(SoundEvents.ITEM_BREAK.value(), 1.0F, player.getVoicePitch());
}
});
}
diff --git a/src/main/resources/META-INF/accesstransformer.cfg b/src/main/resources/META-INF/accesstransformer.cfg
index 38538af1b6..54762d2621 100644
--- a/src/main/resources/META-INF/accesstransformer.cfg
+++ b/src/main/resources/META-INF/accesstransformer.cfg
@@ -116,7 +116,7 @@ public-f net.minecraft.world.level.saveddata.maps.MapItemSavedData trackedDecora
# TFOverlays (partially determines if the quest ram indicator should render below the crosshair, and allows the food bar to be rendered when riding hostile mounts)
public net.minecraft.client.gui.Gui canRenderCrosshairForSpectator(Lnet/minecraft/world/phys/HitResult;)Z
-#public net.minecraft.client.gui.Gui renderFood(Lnet/minecraft/client/gui/GuiGraphics;Lnet/minecraft/world/entity/player/Player;II)V
+public net.minecraft.client.gui.Gui extractFood(Lnet/minecraft/client/gui/GuiGraphicsExtractor;Lnet/minecraft/world/entity/player/Player;II)V
# TFSkyRenderer (allows for rendering the sky)
public net.minecraft.client.renderer.LevelRenderer skyRenderer