Skip to content

Commit fb241ab

Browse files
committed
Rewrite player death handling to make plugins able to set the keepInventory value
1 parent 48d9c83 commit fb241ab

File tree

3 files changed

+72
-76
lines changed

3 files changed

+72
-76
lines changed

patches/minecraft/net/minecraft/server/level/ServerPlayer.java.patch

Lines changed: 31 additions & 73 deletions
Original file line numberDiff line numberDiff line change
@@ -211,7 +211,7 @@
211211
} catch (Throwable throwable) {
212212
CrashReport crashreport = CrashReport.forThrowable(throwable, "Ticking player");
213213
CrashReportCategory crashreportcategory = crashreport.addCategory("Player being ticked");
214-
@@ -563,19 +_,62 @@
214+
@@ -563,16 +_,37 @@
215215
}
216216

217217
private void updateScoreForCriteria(ObjectiveCriteria p_9105_, int p_9106_) {
@@ -222,96 +222,54 @@
222222
});
223223
}
224224

225+
+ //Ketting start - mixin
226+
+ private @Nullable String die$deathMessage;
227+
+ private String die$defaultDeathMessage;
228+
+ //Ketting end
225229
public void die(DamageSource p_9035_) {
226230
this.gameEvent(GameEvent.ENTITY_DIE);
227231
+ if (net.minecraftforge.common.ForgeHooks.onLivingDeath(this, p_9035_)) return;
228-
boolean flag = this.level().getGameRules().getBoolean(GameRules.RULE_SHOWDEATHMESSAGES);
229-
- if (flag) {
230-
- Component component = this.getCombatTracker().getDeathMessage();
231-
- this.connection.send(new ClientboundPlayerCombatKillPacket(this.getId(), component), PacketSendListener.exceptionallySend(() -> {
232232
+ //Ketting start
233233
+ if (this.isRemoved()) return;
234-
+ boolean keepInventory = this.level().getGameRules().getBoolean(GameRules.RULE_KEEPINVENTORY) || this.isSpectator();
235-
+ Inventory copyInv;
236-
+ if (keepInventory) {
237-
+ copyInv = this.getInventory();
238-
+ } else {
239-
+ copyInv = new Inventory(this);
240-
+ copyInv.replaceWith(this.getInventory());
241-
+ }
242-
+ this.dropAllDeathLoot(p_9035_);
243234
+
244-
+ Component defaultMessage = this.getCombatTracker().getDeathMessage();
245-
+ String deathmessage = defaultMessage.getString();
246-
+
247-
+ List<org.bukkit.inventory.ItemStack> loot = new java.util.ArrayList<>();
248-
+ Collection<ItemEntity> drops = this.captureDrops(null);
249-
+
250-
+ if (drops != null) {
251-
+ for (ItemEntity entity : drops) {
252-
+ org.bukkit.craftbukkit.v1_20_R1.inventory.CraftItemStack craftItemStack = org.bukkit.craftbukkit.v1_20_R1.inventory.CraftItemStack.asCraftMirror(entity.getItem());
253-
+ loot.add(craftItemStack);
254-
+ }
235+
+ die$defaultDeathMessage = this.getCombatTracker().getDeathMessage().getString();
236+
+ if (!this.isSpectator()) {
237+
+ this.dropAllDeathLoot(p_9035_);
238+
+ die$deathMessage = this.handlePlayerDeath$event.getDeathMessage();
255239
+ }
256-
+ this.keepLevel = keepInventory;
240+
boolean flag = this.level().getGameRules().getBoolean(GameRules.RULE_SHOWDEATHMESSAGES);
241+
- if (flag) {
242+
- Component component = this.getCombatTracker().getDeathMessage();
243+
+ if (die$deathMessage != null && die$deathMessage.length() > 0 && flag) {
244+
+ Component component;
257245
+
258-
+ Inventory recapturedDrops = new Inventory(this); //recapture drops that got added back to the inventory (eg. soulbound items)
259-
+ if (!keepInventory) {
260-
+ recapturedDrops.replaceWith(this.getInventory());
261-
+ this.getInventory().replaceWith(copyInv);
262-
+ }
263-
+ org.bukkit.event.entity.PlayerDeathEvent event = org.bukkit.craftbukkit.v1_20_R1.event.CraftEventFactory.callPlayerDeathEvent(this, loot, deathmessage, keepInventory);
264-
+ if (this.containerMenu != this.inventoryMenu) {
265-
+ this.closeContainer();
266-
+ }
267-
+ String deathMessage = event.getDeathMessage();
268-
+ if (deathMessage != null && !deathMessage.isEmpty() && flag) {
269-
+ Component itextcomponent;
270-
+ if (deathMessage.equals(deathmessage)) {
271-
+ itextcomponent = this.getCombatTracker().getDeathMessage();
246+
+ if (die$deathMessage.equals(die$defaultDeathMessage)) {
247+
+ component = this.getCombatTracker().getDeathMessage();
272248
+ } else {
273-
+ itextcomponent = org.bukkit.craftbukkit.v1_20_R1.util.CraftChatMessage.fromStringOrNull(deathMessage);
249+
+ component = org.bukkit.craftbukkit.v1_20_R1.util.CraftChatMessage.fromStringOrNull(die$deathMessage);
274250
+ }
275-
+ this.connection.send(new ClientboundPlayerCombatKillPacket(this.getId(), itextcomponent), PacketSendListener.exceptionallySend(() -> {
251+
+ //Ketting end
252+
this.connection.send(new ClientboundPlayerCombatKillPacket(this.getId(), component), PacketSendListener.exceptionallySend(() -> {
276253
int i = 256;
277-
- String s = component.getString(256);
278-
+ String s = itextcomponent.getString(256);
279-
Component component1 = Component.translatable("death.attack.message_too_long", Component.literal(s).withStyle(ChatFormatting.YELLOW));
280-
Component component2 = Component.translatable("death.attack.even_more_magic", this.getDisplayName()).withStyle((p_143420_) -> {
281-
return p_143420_.withHoverEvent(new HoverEvent(HoverEvent.Action.SHOW_TEXT, component1));
282-
@@ -585,12 +_,12 @@
283-
Team team = this.getTeam();
284-
if (team != null && team.getDeathMessageVisibility() != Team.Visibility.ALWAYS) {
285-
if (team.getDeathMessageVisibility() == Team.Visibility.HIDE_FOR_OTHER_TEAMS) {
286-
- this.server.getPlayerList().broadcastSystemToTeam(this, component);
287-
+ this.server.getPlayerList().broadcastSystemToTeam(this, itextcomponent);
288-
} else if (team.getDeathMessageVisibility() == Team.Visibility.HIDE_FOR_OWN_TEAM) {
289-
- this.server.getPlayerList().broadcastSystemToAllExceptTeam(this, component);
290-
+ this.server.getPlayerList().broadcastSystemToAllExceptTeam(this, itextcomponent);
291-
}
292-
} else {
293-
- this.server.getPlayerList().broadcastSystemMessage(component, false);
294-
+ this.server.getPlayerList().broadcastSystemMessage(itextcomponent, false);
295-
}
296-
} else {
297-
this.connection.send(new ClientboundPlayerCombatKillPacket(this.getId(), CommonComponents.EMPTY));
298-
@@ -601,11 +_,16 @@
254+
String s = component.getString(256);
255+
@@ -601,11 +_,19 @@
299256
this.tellNeutralMobsThatIDied();
300257
}
301258

302-
- if (!this.isSpectator()) {
303-
- this.dropAllDeathLoot(p_9035_);
304-
+ this.dropExperience();
305-
+
306-
+ if (!event.getKeepInventory()) {
307-
+ this.getInventory().clearContent();
308-
+ this.getInventory().replaceWith(recapturedDrops); //place the recaptured drops back into the inventory
259+
+ //Ketting start - moved up
260+
+ /*
261+
if (!this.isSpectator()) {
262+
this.dropAllDeathLoot(p_9035_);
309263
}
310-
+ this.setCamera(this);
311-
+ ((org.bukkit.craftbukkit.v1_20_R1.scoreboard.CraftScoreboardManager) org.bukkit.Bukkit.getScoreboardManager()).getScoreboardScores(ObjectiveCriteria.DEATH_COUNT, this.getScoreboardName(), Score::increment);
264+
+ */
312265
+ //Ketting end
266+
+ this.setCamera(this); //Ketting - CraftBukkit: Remove spectated target
313267

314268
- this.getScoreboard().forAllObjectives(ObjectiveCriteria.DEATH_COUNT, this.getScoreboardName(), Score::increment);
269+
+ //Ketting start - replace with CB variant
270+
+ ((org.bukkit.craftbukkit.v1_20_R1.scoreboard.CraftScoreboardManager) org.bukkit.Bukkit.getScoreboardManager()).getScoreboardScores(ObjectiveCriteria.DEATH_COUNT, this.getScoreboardName(), Score::increment);
271+
+ //this.getScoreboard().forAllObjectives(ObjectiveCriteria.DEATH_COUNT, this.getScoreboardName(), Score::increment);
272+
+ //Ketting end
315273
LivingEntity livingentity = this.getKillCredit();
316274
if (livingentity != null) {
317275
this.awardStat(Stats.ENTITY_KILLED_BY.get(livingentity.getType()));

patches/minecraft/net/minecraft/world/entity/LivingEntity.java.patch

Lines changed: 38 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -739,26 +739,61 @@
739739

740740
boolean flag = this.lastHurtByPlayerTime > 0;
741741
if (this.shouldDropLoot() && this.level().getGameRules().getBoolean(GameRules.RULE_DOMOBLOOT)) {
742-
@@ -1349,15 +_,42 @@
742+
@@ -1349,15 +_,76 @@
743743
}
744744

745745
this.dropEquipment();
746746
- this.dropExperience();
747+
- }
747748
+ // this.dropExperience(); //Ketting - moved down
748749
+
749750
+ Collection<ItemEntity> drops = captureDrops(null);
751+
+ if (this instanceof ServerPlayer s) handlePlayerDeath(s, drops); //Ketting
752+
+
750753
+ if (!net.minecraftforge.common.ForgeHooks.onLivingDrops(this, p_21192_, drops, i, lastHurtByPlayerTime > 0))
754+
+ drops.forEach(e -> level().addFreshEntity(e));
755+
+
756+
+ if (this instanceof ServerPlayer s && handlePlayerDeath$swap)
757+
+ s.level().getGameRules().getRule(GameRules.RULE_KEEPINVENTORY).set(handlePlayerDeath$originalKeepInv, s.getServer()); //Ketting
758+
+
759+
+ /*if (!net.minecraftforge.common.ForgeHooks.onLivingDrops(this, p_21192_, drops, i, lastHurtByPlayerTime > 0))
751760
+ //Ketting start - recapture if ServerPlayer
752761
+ {
753762
+ if (this instanceof ServerPlayer)
754763
+ this.captureDrops(drops);
755764
+ else
756765
+ drops.forEach(e -> level().addFreshEntity(e));
757766
+ }
758-
+ //Ketting end
767+
+ //Ketting end*/
759768
+
760769
+ this.dropExperience(); //Ketting
761-
}
770+
+ }
771+
+
772+
+ //Ketting start
773+
+ private boolean handlePlayerDeath$originalKeepInv;
774+
+ private boolean handlePlayerDeath$swap;
775+
+ protected org.bukkit.event.entity.PlayerDeathEvent handlePlayerDeath$event;
776+
+ private void handlePlayerDeath(ServerPlayer cast, Collection<ItemEntity> drops) {
777+
+ List<org.bukkit.inventory.ItemStack> bukkitDrops = io.izzel.tools.collection.XmapList.create((List<ItemEntity>) drops, org.bukkit.inventory.ItemStack.class,
778+
+ (ItemEntity e) -> org.bukkit.craftbukkit.v1_20_R1.inventory.CraftItemStack.asCraftMirror(e.getItem()),
779+
+ itemStack -> {
780+
+ ItemEntity itemEntity = new ItemEntity(cast.level(), cast.getX(), cast.getY(), cast.getZ(), org.bukkit.craftbukkit.v1_20_R1.inventory.CraftItemStack.asNMSCopy(itemStack));
781+
+ itemEntity.setDefaultPickUpDelay();
782+
+ return itemEntity;
783+
+ });
784+
+
785+
+ handlePlayerDeath$originalKeepInv = cast.level().getGameRules().getBoolean(GameRules.RULE_KEEPINVENTORY) || cast.isSpectator();
786+
+
787+
+ cast.keepLevel = handlePlayerDeath$originalKeepInv; // SPIGOT-2222: pre-set keepLevel
788+
+
789+
+ org.bukkit.craftbukkit.v1_20_R1.event.CraftEventFactory.callPlayerDeathEvent$skipDrops.set(true); //item drops are handled by forge
790+
+ handlePlayerDeath$event = org.bukkit.craftbukkit.v1_20_R1.event.CraftEventFactory.callPlayerDeathEvent(cast, bukkitDrops, cast.getCombatTracker().getDeathMessage().getString(), handlePlayerDeath$originalKeepInv);
791+
+
792+
+ boolean cbKeepInv = handlePlayerDeath$event.getKeepInventory();
793+
+ handlePlayerDeath$swap = handlePlayerDeath$originalKeepInv ^ cbKeepInv;
794+
+ if (handlePlayerDeath$swap) cast.level().getGameRules().getRule(GameRules.RULE_KEEPINVENTORY).set(cbKeepInv, cast.getServer());
795+
+ }
796+
+ //Ketting end
762797

763798
protected void dropEquipment() {
764799
}

src/main/java/org/bukkit/craftbukkit/v1_20_R1/event/CraftEventFactory.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -887,6 +887,7 @@ public static EntityDeathEvent callEntityDeathEvent(LivingEntity victim, List<or
887887
return event;
888888
}
889889

890+
public static AtomicBoolean callPlayerDeathEvent$skipDrops = new AtomicBoolean(false); // Ketting
890891
public static PlayerDeathEvent callPlayerDeathEvent(ServerPlayer victim, List<org.bukkit.inventory.ItemStack> drops, String deathMessage, boolean keepInventory) {
891892
CraftPlayer entity = victim.getBukkitEntity();
892893
PlayerDeathEvent event = new PlayerDeathEvent(entity, drops, victim.getExpReward(), 0, deathMessage);
@@ -901,6 +902,8 @@ public static PlayerDeathEvent callPlayerDeathEvent(ServerPlayer victim, List<or
901902
victim.expToDrop = event.getDroppedExp();
902903
victim.newExp = event.getNewExp();
903904

905+
if (callPlayerDeathEvent$skipDrops.getAndSet(false)) return event; //Ketting
906+
904907
for (org.bukkit.inventory.ItemStack stack : event.getDrops()) {
905908
if (stack == null || stack.getType() == Material.AIR) continue;
906909

0 commit comments

Comments
 (0)