Skip to content

Commit

Permalink
Changes made while porting collision patch to Paper
Browse files Browse the repository at this point in the history
1. Need a better solution for EntityMixin block/fire collision
2. Fixed inconsistent Vanilla behavior for ExplosionMixin
   Mostly revolved around the explosion intensity calculator,
   as well as the damage calculator
3. Optimise ExplosionMixin to not call getSeenPercent twice,
   which is a new "feature" of 1.21
4. Optimise VoxelShapeMixin#toAabbsUncached()
   The regular forAllBoxes method on VoxelShape will incur
   indirection costs due to the virtual method invoke on
   the coordinate retrieval as well as on the consumer itself
  • Loading branch information
Spottedleaf committed Jul 11, 2024
1 parent 6d8e12e commit 523e8d9
Show file tree
Hide file tree
Showing 3 changed files with 52 additions and 23 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -202,6 +202,7 @@ public Stream<BlockState> shortCircuitStreamLogic(final Level level, final AABB
)
)
public void checkInsideBlocks(final Entity instance) {
// TODO unfuck these changes
final AABB boundingBox = this.getBoundingBox();
final BlockPos.MutableBlockPos tempPos = new BlockPos.MutableBlockPos();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -468,30 +468,39 @@ public void explode() {
double distZ = entity.getZ() - this.z;
final double distMag = Math.sqrt(distX * distX + distY * distY + distZ * distZ);

if (distMag != 0.0) {
distX /= distMag;
distY /= distMag;
distZ /= distMag;
if (distMag == 0.0) {
continue;
}

// route to new visible fraction calculation, using the existing block cache
final double intensityFraction = (1.0 - normalizedDistanceToCenter) * (double)this.getSeenFraction(center, entity, blockCache, blockPos);
distX /= distMag;
distY /= distMag;
distZ /= distMag;

// route to new visible fraction calculation, using the existing block cache
final double seenFraction = (double)this.getSeenFraction(center, entity, blockCache, blockPos);
if (this.damageCalculator.shouldDamageEntity((Explosion)(Object)this, entity)) {
// inline getEntityDamageAmount so that we can avoid double calling getSeenPercent, which is the MOST
// expensive part of this loop!!!!
final double factor = (1.0 - normalizedDistanceToCenter) * seenFraction;
entity.hurt(this.damageSource, (float)((factor * factor + factor) / 2.0 * 7.0 * diameter + 1.0));
}

entity.hurt(this.damageSource, (float)((int)((intensityFraction * intensityFraction + intensityFraction) / 2.0 * 7.0 * diameter + 1.0)));
final double intensityFraction = (1.0 - normalizedDistanceToCenter) * seenFraction * (double)this.damageCalculator.getKnockbackMultiplier(entity);

final double knockbackFraction;
if (entity instanceof LivingEntity livingEntity) {
knockbackFraction = intensityFraction * (1.0 - livingEntity.getAttributeValue(Attributes.EXPLOSION_KNOCKBACK_RESISTANCE));
} else {
knockbackFraction = intensityFraction;
}

final Vec3 knockback = new Vec3(distX * knockbackFraction, distY * knockbackFraction, distZ * knockbackFraction);
entity.setDeltaMovement(entity.getDeltaMovement().add(knockback));
final double knockbackFraction;
if (entity instanceof LivingEntity livingEntity) {
knockbackFraction = intensityFraction * (1.0 - livingEntity.getAttributeValue(Attributes.EXPLOSION_KNOCKBACK_RESISTANCE));
} else {
knockbackFraction = intensityFraction;
}

if (entity instanceof Player player) {
if (!player.isSpectator() && (!player.isCreative() || !player.getAbilities().flying)) {
this.hitPlayers.put(player, knockback);
}
final Vec3 knockback = new Vec3(distX * knockbackFraction, distY * knockbackFraction, distZ * knockbackFraction);
entity.setDeltaMovement(entity.getDeltaMovement().add(knockback));

if (entity instanceof Player player) {
if (!player.isSpectator() && (!player.isCreative() || !player.getAbilities().flying)) {
this.hitPlayers.put(player, knockback);
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,7 @@ public abstract class VoxelShapeMixin implements CollisionVoxelShape {
return this.rootCoordinatesZ;
}

@Unique
private static double[] extractRawArray(final DoubleList list) {
if (list instanceof DoubleArrayList rawList) {
final double[] raw = rawList.elements();
Expand Down Expand Up @@ -422,9 +423,27 @@ private List<AABB> toAabbsUncached() {
if (this.singleAABBRepresentation != null) {
ret.add(this.singleAABBRepresentation);
} else {
this.forAllBoxes((minX, minY, minZ, maxX, maxY, maxZ) -> {
ret.add(new AABB(minX, minY, minZ, maxX, maxY, maxZ));
});
final double[] coordsX = this.rootCoordinatesX;
final double[] coordsY = this.rootCoordinatesY;
final double[] coordsZ = this.rootCoordinatesZ;

final double offX = this.offsetX;
final double offY = this.offsetY;
final double offZ = this.offsetZ;

this.shape.forAllBoxes((final int minX, final int minY, final int minZ,
final int maxX, final int maxY, final int maxZ) -> {
ret.add(new AABB(
coordsX[minX] + offX,
coordsY[minY] + offY,
coordsZ[minZ] + offZ,


coordsX[maxX] + offX,
coordsY[maxY] + offY,
coordsZ[maxZ] + offZ
));
}, true);
}

// cache result
Expand Down Expand Up @@ -525,7 +544,7 @@ private boolean computeFullBlock() {
}

@Override
public boolean moonrise$isFullBlock() {
public final boolean moonrise$isFullBlock() {
final Boolean ret = this.isFullBlock;

if (ret != null) {
Expand Down

0 comments on commit 523e8d9

Please sign in to comment.