diff --git a/src/main/java/emu/grasscutter/game/ability/actions/AbilityActionHandler.java b/src/main/java/emu/grasscutter/game/ability/actions/AbilityActionHandler.java index 49e08f60e..d75235011 100644 --- a/src/main/java/emu/grasscutter/game/ability/actions/AbilityActionHandler.java +++ b/src/main/java/emu/grasscutter/game/ability/actions/AbilityActionHandler.java @@ -6,7 +6,29 @@ import emu.grasscutter.game.ability.Ability; import emu.grasscutter.game.entity.GameEntity; public abstract class AbilityActionHandler { - public abstract boolean execute( Ability ability, AbilityModifierAction action, ByteString abilityData, GameEntity target); + + /** + * Returns the target entity. + * + * @param ability The ability being invoked. + * @param entity The entity invoking the ability. + * @param target The target entity type. + * @return The target entity. + */ + protected GameEntity getTarget(Ability ability, GameEntity entity, String target) { + return switch (target) { + default -> throw new RuntimeException("Unknown target type: " + target); + case "Self" -> entity; + case "Team" -> ability.getPlayerOwner().getTeamManager().getEntity(); + case "OriginOwner" -> ability.getPlayerOwner() + .getTeamManager().getCurrentAvatarEntity(); + case "Owner" -> ability.getOwner(); + case "Applier" -> entity; // TODO: Validate. + case "CurLocalAvatar" -> ability.getPlayerOwner() + .getTeamManager().getCurrentAvatarEntity(); // TODO: Validate. + case "CasterOriginOwner" -> null; // TODO: Figure out. + }; + } } diff --git a/src/main/java/emu/grasscutter/game/ability/actions/ActionCopyGlobalValue.java b/src/main/java/emu/grasscutter/game/ability/actions/ActionCopyGlobalValue.java new file mode 100644 index 000000000..b480a6edc --- /dev/null +++ b/src/main/java/emu/grasscutter/game/ability/actions/ActionCopyGlobalValue.java @@ -0,0 +1,33 @@ +package emu.grasscutter.game.ability.actions; + +import com.google.protobuf.ByteString; +import emu.grasscutter.Grasscutter; +import emu.grasscutter.data.binout.AbilityModifier.AbilityModifierAction; +import emu.grasscutter.game.ability.Ability; +import emu.grasscutter.game.entity.GameEntity; + +@AbilityAction(AbilityModifierAction.Type.CopyGlobalValue) +public final class ActionCopyGlobalValue extends AbilityActionHandler { + @Override + public boolean execute(Ability ability, AbilityModifierAction action, ByteString abilityData, GameEntity entity) { + // Get the entities referred to. + var source = this.getTarget(ability, entity, action.srcTarget); + var destination = this.getTarget(ability, entity, action.dstTarget); + // Check the entities. + if (source == null || destination == null) { + Grasscutter.getLogger().debug("ActionCopyGlobalValue: source or destination is null"); + return false; + } + + // Get the global value. + var value = source.getGlobalAbilityValues().get(action.srcKey); + if (value == null) { + Grasscutter.getLogger().debug("ActionCopyGlobalValue: source value is null"); + return false; + } + + // Apply the new global value. + destination.getGlobalAbilityValues().put(action.dstKey, value); + return true; + } +}