Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
fb4c73d
Events and hooks port
albazavr-alba Jun 24, 2026
c1de065
Removed every @NotNull and unnecessary line change
albazavr-alba Jul 5, 2026
8ee5f57
Merge branch 'latest' into port-events-and-hooks
albazavr-alba Jul 13, 2026
72a945a
Fixed files
albazavr-alba Jul 15, 2026
aad53bd
Fixed review comment for EntityHooks
albazavr-alba Jul 20, 2026
dc54f61
Fixed ClientGameEvents
albazavr-alba Jul 21, 2026
1d6b091
Fixed ClientRegistrationEvents
albazavr-alba Jul 23, 2026
148624a
Fixed ClientRegistrationEvents
albazavr-alba Jul 23, 2026
bb8ed59
Excluded CloudEvents
albazavr-alba Jul 23, 2026
7f18e76
Fixed OverlayHandler
albazavr-alba Jul 23, 2026
bfce2b6
Fixed TravellersClientEvents
albazavr-alba Jul 23, 2026
3f552eb
Fixed CapabilityEvents.java
albazavr-alba Jul 23, 2026
bc3d093
Merge branch 'latest' into port-events-and-hooks
albazavr-alba Jul 24, 2026
782d0f9
Fixed CharmEvents
albazavr-alba Jul 24, 2026
79807a5
Merge remote-tracking branch 'origin/port-events-and-hooks' into port…
albazavr-alba Jul 24, 2026
6cd6dac
Fixed CapabilityEvents
albazavr-alba Jul 24, 2026
147d3a9
Fixed ProgressionEvents
albazavr-alba Jul 24, 2026
c34a2a8
Fixed CapabilityEvents
albazavr-alba Jul 24, 2026
dcec00e
Fixed EntityEvents
albazavr-alba Jul 24, 2026
87773d2
Fixed CharmEvents
albazavr-alba Jul 24, 2026
6a97e5b
Fixed ProgressionEvents
albazavr-alba Jul 24, 2026
d662f9a
Fixed RegistrationEvents
albazavr-alba Jul 24, 2026
dadbddd
Fixed ToolEvents
albazavr-alba Jul 24, 2026
7bf3324
Fixed FogHandler
albazavr-alba Jul 24, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 4 additions & 5 deletions src/main/java/twilightforest/asmhooks/EntityHooks.java
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -25,7 +25,6 @@ public class EntityHooks {
* Injection Point:<br/>
* {@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;
Expand All @@ -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;
}
Expand Down Expand Up @@ -99,9 +98,9 @@ public static float resetFactorWithUnrestrained(float o, Entity entity) {
* {@link net.minecraft.world.entity.Entity#move(MoverType, Vec3)}<br/>
*/
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;
}
Expand Down
4 changes: 1 addition & 3 deletions src/main/java/twilightforest/asmhooks/MultipartHooks.java
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -39,7 +37,7 @@ public static Iterator<Entity> resolveEntitiesForRendering(Iterator<Entity> 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);
}

Expand Down
2 changes: 0 additions & 2 deletions src/main/java/twilightforest/asmhooks/PlayerHooks.java
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
126 changes: 76 additions & 50 deletions src/main/java/twilightforest/client/event/ClientGameEvents.java
Original file line number Diff line number Diff line change
@@ -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;
Expand All @@ -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;
Expand All @@ -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;
Expand All @@ -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;
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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));
}
}

Expand All @@ -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();
}
}

Expand All @@ -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> biome = mc.level.getBiome(mc.cameraEntity.blockPosition());
Holder<Biome> biome = mc.level.getBiome(mc.getCameraEntity().blockPosition());
if (TFConfig.getValidAuroraBiomes(access).stream().anyMatch(c -> holderMatcher.match(c, biome)))
aurora++;
else
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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
Comment thread
albazavr-alba marked this conversation as resolved.
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();
Expand All @@ -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) {
Comment thread
albazavr-alba marked this conversation as resolved.
event.setCanceled(true);
Expand All @@ -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;
});
}
}
}
Expand Down
Loading
Loading