Skip to content

Commit

Permalink
Merge pull request #320 from kettingpowered/test/player-death-rewrite
Browse files Browse the repository at this point in the history
Player death events rewrite
  • Loading branch information
JustRed23 authored Jul 30, 2024
2 parents 48d9c83 + 7351e88 commit 0c30fb3
Show file tree
Hide file tree
Showing 3 changed files with 86 additions and 83 deletions.
104 changes: 31 additions & 73 deletions patches/minecraft/net/minecraft/server/level/ServerPlayer.java.patch
Original file line number Diff line number Diff line change
Expand Up @@ -211,7 +211,7 @@
} catch (Throwable throwable) {
CrashReport crashreport = CrashReport.forThrowable(throwable, "Ticking player");
CrashReportCategory crashreportcategory = crashreport.addCategory("Player being ticked");
@@ -563,19 +_,62 @@
@@ -563,16 +_,37 @@
}

private void updateScoreForCriteria(ObjectiveCriteria p_9105_, int p_9106_) {
Expand All @@ -222,96 +222,54 @@
});
}

+ //Ketting start - mixin
+ private @Nullable String die$deathMessage;
+ private String die$defaultDeathMessage;
+ //Ketting end
public void die(DamageSource p_9035_) {
this.gameEvent(GameEvent.ENTITY_DIE);
+ if (net.minecraftforge.common.ForgeHooks.onLivingDeath(this, p_9035_)) return;
boolean flag = this.level().getGameRules().getBoolean(GameRules.RULE_SHOWDEATHMESSAGES);
- if (flag) {
- Component component = this.getCombatTracker().getDeathMessage();
- this.connection.send(new ClientboundPlayerCombatKillPacket(this.getId(), component), PacketSendListener.exceptionallySend(() -> {
+ //Ketting start
+ if (this.isRemoved()) return;
+ boolean keepInventory = this.level().getGameRules().getBoolean(GameRules.RULE_KEEPINVENTORY) || this.isSpectator();
+ Inventory copyInv;
+ if (keepInventory) {
+ copyInv = this.getInventory();
+ } else {
+ copyInv = new Inventory(this);
+ copyInv.replaceWith(this.getInventory());
+ }
+ this.dropAllDeathLoot(p_9035_);
+
+ Component defaultMessage = this.getCombatTracker().getDeathMessage();
+ String deathmessage = defaultMessage.getString();
+
+ List<org.bukkit.inventory.ItemStack> loot = new java.util.ArrayList<>();
+ Collection<ItemEntity> drops = this.captureDrops(null);
+
+ if (drops != null) {
+ for (ItemEntity entity : drops) {
+ org.bukkit.craftbukkit.v1_20_R1.inventory.CraftItemStack craftItemStack = org.bukkit.craftbukkit.v1_20_R1.inventory.CraftItemStack.asCraftMirror(entity.getItem());
+ loot.add(craftItemStack);
+ }
+ die$defaultDeathMessage = this.getCombatTracker().getDeathMessage().getString();
+ if (!this.isSpectator()) {
+ this.dropAllDeathLoot(p_9035_);
+ die$deathMessage = this.handlePlayerDeath$event.getDeathMessage();
+ }
+ this.keepLevel = keepInventory;
boolean flag = this.level().getGameRules().getBoolean(GameRules.RULE_SHOWDEATHMESSAGES);
- if (flag) {
- Component component = this.getCombatTracker().getDeathMessage();
+ if (die$deathMessage != null && die$deathMessage.length() > 0 && flag) {
+ Component component;
+
+ Inventory recapturedDrops = new Inventory(this); //recapture drops that got added back to the inventory (eg. soulbound items)
+ if (!keepInventory) {
+ recapturedDrops.replaceWith(this.getInventory());
+ this.getInventory().replaceWith(copyInv);
+ }
+ org.bukkit.event.entity.PlayerDeathEvent event = org.bukkit.craftbukkit.v1_20_R1.event.CraftEventFactory.callPlayerDeathEvent(this, loot, deathmessage, keepInventory);
+ if (this.containerMenu != this.inventoryMenu) {
+ this.closeContainer();
+ }
+ String deathMessage = event.getDeathMessage();
+ if (deathMessage != null && !deathMessage.isEmpty() && flag) {
+ Component itextcomponent;
+ if (deathMessage.equals(deathmessage)) {
+ itextcomponent = this.getCombatTracker().getDeathMessage();
+ if (die$deathMessage.equals(die$defaultDeathMessage)) {
+ component = this.getCombatTracker().getDeathMessage();
+ } else {
+ itextcomponent = org.bukkit.craftbukkit.v1_20_R1.util.CraftChatMessage.fromStringOrNull(deathMessage);
+ component = org.bukkit.craftbukkit.v1_20_R1.util.CraftChatMessage.fromStringOrNull(die$deathMessage);
+ }
+ this.connection.send(new ClientboundPlayerCombatKillPacket(this.getId(), itextcomponent), PacketSendListener.exceptionallySend(() -> {
+ //Ketting end
this.connection.send(new ClientboundPlayerCombatKillPacket(this.getId(), component), PacketSendListener.exceptionallySend(() -> {
int i = 256;
- String s = component.getString(256);
+ String s = itextcomponent.getString(256);
Component component1 = Component.translatable("death.attack.message_too_long", Component.literal(s).withStyle(ChatFormatting.YELLOW));
Component component2 = Component.translatable("death.attack.even_more_magic", this.getDisplayName()).withStyle((p_143420_) -> {
return p_143420_.withHoverEvent(new HoverEvent(HoverEvent.Action.SHOW_TEXT, component1));
@@ -585,12 +_,12 @@
Team team = this.getTeam();
if (team != null && team.getDeathMessageVisibility() != Team.Visibility.ALWAYS) {
if (team.getDeathMessageVisibility() == Team.Visibility.HIDE_FOR_OTHER_TEAMS) {
- this.server.getPlayerList().broadcastSystemToTeam(this, component);
+ this.server.getPlayerList().broadcastSystemToTeam(this, itextcomponent);
} else if (team.getDeathMessageVisibility() == Team.Visibility.HIDE_FOR_OWN_TEAM) {
- this.server.getPlayerList().broadcastSystemToAllExceptTeam(this, component);
+ this.server.getPlayerList().broadcastSystemToAllExceptTeam(this, itextcomponent);
}
} else {
- this.server.getPlayerList().broadcastSystemMessage(component, false);
+ this.server.getPlayerList().broadcastSystemMessage(itextcomponent, false);
}
} else {
this.connection.send(new ClientboundPlayerCombatKillPacket(this.getId(), CommonComponents.EMPTY));
@@ -601,11 +_,16 @@
String s = component.getString(256);
@@ -601,11 +_,19 @@
this.tellNeutralMobsThatIDied();
}

- if (!this.isSpectator()) {
- this.dropAllDeathLoot(p_9035_);
+ this.dropExperience();
+
+ if (!event.getKeepInventory()) {
+ this.getInventory().clearContent();
+ this.getInventory().replaceWith(recapturedDrops); //place the recaptured drops back into the inventory
+ //Ketting start - moved up
+ /*
if (!this.isSpectator()) {
this.dropAllDeathLoot(p_9035_);
}
+ this.setCamera(this);
+ ((org.bukkit.craftbukkit.v1_20_R1.scoreboard.CraftScoreboardManager) org.bukkit.Bukkit.getScoreboardManager()).getScoreboardScores(ObjectiveCriteria.DEATH_COUNT, this.getScoreboardName(), Score::increment);
+ */
+ //Ketting end
+ this.setCamera(this); //Ketting - CraftBukkit: Remove spectated target

- this.getScoreboard().forAllObjectives(ObjectiveCriteria.DEATH_COUNT, this.getScoreboardName(), Score::increment);
+ //Ketting start - replace with CB variant
+ ((org.bukkit.craftbukkit.v1_20_R1.scoreboard.CraftScoreboardManager) org.bukkit.Bukkit.getScoreboardManager()).getScoreboardScores(ObjectiveCriteria.DEATH_COUNT, this.getScoreboardName(), Score::increment);
+ //this.getScoreboard().forAllObjectives(ObjectiveCriteria.DEATH_COUNT, this.getScoreboardName(), Score::increment);
+ //Ketting end
LivingEntity livingentity = this.getKillCredit();
if (livingentity != null) {
this.awardStat(Stats.ENTITY_KILLED_BY.get(livingentity.getType()));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -720,8 +720,11 @@
this.level().addFreshEntity(itementity);
}
}
@@ -1335,12 +_,12 @@
@@ -1333,14 +_,15 @@
}
}

+ private Collection<ItemEntity> dropAllDeathLoot$dropsCopy; //Ketting
protected void dropAllDeathLoot(DamageSource p_21192_) {
Entity entity = p_21192_.getEntity();
- int i;
Expand All @@ -739,26 +742,65 @@

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

this.dropEquipment();
- this.dropExperience();
- }
+ // this.dropExperience(); //Ketting - moved down
+
+ Collection<ItemEntity> drops = captureDrops(null);
+ if (!net.minecraftforge.common.ForgeHooks.onLivingDrops(this, p_21192_, drops, i, lastHurtByPlayerTime > 0))
+ //Ketting start - recapture if ServerPlayer
+ {
+ if (this instanceof ServerPlayer)
+ this.captureDrops(drops);
+ else
+ drops.forEach(e -> level().addFreshEntity(e));
+
+ //Ketting start
+ if (this instanceof ServerPlayer s) {
+ dropAllDeathLoot$dropsCopy = new java.util.ArrayList<ItemEntity>(drops); //Ketting
+ handlePlayerDeath(s, drops);
+ }
+ //Ketting end
+
+ if (!net.minecraftforge.common.ForgeHooks.onLivingDrops(this, p_21192_, drops, i, lastHurtByPlayerTime > 0) && !handlePlayerDeath$cbKeepInv) //Ketting
+ drops.forEach(e -> level().addFreshEntity(e));
+
+ //Ketting start
+ if (this instanceof ServerPlayer s) {
+ if (handlePlayerDeath$swap) s.level().getGameRules().getRule(GameRules.RULE_KEEPINVENTORY).set(handlePlayerDeath$originalKeepInv, s.getServer());
+ if (handlePlayerDeath$cbKeepInv) {
+ if (!drops.isEmpty()) dropAllDeathLoot$dropsCopy.addAll(drops); //Plugins can still add items
+ dropAllDeathLoot$dropsCopy.forEach(e -> s.getInventory().add(e.getItem()));
+ }
+ }
+ //Ketting end
+
+ this.dropExperience(); //Ketting
}
+ }
+
+ //Ketting start
+ private boolean handlePlayerDeath$originalKeepInv;
+ private boolean handlePlayerDeath$cbKeepInv;
+ private boolean handlePlayerDeath$swap;
+ protected org.bukkit.event.entity.PlayerDeathEvent handlePlayerDeath$event;
+ private void handlePlayerDeath(ServerPlayer cast, Collection<ItemEntity> drops) {
+ List<org.bukkit.inventory.ItemStack> bukkitDrops = io.izzel.tools.collection.XmapList.create((List<ItemEntity>) drops, org.bukkit.inventory.ItemStack.class,
+ (ItemEntity e) -> org.bukkit.craftbukkit.v1_20_R1.inventory.CraftItemStack.asCraftMirror(e.getItem()),
+ itemStack -> {
+ ItemEntity itemEntity = new ItemEntity(cast.level(), cast.getX(), cast.getY(), cast.getZ(), org.bukkit.craftbukkit.v1_20_R1.inventory.CraftItemStack.asNMSCopy(itemStack));
+ itemEntity.setDefaultPickUpDelay();
+ return itemEntity;
+ });
+
+ handlePlayerDeath$originalKeepInv = cast.level().getGameRules().getBoolean(GameRules.RULE_KEEPINVENTORY);
+
+ cast.keepLevel = handlePlayerDeath$originalKeepInv || cast.isSpectator(); // SPIGOT-2222: pre-set keepLevel
+
+ org.bukkit.craftbukkit.v1_20_R1.event.CraftEventFactory.callPlayerDeathEvent$skipDrops.set(true); //item drops are handled by forge
+ handlePlayerDeath$event = org.bukkit.craftbukkit.v1_20_R1.event.CraftEventFactory.callPlayerDeathEvent(cast, bukkitDrops, cast.getCombatTracker().getDeathMessage().getString(), handlePlayerDeath$originalKeepInv || cast.isSpectator());
+
+ handlePlayerDeath$cbKeepInv = handlePlayerDeath$event.getKeepInventory();
+ handlePlayerDeath$swap = handlePlayerDeath$originalKeepInv ^ handlePlayerDeath$cbKeepInv;
+ if (handlePlayerDeath$swap) cast.level().getGameRules().getRule(GameRules.RULE_KEEPINVENTORY).set(handlePlayerDeath$cbKeepInv, cast.getServer());
+ }
+ //Ketting end

protected void dropEquipment() {
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -887,6 +887,7 @@ public static EntityDeathEvent callEntityDeathEvent(LivingEntity victim, List<or
return event;
}

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

if (callPlayerDeathEvent$skipDrops.getAndSet(false)) return event; //Ketting

for (org.bukkit.inventory.ItemStack stack : event.getDrops()) {
if (stack == null || stack.getType() == Material.AIR) continue;

Expand Down

0 comments on commit 0c30fb3

Please sign in to comment.