mirror of
https://github.com/MinecraftForge/MinecraftForge.git
synced 2026-11-13 16:54:22 +00:00
Fix container screens closing when opened with an extended REACH attribute. Fixes #10560
Also fixes cases where creative mode effected reach incorrectly.
This commit is contained in:
11 files changed
+134
-27
No files matched your search
@@ -9,7 +9,7 @@
|
||||
+ if (event.isCanceled() || (!this.m_9295_() && event.getResult() == net.minecraftforge.eventbus.api.Event.Result.DENY)) {
|
||||
+ return;
|
||||
+ }
|
||||
+ if (!this.f_9245_.canReach(p_215120_, 1.5)) { // Vanilla check is eye-to-center distance < 6, so padding is 6 - 4.5 = 1.5
|
||||
+ if (!this.f_9245_.canReachRaw(p_215120_, 1.5)) { // Vanilla uses ServerGamePacketListenerImpl.MAX_INTERACTION_DISTANCE which is 6*6, default Block reach is 4.5 so add 1.5 padding
|
||||
this.m_215125_(p_215120_, false, p_215124_, "too far");
|
||||
} else if (p_215120_.m_123342_() >= p_215123_) {
|
||||
this.f_9245_.f_8906_.m_9829_(new ClientboundBlockUpdatePacket(p_215120_, this.f_9244_.m_8055_(p_215120_)));
|
||||
|
||||
+2
-2
@@ -31,7 +31,7 @@
|
||||
BlockPos blockpos = blockhitresult.m_82425_();
|
||||
Vec3 vec31 = Vec3.m_82512_(blockpos);
|
||||
- if (!(this.f_9743_.m_146892_().m_82557_(vec31) > f_215198_)) {
|
||||
+ if (this.f_9743_.canReach(blockpos, 1.5)) { // Vanilla uses eye-to-center distance < 6, which implies a padding of 1.5
|
||||
+ if (this.f_9743_.canReachRaw(blockpos, 1.5)) { // Vanilla uses eye-to-center distance < ServerGamePacketListenerImpl which is 6*6, default block reach is 4.5, so add 1.5 padding
|
||||
Vec3 vec32 = vec3.m_82546_(vec31);
|
||||
double d0 = 1.0000001D;
|
||||
if (Math.abs(vec32.m_7096_()) < 1.0000001D && Math.abs(vec32.m_7098_()) < 1.0000001D && Math.abs(vec32.m_7094_()) < 1.0000001D) {
|
||||
@@ -65,7 +65,7 @@
|
||||
|
||||
AABB aabb = entity.m_20191_();
|
||||
- if (aabb.m_272282_(this.f_9743_.m_146892_()) < f_215198_) {
|
||||
+ if (this.f_9743_.canReach(entity, 3)) { // Vanilla padding is 3.0 (distSq < 6.0 * 6.0)
|
||||
+ if (this.f_9743_.canReachRaw(entity, 3.0)) { // Vanilla uses MAX_INTERACTION_DISTANCE which is 6*6 default entity reach is 3.0 so add 3.0 padding
|
||||
p_9866_.m_179617_(new ServerboundInteractPacket.Handler() {
|
||||
private void m_143678_(InteractionHand p_143679_, ServerGamePacketListenerImpl.EntityInteraction p_143680_) {
|
||||
ItemStack itemstack = ServerGamePacketListenerImpl.this.f_9743_.m_21120_(p_143679_);
|
||||
|
||||
@@ -0,0 +1,18 @@
|
||||
--- a/net/minecraft/world/Container.java
|
||||
+++ b/net/minecraft/world/Container.java
|
||||
@@ -78,10 +_,14 @@
|
||||
}
|
||||
|
||||
static boolean m_272074_(BlockEntity p_273154_, Player p_273222_) {
|
||||
- return m_271806_(p_273154_, p_273222_, 8);
|
||||
+ return stillValidBlockEntity(p_273154_, p_273222_, p_273222_.m_21133_(net.minecraftforge.common.ForgeMod.BLOCK_REACH.get()) + 3.5); // Vanilla uses 8, default reach is 4.5 so add 3.5 padding
|
||||
}
|
||||
|
||||
static boolean m_271806_(BlockEntity p_272877_, Player p_272670_, int p_273411_) {
|
||||
+ return stillValidBlockEntity(p_272877_, p_272670_, (double)p_273411_);
|
||||
+ }
|
||||
+
|
||||
+ static boolean stillValidBlockEntity(BlockEntity p_272877_, Player p_272670_, double p_273411_) {
|
||||
Level level = p_272877_.m_58904_();
|
||||
BlockPos blockpos = p_272877_.m_58899_();
|
||||
if (level == null) {
|
||||
@@ -43,3 +43,14 @@
|
||||
crashreportcategory.m_128159_("Item ID", Item.m_41393_(p_36042_.m_41720_()));
|
||||
crashreportcategory.m_128159_("Item data", p_36042_.m_41773_());
|
||||
crashreportcategory.m_128165_("Item name", () -> {
|
||||
@@ -530,7 +_,9 @@
|
||||
if (this.f_35978_.m_213877_()) {
|
||||
return false;
|
||||
} else {
|
||||
- return !(p_36009_.m_20280_(this.f_35978_) > 64.0D);
|
||||
+ // Vanilla uses 64 which is 8*8. Default reach is 3.0 so add 5.0 padding
|
||||
+ double reach = p_36009_.m_21133_(net.minecraftforge.common.ForgeMod.ENTITY_REACH.get()) + 5.0;
|
||||
+ return !(p_36009_.m_20280_(this.f_35978_) > reach * reach);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -251,15 +251,16 @@
|
||||
}
|
||||
|
||||
float f4 = 0.0F;
|
||||
@@ -1121,8 +_,9 @@
|
||||
@@ -1121,8 +_,10 @@
|
||||
if (flag3) {
|
||||
float f3 = 1.0F + EnchantmentHelper.m_44821_(this) * f;
|
||||
|
||||
- for(LivingEntity livingentity : this.m_9236_().m_45976_(LivingEntity.class, p_36347_.m_20191_().m_82377_(1.0D, 0.25D, 1.0D))) {
|
||||
- if (livingentity != this && livingentity != p_36347_ && !this.m_7307_(livingentity) && (!(livingentity instanceof ArmorStand) || !((ArmorStand)livingentity).m_31677_()) && this.m_20280_(livingentity) < 9.0D) {
|
||||
+ for(LivingEntity livingentity : this.m_9236_().m_45976_(LivingEntity.class, this.m_21120_(InteractionHand.MAIN_HAND).getSweepHitBox(this, p_36347_))) {
|
||||
+ double entityReachSq = Mth.m_144952_(this.getEntityReach()); // Use entity reach instead of constant 9.0. Vanilla uses bottom center-to-center checks here, so don't update this to use canReach, since it uses closest-corner checks.
|
||||
+ if (livingentity != this && livingentity != p_36347_ && !this.m_7307_(livingentity) && (!(livingentity instanceof ArmorStand) || !((ArmorStand)livingentity).m_31677_()) && this.m_20280_(livingentity) < entityReachSq) {
|
||||
+ // Use entity reach instead of constant 9.0. Vanilla uses bottom center-to-center checks here, so don't update this to use canReach, since it uses closest-corner checks.
|
||||
+ var reach = this.m_21133_(net.minecraftforge.common.ForgeMod.ENTITY_REACH.get());
|
||||
+ if (livingentity != this && livingentity != p_36347_ && !this.m_7307_(livingentity) && (!(livingentity instanceof ArmorStand) || !((ArmorStand)livingentity).m_31677_()) && this.m_20280_(livingentity) < reach * reach) {
|
||||
livingentity.m_147240_((double)0.4F, (double)Mth.m_14031_(this.m_146908_() * ((float)Math.PI / 180F)), (double)(-Mth.m_14089_(this.m_146908_() * ((float)Math.PI / 180F))));
|
||||
livingentity.m_6469_(this.m_269291_().m_269075_(this), f3);
|
||||
}
|
||||
|
||||
@@ -10,3 +10,11 @@
|
||||
if (p_219950_ != null) {
|
||||
lootparams$builder.m_287239_(p_219950_.m_36336_()).m_287286_(LootContextParams.f_81455_, p_219950_);
|
||||
}
|
||||
@@ -171,6 +_,6 @@
|
||||
}
|
||||
|
||||
default boolean m_219954_(Player p_219955_) {
|
||||
- return !this.m_213877_() && this.m_20182_().m_82509_(p_219955_.m_20182_(), 8.0D);
|
||||
+ return !this.m_213877_() && this.m_20182_().m_82509_(p_219955_.m_20182_(), p_219955_.m_21133_(net.minecraftforge.common.ForgeMod.ENTITY_REACH.get()) + 5.0); // Vanilla uses 8 default reach is 3.0 so add 5.0 padding
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,16 @@
|
||||
--- a/net/minecraft/world/inventory/AbstractContainerMenu.java
|
||||
+++ b/net/minecraft/world/inventory/AbstractContainerMenu.java
|
||||
@@ -67,7 +_,9 @@
|
||||
|
||||
protected static boolean m_38889_(ContainerLevelAccess p_38890_, Player p_38891_, Block p_38892_) {
|
||||
return p_38890_.m_39299_((p_38916_, p_38917_) -> {
|
||||
- return !p_38916_.m_8055_(p_38917_).m_60713_(p_38892_) ? false : p_38891_.m_20275_((double)p_38917_.m_123341_() + 0.5D, (double)p_38917_.m_123342_() + 0.5D, (double)p_38917_.m_123343_() + 0.5D) <= 64.0D;
|
||||
+ // Vanilla uses 64 which is 8*8. Default reach is 4.5 so add 3.5 padding
|
||||
+ double reach = p_38891_.m_21133_(net.minecraftforge.common.ForgeMod.BLOCK_REACH.get()) + 3.5;
|
||||
+ return !p_38916_.m_8055_(p_38917_).m_60713_(p_38892_) ? false : p_38891_.m_20275_((double)p_38917_.m_123341_() + 0.5D, (double)p_38917_.m_123342_() + 0.5D, (double)p_38917_.m_123343_() + 0.5D) <= reach * reach;
|
||||
}, true);
|
||||
}
|
||||
|
||||
@@ -229,6 +_,8 @@
|
||||
ItemStack itemstack1 = p_150438_.get();
|
||||
this.f_150394_.set(p_150436_, itemstack1);
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
--- a/net/minecraft/world/inventory/HorseInventoryMenu.java
|
||||
+++ b/net/minecraft/world/inventory/HorseInventoryMenu.java
|
||||
@@ -62,7 +_,9 @@
|
||||
}
|
||||
|
||||
public boolean m_6875_(Player p_39661_) {
|
||||
- return !this.f_39654_.m_149511_(this.f_39653_) && this.f_39653_.m_6542_(p_39661_) && this.f_39654_.m_6084_() && this.f_39654_.m_20270_(p_39661_) < 8.0F;
|
||||
+ // Default reach is 3 vanilla uses 8 here so add 5 padding
|
||||
+ double reach = p_39661_.m_21133_(net.minecraftforge.common.ForgeMod.ENTITY_REACH.get()) + 5;
|
||||
+ return !this.f_39654_.m_149511_(this.f_39653_) && this.f_39653_.m_6542_(p_39661_) && this.f_39654_.m_6084_() && this.f_39654_.m_20270_(p_39661_) < reach;
|
||||
}
|
||||
|
||||
private boolean m_150577_(AbstractHorse p_150578_) {
|
||||
@@ -0,0 +1,13 @@
|
||||
--- a/net/minecraft/world/inventory/ItemCombinerMenu.java
|
||||
+++ b/net/minecraft/world/inventory/ItemCombinerMenu.java
|
||||
@@ -108,7 +_,9 @@
|
||||
|
||||
public boolean m_6875_(Player p_39780_) {
|
||||
return this.f_39770_.m_39299_((p_39785_, p_39786_) -> {
|
||||
- return !this.m_8039_(p_39785_.m_8055_(p_39786_)) ? false : p_39780_.m_20275_((double)p_39786_.m_123341_() + 0.5D, (double)p_39786_.m_123342_() + 0.5D, (double)p_39786_.m_123343_() + 0.5D) <= 64.0D;
|
||||
+ // Vanilla uses 64 which is 8*8. Default reach is 4.5 so add 3.5 padding
|
||||
+ double reach = p_39780_.m_21133_(net.minecraftforge.common.ForgeMod.BLOCK_REACH.get()) + 3.5;
|
||||
+ return !this.m_8039_(p_39785_.m_8055_(p_39786_)) ? false : p_39780_.m_20275_((double)p_39786_.m_123341_() + 0.5D, (double)p_39786_.m_123342_() + 0.5D, (double)p_39786_.m_123343_() + 0.5D) <= reach * reach;
|
||||
}, true);
|
||||
}
|
||||
|
||||
@@ -109,7 +109,7 @@
|
||||
float f7 = f2 * f4;
|
||||
- double d0 = 5.0D;
|
||||
- Vec3 vec31 = vec3.m_82520_((double)f6 * 5.0D, (double)f5 * 5.0D, (double)f7 * 5.0D);
|
||||
+ double d0 = p_41437_.getBlockReach();
|
||||
+ double d0 = p_41437_.m_21133_(net.minecraftforge.common.ForgeMod.BLOCK_REACH.get()) + 0.5; // Block reach is 4.5, vanilla uses 5.0 here, so add 0.5 padding
|
||||
+ Vec3 vec31 = vec3.m_82520_((double)f6 * d0, (double)f5 * d0, (double)f7 * d0);
|
||||
return p_41436_.m_45547_(new ClipContext(vec3, vec31, ClipContext.Block.OUTLINE, p_41438_, p_41437_));
|
||||
}
|
||||
|
||||
@@ -6,7 +6,6 @@
|
||||
package net.minecraftforge.common.extensions;
|
||||
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.util.Mth;
|
||||
import net.minecraft.world.entity.Entity;
|
||||
import net.minecraft.world.entity.player.Player;
|
||||
import net.minecraft.world.phys.AABB;
|
||||
@@ -14,30 +13,29 @@ import net.minecraft.world.phys.HitResult;
|
||||
import net.minecraft.world.phys.Vec3;
|
||||
import net.minecraftforge.common.ForgeMod;
|
||||
|
||||
public interface IForgePlayer
|
||||
{
|
||||
|
||||
private Player self()
|
||||
{
|
||||
return (Player) this;
|
||||
public interface IForgePlayer {
|
||||
private Player self() {
|
||||
return (Player)this;
|
||||
}
|
||||
|
||||
/**
|
||||
* The entity reach is increased by 3 for creative players, unless it is currently zero, which disables attacks and entity interactions.
|
||||
* This comes from {@link net.minecraft.client.multiplayer.MultiPlayerGameMode#getPickRange() MultiPlayerGameMode.getPickRange()}
|
||||
* If you want the raw value, get the attribute yourself.
|
||||
* @return The entity reach of this player.
|
||||
*/
|
||||
default double getEntityReach()
|
||||
{
|
||||
default double getEntityReach() {
|
||||
double range = self().getAttributeValue(ForgeMod.ENTITY_REACH.get());
|
||||
return range == 0 ? 0 : range + (self().isCreative() ? 3 : 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* The reach distance is increased by 0.5 for creative players, unless it is currently zero, which disables interactions.
|
||||
* This comes from {@link net.minecraft.client.multiplayer.MultiPlayerGameMode#getPickRange() MultiPlayerGameMode.getPickRange()}
|
||||
* If you want the raw value, get the attribute yourself.
|
||||
* @return The reach distance of this player.
|
||||
*/
|
||||
default double getBlockReach()
|
||||
{
|
||||
default double getBlockReach() {
|
||||
double reach = self().getAttributeValue(ForgeMod.BLOCK_REACH.get());
|
||||
return reach == 0 ? 0 : reach + (self().isCreative() ? 0.5 : 0);
|
||||
}
|
||||
@@ -50,8 +48,7 @@ public interface IForgePlayer
|
||||
* @return If the player can attack the entity.
|
||||
* @apiNote Do not use for block checks, as this method uses {@link #getEntityReach()}
|
||||
*/
|
||||
default boolean canReach(Vec3 entityHitVec, double padding)
|
||||
{
|
||||
default boolean canReach(Vec3 entityHitVec, double padding) {
|
||||
return self().getEyePosition().closerThan(entityHitVec, getEntityReach() + padding);
|
||||
}
|
||||
|
||||
@@ -63,11 +60,27 @@ public interface IForgePlayer
|
||||
* @return If the player can attack the passed entity.
|
||||
* @apiNote Prefer using {@link #canReach(Vec3, double)} if you have a {@link HitResult} available.
|
||||
*/
|
||||
default boolean canReach(Entity entity, double padding)
|
||||
{
|
||||
default boolean canReach(Entity entity, double padding) {
|
||||
return isCloseEnough(entity, getEntityReach() + padding);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the player can reach an entity.<br>
|
||||
* On the server, additional padding is added to account for movement/lag.
|
||||
*
|
||||
* Unlike {@link #getEntityReach()} or {@link #canReach(Entity,double)} this does not
|
||||
* add the 3.0 creative mode implicit padding.
|
||||
*
|
||||
* @param entity The entity being range-checked.
|
||||
* @param padding Extra validation distance.
|
||||
* @return If the player can attack the passed entity.
|
||||
* @apiNote Prefer using {@link #canReach(Vec3, double)} if you have a {@link HitResult} available.
|
||||
*/
|
||||
default boolean canReachRaw(Entity entity, double padding) {
|
||||
double range = self().getAttributeValue(ForgeMod.ENTITY_REACH.get()) + padding;
|
||||
return isCloseEnough(entity, range);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the player can reach a block.<br>
|
||||
* On the server, additional padding is added to account for movement/lag.
|
||||
@@ -75,10 +88,25 @@ public interface IForgePlayer
|
||||
* @param padding Extra validation distance.
|
||||
* @return If the player can interact with this location.
|
||||
*/
|
||||
default boolean canReach(BlockPos pos, double padding)
|
||||
{
|
||||
default boolean canReach(BlockPos pos, double padding) {
|
||||
double reach = this.getBlockReach() + padding;
|
||||
return self().getEyePosition().distanceToSqr(Vec3.atCenterOf(pos)) < reach * reach;
|
||||
return self().getEyePosition().distanceToSqr(Vec3.atCenterOf(pos)) <= reach * reach;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the player can reach a block.<br>
|
||||
* On the server, additional padding is added to account for movement/lag.
|
||||
*
|
||||
* Unlike {@link #getBlockReach()} or {@link #canReach(BlockPos,double)} this does not
|
||||
* add the 0.5 creative mode implicit padding.
|
||||
*
|
||||
* @param pos The position being range-checked.
|
||||
* @param padding Extra validation distance.
|
||||
* @return If the player can interact with this location.
|
||||
*/
|
||||
default boolean canReachRaw(BlockPos pos, double padding) {
|
||||
double reach = self().getAttributeValue(ForgeMod.BLOCK_REACH.get()) + padding;
|
||||
return self().getEyePosition().distanceToSqr(Vec3.atCenterOf(pos)) <= reach * reach;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -88,8 +116,12 @@ public interface IForgePlayer
|
||||
* @return If the eye-to-center distance between this player and the passed entity is less than dist.
|
||||
* @implNote This method inflates the bounding box by the pick radius, which differs from vanilla. But vanilla doesn't use the pick radius, the only entity with > 0 is AbstractHurtingProjectile.
|
||||
*/
|
||||
default boolean isCloseEnough(Entity entity, double dist)
|
||||
{
|
||||
default boolean isCloseEnough(Entity entity, double dist) {
|
||||
// This cuses the "eye-to-closest-corner" checks, which can cause issues with servers.
|
||||
// https://github.com/MinecraftForge/MinecraftForge/issues/9309
|
||||
// But to not break expectations of others, its staying until a config can be set.
|
||||
// The vanilla code is:
|
||||
// return entity.getBoundingBox().distanceToSqr(self().getEyePosition()) < dist * dist;
|
||||
Vec3 eye = self().getEyePosition();
|
||||
AABB aabb = entity.getBoundingBox().inflate(entity.getPickRadius());
|
||||
return aabb.distanceToSqr(eye) < dist * dist;
|
||||
|
||||
Reference in new issue
Block a user