-
-
Notifications
You must be signed in to change notification settings - Fork 3.4k
Add player kill credit to beds/respawn anchors #10200
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
97e2140
1a03c61
70f242d
7e47fd3
cd97a85
a9e25fe
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,60 @@ | ||
| From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 | ||
| From: 2stinkysocks <zmehall@gmail.com> | ||
| Date: Mon, 29 Jan 2024 02:36:33 -0700 | ||
| Subject: [PATCH] Add player kill credit to beds/respawn anchors | ||
|
|
||
|
|
||
| diff --git a/src/main/java/org/bukkit/event/block/BlockExplodeEvent.java b/src/main/java/org/bukkit/event/block/BlockExplodeEvent.java | ||
| index 7dcbb75170296c1dd1d784a032bf369602328b29..151807d64c6d973d0ba1e8955a5a3ed8381d7a8b 100644 | ||
| --- a/src/main/java/org/bukkit/event/block/BlockExplodeEvent.java | ||
| +++ b/src/main/java/org/bukkit/event/block/BlockExplodeEvent.java | ||
| @@ -21,6 +21,7 @@ public class BlockExplodeEvent extends BlockEvent implements Cancellable { | ||
| private final List<Block> blocks; | ||
| private float yield; | ||
| private final org.bukkit.block.BlockState explodedBlockState; // Paper | ||
| + private final org.bukkit.entity.LivingEntity igniter; // Paper - add player kill credit | ||
|
|
||
| @Deprecated @io.papermc.paper.annotation.DoNotUse // Paper | ||
| public BlockExplodeEvent(@NotNull final Block what, @NotNull final List<Block> blocks, final float yield) { | ||
| @@ -28,15 +29,22 @@ public class BlockExplodeEvent extends BlockEvent implements Cancellable { | ||
| this(what, blocks, yield, null); | ||
| } | ||
| @org.jetbrains.annotations.ApiStatus.Internal | ||
| - public BlockExplodeEvent(@NotNull final Block what, @NotNull final List<Block> blocks, final float yield, @org.jetbrains.annotations.Nullable org.bukkit.block.BlockState explodedBlockState) { | ||
| + public BlockExplodeEvent(@NotNull final Block what, @NotNull final List<Block> blocks, final float yield, @org.jetbrains.annotations.Nullable org.bukkit.block.BlockState explodedBlockState, org.bukkit.entity.LivingEntity igniter) { // Paper - add player kill credit | ||
| // Paper end | ||
| super(what); | ||
| this.blocks = blocks; | ||
| this.yield = yield; | ||
| this.cancel = false; | ||
| this.explodedBlockState = explodedBlockState; // Paper | ||
| + this.igniter = igniter; // Paper - add player kill credit | ||
| } | ||
|
|
||
| + // Paper start - add player kill credit | ||
| + public BlockExplodeEvent(@NotNull final Block what, @NotNull final List<Block> blocks, final float yield, @org.jetbrains.annotations.Nullable org.bukkit.block.BlockState explodedBlockState) { | ||
| + this(what, blocks, yield, explodedBlockState, null); | ||
| + } | ||
| + // Paper end - add player kill credit | ||
| + | ||
| @Override | ||
| public boolean isCancelled() { | ||
| return cancel; | ||
| @@ -92,6 +100,17 @@ public class BlockExplodeEvent extends BlockEvent implements Cancellable { | ||
| this.yield = yield; | ||
| } | ||
|
|
||
| + // Paper start - add player kill credit | ||
| + /** | ||
| + * Returns the {@link org.bukkit.entity.LivingEntity} that ignited the block | ||
| + * | ||
| + * @return The {@link org.bukkit.entity.LivingEntity} who ignited the block | ||
| + */ | ||
| + public @org.jetbrains.annotations.Nullable org.bukkit.entity.LivingEntity getIgniter() { | ||
| + return this.igniter; | ||
| + } | ||
| + // Paper end - add player kill credit | ||
| + | ||
| @NotNull | ||
| @Override | ||
| public HandlerList getHandlers() { |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,151 @@ | ||
| From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 | ||
| From: 2stinkysocks <zmehall@gmail.com> | ||
| Date: Mon, 29 Jan 2024 00:30:34 -0700 | ||
| Subject: [PATCH] Add player kill credit to beds/respawn anchors | ||
|
|
||
|
|
||
| diff --git a/src/main/java/net/minecraft/world/damagesource/DamageSource.java b/src/main/java/net/minecraft/world/damagesource/DamageSource.java | ||
| index fc6903b20a6e084729306fc960a6fc80e094f76c..f6f1920d2fe3676b71fad187dfc488aa1689ed9f 100644 | ||
| --- a/src/main/java/net/minecraft/world/damagesource/DamageSource.java | ||
| +++ b/src/main/java/net/minecraft/world/damagesource/DamageSource.java | ||
| @@ -81,6 +81,15 @@ public class DamageSource { | ||
| this(type, (Entity) null, (Entity) null, position); | ||
| } | ||
|
|
||
| + // Paper start - add player kill credit | ||
| + public DamageSource(Holder<DamageType> type, Vec3 position, @Nullable Entity attacker) { | ||
| + this.type = type; | ||
| + this.causingEntity = attacker; | ||
| + this.directEntity = null; | ||
| + this.damageSourcePosition = position; | ||
| + } | ||
| + // Paper end - add player kill credit | ||
| + | ||
| public DamageSource(Holder<DamageType> type, @Nullable Entity attacker) { | ||
| this(type, attacker, attacker); | ||
| } | ||
| diff --git a/src/main/java/net/minecraft/world/damagesource/DamageSources.java b/src/main/java/net/minecraft/world/damagesource/DamageSources.java | ||
| index f339475185645f7be30963e4f980ce81a6f7e536..b41235c47f1e03c25983cb25ff032248609c5bf7 100644 | ||
| --- a/src/main/java/net/minecraft/world/damagesource/DamageSources.java | ||
| +++ b/src/main/java/net/minecraft/world/damagesource/DamageSources.java | ||
| @@ -253,8 +253,14 @@ public class DamageSources { | ||
| return this.badRespawnPointExplosion(position, null); | ||
| } | ||
|
|
||
| + // Paper start - add player kill credit | ||
| public DamageSource badRespawnPointExplosion(Vec3 position, @Nullable org.bukkit.block.BlockState explodedBlockState) { | ||
| - DamageSource source = new DamageSource(this.damageTypes.getHolderOrThrow(DamageTypes.BAD_RESPAWN_POINT), position); | ||
| + return this.badRespawnPointExplosion(position, null, explodedBlockState); | ||
| + } | ||
| + | ||
| + public DamageSource badRespawnPointExplosion(Vec3 position, @Nullable Player player, @Nullable org.bukkit.block.BlockState explodedBlockState) { | ||
| + DamageSource source = new DamageSource(this.damageTypes.getHolderOrThrow(DamageTypes.BAD_RESPAWN_POINT), position, player); | ||
| + // Paper end - add player kill credit | ||
| source.explodedBlockState = explodedBlockState; | ||
| return source; | ||
| // Paper end - add exploded state | ||
| diff --git a/src/main/java/net/minecraft/world/level/Explosion.java b/src/main/java/net/minecraft/world/level/Explosion.java | ||
| index 28ef910885dbd48965fba6f08cec412697b1b7f0..f20e32048b335979d3d2d132800a3a213af5b0e2 100644 | ||
| --- a/src/main/java/net/minecraft/world/level/Explosion.java | ||
| +++ b/src/main/java/net/minecraft/world/level/Explosion.java | ||
| @@ -549,7 +549,7 @@ public class Explosion { | ||
| int i1 = Mth.floor(this.y + (double) f2 + 1.0D); | ||
| int j1 = Mth.floor(this.z - (double) f2 - 1.0D); | ||
| int k1 = Mth.floor(this.z + (double) f2 + 1.0D); | ||
| - List<Entity> list = this.level.getEntities(this.source, new AABB((double) i, (double) l, (double) j1, (double) j, (double) i1, (double) k1), (com.google.common.base.Predicate<Entity>) entity -> entity.isAlive() && !entity.isSpectator()); // Paper - Fix lag from explosions processing dead entities | ||
| + List<Entity> list = this.level.getEntities(this.damageSource.is(net.minecraft.world.damagesource.DamageTypes.BAD_RESPAWN_POINT) ? null : this.source, new AABB((double) i, (double) l, (double) j1, (double) j, (double) i1, (double) k1), (com.google.common.base.Predicate<Entity>) entity -> entity.isAlive() && !entity.isSpectator()); // Paper - Fix lag from explosions processing dead entities, add player kill credit | ||
| Vec3 vec3d = new Vec3(this.x, this.y, this.z); | ||
| Iterator iterator = list.iterator(); | ||
|
|
||
| @@ -680,14 +680,14 @@ public class Explosion { | ||
|
|
||
| List<org.bukkit.block.Block> bukkitBlocks; | ||
|
|
||
| - if (explode != null) { | ||
| + if (!this.damageSource.is(net.minecraft.world.damagesource.DamageTypes.BAD_RESPAWN_POINT) && explode != null) { // Paper - add player kill credit | ||
| EntityExplodeEvent event = new EntityExplodeEvent(explode, location, blockList, this.yield); | ||
| this.level.getCraftServer().getPluginManager().callEvent(event); | ||
| this.wasCanceled = event.isCancelled(); | ||
| bukkitBlocks = event.blockList(); | ||
| this.yield = event.getYield(); | ||
| } else { | ||
| - BlockExplodeEvent event = new BlockExplodeEvent(location.getBlock(), blockList, this.yield, this.damageSource.explodedBlockState); // Paper - add exploded state | ||
| + BlockExplodeEvent event = new BlockExplodeEvent(location.getBlock(), blockList, this.yield, this.damageSource.explodedBlockState, (org.bukkit.entity.LivingEntity) (source != null && source instanceof net.minecraft.world.entity.LivingEntity ? source.getBukkitEntity() : null)); // Paper - add exploded state, add player kill credit | ||
| this.level.getCraftServer().getPluginManager().callEvent(event); | ||
| this.wasCanceled = event.isCancelled(); | ||
| bukkitBlocks = event.blockList(); | ||
| diff --git a/src/main/java/net/minecraft/world/level/block/BedBlock.java b/src/main/java/net/minecraft/world/level/block/BedBlock.java | ||
| index 8677dc684bd2e0bb3cf5f77b659ce02b79627e76..2902a92ba22bb87bf05d85f73f34bf7f956d116e 100644 | ||
| --- a/src/main/java/net/minecraft/world/level/block/BedBlock.java | ||
| +++ b/src/main/java/net/minecraft/world/level/block/BedBlock.java | ||
| @@ -106,10 +106,10 @@ public class BedBlock extends HorizontalDirectionalBlock implements EntityBlock | ||
|
|
||
| Vec3 vec3d = pos.getCenter(); | ||
|
|
||
| - world.explode((Entity) null, world.damageSources().badRespawnPointExplosion(vec3d, explodedBlockState), (ExplosionDamageCalculator) null, vec3d, 5.0F, true, Level.ExplosionInteraction.BLOCK); // Paper - add exploded state | ||
| + world.explode(player, world.damageSources().badRespawnPointExplosion(vec3d, player, explodedBlockState), (ExplosionDamageCalculator) null, vec3d, 5.0F, true, Level.ExplosionInteraction.BLOCK); // Paper - add exploded state, add player kill credit | ||
| return InteractionResult.SUCCESS; | ||
| } else if ((Boolean) state.getValue(BedBlock.OCCUPIED)) { | ||
| - if (!BedBlock.canSetSpawn(world)) return this.explodeBed(state, world, pos); // Paper - check explode first | ||
| + if (!BedBlock.canSetSpawn(world)) return this.explodeBed(state, world, pos, player); // Paper - check explode first, add player kill credit | ||
| if (!this.kickVillagerOutOfBed(world, pos)) { | ||
| player.displayClientMessage(Component.translatable("block.minecraft.bed.occupied"), true); | ||
| } | ||
| @@ -130,7 +130,7 @@ public class BedBlock extends HorizontalDirectionalBlock implements EntityBlock | ||
| // Paper end - PlayerBedFailEnterEvent | ||
| // CraftBukkit start - handling bed explosion from below here | ||
| if (event.getWillExplode()) { // Paper - PlayerBedFailEnterEvent | ||
| - this.explodeBed(finaliblockdata, world, finalblockposition); | ||
| + this.explodeBed(finaliblockdata, world, finalblockposition, player); // Paper - add player kill credit | ||
| } else | ||
| // CraftBukkit end | ||
| if (entityhuman_enumbedresult.getMessage() != null) { | ||
| @@ -146,7 +146,7 @@ public class BedBlock extends HorizontalDirectionalBlock implements EntityBlock | ||
| } | ||
|
|
||
| // CraftBukkit start | ||
| - private InteractionResult explodeBed(BlockState iblockdata, Level world, BlockPos blockposition) { | ||
| + private InteractionResult explodeBed(BlockState iblockdata, Level world, BlockPos blockposition, Player player) { // Paper - add player kill credit | ||
| { | ||
| { | ||
| final org.bukkit.block.BlockState explodedBlockState = org.bukkit.craftbukkit.block.CraftBlockStates.getUnplacedBlockState(world, blockposition, iblockdata); // Paper - add exploded state | ||
| @@ -159,7 +159,7 @@ public class BedBlock extends HorizontalDirectionalBlock implements EntityBlock | ||
|
|
||
| Vec3 vec3d = blockposition.getCenter(); | ||
|
|
||
| - world.explode((Entity) null, world.damageSources().badRespawnPointExplosion(vec3d, explodedBlockState), (ExplosionDamageCalculator) null, vec3d, 5.0F, true, Level.ExplosionInteraction.BLOCK); // Paper - add exploded state | ||
| + world.explode(player, world.damageSources().badRespawnPointExplosion(vec3d, player, explodedBlockState), (ExplosionDamageCalculator) null, vec3d, 5.0F, true, Level.ExplosionInteraction.BLOCK); // Paper - add exploded state, add player kill credit | ||
| return InteractionResult.SUCCESS; | ||
| } | ||
| } | ||
| diff --git a/src/main/java/net/minecraft/world/level/block/RespawnAnchorBlock.java b/src/main/java/net/minecraft/world/level/block/RespawnAnchorBlock.java | ||
| index 088262f306755a9cb785c7a0cf0a9c66ed0965a8..ef1b454ad825702251e097f118eb3589f33d18eb 100644 | ||
| --- a/src/main/java/net/minecraft/world/level/block/RespawnAnchorBlock.java | ||
| +++ b/src/main/java/net/minecraft/world/level/block/RespawnAnchorBlock.java | ||
| @@ -78,7 +78,7 @@ public class RespawnAnchorBlock extends Block { | ||
| return InteractionResult.PASS; | ||
| } else if (!RespawnAnchorBlock.canSetSpawn(world)) { | ||
| if (!world.isClientSide) { | ||
| - this.explode(state, world, pos); | ||
| + this.explode(state, world, pos, player); // Paper - add player kill credit | ||
| } | ||
|
|
||
| return InteractionResult.sidedSuccess(world.isClientSide); | ||
| @@ -130,7 +130,7 @@ public class RespawnAnchorBlock extends Block { | ||
| } | ||
| } | ||
|
|
||
| - private void explode(BlockState state, Level world, final BlockPos explodedPos) { | ||
| + private void explode(BlockState state, Level world, final BlockPos explodedPos, Player player) { // Paper - add player kill credit | ||
| final org.bukkit.block.BlockState explodedBlockState = org.bukkit.craftbukkit.block.CraftBlockStates.getBlockState(explodedPos, state, null); // Paper - add exploded state | ||
| world.removeBlock(explodedPos, false); | ||
| Stream<Direction> stream = Direction.Plane.HORIZONTAL.stream(); // CraftBukkit - decompile error | ||
| @@ -148,7 +148,7 @@ public class RespawnAnchorBlock extends Block { | ||
| }; | ||
| Vec3 vec3d = explodedPos.getCenter(); | ||
|
|
||
| - world.explode((Entity) null, world.damageSources().badRespawnPointExplosion(vec3d, explodedBlockState), explosiondamagecalculator, vec3d, 5.0F, true, Level.ExplosionInteraction.BLOCK); // Paper - add exploded state | ||
| + world.explode(player, world.damageSources().badRespawnPointExplosion(vec3d, player, explodedBlockState), explosiondamagecalculator, vec3d, 5.0F, true, Level.ExplosionInteraction.BLOCK); // Paper - add exploded state, add player kill credit | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. What is the benefit of passing the player as the source here ? Setting the source for the explosion to not null is what is responsible for the pretty ugly checks you have to do in Explosion now.
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. You're right, I totally glossed over this when I was writing it, I'll fix it in my next commit and just pass the entity through the DamageSource. |
||
| } | ||
|
|
||
| public static boolean canSetSpawn(Level world) { | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I am unsure how happy I am with hijacking this field.
Given neither paper nor spigot have a damage source API yet it might be fine, but this is changing vanilla behaviour and spigot behaviour.
Does anything stop us from going down the same path as the critical damage API and add a field + getter/setter for the "igniter" entity ref ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think it makes more sense to just add a setter for the causingEntity field, since this is already used in LivingEntity's hurt method to determine kill credit, I can verify that this works later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I was more referring to the fact that other things might use the
causingEntityfield.Changing that might break things we are not aware of and testing that everything still works fine is kind of hard.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
it's more the fact that "causingEntity" generally has a very explict meaning within the servers code and reusing this field is likely to cause some issues, if not now, maybe in the future; would much rather just add a field this rather than trying to hijack th emeaning of an exisitng one
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Wouldn't this just require more changes to
hurt()in LivingEntity? It seems like all the existing logic in there would just have to be implemented twice, since the entity "causing" the event is still the person who ignited the block. I know that this avoids having unintended side effects with other parts of the code but I don't see a way it could be implemented cleanly without just mostly duplicating the logic. I'll do it if everyone thinks it's the best way, but I just want to put that out there.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Well that is exactly the point tho.
Vanilla does not consider the "igniting entity" the causing entity of the damage.
This PR should not change this. The logic in LivingEntity#hurt acts on the causingEntity of the damage source, which should remain null for explosions from e.g. respawn anchors.
You are merely supposed to hijack the DamageSource to pass through the entity that ignited the block so that the API event can expose it.
Changing what vanilla considers the actual causingEntity is not a good idea, which is why cat and I suggested this to be moved to its own field so existing logic does not change.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I see how I was misunderstanding, it's definitely better for plugin developers to implement this themselves, sorry for the confusion. I'm starting to think this change would be better to make upstream, so I might create a similar pr to spigot that only changes the API. I'll close this pr and will come back to it if I run into problems with spigot.