From ca811271c20c4a16712538a5179ae5c3ae2be87b Mon Sep 17 00:00:00 2001 From: cheaterpaul Date: Thu, 25 Jul 2024 22:33:24 +0200 Subject: [PATCH] add skill handler events --- .../api/entity/player/skills/ISkill.java | 3 +- .../vampirism/api/event/ActionEvent.java | 4 +- .../vampirism/api/event/SkillEvents.java | 119 ++++++++++++++++++ .../entity/player/skills/SkillHandler.java | 9 ++ .../vampirism/util/VampirismEventFactory.java | 30 +++-- 5 files changed, 153 insertions(+), 12 deletions(-) create mode 100644 src/api/java/de/teamlapen/vampirism/api/event/SkillEvents.java diff --git a/src/api/java/de/teamlapen/vampirism/api/entity/player/skills/ISkill.java b/src/api/java/de/teamlapen/vampirism/api/entity/player/skills/ISkill.java index 28776474d..d1fec070c 100755 --- a/src/api/java/de/teamlapen/vampirism/api/entity/player/skills/ISkill.java +++ b/src/api/java/de/teamlapen/vampirism/api/entity/player/skills/ISkill.java @@ -3,7 +3,6 @@ import com.mojang.datafixers.util.Either; import de.teamlapen.vampirism.api.entity.factions.IFaction; import de.teamlapen.vampirism.api.entity.factions.ISkillTree; -import de.teamlapen.vampirism.api.entity.player.IFactionPlayer; import de.teamlapen.vampirism.api.entity.player.ISkillPlayer; import net.minecraft.network.chat.Component; import net.minecraft.network.chat.MutableComponent; @@ -15,7 +14,7 @@ /** * Skill that tha unlocks abilities for a player. */ -public interface ISkill & ISkillPlayer> extends ISkillLike { +public interface ISkill> extends ISkillLike { /** * The description for this skill or null if there is no description. */ diff --git a/src/api/java/de/teamlapen/vampirism/api/event/ActionEvent.java b/src/api/java/de/teamlapen/vampirism/api/event/ActionEvent.java index 74eaa7963..2ed1fbd6a 100644 --- a/src/api/java/de/teamlapen/vampirism/api/event/ActionEvent.java +++ b/src/api/java/de/teamlapen/vampirism/api/event/ActionEvent.java @@ -124,7 +124,7 @@ public void setCancelMessage(@NotNull Component message) { /** * Posted when an action deactivates, either when deactivated manually or when out of time. As regular actions instantly deactivate, this only fires for actions that implement ILastingAction. */ - public static class ActionDeactivatedEvent & ISkillPlayer> extends ActionEvent> { + public static class ActionDeactivatedEvent> extends ActionEvent> { private final int remainingDuration; private int cooldown; private boolean ignoreCooldown; @@ -197,7 +197,7 @@ public void setFullCooldown(boolean fullCooldown) { /** * Posted when an action deactivates, either when deactivated manually or when out of time. As regular actions instantly deactivate, this only fires for actions that implement {@link de.teamlapen.vampirism.api.entity.player.actions.ILastingAction}. */ - public static class ActionUpdateEvent & ISkillPlayer> extends ActionEvent> { + public static class ActionUpdateEvent> extends ActionEvent> { private final int remainingDuration; private boolean deactivate; private boolean skipActionUpdate; diff --git a/src/api/java/de/teamlapen/vampirism/api/event/SkillEvents.java b/src/api/java/de/teamlapen/vampirism/api/event/SkillEvents.java new file mode 100644 index 000000000..3845bede9 --- /dev/null +++ b/src/api/java/de/teamlapen/vampirism/api/event/SkillEvents.java @@ -0,0 +1,119 @@ +package de.teamlapen.vampirism.api.event; + +import de.teamlapen.vampirism.api.entity.player.ISkillPlayer; +import de.teamlapen.vampirism.api.entity.player.skills.ISkill; +import de.teamlapen.vampirism.api.entity.player.skills.ISkillHandler; +import net.minecraft.core.Holder; +import net.minecraft.world.entity.player.Player; +import net.neoforged.bus.api.Event; +import org.jetbrains.annotations.ApiStatus; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +/** + * Event related to any skill changes of players + */ +public abstract class SkillEvents, Z extends ISkill> extends Event { + + @NotNull + private final T factionPlayer; + @NotNull + private final Holder skill; + + @ApiStatus.Internal + public SkillEvents(@NotNull T skillPlayer, @NotNull Holder skill) { + this.factionPlayer = skillPlayer; + this.skill = skill; + } + + /** + * @return The skill Player for which this event is fired + */ + public @NotNull ISkillPlayer getFactionPlayer() { + return this.factionPlayer; + } + + /** + * @return The skill the event is firing for. + */ + public @NotNull Holder skill() { + return this.skill; + } + + /** + * @return The player for which this event is fired + */ + @NotNull + public Player getPlayer() { + return this.factionPlayer.asEntity(); + } + + /** + * This event is posted before the skill check is conducted. + * If {@link #result} is set using {@link #setResult(de.teamlapen.vampirism.api.entity.player.skills.ISkillHandler.Result)} the check will be skipped. and {@link #getResult()} will be used as the result. + */ + public static class SkillUnlockCheckEvent> extends SkillEvents> { + + @Nullable + private ISkillHandler.Result result; + + @ApiStatus.Internal + @SuppressWarnings("unchecked") + public SkillUnlockCheckEvent(@NotNull T skillPlayer, @NotNull Holder> skill) { + super(skillPlayer, (Holder>) skill); + } + + /** + * Set the result of {@link de.teamlapen.vampirism.api.entity.player.skills.ISkillHandler#canSkillBeEnabled(net.minecraft.core.Holder)} + */ + public void setResult(@Nullable ISkillHandler.Result result) { + this.result = result; + } + + /** + * The current result if this event + */ + @Nullable + public ISkillHandler.Result getResult() { + return this.result; + } + + } + + /** + * Fired when a skill is disabled for a player + */ + public static class SkillDisableEvent> extends SkillEvents> { + + @ApiStatus.Internal + @SuppressWarnings("unchecked") + public SkillDisableEvent(@NotNull T skillPlayer, @NotNull Holder> skill) { + super(skillPlayer, (Holder>) skill); + } + + } + + /** + * Fired when a skill is enabled for a player + */ + public static class SkillEnableEvent> extends SkillEvents> { + + private final boolean fromLoading; + + @ApiStatus.Internal + @SuppressWarnings("unchecked") + public SkillEnableEvent(@NotNull T factionPlayer, @NotNull Holder> skill, boolean fromLoading) { + super(factionPlayer, (Holder>) skill); + this.fromLoading = fromLoading; + } + + /** + * @return If the skill is enabled because the player is loaded from the save file + */ + public boolean isFromLoading() { + return fromLoading; + } + + } + +} diff --git a/src/main/java/de/teamlapen/vampirism/entity/player/skills/SkillHandler.java b/src/main/java/de/teamlapen/vampirism/entity/player/skills/SkillHandler.java index ee70e49a5..caa338196 100755 --- a/src/main/java/de/teamlapen/vampirism/entity/player/skills/SkillHandler.java +++ b/src/main/java/de/teamlapen/vampirism/entity/player/skills/SkillHandler.java @@ -18,6 +18,7 @@ import de.teamlapen.vampirism.core.ModStats; import de.teamlapen.vampirism.data.ISkillTreeData; import de.teamlapen.vampirism.util.RegUtil; +import de.teamlapen.vampirism.util.VampirismEventFactory; import net.minecraft.core.Holder; import net.minecraft.core.HolderLookup; import net.minecraft.core.Registry; @@ -62,6 +63,11 @@ public ISkillTreeData getTreeData() { @Override public @NotNull Result canSkillBeEnabled(@NotNull Holder> skill) { + var preResult = VampirismEventFactory.fireSkillUnlockCheckEvent(this.player, skill); + if (preResult != null) { + return preResult; + } + if (player.asEntity().getEffect(ModEffects.OBLIVION) != null) { return Result.LOCKED_BY_PLAYER_STATE; } @@ -91,6 +97,7 @@ public ISkillTreeData getTreeData() { public void disableAllSkills() { for (Holder> skill : enabledSkills) { + VampirismEventFactory.fireSkillDisabledEvent(player, skill); skill.value().onDisable(player); } enabledSkills.clear(); @@ -100,6 +107,7 @@ public void disableAllSkills() { @Override public void disableSkill(@NotNull Holder> skill) { if (enabledSkills.remove(skill)) { + VampirismEventFactory.fireSkillDisabledEvent(player, skill); skill.value().onDisable(player); dirty = true; } @@ -108,6 +116,7 @@ public void disableSkill(@NotNull Holder> skill) { @Override public void enableSkill(@NotNull Holder> skill, boolean fromLoading) { if (!enabledSkills.contains(skill)) { + VampirismEventFactory.fireSkillEnableEvent(player, skill, fromLoading); skill.value().onEnable(player); enabledSkills.add(skill); if (!fromLoading) { diff --git a/src/main/java/de/teamlapen/vampirism/util/VampirismEventFactory.java b/src/main/java/de/teamlapen/vampirism/util/VampirismEventFactory.java index 217b95f9a..8381949b4 100644 --- a/src/main/java/de/teamlapen/vampirism/util/VampirismEventFactory.java +++ b/src/main/java/de/teamlapen/vampirism/util/VampirismEventFactory.java @@ -2,17 +2,15 @@ import de.teamlapen.vampirism.api.entity.factions.IFactionPlayerHandler; import de.teamlapen.vampirism.api.entity.factions.IPlayableFaction; -import de.teamlapen.vampirism.api.entity.player.IFactionPlayer; import de.teamlapen.vampirism.api.entity.player.ISkillPlayer; import de.teamlapen.vampirism.api.entity.player.actions.IAction; import de.teamlapen.vampirism.api.entity.player.actions.ILastingAction; +import de.teamlapen.vampirism.api.entity.player.skills.ISkill; +import de.teamlapen.vampirism.api.entity.player.skills.ISkillHandler; import de.teamlapen.vampirism.api.entity.player.vampire.IDrinkBloodContext; import de.teamlapen.vampirism.api.entity.player.vampire.IVampirePlayer; import de.teamlapen.vampirism.api.entity.vampire.IVampire; -import de.teamlapen.vampirism.api.event.ActionEvent; -import de.teamlapen.vampirism.api.event.BloodDrinkEvent; -import de.teamlapen.vampirism.api.event.PlayerFactionEvent; -import de.teamlapen.vampirism.api.event.VampirismVillageEvent; +import de.teamlapen.vampirism.api.event.*; import de.teamlapen.vampirism.api.world.ITotem; import net.minecraft.core.Holder; import net.minecraft.world.entity.Mob; @@ -87,24 +85,40 @@ public static boolean fireMakeAggressive(@NotNull ITotem totem, @NotNull Village @SuppressWarnings("unchecked") @NotNull - public static & ISkillPlayer> ActionEvent.ActionActivatedEvent fireActionActivatedEvent(@NotNull T factionPlayer, @NotNull Holder> action, int cooldown, int duration) { + public static > ActionEvent.ActionActivatedEvent fireActionActivatedEvent(@NotNull T factionPlayer, @NotNull Holder> action, int cooldown, int duration) { ActionEvent.ActionActivatedEvent event = new ActionEvent.ActionActivatedEvent<>(factionPlayer, (Holder>) action, cooldown, duration); NeoForge.EVENT_BUS.post(event); return event; } @SuppressWarnings("unchecked") - public static & ISkillPlayer> ActionEvent.ActionDeactivatedEvent fireActionDeactivatedEvent(@NotNull T factionPlayer, @NotNull Holder> action, int remainingDuration, int cooldown, boolean ignoreCooldown, boolean fullCooldown) { + public static > ActionEvent.ActionDeactivatedEvent fireActionDeactivatedEvent(@NotNull T factionPlayer, @NotNull Holder> action, int remainingDuration, int cooldown, boolean ignoreCooldown, boolean fullCooldown) { ActionEvent.ActionDeactivatedEvent event = new ActionEvent.ActionDeactivatedEvent<>(factionPlayer, (Holder>) action, remainingDuration, cooldown, ignoreCooldown, fullCooldown); NeoForge.EVENT_BUS.post(event); return event; } @SuppressWarnings("unchecked") - public static & ISkillPlayer> ActionEvent.ActionUpdateEvent fireActionUpdateEvent(@NotNull T factionPlayer, @NotNull Holder> action, int remainingDuration) { + public static > ActionEvent.ActionUpdateEvent fireActionUpdateEvent(@NotNull T factionPlayer, @NotNull Holder> action, int remainingDuration) { ActionEvent.ActionUpdateEvent event = new ActionEvent.ActionUpdateEvent<>(factionPlayer, (Holder>) action, remainingDuration); NeoForge.EVENT_BUS.post(event); return event; } + public static > ISkillHandler.Result fireSkillUnlockCheckEvent(@NotNull T factionPlayer, @NotNull Holder> skill) { + var event = new SkillEvents.SkillUnlockCheckEvent<>(factionPlayer, skill); + NeoForge.EVENT_BUS.post(event); + return event.getResult(); + } + + public static > void fireSkillDisabledEvent(@NotNull T factionPlayer, @NotNull Holder> skill) { + var event = new SkillEvents.SkillDisableEvent<>(factionPlayer, skill); + NeoForge.EVENT_BUS.post(event); + } + + public static > void fireSkillEnableEvent(@NotNull T factionPlayer, @NotNull Holder> skill, boolean fromLoading) { + var event = new SkillEvents.SkillEnableEvent<>(factionPlayer, skill, fromLoading); + NeoForge.EVENT_BUS.post(event); + } + } \ No newline at end of file