mirror of
https://github.com/Samsuik/Sakura.git
synced 2025-12-19 14:59:30 +00:00
341 lines
18 KiB
Diff
341 lines
18 KiB
Diff
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
|
From: Samsuik <kfian294ma4@gmail.com>
|
|
Date: Sat, 9 Sep 2023 18:39:15 +0100
|
|
Subject: [PATCH] Merge Cannon Entities
|
|
|
|
|
|
diff --git a/net/minecraft/server/level/ServerLevel.java b/net/minecraft/server/level/ServerLevel.java
|
|
index 0604b5075122494ec82b4e1b458645958b93c806..8fec4a46a9cf13d832306bd87a4fe17be79bef86 100644
|
|
--- a/net/minecraft/server/level/ServerLevel.java
|
|
+++ b/net/minecraft/server/level/ServerLevel.java
|
|
@@ -697,6 +697,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe
|
|
// Paper end - rewrite chunk system
|
|
this.getCraftServer().addWorld(this.getWorld()); // CraftBukkit
|
|
this.levelTickScheduler.registerNewTask(this.explosionPositions::clear, 0); // Sakura - client visibility settings
|
|
+ this.levelTickScheduler.registerNewTask(this.mergeHandler::expire, 200); // Sakura - merge cannon entities
|
|
}
|
|
|
|
// Paper start
|
|
@@ -811,6 +812,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe
|
|
}
|
|
|
|
io.papermc.paper.entity.activation.ActivationRange.activateEntities(this); // Paper - EAR
|
|
+ final Entity[] previousEntity = new Entity[1]; // Sakura - merge cannon entities
|
|
this.entityTickList
|
|
.forEach(
|
|
entity -> {
|
|
@@ -829,6 +831,15 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe
|
|
entity.stopRiding();
|
|
}
|
|
|
|
+ // Sakura start - merge cannon entities
|
|
+ Entity previous = previousEntity[0];
|
|
+ if (this.mergeHandler.tryMerge(entity, previous)) {
|
|
+ return;
|
|
+ } else {
|
|
+ previousEntity[0] = entity;
|
|
+ }
|
|
+ // Sakura end - merge cannon entities
|
|
+
|
|
profilerFiller.push("tick");
|
|
this.guardEntityTick(this::tickNonPassenger, entity);
|
|
profilerFiller.pop();
|
|
diff --git a/net/minecraft/world/entity/Entity.java b/net/minecraft/world/entity/Entity.java
|
|
index 30e6492e60fc7b5767d09574304ad3a3977e862a..9844928c361cfc31d618186ecd10fba5975bbb7d 100644
|
|
--- a/net/minecraft/world/entity/Entity.java
|
|
+++ b/net/minecraft/world/entity/Entity.java
|
|
@@ -559,6 +559,24 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess
|
|
return to.entityState() != null && to.entityState().comparePositionAndMotion(this);
|
|
}
|
|
// Sakura end - store entity data/state
|
|
+ // Sakura start - merge cannon entities
|
|
+ public final void updateBukkitHandle(Entity entity) {
|
|
+ if (this.bukkitEntity != null) {
|
|
+ this.bukkitEntity.setHandle(entity);
|
|
+ } else {
|
|
+ this.bukkitEntity = entity.getBukkitEntity();
|
|
+ }
|
|
+ }
|
|
+
|
|
+ public final long getPackedOriginPosition() {
|
|
+ org.bukkit.util.Vector origin = this.getOriginVector();
|
|
+ if (origin != null) {
|
|
+ return BlockPos.asLong(origin.getBlockX(), origin.getBlockY(), origin.getBlockZ());
|
|
+ } else {
|
|
+ return Long.MIN_VALUE;
|
|
+ }
|
|
+ }
|
|
+ // Sakura end - merge cannon entities
|
|
|
|
public Entity(EntityType<?> entityType, Level level) {
|
|
this.type = entityType;
|
|
@@ -4960,6 +4978,11 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess
|
|
if (this.removalReason != Entity.RemovalReason.UNLOADED_TO_CHUNK) { this.getPassengers().forEach(Entity::stopRiding); } // Paper - rewrite chunk system
|
|
this.levelCallback.onRemove(removalReason);
|
|
this.onRemoval(removalReason);
|
|
+ // Sakura start - merge cannon entities
|
|
+ if (removalReason == RemovalReason.DISCARDED) {
|
|
+ this.level.mergeHandler.removeEntity(this);
|
|
+ }
|
|
+ // Sakura end - merge cannon entities
|
|
// Paper start - Folia schedulers
|
|
if (!(this instanceof ServerPlayer) && removalReason != RemovalReason.CHANGED_DIMENSION && !alreadyRemoved) {
|
|
// Players need to be special cased, because they are regularly removed from the world
|
|
diff --git a/net/minecraft/world/entity/item/FallingBlockEntity.java b/net/minecraft/world/entity/item/FallingBlockEntity.java
|
|
index b9b8ed9c5e16a703e41997e1a781796363bcf5aa..aa81292b862e22e276cabc9d7611362cbd91602d 100644
|
|
--- a/net/minecraft/world/entity/item/FallingBlockEntity.java
|
|
+++ b/net/minecraft/world/entity/item/FallingBlockEntity.java
|
|
@@ -54,7 +54,7 @@ import org.bukkit.craftbukkit.event.CraftEventFactory;
|
|
import org.bukkit.event.entity.EntityRemoveEvent;
|
|
// CraftBukkit end
|
|
|
|
-public class FallingBlockEntity extends Entity {
|
|
+public class FallingBlockEntity extends Entity implements me.samsuik.sakura.entity.merge.MergeableEntity { // Sakura - merge cannon entities
|
|
private static final Logger LOGGER = LogUtils.getLogger();
|
|
public BlockState blockState = Blocks.SAND.defaultBlockState();
|
|
public int time;
|
|
@@ -70,11 +70,62 @@ public class FallingBlockEntity extends Entity {
|
|
public boolean autoExpire = true; // Paper - Expand FallingBlock API
|
|
public boolean heightParity; // Sakura - falling block height parity api
|
|
|
|
+ // Sakura start - merge cannon entities
|
|
+ private final me.samsuik.sakura.entity.merge.MergeEntityData mergeData = new me.samsuik.sakura.entity.merge.MergeEntityData(this);
|
|
+
|
|
+ @Override
|
|
+ public final me.samsuik.sakura.entity.merge.MergeEntityData getMergeEntityData() {
|
|
+ return this.mergeData;
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public final boolean isSafeToMergeInto(me.samsuik.sakura.entity.merge.MergeableEntity entity, boolean ticksLived) {
|
|
+ return entity instanceof FallingBlockEntity fbe
|
|
+ && fbe.blockState.equals(this.blockState)
|
|
+ && (!ticksLived || fbe.time - 1 == this.time);
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public final void respawnEntity(int count) {
|
|
+ while (count-- >= 1) {
|
|
+ // Unlike PrimedTnt we have to try respawn each stacked entity
|
|
+ FallingBlockEntity fallingBlock = new FallingBlockEntity(EntityType.FALLING_BLOCK, this.level());
|
|
+
|
|
+ // Try to stack the falling block
|
|
+ this.entityState().apply(fallingBlock);
|
|
+ fallingBlock.blockState = this.blockState;
|
|
+ fallingBlock.spawnReason = this.spawnReason;
|
|
+ fallingBlock.time = this.time - 1;
|
|
+ fallingBlock.tick();
|
|
+
|
|
+ // If you horizontal stack into a moving piston block this condition will be met.
|
|
+ if (!fallingBlock.isRemoved()) {
|
|
+ this.mergeData.setCount(count + 1);
|
|
+ fallingBlock.storeEntityState();
|
|
+ fallingBlock.entityState().apply(this);
|
|
+ break;
|
|
+ } else if (count == 0) {
|
|
+ this.discard(EntityRemoveEvent.Cause.DESPAWN);
|
|
+ }
|
|
+ }
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public @Nullable ItemEntity spawnAtLocation(ServerLevel level, net.minecraft.world.level.ItemLike item) { // may be overridden by plugins
|
|
+ ItemEntity itemEntity = null;
|
|
+ for (int i = 0; i < this.mergeData.getCount(); ++i) {
|
|
+ itemEntity = super.spawnAtLocation(level, item);
|
|
+ }
|
|
+ return itemEntity;
|
|
+ }
|
|
+ // Sakura end - merge cannon entities
|
|
+
|
|
public FallingBlockEntity(EntityType<? extends FallingBlockEntity> entityType, Level level) {
|
|
super(entityType, level);
|
|
this.heightParity = level.sakuraConfig().cannons.mechanics.fallingBlockParity; // Sakura - configure cannon mechanics
|
|
this.isFallingBlock = true; // Sakura - client visibility settings
|
|
this.loadChunks = level.sakuraConfig().cannons.loadChunks; // Sakura - load chunks on movement
|
|
+ this.mergeData.setMergeLevel(level.sakuraConfig().cannons.mergeLevel); // Sakura - merge cannon entities
|
|
}
|
|
|
|
public FallingBlockEntity(Level level, double x, double y, double z, BlockState state) {
|
|
@@ -236,6 +287,7 @@ public class FallingBlockEntity extends Entity {
|
|
return;
|
|
}
|
|
// CraftBukkit end
|
|
+ if (this.respawnEntity()) return; // Sakura - merge cannon entities
|
|
if (this.level().setBlock(blockPos, this.blockState, 3)) {
|
|
((ServerLevel)this.level())
|
|
.getChunkSource()
|
|
@@ -342,6 +394,7 @@ public class FallingBlockEntity extends Entity {
|
|
|
|
compound.putBoolean("CancelDrop", this.cancelDrop);
|
|
if (!this.autoExpire) compound.putBoolean("Paper.AutoExpire", false); // Paper - Expand FallingBlock API
|
|
+ compound.putInt("merge_count", this.mergeData.getCount()); // Sakura - merge cannon entities
|
|
}
|
|
|
|
@Override
|
|
@@ -374,6 +427,11 @@ public class FallingBlockEntity extends Entity {
|
|
this.autoExpire = compound.getBoolean("Paper.AutoExpire");
|
|
}
|
|
// Paper end - Expand FallingBlock API
|
|
+ // Sakura start - merge cannon entities
|
|
+ if (compound.contains("merge_count", 3)) {
|
|
+ this.mergeData.setCount(compound.getInt("merge_count"));
|
|
+ }
|
|
+ // Sakura end - merge cannon entities
|
|
}
|
|
|
|
public void setHurtsEntities(float fallDamagePerDistance, int fallDamageMax) {
|
|
diff --git a/net/minecraft/world/entity/item/PrimedTnt.java b/net/minecraft/world/entity/item/PrimedTnt.java
|
|
index b6467f9ff64a76104076a01bfd56852ce712d95b..e6aa1d1a5fc5cd2ffc156125c4eef2d0d1aeef4a 100644
|
|
--- a/net/minecraft/world/entity/item/PrimedTnt.java
|
|
+++ b/net/minecraft/world/entity/item/PrimedTnt.java
|
|
@@ -33,7 +33,7 @@ import org.bukkit.event.entity.EntityRemoveEvent;
|
|
import org.bukkit.event.entity.ExplosionPrimeEvent;
|
|
// CraftBukkit end
|
|
|
|
-public class PrimedTnt extends Entity implements TraceableEntity {
|
|
+public class PrimedTnt extends Entity implements TraceableEntity, me.samsuik.sakura.entity.merge.MergeableEntity { // Sakura - merge cannon entities
|
|
private static final EntityDataAccessor<Integer> DATA_FUSE_ID = SynchedEntityData.defineId(PrimedTnt.class, EntityDataSerializers.INT);
|
|
private static final EntityDataAccessor<BlockState> DATA_BLOCK_STATE_ID = SynchedEntityData.defineId(PrimedTnt.class, EntityDataSerializers.BLOCK_STATE);
|
|
private static final int DEFAULT_FUSE_TIME = 80;
|
|
@@ -58,11 +58,48 @@ public class PrimedTnt extends Entity implements TraceableEntity {
|
|
public float explosionPower = 4.0F;
|
|
public boolean isIncendiary = false; // CraftBukkit - add field
|
|
|
|
+ // Sakura start - merge cannon entities
|
|
+ private final me.samsuik.sakura.entity.merge.MergeEntityData mergeData = new me.samsuik.sakura.entity.merge.MergeEntityData(this);
|
|
+
|
|
+ @Override
|
|
+ public final me.samsuik.sakura.entity.merge.MergeEntityData getMergeEntityData() {
|
|
+ return this.mergeData;
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public final boolean isSafeToMergeInto(me.samsuik.sakura.entity.merge.MergeableEntity entity, boolean ticksLived) {
|
|
+ return entity instanceof PrimedTnt tnt
|
|
+ && tnt.getFuse() + 1 == this.getFuse()
|
|
+ // required to prevent issues with powdered snow
|
|
+ && (tnt.entityState().fallDistance() == this.fallDistance
|
|
+ || tnt.entityState().fallDistance() > 2.5f && this.fallDistance > 2.5f);
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public final void respawnEntity(int count) {
|
|
+ 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();
|
|
+ }
|
|
+ }
|
|
+ // Sakura end - merge cannon entities
|
|
+
|
|
public PrimedTnt(EntityType<? extends PrimedTnt> entityType, Level level) {
|
|
super(entityType, level);
|
|
this.blocksBuilding = true;
|
|
this.isPrimedTNT = true; // Sakura - client visibility settings
|
|
this.loadChunks = level.sakuraConfig().cannons.loadChunks; // Sakura - load chunks on movement
|
|
+ this.mergeData.setMergeLevel(level.sakuraConfig().cannons.mergeLevel); // Sakura - merge cannon entities
|
|
}
|
|
|
|
public PrimedTnt(Level level, double x, double y, double z, @Nullable LivingEntity owner) {
|
|
@@ -142,6 +179,7 @@ public class PrimedTnt extends Entity implements TraceableEntity {
|
|
if (i <= 0) {
|
|
// CraftBukkit start - Need to reverse the order of the explosion and the entity death so we have a location for the event
|
|
//this.discard();
|
|
+ this.respawnEntity(); // Sakura - merge cannon entities
|
|
if (!this.level().isClientSide) {
|
|
this.explode();
|
|
}
|
|
@@ -212,6 +250,7 @@ public class PrimedTnt extends Entity implements TraceableEntity {
|
|
if (this.explosionPower != 4.0F) {
|
|
compound.putFloat("explosion_power", this.explosionPower);
|
|
}
|
|
+ compound.putInt("merge_count", this.mergeData.getCount()); // Sakura - merge cannon entities
|
|
}
|
|
|
|
@Override
|
|
@@ -224,6 +263,11 @@ public class PrimedTnt extends Entity implements TraceableEntity {
|
|
if (compound.contains("explosion_power", 99)) {
|
|
this.explosionPower = Mth.clamp(compound.getFloat("explosion_power"), 0.0F, 128.0F);
|
|
}
|
|
+ // Sakura start - merge cannon entities
|
|
+ if (compound.contains("merge_count", 3)) {
|
|
+ this.mergeData.setCount(compound.getInt("merge_count"));
|
|
+ }
|
|
+ // Sakura end - merge cannon entities
|
|
}
|
|
|
|
@Nullable
|
|
diff --git a/net/minecraft/world/level/Level.java b/net/minecraft/world/level/Level.java
|
|
index 869670abd843d6c10babf8ffaa7bfc919f8a818a..5c4c2823ec6b5e2d9293b9130ddf2bc1c3c12048 100644
|
|
--- a/net/minecraft/world/level/Level.java
|
|
+++ b/net/minecraft/world/level/Level.java
|
|
@@ -841,6 +841,7 @@ public abstract class Level implements LevelAccessor, AutoCloseable, ca.spottedl
|
|
public final me.samsuik.sakura.listener.LevelTickScheduler levelTickScheduler = new me.samsuik.sakura.listener.LevelTickScheduler();
|
|
public final me.samsuik.sakura.listener.BlockChangeTracker blockChangeTracker = new me.samsuik.sakura.listener.BlockChangeTracker(this);
|
|
// Sakura end - track block changes and tick scheduler
|
|
+ public final me.samsuik.sakura.entity.merge.EntityMergeHandler mergeHandler = new me.samsuik.sakura.entity.merge.EntityMergeHandler(); // Sakura - merge cannon entities
|
|
|
|
protected Level(
|
|
WritableLevelData levelData,
|
|
diff --git a/net/minecraft/world/level/block/BasePressurePlateBlock.java b/net/minecraft/world/level/block/BasePressurePlateBlock.java
|
|
index 108c1d23bf80777b943edfa0b5585ebb928540a7..69d490c79e30fb42da69bbd804ecaea7b88fe7b0 100644
|
|
--- a/net/minecraft/world/level/block/BasePressurePlateBlock.java
|
|
+++ b/net/minecraft/world/level/block/BasePressurePlateBlock.java
|
|
@@ -91,7 +91,7 @@ public abstract class BasePressurePlateBlock extends Block {
|
|
}
|
|
|
|
private void checkPressed(@Nullable Entity entity, Level level, BlockPos pos, BlockState state, int currentSignal) {
|
|
- int signalStrength = this.getSignalStrength(level, pos);
|
|
+ int signalStrength = this.getSignalStrength(level, pos, currentSignal == 0); // Sakura - merge cannon entities
|
|
boolean flag = currentSignal > 0;
|
|
boolean flag1 = signalStrength > 0;
|
|
|
|
@@ -168,6 +168,12 @@ public abstract class BasePressurePlateBlock extends Block {
|
|
// CraftBukkit end
|
|
}
|
|
|
|
+ // Sakura start - merge cannon entities
|
|
+ protected int getSignalStrength(Level world, BlockPos pos, boolean entityInside) {
|
|
+ return this.getSignalStrength(world, pos);
|
|
+ }
|
|
+ // Sakura end - merge cannon entities
|
|
+
|
|
protected abstract int getSignalStrength(Level level, BlockPos pos);
|
|
|
|
protected abstract int getSignalForState(BlockState state);
|
|
diff --git a/net/minecraft/world/level/block/WeightedPressurePlateBlock.java b/net/minecraft/world/level/block/WeightedPressurePlateBlock.java
|
|
index 0ad494a861c04aeacb0620000e306cfab813fdde..c49044097fa8d3294de10a681717cd424e6c1078 100644
|
|
--- a/net/minecraft/world/level/block/WeightedPressurePlateBlock.java
|
|
+++ b/net/minecraft/world/level/block/WeightedPressurePlateBlock.java
|
|
@@ -40,6 +40,11 @@ public class WeightedPressurePlateBlock extends BasePressurePlateBlock {
|
|
|
|
@Override
|
|
protected int getSignalStrength(Level level, BlockPos pos) {
|
|
+ // Sakura start - merge cannon entities
|
|
+ return this.getSignalStrength(level, pos, false);
|
|
+ }
|
|
+ protected final int getSignalStrength(Level level, BlockPos pos, boolean entityInside) {
|
|
+ // Sakura end - merge cannon entities
|
|
// CraftBukkit start
|
|
// int min = Math.min(getEntityCount(level, TOUCH_AABB.move(pos), Entity.class), this.maxWeight);
|
|
int min = 0;
|
|
@@ -55,7 +60,7 @@ public class WeightedPressurePlateBlock extends BasePressurePlateBlock {
|
|
|
|
// We only want to block turning the plate on if all events are cancelled
|
|
if (!cancellable.isCancelled()) {
|
|
- min++;
|
|
+ min += !entityInside && entity instanceof me.samsuik.sakura.entity.merge.MergeableEntity mergeEntity ? mergeEntity.getMergeEntityData().getCount() : 1; // Sakura - merge cannon entities
|
|
}
|
|
}
|
|
|