From 7fca9aa1146936ae85382ce4401a684ba35eb8fa Mon Sep 17 00:00:00 2001 From: AlphaKR93 Date: Sat, 12 Nov 2022 22:26:13 +0900 Subject: [PATCH] Backport Purpur PR #1146, #1173 --- ...pur-PR-1173-Added-GoatRamEntityEvent.patch | 92 +++++++++ ...pur-PR-1173-Added-GoatRamEntityEvent.patch | 38 ++++ ...1146-feat-Cure-effects-food-property.patch | 178 ++++++++++++++++++ 3 files changed, 308 insertions(+) create mode 100644 patches/api/0009-Purpur-PR-1173-Added-GoatRamEntityEvent.patch create mode 100644 patches/server/0035-Purpur-PR-1173-Added-GoatRamEntityEvent.patch create mode 100644 patches/server/0036-Purpur-PR-1146-feat-Cure-effects-food-property.patch diff --git a/patches/api/0009-Purpur-PR-1173-Added-GoatRamEntityEvent.patch b/patches/api/0009-Purpur-PR-1173-Added-GoatRamEntityEvent.patch new file mode 100644 index 0000000..367d19c --- /dev/null +++ b/patches/api/0009-Purpur-PR-1173-Added-GoatRamEntityEvent.patch @@ -0,0 +1,92 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: AlphaKR93 +Date: Sat, 12 Nov 2022 22:19:23 +0900 +Subject: [PATCH] Purpur PR (#1173) - Added GoatRamEntityEvent + +Original by SageSphinx63920 + +Copyright (C) 2022 PurpurMC LLC + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the Software), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +diff --git a/src/main/java/org/purpurmc/purpur/event/entity/GoatRamEntityEvent.java b/src/main/java/org/purpurmc/purpur/event/entity/GoatRamEntityEvent.java +new file mode 100644 +index 0000000000000000000000000000000000000000..a07084a72340a4fc12d161e4df8a34c2835e2cfc +--- /dev/null ++++ b/src/main/java/org/purpurmc/purpur/event/entity/GoatRamEntityEvent.java +@@ -0,0 +1,59 @@ ++package org.purpurmc.purpur.event.entity; ++ ++import org.bukkit.entity.Goat; ++import org.bukkit.entity.LivingEntity; ++import org.bukkit.event.Cancellable; ++import org.bukkit.event.HandlerList; ++import org.bukkit.event.entity.EntityEvent; ++import org.jetbrains.annotations.NotNull; ++ ++/** ++ * Called when a goat rams an entity ++ */ ++public class GoatRamEntityEvent extends EntityEvent implements Cancellable { ++ private static final HandlerList handlers = new HandlerList(); ++ private final LivingEntity rammedEntity; ++ private boolean cancelled; ++ ++ public GoatRamEntityEvent(@NotNull Goat goat, @NotNull LivingEntity rammedEntity) { ++ super(goat); ++ this.rammedEntity = rammedEntity; ++ } ++ ++ /** ++ * Returns the entity that was rammed by the goat ++ * ++ * @return The rammed entity ++ */ ++ @NotNull ++ public LivingEntity getRammedEntity() { ++ return this.rammedEntity; ++ } ++ ++ @Override ++ @NotNull ++ public Goat getEntity() { ++ return (Goat) super.getEntity(); ++ } ++ ++ @Override ++ @NotNull ++ public HandlerList getHandlers() { ++ return handlers; ++ } ++ ++ @NotNull ++ public static HandlerList getHandlerList() { ++ return handlers; ++ } ++ ++ @Override ++ public boolean isCancelled() { ++ return this.cancelled; ++ } ++ ++ @Override ++ public void setCancelled(boolean cancel) { ++ this.cancelled = cancel; ++ } ++} +\ No newline at end of file diff --git a/patches/server/0035-Purpur-PR-1173-Added-GoatRamEntityEvent.patch b/patches/server/0035-Purpur-PR-1173-Added-GoatRamEntityEvent.patch new file mode 100644 index 0000000..e6b5c2d --- /dev/null +++ b/patches/server/0035-Purpur-PR-1173-Added-GoatRamEntityEvent.patch @@ -0,0 +1,38 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: AlphaKR93 +Date: Sat, 12 Nov 2022 22:18:23 +0900 +Subject: [PATCH] Purpur PR (#1173) - Added GoatRamEntityEvent + +Original by SageSphinx63920 + +Copyright (C) 2022 PurpurMC LLC + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the Software), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +diff --git a/src/main/java/net/minecraft/world/entity/animal/goat/Goat.java b/src/main/java/net/minecraft/world/entity/animal/goat/Goat.java +index 6df25a181567021ee60ea72847459e25b9ee5b99..55a9a1c9fb88773db7b84ee8857b9791c6fd5334 100644 +--- a/src/main/java/net/minecraft/world/entity/animal/goat/Goat.java ++++ b/src/main/java/net/minecraft/world/entity/animal/goat/Goat.java +@@ -401,6 +401,7 @@ public class Goat extends Animal { + + // Paper start - Goat ram API + public void ram(net.minecraft.world.entity.LivingEntity entity) { ++ if (!new org.purpurmc.purpur.event.entity.GoatRamEntityEvent((org.bukkit.entity.Goat) getBukkitEntity(), (org.bukkit.entity.LivingEntity) entity.getBukkitLivingEntity()).callEvent()) return; // Purpur + Brain brain = this.getBrain(); + brain.setMemory(MemoryModuleType.RAM_TARGET, entity.position()); + brain.eraseMemory(MemoryModuleType.RAM_COOLDOWN_TICKS); diff --git a/patches/server/0036-Purpur-PR-1146-feat-Cure-effects-food-property.patch b/patches/server/0036-Purpur-PR-1146-feat-Cure-effects-food-property.patch new file mode 100644 index 0000000..6ba095d --- /dev/null +++ b/patches/server/0036-Purpur-PR-1146-feat-Cure-effects-food-property.patch @@ -0,0 +1,178 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: AlphaKR93 +Date: Sat, 12 Nov 2022 22:25:17 +0900 +Subject: [PATCH] Purpur PR (#1146) - feat: Cure effects food property + +Original by Aniket Joshi + +Copyright (C) 2022 PurpurMC LLC + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the Software), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +diff --git a/src/main/java/net/minecraft/world/entity/LivingEntity.java b/src/main/java/net/minecraft/world/entity/LivingEntity.java +index ec097aae56979a38b482c7615b8d11264eaa4ff5..a776e8b705725d82758e96b36892b549b5df71b3 100644 +--- a/src/main/java/net/minecraft/world/entity/LivingEntity.java ++++ b/src/main/java/net/minecraft/world/entity/LivingEntity.java +@@ -4375,6 +4375,7 @@ public abstract class LivingEntity extends Entity { + if (stack.isEdible()) { + world.playSound((net.minecraft.world.entity.player.Player) null, this.getX(), this.getY(), this.getZ(), this.getEatingSound(stack), SoundSource.NEUTRAL, 1.0F, 1.0F + (world.random.nextFloat() - world.random.nextFloat()) * 0.4F); + this.addEatEffect(stack, world, this); ++ this.removeEatEffect(stack, world, this); // Purpur + if (!(this instanceof net.minecraft.world.entity.player.Player) || !((net.minecraft.world.entity.player.Player) this).getAbilities().instabuild) { + stack.shrink(1); + } +@@ -4403,6 +4404,23 @@ public abstract class LivingEntity extends Entity { + + } + ++ // Purpur start ++ private void removeEatEffect(ItemStack stack, Level world, LivingEntity targetEntity) { ++ Item item = stack.getItem(); ++ List list = item.getFoodProperties() != null ? item.getFoodProperties().getEffectsToCure() : null; ++ ++ if (list != null && !world.isClientSide && item.isEdible() && !list.isEmpty()) { ++ Map effects = targetEntity.activeEffects; ++ if (!effects.isEmpty()) { ++ for (MobEffect effect : effects.keySet()) { ++ if (list.contains(effect)) ++ targetEntity.removeEffect(effect, org.bukkit.event.entity.EntityPotionEffectEvent.Cause.FOOD); ++ } ++ } ++ } ++ } ++ // Purpur end ++ + private static byte entityEventForEquipmentBreak(EquipmentSlot slot) { + switch (slot) { + case MAINHAND: +diff --git a/src/main/java/net/minecraft/world/food/FoodProperties.java b/src/main/java/net/minecraft/world/food/FoodProperties.java +index 6c945ae8fe8b1517e312c688f829fab41f12d9f4..1ac64b2dd7cd86f994e66cfd98a41b94cf388678 100644 +--- a/src/main/java/net/minecraft/world/food/FoodProperties.java ++++ b/src/main/java/net/minecraft/world/food/FoodProperties.java +@@ -15,12 +15,20 @@ public class FoodProperties { + private boolean canAlwaysEat; public void setCanAlwaysEat(boolean canAlwaysEat) { this.canAlwaysEat = canAlwaysEat; } + private boolean fastFood; public void setFastFood(boolean isFastFood) { this.fastFood = isFastFood; } + public FoodProperties copy() { +- return new FoodProperties(this.nutrition, this.saturationModifier, this.isMeat, this.canAlwaysEat, this.fastFood, new ArrayList<>(this.effects)); ++ return new FoodProperties(this.nutrition, this.saturationModifier, this.isMeat, this.canAlwaysEat, this.fastFood, new ArrayList<>(this.effects), effectsToCure); + } ++ private final List effectsToCure; + // Purpur end + private final List> effects; + + FoodProperties(int hunger, float saturationModifier, boolean meat, boolean alwaysEdible, boolean snack, List> statusEffects) { ++ // Purpur start ++ this(hunger, saturationModifier, meat, alwaysEdible, snack, statusEffects, null); ++ } ++ ++ FoodProperties(int hunger, float saturationModifier, boolean meat, boolean alwaysEdible, boolean snack, List> statusEffects, List effectsToCure) { ++ this.effectsToCure = effectsToCure; ++ // Purpur end + this.nutrition = hunger; + this.saturationModifier = saturationModifier; + this.isMeat = meat; +@@ -53,6 +61,12 @@ public class FoodProperties { + return this.effects; + } + ++ // Purpur start ++ public List getEffectsToCure() { ++ return this.effectsToCure; ++ } ++ // Purpur end ++ + public static class Builder { + private int nutrition; + private float saturationModifier; +@@ -60,6 +74,7 @@ public class FoodProperties { + private boolean canAlwaysEat; + private boolean fastFood; + private final List> effects = Lists.newArrayList(); ++ private final List effectsToCure = new ArrayList<>(); // Purpur + + public FoodProperties.Builder nutrition(int hunger) { + this.nutrition = hunger; +@@ -91,8 +106,15 @@ public class FoodProperties { + return this; + } + ++ // Purpur start ++ public FoodProperties.Builder effectToCure(net.minecraft.world.effect.MobEffect effect) { ++ this.effectsToCure.add(effect); ++ return this; ++ } ++ // Purpur end ++ + public FoodProperties build() { +- return new FoodProperties(this.nutrition, this.saturationModifier, this.isMeat, this.canAlwaysEat, this.fastFood, this.effects); ++ return new FoodProperties(this.nutrition, this.saturationModifier, this.isMeat, this.canAlwaysEat, this.fastFood, this.effects, this.effectsToCure); // Purpur + } + } + } +diff --git a/src/main/java/net/minecraft/world/food/Foods.java b/src/main/java/net/minecraft/world/food/Foods.java +index 71beab673f04cd051c46ea37f8c847316885d38d..254611b8ae84e3ede3d61768079a35a4134ab306 100644 +--- a/src/main/java/net/minecraft/world/food/Foods.java ++++ b/src/main/java/net/minecraft/world/food/Foods.java +@@ -29,7 +29,7 @@ public class Foods { + public static final FoodProperties ENCHANTED_GOLDEN_APPLE = (new FoodProperties.Builder()).nutrition(4).saturationMod(1.2F).effect(new MobEffectInstance(MobEffects.REGENERATION, 400, 1), 1.0F).effect(new MobEffectInstance(MobEffects.DAMAGE_RESISTANCE, 6000, 0), 1.0F).effect(new MobEffectInstance(MobEffects.FIRE_RESISTANCE, 6000, 0), 1.0F).effect(new MobEffectInstance(MobEffects.ABSORPTION, 2400, 3), 1.0F).alwaysEat().build(); + public static final FoodProperties GOLDEN_APPLE = (new FoodProperties.Builder()).nutrition(4).saturationMod(1.2F).effect(new MobEffectInstance(MobEffects.REGENERATION, 100, 1), 1.0F).effect(new MobEffectInstance(MobEffects.ABSORPTION, 2400, 0), 1.0F).alwaysEat().build(); + public static final FoodProperties GOLDEN_CARROT = (new FoodProperties.Builder()).nutrition(6).saturationMod(1.2F).build(); +- public static final FoodProperties HONEY_BOTTLE = (new FoodProperties.Builder()).nutrition(6).saturationMod(0.1F).build(); ++ public static final FoodProperties HONEY_BOTTLE = (new FoodProperties.Builder()).nutrition(6).saturationMod(0.1F).effectToCure(MobEffects.POISON).build(); // Purpur + public static final FoodProperties MELON_SLICE = (new FoodProperties.Builder()).nutrition(2).saturationMod(0.3F).build(); + public static final FoodProperties MUSHROOM_STEW = stew(6).build(); + public static final FoodProperties MUTTON = (new FoodProperties.Builder()).nutrition(2).saturationMod(0.3F).meat().build(); +diff --git a/src/main/java/net/minecraft/world/item/HoneyBottleItem.java b/src/main/java/net/minecraft/world/item/HoneyBottleItem.java +index c8d6b5e60b6c8c612fa8580c63a32c4a8f8b0a7b..54c3c7b82cbd2cab801f80dd711b6a7cf117a5b9 100644 +--- a/src/main/java/net/minecraft/world/item/HoneyBottleItem.java ++++ b/src/main/java/net/minecraft/world/item/HoneyBottleItem.java +@@ -27,9 +27,11 @@ public class HoneyBottleItem extends Item { + serverPlayer.awardStat(Stats.ITEM_USED.get(this)); + } + ++ /* // Purpur - moved this to default food properties. + if (!world.isClientSide) { + user.removeEffect(MobEffects.POISON, org.bukkit.event.entity.EntityPotionEffectEvent.Cause.FOOD); // Paper + } ++ */ // Purpur - moved this to default food properties. + + if (stack.isEmpty()) { + return new ItemStack(Items.GLASS_BOTTLE); +diff --git a/src/main/java/org/purpurmc/purpur/PurpurConfig.java b/src/main/java/org/purpurmc/purpur/PurpurConfig.java +index 369208531e284e8cd84df3dd8f5af0861f06792a..224f638d3f08d5f25aef6a5151fdc5a92e42e27b 100644 +--- a/src/main/java/org/purpurmc/purpur/PurpurConfig.java ++++ b/src/main/java/org/purpurmc/purpur/PurpurConfig.java +@@ -575,6 +575,18 @@ public class PurpurConfig { + food.getEffects().add(Pair.of(new MobEffectInstance(effect, duration, amplifier, ambient, visible, showIcon), chance)); + }); + } ++ List effectsToCure = properties.getStringList(foodKey + ".cure-effects"); ++ if (!effectsToCure.isEmpty()) { ++ effectsToCure.forEach(effectKey -> { ++ MobEffect effect = Registry.MOB_EFFECT.get(new ResourceLocation(effectKey)); ++ if (effect == null) { ++ PurpurConfig.log(Level.SEVERE, "Invalid food property cure effect for " + foodKey + ": " + effectKey); ++ return; ++ } ++ food.getEffectsToCure().removeIf(pair -> pair == effect); ++ food.getEffectsToCure().add(effect); ++ }); ++ } else food.getEffectsToCure().clear(); + }); + } +