From c5df81cb7d0c74682e83951407ad75292a3e7e0c Mon Sep 17 00:00:00 2001 From: Campbell Suter Date: Tue, 16 Jun 2020 12:42:38 +1200 Subject: [PATCH 1/3] Add the PlayerXpEvent events (add XP points/level, pickup XP orb) --- .../entity/player/PlayerPickupXpEvent.java | 34 +++++++ .../event/entity/player/PlayerXpEvent.java | 90 +++++++++++++++++++ .../entity/MixinExperienceOrbEntity.java | 47 ++++++++++ .../mixin/event/entity/MixinPlayerEntity.java | 26 ++++++ .../patchwork-events-entity.mixins.json | 1 + 5 files changed, 198 insertions(+) create mode 100644 patchwork-events-entity/src/main/java/net/minecraftforge/event/entity/player/PlayerPickupXpEvent.java create mode 100644 patchwork-events-entity/src/main/java/net/minecraftforge/event/entity/player/PlayerXpEvent.java create mode 100644 patchwork-events-entity/src/main/java/net/patchworkmc/mixin/event/entity/MixinExperienceOrbEntity.java diff --git a/patchwork-events-entity/src/main/java/net/minecraftforge/event/entity/player/PlayerPickupXpEvent.java b/patchwork-events-entity/src/main/java/net/minecraftforge/event/entity/player/PlayerPickupXpEvent.java new file mode 100644 index 00000000..fe2ae604 --- /dev/null +++ b/patchwork-events-entity/src/main/java/net/minecraftforge/event/entity/player/PlayerPickupXpEvent.java @@ -0,0 +1,34 @@ +/* + * Minecraft Forge, Patchwork Project + * Copyright (c) 2016-2020, 2019-2020 + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation version 2.1 + * of the License. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +package net.minecraftforge.event.entity.player; + +import net.minecraft.entity.ExperienceOrbEntity; +import net.minecraft.entity.player.PlayerEntity; + +/** + * Legacy version of PlayerXpEvent.PickupXp. Mods should move to PickupXp, and + * this class is removed in 1.15. + */ +@Deprecated +public class PlayerPickupXpEvent extends PlayerXpEvent.PickupXp { + public PlayerPickupXpEvent(PlayerEntity player, ExperienceOrbEntity orb) { + super(player, orb); + } +} diff --git a/patchwork-events-entity/src/main/java/net/minecraftforge/event/entity/player/PlayerXpEvent.java b/patchwork-events-entity/src/main/java/net/minecraftforge/event/entity/player/PlayerXpEvent.java new file mode 100644 index 00000000..a639049b --- /dev/null +++ b/patchwork-events-entity/src/main/java/net/minecraftforge/event/entity/player/PlayerXpEvent.java @@ -0,0 +1,90 @@ +/* + * Minecraft Forge, Patchwork Project + * Copyright (c) 2016-2020, 2019-2020 + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation version 2.1 + * of the License. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +package net.minecraftforge.event.entity.player; + +import net.minecraft.entity.ExperienceOrbEntity; +import net.minecraft.entity.player.PlayerEntity; + +public abstract class PlayerXpEvent extends PlayerEvent { + public PlayerXpEvent(PlayerEntity player) { + super(player); + } + + // For legacy reasons, the instances of this class should actually be of + // type PlayerPickupXpEvent + public static class PickupXp extends CancelablePlayerXpEvent { + private final ExperienceOrbEntity orb; + + public PickupXp(PlayerEntity player, ExperienceOrbEntity orb) { + super(player); + this.orb = orb; + } + + public ExperienceOrbEntity getOrb() { + return orb; + } + } + + public static class XpChange extends CancelablePlayerXpEvent { + private int amount; + + public XpChange(PlayerEntity player, int amount) { + super(player); + this.amount = amount; + } + + public int getAmount() { + return amount; + } + + public void setAmount(int amount) { + this.amount = amount; + } + } + + public static class LevelChange extends CancelablePlayerXpEvent { + private int levels; + + public LevelChange(PlayerEntity player, int levels) { + super(player); + this.levels = levels; + } + + public int getLevels() { + return this.levels; + } + + public void setLevels(int levels) { + this.levels = levels; + } + } + + // Helper, so we don't have to repeat isCancelable all the time + private static class CancelablePlayerXpEvent extends PlayerXpEvent { + private CancelablePlayerXpEvent(PlayerEntity player) { + super(player); + } + + @Override + public boolean isCancelable() { + return true; + } + } +} diff --git a/patchwork-events-entity/src/main/java/net/patchworkmc/mixin/event/entity/MixinExperienceOrbEntity.java b/patchwork-events-entity/src/main/java/net/patchworkmc/mixin/event/entity/MixinExperienceOrbEntity.java new file mode 100644 index 00000000..01e2bdaa --- /dev/null +++ b/patchwork-events-entity/src/main/java/net/patchworkmc/mixin/event/entity/MixinExperienceOrbEntity.java @@ -0,0 +1,47 @@ +/* + * Minecraft Forge, Patchwork Project + * Copyright (c) 2016-2020, 2019-2020 + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation version 2.1 + * of the License. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +package net.patchworkmc.mixin.event.entity; + +import net.minecraftforge.common.MinecraftForge; +import net.minecraftforge.event.entity.player.PlayerPickupXpEvent; +import org.objectweb.asm.Opcodes; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; + +import net.minecraft.entity.player.PlayerEntity; +import net.minecraft.entity.ExperienceOrbEntity; + +@Mixin(ExperienceOrbEntity.class) +public class MixinExperienceOrbEntity { + // After checking we're on the server and the player is ready to pick up the orb, the first + // thing the target method does is set experiencePickUpDelay, hence hook just before that. + @Inject(method = "onPlayerCollision", cancellable = true, at = @At(value = "FIELD", opcode = Opcodes.H_PUTFIELD, ordinal = 0, + target = "net/minecraft/entity/player/PlayerEntity.experiencePickUpDelay:I")) + private void hookOnPlayerCollisionForPickup(PlayerEntity player, CallbackInfo ci) { + @SuppressWarnings("ConstantConditions") + ExperienceOrbEntity entity = (ExperienceOrbEntity) (Object) this; + + if (MinecraftForge.EVENT_BUS.post(new PlayerPickupXpEvent(player, entity))) { + ci.cancel(); + } + } +} diff --git a/patchwork-events-entity/src/main/java/net/patchworkmc/mixin/event/entity/MixinPlayerEntity.java b/patchwork-events-entity/src/main/java/net/patchworkmc/mixin/event/entity/MixinPlayerEntity.java index 8ab0389b..1cdbfb47 100644 --- a/patchwork-events-entity/src/main/java/net/patchworkmc/mixin/event/entity/MixinPlayerEntity.java +++ b/patchwork-events-entity/src/main/java/net/patchworkmc/mixin/event/entity/MixinPlayerEntity.java @@ -19,6 +19,8 @@ package net.patchworkmc.mixin.event.entity; +import net.minecraftforge.common.MinecraftForge; +import net.minecraftforge.event.entity.player.PlayerXpEvent; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Shadow; import org.spongepowered.asm.mixin.injection.At; @@ -128,4 +130,28 @@ private void onAttackEntity(Entity target, CallbackInfo callback) { callback.cancel(); } } + + @ModifyVariable(method = "addExperience", at = @At("HEAD"), ordinal = 0) + private int onAddExperience(int points) { + @SuppressWarnings("ConstantConditions") + PlayerEntity player = (PlayerEntity) (Object) this; + + PlayerXpEvent.XpChange event = new PlayerXpEvent.XpChange(player, points); + MinecraftForge.EVENT_BUS.post(event); + + // The only effect of passing in zero is a call to addScore(0), which shouldn't have any effect. + return event.isCanceled() ? 0 : event.getAmount(); + } + + @ModifyVariable(method = "addExperienceLevels", at = @At("HEAD"), ordinal = 0) + private int onAddExperienceLevels(int levels) { + @SuppressWarnings("ConstantConditions") + PlayerEntity player = (PlayerEntity) (Object) this; + + PlayerXpEvent.LevelChange event = new PlayerXpEvent.LevelChange(player, levels); + MinecraftForge.EVENT_BUS.post(event); + + // There are no effects from passing in zero levels, so do that if we've been canceled + return event.isCanceled() ? 0 : event.getLevels(); + } } diff --git a/patchwork-events-entity/src/main/resources/patchwork-events-entity.mixins.json b/patchwork-events-entity/src/main/resources/patchwork-events-entity.mixins.json index 24e97798..3cb142e6 100644 --- a/patchwork-events-entity/src/main/resources/patchwork-events-entity.mixins.json +++ b/patchwork-events-entity/src/main/resources/patchwork-events-entity.mixins.json @@ -5,6 +5,7 @@ "mixins": [ "MixinEntity", "MixinEntityType", + "MixinExperienceOrbEntity", "MixinLivingEntity", "MixinMobEntity", "MixinMobSpawnerLogic", From d5f0ff4b0601a6e3276212a44f36c7824f66e43c Mon Sep 17 00:00:00 2001 From: Campbell Suter Date: Fri, 19 Jun 2020 17:54:20 +1200 Subject: [PATCH 2/3] Fix the Javadoc for PlayerXpEvent.PickupXp --- .../event/entity/player/PlayerXpEvent.java | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/patchwork-events-entity/src/main/java/net/minecraftforge/event/entity/player/PlayerXpEvent.java b/patchwork-events-entity/src/main/java/net/minecraftforge/event/entity/player/PlayerXpEvent.java index a639049b..d53f91f1 100644 --- a/patchwork-events-entity/src/main/java/net/minecraftforge/event/entity/player/PlayerXpEvent.java +++ b/patchwork-events-entity/src/main/java/net/minecraftforge/event/entity/player/PlayerXpEvent.java @@ -27,8 +27,13 @@ public PlayerXpEvent(PlayerEntity player) { super(player); } - // For legacy reasons, the instances of this class should actually be of - // type PlayerPickupXpEvent + /** + * An event representing a player picking up an XP orb entity. + *

+ * For legacy reasons, the instances of this class should actually be of + * type {@link PlayerPickupXpEvent} + *

+ */ public static class PickupXp extends CancelablePlayerXpEvent { private final ExperienceOrbEntity orb; From ed8c8d4d9a41e7456c588d3b4be9a37417e0327f Mon Sep 17 00:00:00 2001 From: Campbell Suter Date: Sat, 20 Jun 2020 13:17:40 +1200 Subject: [PATCH 3/3] Bump patchwork-events-entity from v0.3.0 to v0.4.0 --- patchwork-events-entity/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/patchwork-events-entity/build.gradle b/patchwork-events-entity/build.gradle index ee9ee549..057f81d7 100644 --- a/patchwork-events-entity/build.gradle +++ b/patchwork-events-entity/build.gradle @@ -1,5 +1,5 @@ archivesBaseName = "patchwork-events-entity" -version = getSubprojectVersion(project, "0.3.0") +version = getSubprojectVersion(project, "0.4.0") dependencies { compile project(path: ':patchwork-fml', configuration: 'dev')