Skip to content

Commit

Permalink
introduce action use result with customizable message
Browse files Browse the repository at this point in the history
  • Loading branch information
Cheaterpaul committed Jul 6, 2024
1 parent efec77a commit 3ee3f44
Show file tree
Hide file tree
Showing 27 changed files with 230 additions and 123 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -28,19 +28,19 @@ public void addEffectInstance(@NotNull T player, @NotNull MobEffectInstance inst
/**
* Can be overridden to check additional requirements
*/
public boolean canBeUsedBy(T player) {
return true;
public IActionResult canBeUsedBy(T player) {
return IActionResult.SUCCESS;
}

@Override
public final IAction.@NotNull PERM canUse(@NotNull T player) {
public final @NotNull IActionResult canUse(@NotNull T player) {
if (!isEnabled()) {
return IAction.PERM.DISABLED;
return IActionResult.DISABLED_CONFIG;
}
if (IFaction.is(player.getFaction(), this.factions())) {
return (canBeUsedBy(player) ? IAction.PERM.ALLOWED : IAction.PERM.DISALLOWED);
return canBeUsedBy(player);
} else {
throw new IllegalArgumentException("Faction player is not allowed to use action");
return IActionResult.DISALLOWED_FACTION;
}

}
Expand All @@ -60,7 +60,7 @@ public boolean canBeUsedBy(T player) {
public abstract boolean isEnabled();

@Override
public boolean onActivated(@NotNull T player, ActivationContext context) {
public IActionResult onActivated(@NotNull T player, ActivationContext context) {
if (IFaction.is(player.getFaction(), this.factions())) {
return activate(player, context);
} else {
Expand Down Expand Up @@ -97,7 +97,7 @@ public ISkill<T> asSkill() {
*
* @return Whether the action was successfully activated. !Does not give any feedback to the user!
*/
protected abstract boolean activate(T player, ActivationContext context);
protected abstract IActionResult activate(T player, ActivationContext context);

private @Nullable ResourceLocation getRegistryName() {
return VampirismRegistries.ACTION.get().getKey(this);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ public interface IAction<T extends ISkillPlayer<T>> extends ISkillLike<T> {
*
* @param player Must be an instance of class that belongs to {@link IAction#getFaction()}
*/
PERM canUse(T player);
IActionResult canUse(T player);


/**
Expand Down Expand Up @@ -55,11 +55,11 @@ default MutableComponent getName() {
/**
* Called when the action is activated. Only called server side
*
* @param player Must be instance of class that belongs to {@link IAction#getFaction()}
* @param player Must be instance of class that belongs to {@link de.teamlapen.vampirism.api.entity.player.actions.IAction#factions()}
* @param context Holds Block/Entity the player was looking at when activating if any
* @return Whether the action was successfully activated. !Does not give any feedback to the user!
*/
boolean onActivated(T player, ActivationContext context);
IActionResult onActivated(T player, ActivationContext context);

/**
* @return if the action should be shown in the action select screen
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -150,11 +150,6 @@ default void resetTimer(@NotNull IAction<T> action) {

void resetTimer(@NotNull Holder<? extends IAction<T>> action);

@Deprecated(forRemoval = true, since = "1.11")
default IAction.PERM toggleAction(IAction<T> action, IAction.ActivationContext context) {
return toggleAction(RegUtil.holder(action), context);
}

/**
* Toggle the action (server side).
* If you just want to make sure it is deactivated, call {@link #deactivateAction(ILastingAction)}
Expand All @@ -163,7 +158,7 @@ default IAction.PERM toggleAction(IAction<T> action, IAction.ActivationContext c
* @param context Context holding Block/Entity the player was looking at when activating if any
* @return result
*/
IAction.PERM toggleAction(Holder<? extends IAction<T>> action, IAction.ActivationContext context);
IActionResult toggleAction(Holder<? extends IAction<T>> action, IAction.ActivationContext context);

@Deprecated(forRemoval = true, since = "1.11")
default void deactivateAction(ILastingAction<T> action) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
package de.teamlapen.vampirism.api.entity.player.actions;

import de.teamlapen.vampirism.api.entity.player.ISkillPlayer;
import net.minecraft.Util;
import net.minecraft.core.Holder;
import net.minecraft.network.chat.Component;
import net.minecraft.resources.ResourceKey;

public interface IActionResult {

IActionResult SUCCESS = new Custom(true, Component.empty());
IActionResult ON_COOLDOWN = new Custom(false, Component.translatable("text.vampirism.action.cooldown_not_over"));
IActionResult RESTRICTED = new Custom(false, Component.translatable("text.vampirism.action.restricted"));
IActionResult NOT_UNLOCKED = new Custom(false, Component.translatable("text.vampirism.action.not_unlocked"));
IActionResult DISALLOWED_PERMISSION = new Custom(false, Component.translatable("text.vampirism.action.permission_disallowed"), false);
IActionResult DISABLED_CONFIG = new Custom(false, Component.translatable("text.vampirism.action.deactivated_by_serveradmin"), false);
IActionResult DISALLOWED_FACTION = new Custom(false, Component.translatable("text.vampirism.action.invalid_faction"), false);


boolean successful();

Component message();

boolean sendToStatusBar();

record Custom(boolean successful, Component message, boolean sendToStatusBar) implements IActionResult {

Custom(boolean successful, Component message) {
this(successful, message, true);
}
}

static IActionResult disallowed(Component message) {
return new Custom(false, message);
}

static <T extends ISkillPlayer<T>> IActionResult otherAction(IActionHandler<T> handler, Holder<? extends ILastingAction<T>> otherAction) {
return handler.isActionActive(otherAction) ? new Custom(false, Component.translatable("text.vampirism.action.other_action", Component.translatable(Util.makeDescriptionId("action", otherAction.unwrapKey().map(ResourceKey::location).orElseThrow())))) : SUCCESS;
}
}
18 changes: 18 additions & 0 deletions src/api/java/de/teamlapen/vampirism/api/event/ActionEvent.java
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
import de.teamlapen.vampirism.api.entity.player.actions.ILastingAction;
import de.teamlapen.vampirism.api.util.RegUtil;
import net.minecraft.core.Holder;
import net.minecraft.network.chat.Component;
import net.neoforged.bus.api.Event;
import net.neoforged.bus.api.ICancellableEvent;
import org.jetbrains.annotations.ApiStatus;
Expand Down Expand Up @@ -61,6 +62,8 @@ public static class ActionActivatedEvent<T extends IFactionPlayer<T> & ISkillPla

private int cooldown;
private int duration;
@NotNull
private Component cancelMessage = Component.translatable("text.vampirism.action.cancelled");

@ApiStatus.Internal
public ActionActivatedEvent(@NotNull T factionPlayer, @NotNull Holder<IAction<T>> action, int cooldown, int duration) {
Expand Down Expand Up @@ -101,6 +104,21 @@ public int getDuration() {
public void setDuration(int duration) {
this.duration = duration;
}

/**
* @return The message that is shown to the player if the event is cancelled
*/
@NotNull
public Component getCancelMessage() {
return cancelMessage;
}

/**
* sets the message that is shown to the player if the event is cancelled
* */
public void setCancelMessage(@NotNull Component message) {
this.cancelMessage = message;
}
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ public void drawSlice(IRadialMenuSlot<Holder<IAction<?>>> slot, boolean highligh
@SuppressWarnings("unchecked")
Holder<IAction<T>> iActionHolder = (Holder<IAction<T>>) (Object) slot.primarySlotIcon();
float actionPercentage = actionHandler.getPercentageForAction(iActionHolder);
if (iActionHolder.value().canUse(this.player) != IAction.PERM.ALLOWED) {
if (!iActionHolder.value().canUse(this.player).successful()) {
actionPercentage = -1;
}
if (actionPercentage == 0) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
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.IActionHandler;
import de.teamlapen.vampirism.api.entity.player.actions.IActionResult;
import de.teamlapen.vampirism.api.entity.player.actions.ILastingAction;
import de.teamlapen.vampirism.api.event.ActionEvent;
import de.teamlapen.vampirism.core.ModRegistries;
Expand Down Expand Up @@ -111,7 +112,7 @@ public void extendActionTimer(@NotNull Holder<? extends ILastingAction<T>> actio

@Override
public @NotNull List<Holder<? extends IAction<T>>> getAvailableActionsHolder() {
return this.unlockedActions.stream().filter(s -> s.value().canUse(this.player) == IAction.PERM.ALLOWED).toList();
return this.unlockedActions.stream().filter(s -> s.value().canUse(this.player).successful()).toList();
}

@Override
Expand Down Expand Up @@ -309,27 +310,28 @@ public void resetTimer(@NotNull Holder<? extends IAction<T>> action) {
* @param context Context holding Block/Entity the player was looking at when activating if any
*/
@Override
public IAction.@NotNull PERM toggleAction(@NotNull Holder<? extends IAction<T>> action, IAction.@NotNull ActivationContext context) {
public @NotNull IActionResult toggleAction(@NotNull Holder<? extends IAction<T>> action, IAction.@NotNull ActivationContext context) {
if (activeTimers.containsKey(action)) {
deactivateAction((Holder<ILastingAction<T>>) action);
dirty = true;
return IAction.PERM.ALLOWED;
return IActionResult.SUCCESS;
} else if (cooldownTimers.containsKey(action)) {
return IAction.PERM.COOLDOWN;
return IActionResult.ON_COOLDOWN;
} else {
if (this.player.asEntity().isSpectator()) return IAction.PERM.DISALLOWED;
if (!isActionUnlocked(action)) return IAction.PERM.NOT_UNLOCKED;
if (!isActionAllowedPermission(action)) return IAction.PERM.PERMISSION_DISALLOWED;
if (this.player.asEntity().isSpectator()) return IActionResult.RESTRICTED;
if (!isActionUnlocked(action)) return IActionResult.NOT_UNLOCKED;
if (!isActionAllowedPermission(action)) return IActionResult.DISALLOWED_PERMISSION;

IAction.PERM r = action.value().canUse(player);
if (r == IAction.PERM.ALLOWED) {
IActionResult r = action.value().canUse(player);
if (r.successful()) {
/*
* Only lasting actions have a duration, so regular actions will return a duration of -1.
*/
int duration = action.value() instanceof ILastingAction<T> lasting ? lasting.getDuration(player) : -1;
ActionEvent.ActionActivatedEvent<T> activationEvent = VampirismEventFactory.fireActionActivatedEvent(player, action, action.value().getCooldown(player), duration);
if (activationEvent.isCanceled()) return IAction.PERM.DISALLOWED;
if (action.value().onActivated(player, context)) {
if (activationEvent.isCanceled()) return IActionResult.disallowed(activationEvent.getCancelMessage());
r = action.value().onActivated(player, context);
if (r.successful()) {
player.asEntity().awardStat(ModStats.ACTION_USED.get().get(action.value()));
//Even though lasting actions do not activate their cooldown until they deactivate
//we probably want to keep this here so that they are edited by one event.
Expand All @@ -345,10 +347,8 @@ public void resetTimer(@NotNull Holder<? extends IAction<T>> action) {
}
dirty = true;
}
return IAction.PERM.ALLOWED;
} else {
return r;
}
return r;
}
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,17 +1,14 @@
package de.teamlapen.vampirism.entity.player.hunter.actions;

import de.teamlapen.vampirism.api.VReference;
import de.teamlapen.vampirism.api.VampirismAPI;
import de.teamlapen.vampirism.api.entity.player.actions.IActionResult;
import de.teamlapen.vampirism.api.entity.player.actions.ILastingAction;
import de.teamlapen.vampirism.api.entity.player.hunter.DefaultHunterAction;
import de.teamlapen.vampirism.api.entity.player.hunter.IHunterPlayer;
import de.teamlapen.vampirism.config.VampirismConfig;
import de.teamlapen.vampirism.core.ModFactions;
import de.teamlapen.vampirism.entity.player.hunter.HunterPlayer;
import net.minecraft.world.entity.LivingEntity;
import net.minecraft.world.entity.ai.targeting.TargetingConditions;
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.phys.AABB;
import org.jetbrains.annotations.NotNull;

public class AwarenessHunterAction extends DefaultHunterAction implements ILastingAction<IHunterPlayer> {
Expand All @@ -23,8 +20,8 @@ public AwarenessHunterAction() {
}

@Override
public boolean canBeUsedBy(@NotNull IHunterPlayer player) {
return !player.getActionHandler().isActionActive(HunterActions.DISGUISE_HUNTER);
public @NotNull IActionResult canBeUsedBy(@NotNull IHunterPlayer player) {
return IActionResult.otherAction(player.getActionHandler(), HunterActions.DISGUISE_HUNTER);
}

@Override
Expand Down Expand Up @@ -62,8 +59,8 @@ public boolean onUpdate(@NotNull IHunterPlayer player) {
}

@Override
protected boolean activate(IHunterPlayer player, ActivationContext context) {
return true;
protected IActionResult activate(IHunterPlayer player, ActivationContext context) {
return IActionResult.SUCCESS;
}

@Override
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package de.teamlapen.vampirism.entity.player.hunter.actions;

import de.teamlapen.vampirism.api.entity.player.actions.IActionResult;
import de.teamlapen.vampirism.api.entity.player.actions.ILastingAction;
import de.teamlapen.vampirism.api.entity.player.hunter.DefaultHunterAction;
import de.teamlapen.vampirism.api.entity.player.hunter.IHunterPlayer;
Expand All @@ -19,14 +20,14 @@ public DisguiseHunterAction() {
}

@Override
public boolean activate(@NotNull IHunterPlayer player, ActivationContext context) {
public IActionResult activate(@NotNull IHunterPlayer player, ActivationContext context) {
((HunterPlayer) player).getSpecialAttributes().activateDisguise();
return true;
return IActionResult.SUCCESS;
}

@Override
public boolean canBeUsedBy(@NotNull IHunterPlayer player) {
return !player.getActionHandler().isActionActive(HunterActions.AWARENESS_HUNTER);
public IActionResult canBeUsedBy(@NotNull IHunterPlayer player) {
return IActionResult.otherAction(player.getActionHandler(), HunterActions.AWARENESS_HUNTER);
}

@Override
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package de.teamlapen.vampirism.entity.player.hunter.actions;

import de.teamlapen.vampirism.api.entity.player.actions.IActionResult;
import de.teamlapen.vampirism.api.entity.player.actions.ILastingAction;
import de.teamlapen.vampirism.api.entity.player.hunter.DefaultHunterAction;
import de.teamlapen.vampirism.api.entity.player.hunter.IHunterPlayer;
Expand Down Expand Up @@ -59,9 +60,9 @@ public boolean onUpdate(@NotNull IHunterPlayer player) {
}

@Override
protected boolean activate(@NotNull IHunterPlayer player, ActivationContext context) {
protected IActionResult activate(@NotNull IHunterPlayer player, ActivationContext context) {
onUpdate(player);
return true;
return IActionResult.SUCCESS;
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,11 @@
import de.teamlapen.vampirism.api.entity.player.IFactionPlayer;
import de.teamlapen.vampirism.api.entity.player.ISkillPlayer;
import de.teamlapen.vampirism.api.entity.player.actions.DefaultAction;
import de.teamlapen.vampirism.api.entity.player.actions.IActionResult;
import de.teamlapen.vampirism.entity.factions.FactionPlayerHandler;
import de.teamlapen.vampirism.entity.player.IVampirismPlayer;
import net.minecraft.core.Holder;
import net.minecraft.network.chat.Component;
import net.minecraft.tags.TagKey;
import net.minecraft.world.effect.MobEffect;
import net.minecraft.world.effect.MobEffectInstance;
Expand All @@ -28,7 +30,7 @@ public LordRangeEffectAction(Holder<MobEffect> effect) {
}

@Override
protected boolean activate(@NotNull T player, ActivationContext context) {
protected IActionResult activate(@NotNull T player, ActivationContext context) {
int lordLevel = FactionPlayerHandler.get(player.asEntity()).getLordLevel();
List<LivingEntity> entitiesOfClass = player.asEntity().level().getEntitiesOfClass(LivingEntity.class, new AABB(player.asEntity().blockPosition()).inflate(10, 10, 10), e -> IFaction.is(player.getFaction(), VampirismAPI.factionRegistry().getFaction(e)));
for (LivingEntity entity : entitiesOfClass) {
Expand All @@ -37,7 +39,11 @@ protected boolean activate(@NotNull T player, ActivationContext context) {
}
entity.addEffect(new MobEffectInstance(effect, getEffectDuration(player), getEffectAmplifier(player)));
}
return !entitiesOfClass.isEmpty();
if (entitiesOfClass.isEmpty()) {
return IActionResult.disallowed(Component.translatable("text.vampirism.action.lord_range.no_target"));
} else {
return IActionResult.SUCCESS;
}
}

protected abstract int getEffectDuration(T player);
Expand Down
Loading

0 comments on commit 3ee3f44

Please sign in to comment.