mirror of
https://github.com/Samsuik/Sakura.git
synced 2025-12-29 19:59:08 +00:00
Upstream has released updates that appear to apply and compile correctly Paper Changes: PaperMC/Paper@914fb08 Fix Entity#updateFluidHeightAndDoFluidPushing inconsistency with Vanilla PaperMC/Paper@e9fa3a7 Use correct queue when blocking on futures PaperMC/Paper@0ff899d Prevent world mutation on copper golem spawn cancel (#13152) PaperMC/Paper@bae47d3 Update to 1.21.10 (#13127) PaperMC/Paper@8339bb3 Update DataConverter constants for 1.21.10 PaperMC/Paper@3982efa Sync Moonrise PaperMC/Paper@fa57d4b Remove Vanilla packet processing at start of tick PaperMC/Paper@fba780d Rebuild patches
234 lines
13 KiB
Diff
234 lines
13 KiB
Diff
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
|
From: Samsuik <kfian294ma4@gmail.com>
|
|
Date: Fri, 3 May 2024 15:04:31 +0100
|
|
Subject: [PATCH] Specialised Explosions
|
|
|
|
|
|
diff --git a/net/minecraft/server/level/ServerLevel.java b/net/minecraft/server/level/ServerLevel.java
|
|
index f698366f23e9064db89b1b9840f198e9963826c5..0b9ac2b9e07102babf3c8975cae42841b63f1c63 100644
|
|
--- a/net/minecraft/server/level/ServerLevel.java
|
|
+++ b/net/minecraft/server/level/ServerLevel.java
|
|
@@ -1954,7 +1954,14 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe
|
|
case STANDARD -> Explosion.BlockInteraction.DESTROY; // CraftBukkit - handle custom explosion type
|
|
};
|
|
Vec3 vec3 = new Vec3(x, y, z);
|
|
- ServerExplosion serverExplosion = new ServerExplosion(this, source, damageSource, damageCalculator, vec3, radius, fire, blockInteraction);
|
|
+ // Sakura start - specialised explosions
|
|
+ final ServerExplosion serverExplosion;
|
|
+ if (source instanceof net.minecraft.world.entity.item.PrimedTnt tnt) {
|
|
+ serverExplosion = new me.samsuik.sakura.explosion.TntExplosion(this, tnt, damageSource, damageCalculator, vec3, radius, fire, blockInteraction);
|
|
+ } else {
|
|
+ serverExplosion = new ServerExplosion(this, source, damageSource, damageCalculator, vec3, radius, fire, blockInteraction);
|
|
+ }
|
|
+ // Sakura end - specialised explosions
|
|
if (configurator != null) configurator.accept(serverExplosion);// Paper - Allow explosions to damage source
|
|
int i = serverExplosion.explode();
|
|
// CraftBukkit start
|
|
@@ -1962,6 +1969,29 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe
|
|
return serverExplosion;
|
|
}
|
|
// CraftBukkit end
|
|
+ // Sakura start - specialised explosions
|
|
+ if (serverExplosion instanceof me.samsuik.sakura.explosion.SpecialisedExplosion<?> specialisedExplosion) {
|
|
+ me.samsuik.sakura.explosion.ExplosionToSend explosionToSend;
|
|
+ while ((explosionToSend = specialisedExplosion.getExplosionsToSend().poll()) != null) {
|
|
+ this.notifyPlayersOfExplosion(serverExplosion, explosionToSend.position(), radius, explosionToSend.blocksDestroyed(), smallExplosionParticles, largeExplosionParticles, explosionSound, blockParticles);
|
|
+ }
|
|
+ }
|
|
+
|
|
+ this.notifyPlayersOfExplosion(serverExplosion, vec3, radius, i, smallExplosionParticles, largeExplosionParticles, explosionSound, blockParticles);
|
|
+ return serverExplosion;
|
|
+ }
|
|
+
|
|
+ private void notifyPlayersOfExplosion(
|
|
+ final ServerExplosion serverExplosion,
|
|
+ final Vec3 vec3,
|
|
+ final float radius,
|
|
+ final int i,
|
|
+ final ParticleOptions smallExplosionParticles,
|
|
+ final ParticleOptions largeExplosionParticles,
|
|
+ final Holder<SoundEvent> explosionSound,
|
|
+ final WeightedList<ExplosionParticleInfo> blockParticles
|
|
+ ) {
|
|
+ // Sakura end - specialised explosions
|
|
ParticleOptions particleOptions = serverExplosion.isSmall() ? smallExplosionParticles : largeExplosionParticles;
|
|
|
|
for (ServerPlayer serverPlayer : this.players) {
|
|
@@ -1984,7 +2014,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe
|
|
}
|
|
}
|
|
|
|
- return serverExplosion; // CraftBukkit
|
|
+ serverExplosion.getHitPlayers().clear(); // Sakura - specialised explosions
|
|
}
|
|
|
|
private Explosion.BlockInteraction getDestroyType(GameRules.Key<GameRules.BooleanValue> decayGameRule) {
|
|
diff --git a/net/minecraft/world/entity/item/PrimedTnt.java b/net/minecraft/world/entity/item/PrimedTnt.java
|
|
index 8a36e0ce4792e7152905256dde7746fd09d42729..b349149592b09512b573911e95fd13915ba698cd 100644
|
|
--- a/net/minecraft/world/entity/item/PrimedTnt.java
|
|
+++ b/net/minecraft/world/entity/item/PrimedTnt.java
|
|
@@ -79,20 +79,7 @@ public class PrimedTnt extends Entity implements TraceableEntity, me.samsuik.sak
|
|
|
|
@Override
|
|
public final void respawnEntity(int count) {
|
|
- final PrimedTnt tnt = new PrimedTnt(EntityType.TNT, this.level());
|
|
- tnt.updateBukkitHandle(this); // update handle for plugins
|
|
- while (count-- > 1) {
|
|
- this.setFuse(100); // Prevent unwanted explosions while ticking
|
|
-
|
|
- // Cause an explosion to affect this entity
|
|
- tnt.setPos(this.position());
|
|
- tnt.setDeltaMovement(this.getDeltaMovement());
|
|
- this.entityState().apply(this);
|
|
- tnt.explode();
|
|
- this.storeEntityState();
|
|
-
|
|
- this.tick();
|
|
- }
|
|
+ this.mergeData.count = count; // Sakura - specialised explosions
|
|
}
|
|
// Sakura end - merge cannon entities
|
|
|
|
diff --git a/net/minecraft/world/level/ServerExplosion.java b/net/minecraft/world/level/ServerExplosion.java
|
|
index 9833450075b97720371340ac05f485cdc62edab9..301c8846d4c77c450d693ab3b42be476ec07dfcc 100644
|
|
--- a/net/minecraft/world/level/ServerExplosion.java
|
|
+++ b/net/minecraft/world/level/ServerExplosion.java
|
|
@@ -327,6 +327,38 @@ public class ServerExplosion implements Explosion {
|
|
return true;
|
|
}
|
|
// Sakura end - optimise explosion protected regions
|
|
+ // Sakura start - specialised explosions
|
|
+ protected final void createBlockCache() {
|
|
+ // Paper start - collision optimisations
|
|
+ this.blockCache = new it.unimi.dsi.fastutil.longs.Long2ObjectOpenHashMap<>();
|
|
+ this.chunkPosCache = new long[CHUNK_CACHE_WIDTH * CHUNK_CACHE_WIDTH];
|
|
+ java.util.Arrays.fill(this.chunkPosCache, ChunkPos.INVALID_CHUNK_POS);
|
|
+ this.chunkCache = new net.minecraft.world.level.chunk.LevelChunk[CHUNK_CACHE_WIDTH * CHUNK_CACHE_WIDTH];
|
|
+ this.directMappedBlockCache = new ca.spottedleaf.moonrise.patches.collisions.ExplosionBlockCache[BLOCK_EXPLOSION_CACHE_WIDTH * BLOCK_EXPLOSION_CACHE_WIDTH * BLOCK_EXPLOSION_CACHE_WIDTH];
|
|
+ this.mutablePos = new BlockPos.MutableBlockPos();
|
|
+ // Paper end - collision optimisations
|
|
+ }
|
|
+
|
|
+ protected final void clearBlockCache() {
|
|
+ // Paper start - collision optimisations
|
|
+ this.blockCache = null;
|
|
+ this.chunkPosCache = null;
|
|
+ this.chunkCache = null;
|
|
+ this.directMappedBlockCache = null;
|
|
+ this.mutablePos = null;
|
|
+ // Paper end - collision optimisations
|
|
+ }
|
|
+
|
|
+ protected final void markBlocksInCacheAsExplodable(final List<BlockPos> explodedPositions) {
|
|
+ for (final BlockPos explodedPos : explodedPositions) {
|
|
+ final ca.spottedleaf.moonrise.patches.collisions.ExplosionBlockCache cache = this.blockCache.get(explodedPos.asLong());
|
|
+ // May be null if the blockCache is cleared then retrieved from the recent block cache
|
|
+ if (cache != null) {
|
|
+ cache.shouldExplode = null;
|
|
+ }
|
|
+ }
|
|
+ }
|
|
+ // Sakura end - specialised explosions
|
|
|
|
public ServerExplosion(
|
|
ServerLevel level,
|
|
@@ -520,14 +552,25 @@ public class ServerExplosion implements Explosion {
|
|
|
|
private void hurtEntities() {
|
|
float f = this.radius * 2.0F;
|
|
+ // Sakura start - specialised explosions
|
|
+ for (final Entity entity : this.level.getEntities(null, this.getExplosionBounds(f))) {
|
|
+ this.impactEntity(f, entity);
|
|
+ }
|
|
+ }
|
|
+
|
|
+ private AABB getExplosionBounds(final float f) {
|
|
int floor = Mth.floor(this.center.x - f - 1.0);
|
|
int floor1 = Mth.floor(this.center.x + f + 1.0);
|
|
int floor2 = Mth.floor(this.center.y - f - 1.0);
|
|
int floor3 = Mth.floor(this.center.y + f + 1.0);
|
|
int floor4 = Mth.floor(this.center.z - f - 1.0);
|
|
int floor5 = Mth.floor(this.center.z + f + 1.0);
|
|
- List <Entity> list = this.level.getEntities(this.excludeSourceFromDamage ? this.source : null, new AABB(floor, floor2, floor4, floor1, floor3, floor5), entity -> entity.isAlive() && !entity.isSpectator()); // Paper - Fix lag from explosions processing dead entities, Allow explosions to damage source
|
|
- for (Entity entity : list) { // Paper - used in loop
|
|
+ return new AABB(floor, floor2, floor4, floor1, floor3, floor5);
|
|
+ }
|
|
+
|
|
+ protected final void impactEntity(final float f, final Entity entity) {
|
|
+ if (entity.isAlive() && !entity.isSpectator() && (!this.excludeSourceFromDamage || entity != this.source)) { // Paper - Fix lag from explosions processing dead entities, Allow explosions to damage source
|
|
+ // Sakura end - specialised explosions
|
|
if (!entity.ignoreExplosion(this)) {
|
|
double d = Math.sqrt(entity.distanceToSqr(this.center)) / f;
|
|
if (!(d > 1.0)) {
|
|
@@ -546,15 +589,16 @@ public class ServerExplosion implements Explosion {
|
|
// - Damaging EnderDragon does nothing
|
|
// - EnderDragon hitbox always covers the other parts and is therefore always present
|
|
if (entity instanceof EnderDragonPart) {
|
|
- continue;
|
|
+ return; // Sakura - specialised explosions
|
|
}
|
|
|
|
entity.lastDamageCancelled = false;
|
|
|
|
if (entity instanceof EnderDragon) {
|
|
+ final AABB explosionBounds = this.getExplosionBounds(f); // Sakura - specialised explosions
|
|
for (EnderDragonPart dragonPart : ((EnderDragon) entity).getSubEntities()) {
|
|
// Calculate damage separately for each EntityComplexPart
|
|
- if (list.contains(dragonPart)) {
|
|
+ if (explosionBounds.intersects(dragonPart.getBoundingBox())) { // Sakura - specialised explosions
|
|
dragonPart.hurtServer(this.level, this.damageSource, this.damageCalculator.getEntityDamageAmount(this, dragonPart, f1));
|
|
}
|
|
}
|
|
@@ -563,7 +607,7 @@ public class ServerExplosion implements Explosion {
|
|
}
|
|
|
|
if (entity.lastDamageCancelled) { // SPIGOT-5339, SPIGOT-6252, SPIGOT-6777: Skip entity if damage event was cancelled
|
|
- continue;
|
|
+ return; // Sakura - specialised explosions
|
|
}
|
|
// CraftBukkit end
|
|
}
|
|
@@ -583,7 +627,10 @@ public class ServerExplosion implements Explosion {
|
|
if (entity.getType().is(EntityTypeTags.REDIRECTABLE_PROJECTILE) && entity instanceof Projectile projectile) {
|
|
projectile.setOwner(this.damageSource.getEntity());
|
|
} else if (entity instanceof Player player && !player.isSpectator() && (!player.isCreative() || !player.getAbilities().flying) && !level.paperConfig().environment.disableExplosionKnockback) { // Paper - Option to disable explosion knockback
|
|
- this.hitPlayers.put(player, vec32);
|
|
+ // Sakura start - specialised explosions; tally player velocity
|
|
+ final Vec3 explosionImpact = vec32;
|
|
+ this.hitPlayers.compute(player, (p, v) -> v != null ? v.add(explosionImpact) : explosionImpact);
|
|
+ // Sakura end - specialised explosions; tally player velocity
|
|
}
|
|
|
|
entity.onExplosionHit(this.source);
|
|
@@ -687,14 +734,7 @@ public class ServerExplosion implements Explosion {
|
|
}
|
|
|
|
public int explode() {
|
|
- // Paper start - collision optimisations
|
|
- this.blockCache = new it.unimi.dsi.fastutil.longs.Long2ObjectOpenHashMap<>();
|
|
- this.chunkPosCache = new long[CHUNK_CACHE_WIDTH * CHUNK_CACHE_WIDTH];
|
|
- java.util.Arrays.fill(this.chunkPosCache, ChunkPos.INVALID_CHUNK_POS);
|
|
- this.chunkCache = new net.minecraft.world.level.chunk.LevelChunk[CHUNK_CACHE_WIDTH * CHUNK_CACHE_WIDTH];
|
|
- this.directMappedBlockCache = new ca.spottedleaf.moonrise.patches.collisions.ExplosionBlockCache[BLOCK_EXPLOSION_CACHE_WIDTH * BLOCK_EXPLOSION_CACHE_WIDTH * BLOCK_EXPLOSION_CACHE_WIDTH];
|
|
- this.mutablePos = new BlockPos.MutableBlockPos();
|
|
- // Paper end - collision optimisations
|
|
+ this.createBlockCache(); // Sakura - specialised explosions
|
|
this.level.gameEvent(this.source, GameEvent.EXPLODE, this.center);
|
|
List<BlockPos> list = this.calculateExplodedPositions();
|
|
this.hurtEntities();
|
|
@@ -709,13 +749,7 @@ public class ServerExplosion implements Explosion {
|
|
this.createFire(list);
|
|
}
|
|
|
|
- // Paper start - collision optimisations
|
|
- this.blockCache = null;
|
|
- this.chunkPosCache = null;
|
|
- this.chunkCache = null;
|
|
- this.directMappedBlockCache = null;
|
|
- this.mutablePos = null;
|
|
- // Paper end - collision optimisations
|
|
+ this.clearBlockCache(); // Sakura - specialised explosions
|
|
return list.size();
|
|
}
|
|
|