From 5498f5df1e3e32b3c5245fc9f3333383c2a62077 Mon Sep 17 00:00:00 2001 From: Sekwah Date: Sat, 14 Sep 2024 03:03:47 +0100 Subject: [PATCH] wip: altering hwo tags work to allow always triggers --- .../core/destination/Destination.java | 56 ++++++++--- .../core/portal/AdvancedPortal.java | 15 ++- .../core/registry/TagRegistry.java | 26 +++-- .../advancedportals/core/tags/DestiTag.java | 45 ++++++--- .../advancedportals/core/tags/MessageTag.java | 95 +++++++++++++++++++ .../advancedportals/core/util/Lang.java | 7 +- .../advancedportals/core/warphandler/Tag.java | 14 +-- lang/src/main/resources/lang/en_GB.lang | 3 +- 8 files changed, 211 insertions(+), 50 deletions(-) create mode 100644 core/src/main/java/com/sekwah/advancedportals/core/tags/MessageTag.java diff --git a/core/src/main/java/com/sekwah/advancedportals/core/destination/Destination.java b/core/src/main/java/com/sekwah/advancedportals/core/destination/Destination.java index c202cddc..46c4a6db 100644 --- a/core/src/main/java/com/sekwah/advancedportals/core/destination/Destination.java +++ b/core/src/main/java/com/sekwah/advancedportals/core/destination/Destination.java @@ -10,10 +10,7 @@ import com.sekwah.advancedportals.core.warphandler.Tag; import com.sekwah.advancedportals.core.warphandler.TriggerType; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.Map; -import java.util.Set; +import java.util.*; /** * Possibly look at adding the ability to add some tags to destinations such as @@ -33,8 +30,9 @@ public class Destination implements TagTarget { private PlayerLocation loc; private HashMap args = new HashMap<>(); + private transient List destiTags = new ArrayList<>(); - private transient Set argsCol; + private transient boolean isSorted = false; public Destination() { this.loc = new PlayerLocation(); @@ -51,26 +49,56 @@ public String[] getArgValues(String argName) { @Override public void setArgValues(String argName, String[] argValue) { + this.isSorted = false; this.args.put(argName, argValue); } @Override public void addArg(String argName, String argValues) { + this.isSorted = false; } public void setArgValues(DataTag portalTag) { + this.isSorted = false; this.setArgValues(portalTag.NAME, portalTag.VALUES); } public void removeArg(String arg) { + this.isSorted = false; this.args.remove(arg); } + private void updateDestiTagList() { + destiTags.clear(); + int i = 0; + for (Map.Entry entry : args.entrySet()) { + this.destiTags.add(new DataTag(entry.getKey(), entry.getValue())); + } + + this.tagRegistry.getAlwaysTriggerTags().forEach((key, value) -> { + if (value.getTagTypes().length == 0) { + this.destiTags.add(new DataTag(key)); + } + }); + + this.destiTags.sort(Comparator.comparingInt(o -> { + var tag = tagRegistry.getTag(o.NAME); + if (tag instanceof Tag.OrderPriority tagPriority) { + return tagPriority.getPriority().ordinal(); + } else { + return Tag.Priority.NORMAL.ordinal(); + } + })); + isSorted = true; + } + public boolean activate(PlayerContainer player) { ActivationData data = new ActivationData(TriggerType.MANUAL); - this.portalActivate(player, data); - this.postActivate(player, data); - return true; + if(this.portalActivate(player, data)) { + this.postActivate(player, data); + return true; + } + return false; } public boolean portalActivate(PlayerContainer player, ActivationData data) { @@ -81,15 +109,15 @@ public boolean portalActivate(PlayerContainer player, ActivationData data) { } for (DataTag destiTag : destiTags) { Tag.Activation activationHandler = - tagRegistry.getActivationHandler(destiTag.NAME); - if (activationHandler != null) { - activationHandler.preActivated( - this, player, data, this.getArgValues(destiTag.NAME)); + tagRegistry.getActivationHandler(destiTag.NAME, Tag.TagType.DESTINATION); + if (activationHandler != null && !activationHandler.preActivated( + this, player, data, this.getArgValues(destiTag.NAME))) { + return false; } } for (DataTag destiTag : destiTags) { Tag.Activation activationHandler = - tagRegistry.getActivationHandler(destiTag.NAME); + tagRegistry.getActivationHandler(destiTag.NAME, Tag.TagType.DESTINATION); if (activationHandler != null) { activationHandler.activated(this, player, data, this.getArgValues(destiTag.NAME)); @@ -106,7 +134,7 @@ public void postActivate(PlayerContainer player, ActivationData data) { } for (DataTag destiTag : destiTags) { Tag.Activation activationHandler = - tagRegistry.getActivationHandler(destiTag.NAME); + tagRegistry.getActivationHandler(destiTag.NAME, Tag.TagType.DESTINATION); if (activationHandler != null) { activationHandler.postActivated( this, player, data, this.getArgValues(destiTag.NAME)); diff --git a/core/src/main/java/com/sekwah/advancedportals/core/portal/AdvancedPortal.java b/core/src/main/java/com/sekwah/advancedportals/core/portal/AdvancedPortal.java index abf8b51e..79bdc7fc 100644 --- a/core/src/main/java/com/sekwah/advancedportals/core/portal/AdvancedPortal.java +++ b/core/src/main/java/com/sekwah/advancedportals/core/portal/AdvancedPortal.java @@ -83,6 +83,13 @@ private void updatePortalTagList() { for (Map.Entry entry : args.entrySet()) { this.portalTags.add(new DataTag(entry.getKey(), entry.getValue())); } + + this.tagRegistry.getAlwaysTriggerTags().forEach((key, value) -> { + if (value.getTagTypes().length == 0) { + this.portalTags.add(new DataTag(key)); + } + }); + // sort the tags by priority this.portalTags.sort(Comparator.comparingInt(o -> { var tag = tagRegistry.getTag(o.NAME); @@ -92,6 +99,7 @@ private void updatePortalTagList() { return Tag.Priority.NORMAL.ordinal(); } })); + isSorted = true; } @Override @@ -138,7 +146,6 @@ public void updateBounds(BlockLocation loc1, BlockLocation loc2) { public ActivationResult activate(PlayerContainer player, TriggerType triggerType) { if(!isSorted) { updatePortalTagList(); - isSorted = true; } var playerData = playerDataServices.getPlayerData(player); @@ -162,7 +169,7 @@ public ActivationResult activate(PlayerContainer player, TriggerType triggerType for (DataTag portalTag : this.portalTags) { Tag.Activation activationHandler = - tagRegistry.getActivationHandler(portalTag.NAME); + tagRegistry.getActivationHandler(portalTag.NAME, Tag.TagType.PORTAL); if (activationHandler != null) { var preActivated = activationHandler.preActivated( this, player, data, this.getArgValues(portalTag.NAME)); @@ -177,7 +184,7 @@ public ActivationResult activate(PlayerContainer player, TriggerType triggerType } for (DataTag portalTag : this.portalTags) { Tag.Activation activationHandler = - tagRegistry.getActivationHandler(portalTag.NAME); + tagRegistry.getActivationHandler(portalTag.NAME, Tag.TagType.PORTAL); if (activationHandler != null && !activationHandler.activated( this, player, data, this.getArgValues(portalTag.NAME))) { @@ -186,7 +193,7 @@ public ActivationResult activate(PlayerContainer player, TriggerType triggerType } for (DataTag portalTag : this.portalTags) { Tag.Activation activationHandler = - tagRegistry.getActivationHandler(portalTag.NAME); + tagRegistry.getActivationHandler(portalTag.NAME, Tag.TagType.PORTAL); if (activationHandler != null) { activationHandler.postActivated( this, player, data, this.getArgValues(portalTag.NAME)); diff --git a/core/src/main/java/com/sekwah/advancedportals/core/registry/TagRegistry.java b/core/src/main/java/com/sekwah/advancedportals/core/registry/TagRegistry.java index 9bcdf976..548d8c66 100644 --- a/core/src/main/java/com/sekwah/advancedportals/core/registry/TagRegistry.java +++ b/core/src/main/java/com/sekwah/advancedportals/core/registry/TagRegistry.java @@ -19,6 +19,8 @@ public class TagRegistry { private final ArrayList tags = new ArrayList<>(); + private final Map tagMap = new HashMap<>(); + private final Map alwaysTriggerTags = new HashMap<>(); private final Map activationTags = new HashMap<>(); private final Map creationTags = new HashMap<>(); private final Map statusTags = new HashMap<>(); @@ -32,8 +34,12 @@ public class TagRegistry { * @param arg * @return */ - public Tag.Activation getActivationHandler(String arg) { - return this.activationTags.get(arg); + public Tag.Activation getActivationHandler(String arg, Tag.TagType targetType) { + var tag = this.activationTags.get(arg); + if (tag != null && Arrays.asList(tag.getTagTypes()).contains(targetType)) { + return tag; + } + return null; } /** @@ -54,6 +60,10 @@ public Tag.TagStatus getStatusHandler(String arg) { return this.statusTags.get(arg); } + public Map getAlwaysTriggerTags() { + return this.alwaysTriggerTags; + } + /** * File must extend * @return if the tag has been registered or if it already exists. @@ -91,8 +101,13 @@ public boolean registerTag(Tag tag) { return false; } + this.tagMap.put(tagName, tag); + if (tag instanceof Tag.Activation tagActivation) { this.activationTags.put(tagName, tagActivation); + if(tagActivation.triggerWithNoArgs()) { + this.alwaysTriggerTags.put(tagName, tagActivation); + } } if (tag instanceof Tag.TagStatus tagStatus) { this.statusTags.put(tagName, tagStatus); @@ -104,12 +119,7 @@ public boolean registerTag(Tag tag) { } public Tag getTag(String tagName) { - for (Tag tag : this.tags) { - if (tag.getName().equals(tagName)) { - return tag; - } - } - return null; + return this.tagMap.get(tagName); } public List getTags() { diff --git a/core/src/main/java/com/sekwah/advancedportals/core/tags/DestiTag.java b/core/src/main/java/com/sekwah/advancedportals/core/tags/DestiTag.java index 597b8c16..8c38cef5 100644 --- a/core/src/main/java/com/sekwah/advancedportals/core/tags/DestiTag.java +++ b/core/src/main/java/com/sekwah/advancedportals/core/tags/DestiTag.java @@ -4,6 +4,7 @@ import com.sekwah.advancedportals.core.connector.containers.PlayerContainer; import com.sekwah.advancedportals.core.destination.Destination; import com.sekwah.advancedportals.core.effect.WarpEffect; +import com.sekwah.advancedportals.core.registry.TagRegistry; import com.sekwah.advancedportals.core.registry.TagTarget; import com.sekwah.advancedportals.core.registry.WarpEffectRegistry; import com.sekwah.advancedportals.core.repository.ConfigRepository; @@ -13,7 +14,9 @@ import com.sekwah.advancedportals.core.warphandler.Tag; import javax.annotation.Nullable; +import java.util.Arrays; import java.util.List; +import java.util.Random; public class DestiTag implements Tag.Activation, Tag.AutoComplete, Tag.Split { public static String TAG_NAME = "destination"; @@ -24,7 +27,7 @@ public class DestiTag implements Tag.Activation, Tag.AutoComplete, Tag.Split { WarpEffectRegistry warpEffectRegistry; @Inject - ConfigRepository configRepository; + private transient TagRegistry tagRegistry; private final TagType[] tagTypes = new TagType[] {TagType.PORTAL}; @@ -38,6 +41,8 @@ public String getName() { return TAG_NAME; } + private final Random random = new Random(); + @Override public String[] getAliases() { return new String[] {"desti"}; @@ -54,30 +59,54 @@ public boolean preActivated(TagTarget target, PlayerContainer player, if (argData.length == 0) { return false; } - - String selectedArg = argData[new java.util.Random().nextInt(argData.length)]; + String selectedArg = argData[random.nextInt(argData.length)]; activeData.setMetadata(TAG_NAME, selectedArg); - if(destinationServices.getDestination(selectedArg) == null) { player.sendMessage(Lang.getNegativePrefix() + Lang.translateInsertVariables("desti.error.notfound", selectedArg)); return false; } + // Check and trigger all tags on the destination + Destination destination = destinationServices.getDestination(selectedArg); + if (destination != null) { + + for (var destiTag : destination.getArgs()) { + Tag.Activation activationHandler = + tagRegistry.getActivationHandler(destiTag.NAME, Tag.TagType.DESTINATION); + if (activationHandler != null + && !activationHandler.preActivated(target, player, activeData, argData)) { + return false; + } + } + } + return true; } @Override public void postActivated(TagTarget target, PlayerContainer player, ActivationData activationData, String[] argData) { + var selectedArg = activationData.getMetadata(TAG_NAME); + Destination destination = destinationServices.getDestination(selectedArg); + if (destination != null) { + for (var destiTag : destination.getArgs()) { + Tag.Activation activationHandler = + tagRegistry.getActivationHandler(destiTag.NAME, Tag.TagType.DESTINATION); + if (activationHandler != null) { + activationHandler.postActivated(target, player, activationData, argData); + } + } + } } @Override public boolean activated(TagTarget target, PlayerContainer player, ActivationData activationData, String[] argData) { + var selectedArg = activationData.getMetadata(TAG_NAME); Destination destination = - destinationServices.getDestination(argData[0]); + destinationServices.getDestination(selectedArg); if (destination != null) { var warpEffectVisual = warpEffectRegistry.getVisualEffect("ender"); if (warpEffectVisual != null) { @@ -95,12 +124,6 @@ public boolean activated(TagTarget target, PlayerContainer player, warpEffectSound.onWarpSound(player, WarpEffect.Action.EXIT); } activationData.setWarpStatus(ActivationData.WarpedStatus.WARPED); - if(this.configRepository.warpMessageOnActionBar()) { - player.sendMessage(Lang.translateInsertVariables("desti.warp", destination.getName())); - } - else if(this.configRepository.warpMessageInChat()) { - player.sendMessage(Lang.getPositivePrefix() + Lang.translateInsertVariables("desti.warp", destination.getName())); - } } return true; } diff --git a/core/src/main/java/com/sekwah/advancedportals/core/tags/MessageTag.java b/core/src/main/java/com/sekwah/advancedportals/core/tags/MessageTag.java new file mode 100644 index 00000000..27f96d60 --- /dev/null +++ b/core/src/main/java/com/sekwah/advancedportals/core/tags/MessageTag.java @@ -0,0 +1,95 @@ +package com.sekwah.advancedportals.core.tags; + +import com.google.inject.Inject; +import com.sekwah.advancedportals.core.connector.containers.PlayerContainer; +import com.sekwah.advancedportals.core.registry.TagTarget; +import com.sekwah.advancedportals.core.repository.ConfigRepository; +import com.sekwah.advancedportals.core.util.Lang; +import com.sekwah.advancedportals.core.warphandler.ActivationData; +import com.sekwah.advancedportals.core.warphandler.Tag; + +import javax.annotation.Nullable; +import java.util.List; +import java.util.Random; + +/** + * The name of the destination or portal. + * + *

Most of the implementation of this tag is external, this is just to allow + * for the tag to be used. + * + *

Most tags shouldn't be like this unless they are to be paired with + * another tag. + */ +public class MessageTag implements Tag.Activation { + + @Inject + ConfigRepository configRepository; + + public static String TAG_NAME = "message"; + + private final TagType[] tagTypes = + new TagType[] {TagType.PORTAL, TagType.DESTINATION}; + + private final Random random = new Random(); + + @Override + public TagType[] getTagTypes() { + return tagTypes; + } + + @Override + public boolean triggerWithNoArgs() { + return true; + } + + @Override + public String getName() { + return TAG_NAME; + } + + @Override + public String[] getAliases() { + return null; + } + + @Override + public String description() { + return Lang.translate("tag.message.description"); + } + + @Override + public boolean preActivated(TagTarget target, PlayerContainer player, ActivationData activeData, String[] argData) { + return false; + } + + @Override + public void postActivated(TagTarget target, PlayerContainer player, ActivationData activationData, String[] argData) { + if(argData.length != 0) { + String selectedArg = argData[random.nextInt(argData.length)]; + + sendMessage(player, selectedArg); + } + + var destination = activationData.getMetadata(DestiTag.TAG_NAME); + if (destination == null) { + return; + } + + player.sendMessage(Lang.getNegativePrefix() + Lang.translateInsertVariables("desti.warp", destination.replaceAll("_", " "))); + } + + @Override + public boolean activated(TagTarget target, PlayerContainer player, ActivationData activationData, String[] argData) { + return true; + } + + public void sendMessage(PlayerContainer player, String message) { + if(this.configRepository.warpMessageOnActionBar()) { + player.sendMessage(Lang.convertColors(message)); + } + else if(this.configRepository.warpMessageInChat()) { + player.sendMessage(Lang.getPositivePrefix() + " " + Lang.convertColors(message)); + } + } +} diff --git a/core/src/main/java/com/sekwah/advancedportals/core/util/Lang.java b/core/src/main/java/com/sekwah/advancedportals/core/util/Lang.java index 96368f45..e115e443 100644 --- a/core/src/main/java/com/sekwah/advancedportals/core/util/Lang.java +++ b/core/src/main/java/com/sekwah/advancedportals/core/util/Lang.java @@ -56,14 +56,17 @@ public static String translate(String s) { String translation = instance.languageMap.get(s); // noinspection ALL (not sure what the specific warning is for // escaped unicode) - translation = - translation.replaceAll("&([0-9a-frk-ox])", "\u00A7$1"); + translation = convertColors(translation); return translation; } else { return s; } } + public static String convertColors(String s) { + return s.replaceAll("&([0-9a-frk-ox])", "\u00A7$1"); + } + public static String translateInsertVariables(String s, Object... args) { String translation = translate(s); for (int i = 1; i <= args.length; i++) { diff --git a/core/src/main/java/com/sekwah/advancedportals/core/warphandler/Tag.java b/core/src/main/java/com/sekwah/advancedportals/core/warphandler/Tag.java index 722dc3ef..37918a90 100644 --- a/core/src/main/java/com/sekwah/advancedportals/core/warphandler/Tag.java +++ b/core/src/main/java/com/sekwah/advancedportals/core/warphandler/Tag.java @@ -55,16 +55,6 @@ enum Behaviour { SILENT, KNOCKBACK } Behaviour getDenyBehavior(); } - /** - * Used to flag if the tag should always trigger even if the tag is not - * present. Example the default message behavior being overwritten by adding a tag. - *

- * This should be avoided where possible as it will also affect all existing portals. - */ - interface AlwaysTrigger extends Tag { - - } - interface AutoComplete extends Tag { /** * This is used to get the auto complete for the tag. This is called @@ -139,6 +129,10 @@ interface Activation extends Tag { boolean preActivated(TagTarget target, PlayerContainer player, ActivationData activeData, String[] argData); + default boolean triggerWithNoArgs() { + return false; + } + /** * Activates after activation, should be used for actions such as * removing money for a teleport. diff --git a/lang/src/main/resources/lang/en_GB.lang b/lang/src/main/resources/lang/en_GB.lang index d4383023..32647bb9 100644 --- a/lang/src/main/resources/lang/en_GB.lang +++ b/lang/src/main/resources/lang/en_GB.lang @@ -151,7 +151,7 @@ desti.error.save= There was a problem saving the destination. desti.error.noname= You must specify a name. (name:someNameHere) desti.error.notfound= No destination by the name &e%1$s &cwas found. -desti.warp= &aYou have warped to &e%1$s&a. +desti.warpdesti.warp= &aYou have warped to &e%1$s&a. error.notplayer=Only players can do that. @@ -179,6 +179,7 @@ tag.name.error.nospaces= The name cannot contain spaces. tag.triggerblock.description=Sets the trigger block/s of the portal. Comma separated or multi tag. tag.command.description=Sets a command on the post activation of the portal. Comma separated or multi tag. tag.portalEvent.description=Triggers the portal from portal events rather than the player entering the portal. (survival nether portal) +tag.message.description=Sets the message to be displayed when the portal is activated tag.cooldown.fail= The cooldown must be a number. tag.command.nopermission= You do not have permission to create a command at %1$s command level